db_input.c revision 4
14Srgrimes/* 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 54Srgrimes * 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. 114Srgrimes * 124Srgrimes * 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. 154Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 174Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 224Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie the 244Srgrimes * rights to redistribute these changes. 254Srgrimes */ 264Srgrimes/* 274Srgrimes * HISTORY 284Srgrimes * $Log: db_input.c,v $ 294Srgrimes * Revision 1.1 1992/03/25 21:45:10 pace 304Srgrimes * Initial revision 314Srgrimes * 324Srgrimes * Revision 2.4 91/02/14 14:41:53 mrt 334Srgrimes * Add input line editing. 344Srgrimes * [90/11/11 dbg] 354Srgrimes * 364Srgrimes * Revision 2.3 91/02/05 17:06:32 mrt 374Srgrimes * Changed to new Mach copyright 384Srgrimes * [91/01/31 16:18:13 mrt] 394Srgrimes * 404Srgrimes * Revision 2.2 90/08/27 21:51:03 dbg 414Srgrimes * Reduce lint. 424Srgrimes * [90/08/07 dbg] 434Srgrimes * Created. 444Srgrimes * [90/07/25 dbg] 454Srgrimes * 464Srgrimes */ 474Srgrimes/* 484Srgrimes * Author: David B. Golub, Carnegie Mellon University 494Srgrimes * Date: 7/90 504Srgrimes */ 514Srgrimes 524Srgrimes#include "param.h" 534Srgrimes#include "proc.h" 544Srgrimes#include <ddb/db_output.h> 554Srgrimes 564Srgrimes/* 574Srgrimes * Character input and editing. 584Srgrimes */ 594Srgrimes 604Srgrimes/* 614Srgrimes * We don't track output position while editing input, 624Srgrimes * since input always ends with a new-line. We just 634Srgrimes * reset the line position at the end. 644Srgrimes */ 654Srgrimeschar * db_lbuf_start; /* start of input line buffer */ 664Srgrimeschar * db_lbuf_end; /* end of input line buffer */ 674Srgrimeschar * db_lc; /* current character */ 684Srgrimeschar * db_le; /* one past last character */ 694Srgrimes 704Srgrimes#define CTRL(c) ((c) & 0x1f) 714Srgrimes#define isspace(c) ((c) == ' ' || (c) == '\t') 724Srgrimes#define BLANK ' ' 734Srgrimes#define BACKUP '\b' 744Srgrimes 754Srgrimesvoid 764Srgrimesdb_putstring(s, count) 774Srgrimes char *s; 784Srgrimes int count; 794Srgrimes{ 804Srgrimes while (--count >= 0) 814Srgrimes cnputc(*s++); 824Srgrimes} 834Srgrimes 844Srgrimesvoid 854Srgrimesdb_putnchars(c, count) 864Srgrimes int c; 874Srgrimes int count; 884Srgrimes{ 894Srgrimes while (--count >= 0) 904Srgrimes cnputc(c); 914Srgrimes} 924Srgrimes 934Srgrimes/* 944Srgrimes * Delete N characters, forward or backward 954Srgrimes */ 964Srgrimes#define DEL_FWD 0 974Srgrimes#define DEL_BWD 1 984Srgrimesvoid 994Srgrimesdb_delete(n, bwd) 1004Srgrimes int n; 1014Srgrimes int bwd; 1024Srgrimes{ 1034Srgrimes register char *p; 1044Srgrimes 1054Srgrimes if (bwd) { 1064Srgrimes db_lc -= n; 1074Srgrimes db_putnchars(BACKUP, n); 1084Srgrimes } 1094Srgrimes for (p = db_lc; p < db_le-n; p++) { 1104Srgrimes *p = *(p+n); 1114Srgrimes cnputc(*p); 1124Srgrimes } 1134Srgrimes db_putnchars(BLANK, n); 1144Srgrimes db_putnchars(BACKUP, db_le - db_lc); 1154Srgrimes db_le -= n; 1164Srgrimes} 1174Srgrimes 1184Srgrimes/* returns TRUE at end-of-line */ 1194Srgrimesint 1204Srgrimesdb_inputchar(c) 1214Srgrimes int c; 1224Srgrimes{ 1234Srgrimes switch (c) { 1244Srgrimes case CTRL('b'): 1254Srgrimes /* back up one character */ 1264Srgrimes if (db_lc > db_lbuf_start) { 1274Srgrimes cnputc(BACKUP); 1284Srgrimes db_lc--; 1294Srgrimes } 1304Srgrimes break; 1314Srgrimes case CTRL('f'): 1324Srgrimes /* forward one character */ 1334Srgrimes if (db_lc < db_le) { 1344Srgrimes cnputc(*db_lc); 1354Srgrimes db_lc++; 1364Srgrimes } 1374Srgrimes break; 1384Srgrimes case CTRL('a'): 1394Srgrimes /* beginning of line */ 1404Srgrimes while (db_lc > db_lbuf_start) { 1414Srgrimes cnputc(BACKUP); 1424Srgrimes db_lc--; 1434Srgrimes } 1444Srgrimes break; 1454Srgrimes case CTRL('e'): 1464Srgrimes /* end of line */ 1474Srgrimes while (db_lc < db_le) { 1484Srgrimes cnputc(*db_lc); 1494Srgrimes db_lc++; 1504Srgrimes } 1514Srgrimes break; 1524Srgrimes case CTRL('h'): 1534Srgrimes case 0177: 1544Srgrimes /* erase previous character */ 1554Srgrimes if (db_lc > db_lbuf_start) 1564Srgrimes db_delete(1, DEL_BWD); 1574Srgrimes break; 1584Srgrimes case CTRL('d'): 1594Srgrimes /* erase next character */ 1604Srgrimes if (db_lc < db_le) 1614Srgrimes db_delete(1, DEL_FWD); 1624Srgrimes break; 1634Srgrimes case CTRL('k'): 1644Srgrimes /* delete to end of line */ 1654Srgrimes if (db_lc < db_le) 1664Srgrimes db_delete(db_le - db_lc, DEL_FWD); 1674Srgrimes break; 1684Srgrimes case CTRL('t'): 1694Srgrimes /* twiddle last 2 characters */ 1704Srgrimes if (db_lc >= db_lbuf_start + 2) { 1714Srgrimes c = db_lc[-2]; 1724Srgrimes db_lc[-2] = db_lc[-1]; 1734Srgrimes db_lc[-1] = c; 1744Srgrimes cnputc(BACKUP); 1754Srgrimes cnputc(BACKUP); 1764Srgrimes cnputc(db_lc[-2]); 1774Srgrimes cnputc(db_lc[-1]); 1784Srgrimes } 1794Srgrimes break; 1804Srgrimes case CTRL('r'): 1814Srgrimes db_putstring("^R\n", 3); 1824Srgrimes if (db_le > db_lbuf_start) { 1834Srgrimes db_putstring(db_lbuf_start, db_le - db_lbuf_start); 1844Srgrimes db_putnchars(BACKUP, db_le - db_lc); 1854Srgrimes } 1864Srgrimes break; 1874Srgrimes case '\n': 1884Srgrimes case '\r': 1894Srgrimes *db_le++ = c; 1904Srgrimes return (1); 1914Srgrimes default: 1924Srgrimes if (db_le == db_lbuf_end) { 1934Srgrimes cnputc('\007'); 1944Srgrimes } 1954Srgrimes else if (c >= ' ' && c <= '~') { 1964Srgrimes register char *p; 1974Srgrimes 1984Srgrimes for (p = db_le; p > db_lc; p--) 1994Srgrimes *p = *(p-1); 2004Srgrimes *db_lc++ = c; 2014Srgrimes db_le++; 2024Srgrimes cnputc(c); 2034Srgrimes db_putstring(db_lc, db_le - db_lc); 2044Srgrimes db_putnchars(BACKUP, db_le - db_lc); 2054Srgrimes } 2064Srgrimes break; 2074Srgrimes } 2084Srgrimes return (0); 2094Srgrimes} 2104Srgrimes 2114Srgrimesint 2124Srgrimesdb_readline(lstart, lsize) 2134Srgrimes char * lstart; 2144Srgrimes int lsize; 2154Srgrimes{ 2164Srgrimes db_force_whitespace(); /* synch output position */ 2174Srgrimes 2184Srgrimes db_lbuf_start = lstart; 2194Srgrimes db_lbuf_end = lstart + lsize; 2204Srgrimes db_lc = lstart; 2214Srgrimes db_le = lstart; 2224Srgrimes 2234Srgrimes while (!db_inputchar(cngetc())) 2244Srgrimes continue; 2254Srgrimes 2264Srgrimes db_putchar('\n'); /* synch output position */ 2274Srgrimes 2284Srgrimes *db_le = 0; 2294Srgrimes return (db_le - db_lbuf_start); 2304Srgrimes} 2314Srgrimes 2324Srgrimesvoid 2334Srgrimesdb_check_interrupt() 2344Srgrimes{ 2354Srgrimes register int c; 2364Srgrimes 2374Srgrimes c = cnmaygetc(); 2384Srgrimes switch (c) { 2394Srgrimes case -1: /* no character */ 2404Srgrimes return; 2414Srgrimes 2424Srgrimes case CTRL('c'): 2434Srgrimes db_error((char *)0); 2444Srgrimes /*NOTREACHED*/ 2454Srgrimes 2464Srgrimes case CTRL('s'): 2474Srgrimes do { 2484Srgrimes c = cnmaygetc(); 2494Srgrimes if (c == CTRL('c')) 2504Srgrimes db_error((char *)0); 2514Srgrimes } while (c != CTRL('q')); 2524Srgrimes break; 2534Srgrimes 2544Srgrimes default: 2554Srgrimes /* drop on floor */ 2564Srgrimes break; 2574Srgrimes } 2584Srgrimes} 2594Srgrimes 2604Srgrimescnmaygetc () 2614Srgrimes{ 2624Srgrimes return (-1); 2634Srgrimes} 2644Srgrimes 2654Srgrimes/* called from kdb_trap in db_interface.c */ 2664Srgrimescnpollc (flag) 2674Srgrimes{ 2684Srgrimes} 269