/* input editor for interactive streams. this should get replaced when we have more intelligient underlying streams... */ #include "io-defs.h" #include "buckybits.h" /* helper fun for displaying partial line. */ local redisplay(s, buf, start, space, fun) struct streamoid * s; char * buf; int start; /* start offset in fun */ int space; /* if draw space at end */ int (* fun)(); /* display_char fun */ { char * p = buf + start; int n = 0; /* n chars displayed */ while (*p) { (*fun)(s, *p++); ++n; } if (space) { (*fun)(s, ' '); ++n; } while (n-- > 0) (*fun)(s, '\b'); } int __input_editor(s, buf, nbytes_buf, get_char_fun, display_char_fun) struct streamoid * s; /* streamoid we're using */ char * buf; /* buf to fill */ int nbytes_buf; /* max size */ int (* get_char_fun)(); /* fun to apply to stream for char */ int (* display_char_fun)(); /* fun to apply to s, char */ { /* for now, just do a few simple things */ int ch; /* char we read from stream */ int nbytes; /* nbytes valid in buf now */ int i, j; /* idx in buf */ char * p; int done = 0; nbytes = strlen(buf); /* display the string */ for (p = buf ; *p ; p++) (*display_char_fun)(s, *p); i = nbytes; for ( ; !done ; ) { ch = (*get_char_fun)(s); /* kludge for ^Z */ if (ch == 0x1A) ch = EOF_VALUE; switch(ch) { case EOF_VALUE: case '\r': case '\n': done++; break; case 0x08: /* backspace */ case 0x7F: if (i > 0) /* anything to rub out? */ { /* this case is kludged for brain-dead ST console */ if (ch == 0x7F) { (*display_char_fun)(s, '\b'); (*display_char_fun)(s, ' '); (*display_char_fun)(s, '\b'); (*display_char_fun)(s, '\b'); } /* do the real rubout */ (*display_char_fun)(s, '\b'); --i; strcpy(buf + i, buf + i + 1); --nbytes; redisplay(s, buf, i, 1, display_char_fun); } break; case 0x00: /* nul? */ break; /* just ignore it */ case 0x01: /* ^A. go to bol */ while (i) { (*display_char_fun)(s, '\b'); --i; } break; case 0x02: /* ^B */ if (i) { (*display_char_fun)(s, '\b'); --i; } break; case 0x03: /* ^C */ break; case 0x04: /* ^D */ if (i < nbytes) { strcpy(buf + i, buf + i + 1); --nbytes; redisplay(s, buf, i, 1, display_char_fun); } break; case 0x05: /* ^E */ while (i < nbytes) { (*display_char_fun)(s, buf[i]); ++i; } break; case 0x06: /* ^F */ if (i < nbytes) { (*display_char_fun)(s, buf[i]); ++i; } break; case 0x07: case 0x09: /* tab?!? */ (*display_char_fun)(s, 0x07); break; case 0x0B: break; case 0x0C: /* ^L */ for (j = i ; j > 0 ; j--) (* display_char_fun)(s, '\b'); for (j = 0 ; j < nbytes ; j++) (* display_char_fun)(s, buf[j]); for (j = nbytes ; j > i ; j--) (* display_char_fun)(s, '\b'); break; case 0x0E: case 0x0F: case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: break; /* more later... */ default: for (j = nbytes ; j > i - 1 ; j--) buf[j + 1] = buf[j]; nbytes++; buf[i++] = ch; redisplay(s, buf, i, 0, display_char_fun); if (nbytes + 1 >= nbytes_buf) done++; break; } /* done dispatching on chars */ } return(ch); /* return terminating char */ }