db_input.c revision 12734
1218887Sdim/* 2218887Sdim * Mach Operating System 3218887Sdim * Copyright (c) 1991,1990 Carnegie Mellon University 4218887Sdim * All Rights Reserved. 5218887Sdim * 6218887Sdim * Permission to use, copy, modify and distribute this software and its 7218887Sdim * documentation is hereby granted, provided that both the copyright 8218887Sdim * notice and this permission notice appear in all copies of the 9218887Sdim * software, derivative works or modified versions, and any portions 10218887Sdim * thereof, and that both notices appear in supporting documentation. 11218887Sdim * 12218887Sdim * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 13249423Sdim * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14249423Sdim * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15249423Sdim * 16218887Sdim * Carnegie Mellon requests users of this software to return to 17218887Sdim * 18239462Sdim * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19218887Sdim * School of Computer Science 20218887Sdim * Carnegie Mellon University 21263508Sdim * Pittsburgh PA 15213-3890 22218887Sdim * 23218887Sdim * any improvements or extensions that they make and grant Carnegie the 24218887Sdim * rights to redistribute these changes. 25218887Sdim * 26218887Sdim * $Id: db_input.c,v 1.11 1995/12/10 13:32:37 phk Exp $ 27218887Sdim */ 28218887Sdim 29218887Sdim/* 30218887Sdim * Author: David B. Golub, Carnegie Mellon University 31218887Sdim * Date: 7/90 32218887Sdim */ 33218887Sdim 34218887Sdim#include <sys/param.h> 35218887Sdim#include <sys/systm.h> 36218887Sdim 37226633Sdim#include <machine/cons.h> 38218887Sdim 39239462Sdim#include <ddb/ddb.h> 40239462Sdim#include <ddb/db_output.h> 41218887Sdim 42218887Sdim/* 43226633Sdim * Character input and editing. 44239462Sdim */ 45218887Sdim 46218887Sdim/* 47218887Sdim * We don't track output position while editing input, 48218887Sdim * since input always ends with a new-line. We just 49218887Sdim * reset the line position at the end. 50218887Sdim */ 51218887Sdimstatic char * db_lbuf_start; /* start of input line buffer */ 52218887Sdimstatic char * db_lbuf_end; /* end of input line buffer */ 53218887Sdimstatic char * db_lc; /* current character */ 54218887Sdimstatic char * db_le; /* one past last character */ 55218887Sdim 56218887Sdim#define CTRL(c) ((c) & 0x1f) 57218887Sdim#define isspace(c) ((c) == ' ' || (c) == '\t') 58218887Sdim#define BLANK ' ' 59218887Sdim#define BACKUP '\b' 60218887Sdim 61218887Sdimstatic int cnmaygetc __P((void)); 62218887Sdimstatic void db_delete __P((int n, int bwd)); 63218887Sdimstatic int db_inputchar __P((int c)); 64218887Sdimstatic void db_putnchars __P((int c, int count)); 65218887Sdimstatic void db_putstring __P((char *s, int count)); 66218887Sdim 67218887Sdimvoid 68218887Sdimdb_putstring(s, count) 69218887Sdim char *s; 70218887Sdim int count; 71218887Sdim{ 72218887Sdim while (--count >= 0) 73218887Sdim cnputc(*s++); 74218887Sdim} 75218887Sdim 76218887Sdimvoid 77218887Sdimdb_putnchars(c, count) 78218887Sdim int c; 79218887Sdim int count; 80218887Sdim{ 81218887Sdim while (--count >= 0) 82218887Sdim cnputc(c); 83218887Sdim} 84218887Sdim 85218887Sdim/* 86218887Sdim * Delete N characters, forward or backward 87218887Sdim */ 88218887Sdim#define DEL_FWD 0 89218887Sdim#define DEL_BWD 1 90218887Sdimvoid 91234353Sdimdb_delete(n, bwd) 92234353Sdim int n; 93234353Sdim int bwd; 94234353Sdim{ 95234353Sdim register char *p; 96234353Sdim 97234353Sdim if (bwd) { 98234353Sdim db_lc -= n; 99234353Sdim db_putnchars(BACKUP, n); 100234353Sdim } 101234353Sdim for (p = db_lc; p < db_le-n; p++) { 102234353Sdim *p = *(p+n); 103234353Sdim cnputc(*p); 104234353Sdim } 105234353Sdim db_putnchars(BLANK, n); 106234353Sdim db_putnchars(BACKUP, db_le - db_lc); 107218887Sdim db_le -= n; 108218887Sdim} 109218887Sdim 110218887Sdim/* returns TRUE at end-of-line */ 111218887Sdimint 112218887Sdimdb_inputchar(c) 113218887Sdim int c; 114239462Sdim{ 115239462Sdim switch (c) { 116239462Sdim case CTRL('b'): 117218887Sdim /* back up one character */ 118239462Sdim if (db_lc > db_lbuf_start) { 119218887Sdim cnputc(BACKUP); 120218887Sdim db_lc--; 121218887Sdim } 122218887Sdim break; 123218887Sdim case CTRL('f'): 124239462Sdim /* forward one character */ 125218887Sdim if (db_lc < db_le) { 126218887Sdim cnputc(*db_lc); 127218887Sdim db_lc++; 128218887Sdim } 129218887Sdim break; 130218887Sdim case CTRL('a'): 131218887Sdim /* beginning of line */ 132218887Sdim while (db_lc > db_lbuf_start) { 133239462Sdim cnputc(BACKUP); 134239462Sdim db_lc--; 135239462Sdim } 136218887Sdim break; 137218887Sdim case CTRL('e'): 138218887Sdim /* end of line */ 139218887Sdim while (db_lc < db_le) { 140218887Sdim cnputc(*db_lc); 141218887Sdim db_lc++; 142218887Sdim } 143218887Sdim break; 144239462Sdim case CTRL('h'): 145218887Sdim case 0177: 146218887Sdim /* erase previous character */ 147239462Sdim if (db_lc > db_lbuf_start) 148218887Sdim db_delete(1, DEL_BWD); 149218887Sdim break; 150218887Sdim case CTRL('d'): 151218887Sdim /* erase next character */ 152218887Sdim if (db_lc < db_le) 153218887Sdim db_delete(1, DEL_FWD); 154218887Sdim break; 155218887Sdim case CTRL('k'): 156218887Sdim /* delete to end of line */ 157218887Sdim if (db_lc < db_le) 158218887Sdim db_delete(db_le - db_lc, DEL_FWD); 159218887Sdim break; 160218887Sdim case CTRL('t'): 161218887Sdim /* twiddle last 2 characters */ 162218887Sdim if (db_lc >= db_lbuf_start + 2) { 163218887Sdim c = db_lc[-2]; 164218887Sdim db_lc[-2] = db_lc[-1]; 165239462Sdim db_lc[-1] = c; 166239462Sdim cnputc(BACKUP); 167239462Sdim cnputc(BACKUP); 168239462Sdim cnputc(db_lc[-2]); 169239462Sdim cnputc(db_lc[-1]); 170239462Sdim } 171239462Sdim break; 172239462Sdim case CTRL('r'): 173239462Sdim db_putstring("^R\n", 3); 174239462Sdim if (db_le > db_lbuf_start) { 175239462Sdim db_putstring(db_lbuf_start, db_le - db_lbuf_start); 176239462Sdim db_putnchars(BACKUP, db_le - db_lc); 177239462Sdim } 178239462Sdim break; 179239462Sdim case '\n': 180239462Sdim case '\r': 181239462Sdim *db_le++ = c; 182239462Sdim return (1); 183263508Sdim default: 184263508Sdim if (db_le == db_lbuf_end) { 185263508Sdim cnputc('\007'); 186263508Sdim } 187239462Sdim else if (c >= ' ' && c <= '~') { 188239462Sdim register char *p; 189263508Sdim 190263508Sdim for (p = db_le; p > db_lc; p--) 191239462Sdim *p = *(p-1); 192239462Sdim *db_lc++ = c; 193239462Sdim db_le++; 194239462Sdim cnputc(c); 195239462Sdim db_putstring(db_lc, db_le - db_lc); 196239462Sdim db_putnchars(BACKUP, db_le - db_lc); 197218887Sdim } 198218887Sdim break; 199218887Sdim } 200218887Sdim return (0); 201218887Sdim} 202239462Sdim 203234353Sdimint 204234353Sdimcnmaygetc() 205234353Sdim{ 206234353Sdim return (-1); 207239462Sdim} 208239462Sdim 209239462Sdimint 210239462Sdimdb_readline(lstart, lsize) 211239462Sdim char * lstart; 212239462Sdim int lsize; 213239462Sdim{ 214239462Sdim db_force_whitespace(); /* synch output position */ 215239462Sdim 216239462Sdim db_lbuf_start = lstart; 217239462Sdim db_lbuf_end = lstart + lsize; 218239462Sdim db_lc = lstart; 219239462Sdim db_le = lstart; 220234353Sdim 221226633Sdim while (!db_inputchar(cngetc())) 222226633Sdim continue; 223218887Sdim 224218887Sdim db_putchar('\n'); /* synch output position */ 225218887Sdim 226218887Sdim *db_le = 0; 227218887Sdim return (db_le - db_lbuf_start); 228218887Sdim} 229221345Sdim 230218887Sdimvoid 231218887Sdimdb_check_interrupt() 232218887Sdim{ 233218887Sdim register int c; 234218887Sdim 235218887Sdim c = cnmaygetc(); 236218887Sdim switch (c) { 237218887Sdim case -1: /* no character */ 238218887Sdim return; 239218887Sdim 240218887Sdim case CTRL('c'): 241234353Sdim db_error((char *)0); 242218887Sdim /*NOTREACHED*/ 243234353Sdim 244218887Sdim case CTRL('s'): 245234353Sdim do { 246218887Sdim c = cnmaygetc(); 247234353Sdim if (c == CTRL('c')) 248218887Sdim db_error((char *)0); 249218887Sdim } while (c != CTRL('q')); 250218887Sdim break; 251218887Sdim 252239462Sdim default: 253218887Sdim /* drop on floor */ 254218887Sdim break; 255218887Sdim } 256218887Sdim} 257218887Sdim 258218887Sdim/* called from kdb_trap in db_interface.c */ 259218887Sdimvoid 260218887Sdimcnpollc (flag) 261218887Sdim int flag; 262218887Sdim{ 263218887Sdim} 264226633Sdim