db_input.c revision 12720
18876Srgrimes/* 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 58876Srgrimes * 64Srgrimes * Permission to use, copy, modify and distribute this software and its 74Srgrimes * documentation is hereby granted, provided that both the copyright 84Srgrimes * notice and this permission notice appear in all copies of the 94Srgrimes * software, derivative works or modified versions, and any portions 104Srgrimes * thereof, and that both notices appear in supporting documentation. 118876Srgrimes * 128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 134Srgrimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 158876Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 178876Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 228876Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie the 244Srgrimes * rights to redistribute these changes. 254Srgrimes * 2612720Sphk * $Id: db_input.c,v 1.10 1995/12/07 12:44:51 davidg Exp $ 274Srgrimes */ 28623Srgrimes 294Srgrimes/* 304Srgrimes * Author: David B. Golub, Carnegie Mellon University 314Srgrimes * Date: 7/90 324Srgrimes */ 334Srgrimes 342056Swollman#include <sys/param.h> 352056Swollman#include <sys/systm.h> 362056Swollman#include <sys/proc.h> 3712662Sdg#include <vm/vm_param.h> 382056Swollman#include <ddb/ddb.h> 392056Swollman#include <ddb/db_output.h> 402056Swollman#include <machine/cons.h> 414Srgrimes 424Srgrimes/* 434Srgrimes * Character input and editing. 444Srgrimes */ 454Srgrimes 464Srgrimes/* 474Srgrimes * We don't track output position while editing input, 484Srgrimes * since input always ends with a new-line. We just 494Srgrimes * reset the line position at the end. 504Srgrimes */ 5112720Sphkstatic char * db_lbuf_start; /* start of input line buffer */ 5212720Sphkstatic char * db_lbuf_end; /* end of input line buffer */ 5312720Sphkstatic char * db_lc; /* current character */ 5412720Sphkstatic char * db_le; /* one past last character */ 554Srgrimes 564Srgrimes#define CTRL(c) ((c) & 0x1f) 574Srgrimes#define isspace(c) ((c) == ' ' || (c) == '\t') 584Srgrimes#define BLANK ' ' 594Srgrimes#define BACKUP '\b' 604Srgrimes 6112515Sphkstatic int cnmaygetc __P((void)); 6212515Sphkstatic void db_delete __P((int n, int bwd)); 6312515Sphkstatic int db_inputchar __P((int c)); 6412515Sphkstatic void db_putnchars __P((int c, int count)); 6512515Sphkstatic void db_putstring __P((char *s, int count)); 6612473Sbde 674Srgrimesvoid 684Srgrimesdb_putstring(s, count) 694Srgrimes char *s; 704Srgrimes int count; 714Srgrimes{ 724Srgrimes while (--count >= 0) 734Srgrimes cnputc(*s++); 744Srgrimes} 754Srgrimes 764Srgrimesvoid 774Srgrimesdb_putnchars(c, count) 784Srgrimes int c; 794Srgrimes int count; 804Srgrimes{ 814Srgrimes while (--count >= 0) 824Srgrimes cnputc(c); 834Srgrimes} 844Srgrimes 854Srgrimes/* 864Srgrimes * Delete N characters, forward or backward 874Srgrimes */ 884Srgrimes#define DEL_FWD 0 894Srgrimes#define DEL_BWD 1 904Srgrimesvoid 914Srgrimesdb_delete(n, bwd) 924Srgrimes int n; 934Srgrimes int bwd; 944Srgrimes{ 954Srgrimes register char *p; 964Srgrimes 974Srgrimes if (bwd) { 984Srgrimes db_lc -= n; 994Srgrimes db_putnchars(BACKUP, n); 1004Srgrimes } 1014Srgrimes for (p = db_lc; p < db_le-n; p++) { 1024Srgrimes *p = *(p+n); 1034Srgrimes cnputc(*p); 1044Srgrimes } 1054Srgrimes db_putnchars(BLANK, n); 1064Srgrimes db_putnchars(BACKUP, db_le - db_lc); 1074Srgrimes db_le -= n; 1084Srgrimes} 1094Srgrimes 1104Srgrimes/* returns TRUE at end-of-line */ 1114Srgrimesint 1124Srgrimesdb_inputchar(c) 1134Srgrimes int c; 1144Srgrimes{ 1154Srgrimes switch (c) { 1164Srgrimes case CTRL('b'): 1174Srgrimes /* back up one character */ 1184Srgrimes if (db_lc > db_lbuf_start) { 1194Srgrimes cnputc(BACKUP); 1204Srgrimes db_lc--; 1214Srgrimes } 1224Srgrimes break; 1234Srgrimes case CTRL('f'): 1244Srgrimes /* forward one character */ 1254Srgrimes if (db_lc < db_le) { 1264Srgrimes cnputc(*db_lc); 1274Srgrimes db_lc++; 1284Srgrimes } 1294Srgrimes break; 1304Srgrimes case CTRL('a'): 1314Srgrimes /* beginning of line */ 1324Srgrimes while (db_lc > db_lbuf_start) { 1334Srgrimes cnputc(BACKUP); 1344Srgrimes db_lc--; 1354Srgrimes } 1364Srgrimes break; 1374Srgrimes case CTRL('e'): 1384Srgrimes /* end of line */ 1394Srgrimes while (db_lc < db_le) { 1404Srgrimes cnputc(*db_lc); 1414Srgrimes db_lc++; 1424Srgrimes } 1434Srgrimes break; 1444Srgrimes case CTRL('h'): 1454Srgrimes case 0177: 1464Srgrimes /* erase previous character */ 1474Srgrimes if (db_lc > db_lbuf_start) 1484Srgrimes db_delete(1, DEL_BWD); 1494Srgrimes break; 1504Srgrimes case CTRL('d'): 1514Srgrimes /* erase next character */ 1524Srgrimes if (db_lc < db_le) 1534Srgrimes db_delete(1, DEL_FWD); 1544Srgrimes break; 1554Srgrimes case CTRL('k'): 1564Srgrimes /* delete to end of line */ 1574Srgrimes if (db_lc < db_le) 1584Srgrimes db_delete(db_le - db_lc, DEL_FWD); 1594Srgrimes break; 1604Srgrimes case CTRL('t'): 1614Srgrimes /* twiddle last 2 characters */ 1624Srgrimes if (db_lc >= db_lbuf_start + 2) { 1634Srgrimes c = db_lc[-2]; 1644Srgrimes db_lc[-2] = db_lc[-1]; 1654Srgrimes db_lc[-1] = c; 1664Srgrimes cnputc(BACKUP); 1674Srgrimes cnputc(BACKUP); 1684Srgrimes cnputc(db_lc[-2]); 1694Srgrimes cnputc(db_lc[-1]); 1704Srgrimes } 1714Srgrimes break; 1724Srgrimes case CTRL('r'): 1734Srgrimes db_putstring("^R\n", 3); 1744Srgrimes if (db_le > db_lbuf_start) { 1754Srgrimes db_putstring(db_lbuf_start, db_le - db_lbuf_start); 1764Srgrimes db_putnchars(BACKUP, db_le - db_lc); 1774Srgrimes } 1784Srgrimes break; 1794Srgrimes case '\n': 1804Srgrimes case '\r': 1814Srgrimes *db_le++ = c; 1824Srgrimes return (1); 1834Srgrimes default: 1844Srgrimes if (db_le == db_lbuf_end) { 1854Srgrimes cnputc('\007'); 1864Srgrimes } 1874Srgrimes else if (c >= ' ' && c <= '~') { 1884Srgrimes register char *p; 1894Srgrimes 1904Srgrimes for (p = db_le; p > db_lc; p--) 1914Srgrimes *p = *(p-1); 1924Srgrimes *db_lc++ = c; 1934Srgrimes db_le++; 1944Srgrimes cnputc(c); 1954Srgrimes db_putstring(db_lc, db_le - db_lc); 1964Srgrimes db_putnchars(BACKUP, db_le - db_lc); 1974Srgrimes } 1984Srgrimes break; 1994Srgrimes } 2004Srgrimes return (0); 2014Srgrimes} 2024Srgrimes 2034Srgrimesint 20412473Sbdecnmaygetc() 2052112Swollman{ 2062112Swollman return (-1); 2072112Swollman} 2082112Swollman 2092112Swollmanint 2104Srgrimesdb_readline(lstart, lsize) 2114Srgrimes char * lstart; 2124Srgrimes int lsize; 2134Srgrimes{ 2144Srgrimes db_force_whitespace(); /* synch output position */ 2154Srgrimes 2164Srgrimes db_lbuf_start = lstart; 2174Srgrimes db_lbuf_end = lstart + lsize; 2184Srgrimes db_lc = lstart; 2194Srgrimes db_le = lstart; 2204Srgrimes 2214Srgrimes while (!db_inputchar(cngetc())) 2224Srgrimes continue; 2234Srgrimes 2244Srgrimes db_putchar('\n'); /* synch output position */ 2254Srgrimes 2264Srgrimes *db_le = 0; 2274Srgrimes return (db_le - db_lbuf_start); 2284Srgrimes} 2294Srgrimes 2304Srgrimesvoid 2314Srgrimesdb_check_interrupt() 2324Srgrimes{ 2334Srgrimes register int c; 2344Srgrimes 2354Srgrimes c = cnmaygetc(); 2364Srgrimes switch (c) { 2374Srgrimes case -1: /* no character */ 2384Srgrimes return; 2394Srgrimes 2404Srgrimes case CTRL('c'): 2414Srgrimes db_error((char *)0); 2424Srgrimes /*NOTREACHED*/ 2434Srgrimes 2444Srgrimes case CTRL('s'): 2454Srgrimes do { 2464Srgrimes c = cnmaygetc(); 2474Srgrimes if (c == CTRL('c')) 2484Srgrimes db_error((char *)0); 2494Srgrimes } while (c != CTRL('q')); 2504Srgrimes break; 2514Srgrimes 2524Srgrimes default: 2534Srgrimes /* drop on floor */ 2544Srgrimes break; 2554Srgrimes } 2564Srgrimes} 2574Srgrimes 2584Srgrimes/* called from kdb_trap in db_interface.c */ 259798Swollmanvoid 2604Srgrimescnpollc (flag) 261798Swollman int flag; 2624Srgrimes{ 2638876Srgrimes} 264