db_input.c revision 2112
1156136Sdavidxu/* 2156136Sdavidxu * Mach Operating System 3156136Sdavidxu * Copyright (c) 1991,1990 Carnegie Mellon University 4156136Sdavidxu * All Rights Reserved. 5156136Sdavidxu * 6156136Sdavidxu * Permission to use, copy, modify and distribute this software and its 7156136Sdavidxu * documentation is hereby granted, provided that both the copyright 8156136Sdavidxu * notice and this permission notice appear in all copies of the 9156136Sdavidxu * software, derivative works or modified versions, and any portions 10156136Sdavidxu * thereof, and that both notices appear in supporting documentation. 11156136Sdavidxu * 12156136Sdavidxu * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 13156136Sdavidxu * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14156136Sdavidxu * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15156136Sdavidxu * 16156136Sdavidxu * Carnegie Mellon requests users of this software to return to 17156136Sdavidxu * 18156136Sdavidxu * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19156136Sdavidxu * School of Computer Science 20156136Sdavidxu * Carnegie Mellon University 21156136Sdavidxu * Pittsburgh PA 15213-3890 22156136Sdavidxu * 23156136Sdavidxu * any improvements or extensions that they make and grant Carnegie the 24156136Sdavidxu * rights to redistribute these changes. 25156136Sdavidxu * 26156136Sdavidxu * $Id: db_input.c,v 1.5 1994/08/13 03:49:19 wollman Exp $ 27156136Sdavidxu */ 28156136Sdavidxu 29156136Sdavidxu/* 30156136Sdavidxu * Author: David B. Golub, Carnegie Mellon University 31156136Sdavidxu * Date: 7/90 32156136Sdavidxu */ 33156136Sdavidxu 34156136Sdavidxu#include <sys/param.h> 35156136Sdavidxu#include <sys/systm.h> 36156136Sdavidxu#include <sys/proc.h> 37156136Sdavidxu#include <ddb/ddb.h> 38156136Sdavidxu#include <ddb/db_output.h> 39156136Sdavidxu#include <machine/cons.h> 40156136Sdavidxu 41156136Sdavidxu/* 42156136Sdavidxu * Character input and editing. 43156136Sdavidxu */ 44156136Sdavidxu 45156136Sdavidxu/* 46156136Sdavidxu * We don't track output position while editing input, 47156136Sdavidxu * since input always ends with a new-line. We just 48156136Sdavidxu * reset the line position at the end. 49156136Sdavidxu */ 50156136Sdavidxuchar * db_lbuf_start; /* start of input line buffer */ 51156136Sdavidxuchar * db_lbuf_end; /* end of input line buffer */ 52156136Sdavidxuchar * db_lc; /* current character */ 53156136Sdavidxuchar * db_le; /* one past last character */ 54156136Sdavidxu 55156136Sdavidxu#define CTRL(c) ((c) & 0x1f) 56156136Sdavidxu#define isspace(c) ((c) == ' ' || (c) == '\t') 57156136Sdavidxu#define BLANK ' ' 58156136Sdavidxu#define BACKUP '\b' 59156136Sdavidxu 60156136Sdavidxuvoid 61156136Sdavidxudb_putstring(s, count) 62156136Sdavidxu char *s; 63156136Sdavidxu int count; 64156136Sdavidxu{ 65156142Sdavidxu while (--count >= 0) 66156142Sdavidxu cnputc(*s++); 67156142Sdavidxu} 68156142Sdavidxu 69156142Sdavidxuvoid 70156142Sdavidxudb_putnchars(c, count) 71156142Sdavidxu int c; 72156142Sdavidxu int count; 73156142Sdavidxu{ 74156142Sdavidxu while (--count >= 0) 75156142Sdavidxu cnputc(c); 76156142Sdavidxu} 77156142Sdavidxu 78156142Sdavidxu/* 79156142Sdavidxu * Delete N characters, forward or backward 80156136Sdavidxu */ 81156136Sdavidxu#define DEL_FWD 0 82156136Sdavidxu#define DEL_BWD 1 83156136Sdavidxuvoid 84156136Sdavidxudb_delete(n, bwd) 85156136Sdavidxu int n; 86156136Sdavidxu int bwd; 87156136Sdavidxu{ 88156136Sdavidxu register char *p; 89156136Sdavidxu 90156136Sdavidxu if (bwd) { 91156136Sdavidxu db_lc -= n; 92156136Sdavidxu db_putnchars(BACKUP, n); 93156136Sdavidxu } 94156136Sdavidxu for (p = db_lc; p < db_le-n; p++) { 95156136Sdavidxu *p = *(p+n); 96156136Sdavidxu cnputc(*p); 97156136Sdavidxu } 98156136Sdavidxu db_putnchars(BLANK, n); 99156136Sdavidxu db_putnchars(BACKUP, db_le - db_lc); 100156136Sdavidxu db_le -= n; 101156136Sdavidxu} 102156136Sdavidxu 103156136Sdavidxu/* returns TRUE at end-of-line */ 104156136Sdavidxuint 105156136Sdavidxudb_inputchar(c) 106156136Sdavidxu int c; 107156136Sdavidxu{ 108156136Sdavidxu switch (c) { 109156136Sdavidxu case CTRL('b'): 110156136Sdavidxu /* back up one character */ 111156136Sdavidxu if (db_lc > db_lbuf_start) { 112156136Sdavidxu cnputc(BACKUP); 113156136Sdavidxu db_lc--; 114156136Sdavidxu } 115156136Sdavidxu break; 116156136Sdavidxu case CTRL('f'): 117156136Sdavidxu /* forward one character */ 118156136Sdavidxu if (db_lc < db_le) { 119156136Sdavidxu cnputc(*db_lc); 120156136Sdavidxu db_lc++; 121156136Sdavidxu } 122156136Sdavidxu break; 123156136Sdavidxu case CTRL('a'): 124156136Sdavidxu /* beginning of line */ 125156136Sdavidxu while (db_lc > db_lbuf_start) { 126156136Sdavidxu cnputc(BACKUP); 127156136Sdavidxu db_lc--; 128156136Sdavidxu } 129156136Sdavidxu break; 130156136Sdavidxu case CTRL('e'): 131156136Sdavidxu /* end of line */ 132156136Sdavidxu while (db_lc < db_le) { 133156136Sdavidxu cnputc(*db_lc); 134156136Sdavidxu db_lc++; 135156136Sdavidxu } 136156136Sdavidxu break; 137156136Sdavidxu case CTRL('h'): 138156136Sdavidxu case 0177: 139156136Sdavidxu /* erase previous character */ 140156136Sdavidxu if (db_lc > db_lbuf_start) 141156136Sdavidxu db_delete(1, DEL_BWD); 142156136Sdavidxu break; 143156136Sdavidxu case CTRL('d'): 144156136Sdavidxu /* erase next character */ 145156136Sdavidxu if (db_lc < db_le) 146156136Sdavidxu db_delete(1, DEL_FWD); 147156136Sdavidxu break; 148156136Sdavidxu case CTRL('k'): 149156136Sdavidxu /* delete to end of line */ 150156136Sdavidxu if (db_lc < db_le) 151156136Sdavidxu db_delete(db_le - db_lc, DEL_FWD); 152156136Sdavidxu break; 153156136Sdavidxu case CTRL('t'): 154156136Sdavidxu /* twiddle last 2 characters */ 155156136Sdavidxu if (db_lc >= db_lbuf_start + 2) { 156156136Sdavidxu c = db_lc[-2]; 157156136Sdavidxu db_lc[-2] = db_lc[-1]; 158156136Sdavidxu db_lc[-1] = c; 159156136Sdavidxu cnputc(BACKUP); 160156136Sdavidxu cnputc(BACKUP); 161156136Sdavidxu cnputc(db_lc[-2]); 162156136Sdavidxu cnputc(db_lc[-1]); 163156136Sdavidxu } 164156136Sdavidxu break; 165156136Sdavidxu case CTRL('r'): 166156136Sdavidxu db_putstring("^R\n", 3); 167156136Sdavidxu if (db_le > db_lbuf_start) { 168156136Sdavidxu db_putstring(db_lbuf_start, db_le - db_lbuf_start); 169156136Sdavidxu db_putnchars(BACKUP, db_le - db_lc); 170156136Sdavidxu } 171156136Sdavidxu break; 172156136Sdavidxu case '\n': 173156136Sdavidxu case '\r': 174156136Sdavidxu *db_le++ = c; 175156136Sdavidxu return (1); 176156136Sdavidxu default: 177156136Sdavidxu if (db_le == db_lbuf_end) { 178156136Sdavidxu cnputc('\007'); 179156136Sdavidxu } 180156136Sdavidxu else if (c >= ' ' && c <= '~') { 181156136Sdavidxu register char *p; 182156136Sdavidxu 183156136Sdavidxu for (p = db_le; p > db_lc; p--) 184156136Sdavidxu *p = *(p-1); 185156136Sdavidxu *db_lc++ = c; 186156136Sdavidxu db_le++; 187156136Sdavidxu cnputc(c); 188156136Sdavidxu db_putstring(db_lc, db_le - db_lc); 189156136Sdavidxu db_putnchars(BACKUP, db_le - db_lc); 190156136Sdavidxu } 191156136Sdavidxu break; 192156136Sdavidxu } 193156136Sdavidxu return (0); 194156136Sdavidxu} 195156136Sdavidxu 196156136Sdavidxuint 197156136Sdavidxucnmaygetc (void) 198156136Sdavidxu{ 199156136Sdavidxu return (-1); 200156136Sdavidxu} 201156136Sdavidxu 202156136Sdavidxuint 203156136Sdavidxudb_readline(lstart, lsize) 204156136Sdavidxu char * lstart; 205156136Sdavidxu int lsize; 206156136Sdavidxu{ 207156136Sdavidxu db_force_whitespace(); /* synch output position */ 208156136Sdavidxu 209156136Sdavidxu db_lbuf_start = lstart; 210156136Sdavidxu db_lbuf_end = lstart + lsize; 211156136Sdavidxu db_lc = lstart; 212156136Sdavidxu db_le = lstart; 213156136Sdavidxu 214156136Sdavidxu while (!db_inputchar(cngetc())) 215156136Sdavidxu continue; 216156136Sdavidxu 217156136Sdavidxu db_putchar('\n'); /* synch output position */ 218156136Sdavidxu 219156136Sdavidxu *db_le = 0; 220156136Sdavidxu return (db_le - db_lbuf_start); 221156136Sdavidxu} 222156136Sdavidxu 223156136Sdavidxuvoid 224156136Sdavidxudb_check_interrupt() 225156136Sdavidxu{ 226156136Sdavidxu register int c; 227156136Sdavidxu 228156136Sdavidxu c = cnmaygetc(); 229156136Sdavidxu switch (c) { 230156136Sdavidxu case -1: /* no character */ 231156136Sdavidxu return; 232156136Sdavidxu 233156136Sdavidxu case CTRL('c'): 234156136Sdavidxu db_error((char *)0); 235156136Sdavidxu /*NOTREACHED*/ 236156136Sdavidxu 237156136Sdavidxu case CTRL('s'): 238156136Sdavidxu do { 239156136Sdavidxu c = cnmaygetc(); 240156136Sdavidxu if (c == CTRL('c')) 241156136Sdavidxu db_error((char *)0); 242156136Sdavidxu } while (c != CTRL('q')); 243156136Sdavidxu break; 244156136Sdavidxu 245156136Sdavidxu default: 246156136Sdavidxu /* drop on floor */ 247156136Sdavidxu break; 248156136Sdavidxu } 249156136Sdavidxu} 250156136Sdavidxu 251156136Sdavidxu/* called from kdb_trap in db_interface.c */ 252156136Sdavidxuvoid 253156136Sdavidxucnpollc (flag) 254156136Sdavidxu int flag; 255156136Sdavidxu{ 256156136Sdavidxu} 257156136Sdavidxu