/* * HISTORY.C - command line history. * * * * Comments: * * 14/01/95 (Tim Norman) --------------------------------------------------- * started. * * 08/08/95 (Matt Rains) --------------------------------------------------- * i have cleaned up the source code. changes now bring this source into * guidelines for recommended programming practice. */ #include #include #include #define MAXLINES 128 unsigned history_size = 256; /* make this configurable later */ void history(int dir, char *commandline) { static char *history = NULL; static char *lines[MAXLINES]; static unsigned int curline = 0; static unsigned int numlines = 0; static unsigned int maxpos = 0; int count; int length; if(!history) { history = malloc(history_size * sizeof(char)); lines[0] = history; history[0] = 0; } if(dir > 0) /* next command */ { if(curline < numlines) { curline++; } if(curline == numlines) { commandline[0] = 0; } else { strcpy(commandline, lines[curline]); } } else if(dir < 0) /* prev command */ { if(curline > 0) { curline--; } strcpy(commandline, lines[curline]); } else /* add to history */ { /* remove oldest string until there's enough room for next one */ /* strlen (commandline) must be less than history_size! */ while(maxpos + strlen (commandline) + 1 > history_size || numlines >= MAXLINES) { length = strlen(lines[0]) + 1; for(count = 0; count < maxpos && count + (lines[1] - lines[0]) < history_size; count++) { history[count] = history[count + length]; } maxpos -= length; for(count = 0; count <= numlines && count < MAXLINES; count++) { lines[count] = lines[count + 1] - length; } numlines--; #ifdef DEBUG printf("Reduced size: %ld lines\n", numlines); for(count = 0; count < numlines; count++) { printf("%d: %s\n", count, lines[count]); } #endif } strcpy(lines[numlines], commandline); numlines++; lines[numlines] = lines[numlines - 1] + strlen (commandline) + 1; maxpos += strlen(commandline) + 1; curline = numlines; /* last line, empty */ } return; }