void db_delete(int n, int bwd) { char *p; if (bwd) { db_lc -= n; db_putnchars(BACKUP, n); } for (p = db_lc; p < db_le-n; p++) { *p = *(p+n); cnputc(*p); } db_putnchars(BLANK, n); db_putnchars(BACKUP, db_le - db_lc); db_le -= n; }
/* returns TRUE at end-of-line */ int db_inputchar(int c) { static int escstate; if (escstate == 1) { /* ESC seen, look for [ or O */ if (c == '[' || c == 'O') escstate++; else escstate = 0; /* re-init state machine */ return (0); } else if (escstate == 2) { escstate = 0; /* * If a valid cursor key has been found, translate * into an emacs-style control key, and fall through. * Otherwise, drop off. */ switch (c) { case 'A': /* up */ c = CTRL('p'); break; case 'B': /* down */ c = CTRL('n'); break; case 'C': /* right */ c = CTRL('f'); break; case 'D': /* left */ c = CTRL('b'); break; default: return (0); } } switch (c) { case CTRL('['): escstate = 1; break; case CTRL('b'): /* back up one character */ if (db_lc > db_lbuf_start) { cnputc(BACKUP); db_lc--; } break; case CTRL('f'): /* forward one character */ if (db_lc < db_le) { cnputc(*db_lc); db_lc++; } break; case CTRL('a'): /* beginning of line */ while (db_lc > db_lbuf_start) { cnputc(BACKUP); db_lc--; } break; case CTRL('e'): /* end of line */ while (db_lc < db_le) { cnputc(*db_lc); db_lc++; } break; case CTRL('h'): case 0177: /* erase previous character */ if (db_lc > db_lbuf_start) db_delete(1, DEL_BWD); break; case CTRL('d'): /* erase next character */ if (db_lc < db_le) db_delete(1, DEL_FWD); break; case CTRL('u'): /* kill entire line: */ /* at first, delete to beginning of line */ if (db_lc > db_lbuf_start) db_delete(db_lc - db_lbuf_start, DEL_BWD); /* FALLTHROUGH */ case CTRL('k'): /* delete to end of line */ if (db_lc < db_le) db_delete(db_le - db_lc, DEL_FWD); break; case CTRL('t'): /* twiddle last 2 characters */ if (db_lc >= db_lbuf_start + 2) { c = db_lc[-2]; db_lc[-2] = db_lc[-1]; db_lc[-1] = c; cnputc(BACKUP); cnputc(BACKUP); cnputc(db_lc[-2]); cnputc(db_lc[-1]); } break; case CTRL('r'): db_putstring("^R\n", 3); redraw: if (db_le > db_lbuf_start) { db_putstring(db_lbuf_start, db_le - db_lbuf_start); db_putnchars(BACKUP, db_le - db_lc); } break; case CTRL('p'): /* Make previous history line the active one. */ if (db_lhistcur >= 0) { bcopy(db_lhistory + db_lhistcur * db_lhistlsize, db_lbuf_start, db_lhistlsize); db_lhistcur--; goto hist_redraw; } break; case CTRL('n'): /* Make next history line the active one. */ if (db_lhistcur < db_lhistidx - 1) { db_lhistcur += 2; bcopy(db_lhistory + db_lhistcur * db_lhistlsize, db_lbuf_start, db_lhistlsize); } else { /* * ^N through tail of history, reset the * buffer to zero length. */ *db_lbuf_start = '\0'; db_lhistcur = db_lhistidx; } hist_redraw: db_putnchars(BACKUP, db_le - db_lbuf_start); db_putnchars(BLANK, db_le - db_lbuf_start); db_putnchars(BACKUP, db_le - db_lbuf_start); db_le = index(db_lbuf_start, '\0'); if (db_le[-1] == '\r' || db_le[-1] == '\n') *--db_le = '\0'; db_lc = db_le; goto redraw; case -1: /* * eek! the console returned eof. * probably that means we HAVE no console.. we should try bail * XXX */ return (0); case '\n': case '\r': *db_le++ = c; return (1); default: if (db_le == db_lbuf_end) { cnputc('\007'); } else if (c >= ' ' && c <= '~') { char *p; for (p = db_le; p > db_lc; p--) *p = *(p-1); *db_lc++ = c; db_le++; cnputc(c); db_putstring(db_lc, db_le - db_lc); db_putnchars(BACKUP, db_le - db_lc); } break; } return (0); }
/* returns TRUE at end-of-line */ int db_inputchar(int c) { switch (c) { case CTRL('b'): /* back up one character */ if (db_lc > db_lbuf_start) { cnputc(BACKUP); db_lc--; } break; case CTRL('f'): /* forward one character */ if (db_lc < db_le) { cnputc(*db_lc); db_lc++; } break; case CTRL('a'): /* beginning of line */ while (db_lc > db_lbuf_start) { cnputc(BACKUP); db_lc--; } break; case CTRL('e'): /* end of line */ while (db_lc < db_le) { cnputc(*db_lc); db_lc++; } break; case CTRL('w'): /* erase word back */ while (db_lc > db_lbuf_start && db_lc[-1] != BLANK) db_delete(1, DEL_BWD); break; case CTRL('h'): case 0177: /* erase previous character */ if (db_lc > db_lbuf_start) db_delete(1, DEL_BWD); break; case CTRL('d'): /* erase next character */ if (db_lc < db_le) db_delete(1, DEL_FWD); break; case CTRL('k'): /* delete to end of line */ if (db_lc < db_le) db_delete(db_le - db_lc, DEL_FWD); break; case CTRL('u'): /* delete line */ db_delete_line(); break; case CTRL('t'): /* twiddle last 2 characters */ if (db_lc >= db_lbuf_start + 2) { c = db_lc[-2]; db_lc[-2] = db_lc[-1]; db_lc[-1] = c; cnputc(BACKUP); cnputc(BACKUP); cnputc(db_lc[-2]); cnputc(db_lc[-1]); } break; #if DB_HISTORY_SIZE != 0 case CTRL('p'): DEC_DB_CURR(); while (db_history_curr != db_history_last) { DEC_DB_CURR(); if (*db_history_curr == '\0') break; } db_delete_line(); if (db_history_curr == db_history_last) { INC_DB_CURR(); db_le = db_lc = db_lbuf_start; } else { char *p; INC_DB_CURR(); for (p = db_history_curr, db_le = db_lbuf_start;*p; ) { *db_le++ = *p++; if (p == db_history + db_history_size) p = db_history; } db_lc = db_le; } db_putstring(db_lbuf_start, db_le - db_lbuf_start); break; case CTRL('n'): while (db_history_curr != db_history_last) { if (*db_history_curr == '\0') break; INC_DB_CURR(); } if (db_history_curr != db_history_last) { INC_DB_CURR(); db_delete_line(); if (db_history_curr != db_history_last) { char *p; for (p = db_history_curr, db_le = db_lbuf_start; *p;) { *db_le++ = *p++; if (p == db_history + db_history_size) p = db_history; } db_lc = db_le; } db_putstring(db_lbuf_start, db_le - db_lbuf_start); } break; #endif case CTRL('r'): db_putstring("^R\n", 3); if (db_le > db_lbuf_start) { db_putstring(db_lbuf_start, db_le - db_lbuf_start); db_putnchars(BACKUP, db_le - db_lc); } break; case '\n': case '\r': #if DB_HISTORY_SIZE != 0 /* * Check whether current line is the same * as previous saved line. If it is, don`t * save it. */ if (db_history_curr == db_history_prev) { char *pp, *pc; /* * Is it the same? */ for (pp = db_history_prev, pc = db_lbuf_start; pc != db_le && *pp; ) { if (*pp != *pc) break; if (++pp == db_history + db_history_size) pp = db_history; pc++; } if (!*pp && pc == db_le) { /* * Repeated previous line. Don`t save. */ db_history_curr = db_history_last; *db_le++ = c; return TRUE; } } if (db_le != db_lbuf_start) { char *p; db_history_prev = db_history_last; for (p = db_lbuf_start; p != db_le; p++) { *db_history_last++ = *p; if (db_history_last == db_history + db_history_size) db_history_last = db_history; } *db_history_last++ = '\0'; } db_history_curr = db_history_last; #endif *db_le++ = c; return TRUE; default: if (db_le == db_lbuf_end) { cnputc('\007'); } else if (c >= ' ' && c <= '~') { char *p; for (p = db_le; p > db_lc; p--) *p = *(p-1); *db_lc++ = c; db_le++; cnputc(c); db_putstring(db_lc, db_le - db_lc); db_putnchars(BACKUP, db_le - db_lc); } break; } return FALSE; }