1 /* 2 * Mach Operating System 3 * Copyright (c) 1991,1990 Carnegie Mellon University 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify and distribute this software and its 7 * documentation is hereby granted, provided that both the copyright 8 * notice and this permission notice appear in all copies of the 9 * software, derivative works or modified versions, and any portions 10 * thereof, and that both notices appear in supporting documentation. 11 * 12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 * 16 * Carnegie Mellon requests users of this software to return to 17 * 18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 * School of Computer Science 20 * Carnegie Mellon University 21 * Pittsburgh PA 15213-3890 22 * 23 * any improvements or extensions that they make and grant Carnegie the 24 * rights to redistribute these changes. 25 * 26 * $Id: db_input.c,v 1.3 1993/11/25 01:30:06 wollman Exp $ 27 */ 28 29 /* 30 * Author: David B. Golub, Carnegie Mellon University 31 * Date: 7/90 32 */ 33 34 #include "param.h" 35 #include "systm.h" 36 #include "proc.h" 37 #include "ddb/ddb.h" 38 #include "ddb/db_output.h" 39 #include "machine/cons.h" 40 41 /* 42 * Character input and editing. 43 */ 44 45 /* 46 * We don't track output position while editing input, 47 * since input always ends with a new-line. We just 48 * reset the line position at the end. 49 */ 50 char * db_lbuf_start; /* start of input line buffer */ 51 char * db_lbuf_end; /* end of input line buffer */ 52 char * db_lc; /* current character */ 53 char * db_le; /* one past last character */ 54 55 #define CTRL(c) ((c) & 0x1f) 56 #define isspace(c) ((c) == ' ' || (c) == '\t') 57 #define BLANK ' ' 58 #define BACKUP '\b' 59 60 void 61 db_putstring(s, count) 62 char *s; 63 int count; 64 { 65 while (--count >= 0) 66 cnputc(*s++); 67 } 68 69 void 70 db_putnchars(c, count) 71 int c; 72 int count; 73 { 74 while (--count >= 0) 75 cnputc(c); 76 } 77 78 /* 79 * Delete N characters, forward or backward 80 */ 81 #define DEL_FWD 0 82 #define DEL_BWD 1 83 void 84 db_delete(n, bwd) 85 int n; 86 int bwd; 87 { 88 register char *p; 89 90 if (bwd) { 91 db_lc -= n; 92 db_putnchars(BACKUP, n); 93 } 94 for (p = db_lc; p < db_le-n; p++) { 95 *p = *(p+n); 96 cnputc(*p); 97 } 98 db_putnchars(BLANK, n); 99 db_putnchars(BACKUP, db_le - db_lc); 100 db_le -= n; 101 } 102 103 /* returns TRUE at end-of-line */ 104 int 105 db_inputchar(c) 106 int c; 107 { 108 switch (c) { 109 case CTRL('b'): 110 /* back up one character */ 111 if (db_lc > db_lbuf_start) { 112 cnputc(BACKUP); 113 db_lc--; 114 } 115 break; 116 case CTRL('f'): 117 /* forward one character */ 118 if (db_lc < db_le) { 119 cnputc(*db_lc); 120 db_lc++; 121 } 122 break; 123 case CTRL('a'): 124 /* beginning of line */ 125 while (db_lc > db_lbuf_start) { 126 cnputc(BACKUP); 127 db_lc--; 128 } 129 break; 130 case CTRL('e'): 131 /* end of line */ 132 while (db_lc < db_le) { 133 cnputc(*db_lc); 134 db_lc++; 135 } 136 break; 137 case CTRL('h'): 138 case 0177: 139 /* erase previous character */ 140 if (db_lc > db_lbuf_start) 141 db_delete(1, DEL_BWD); 142 break; 143 case CTRL('d'): 144 /* erase next character */ 145 if (db_lc < db_le) 146 db_delete(1, DEL_FWD); 147 break; 148 case CTRL('k'): 149 /* delete to end of line */ 150 if (db_lc < db_le) 151 db_delete(db_le - db_lc, DEL_FWD); 152 break; 153 case CTRL('t'): 154 /* twiddle last 2 characters */ 155 if (db_lc >= db_lbuf_start + 2) { 156 c = db_lc[-2]; 157 db_lc[-2] = db_lc[-1]; 158 db_lc[-1] = c; 159 cnputc(BACKUP); 160 cnputc(BACKUP); 161 cnputc(db_lc[-2]); 162 cnputc(db_lc[-1]); 163 } 164 break; 165 case CTRL('r'): 166 db_putstring("^R\n", 3); 167 if (db_le > db_lbuf_start) { 168 db_putstring(db_lbuf_start, db_le - db_lbuf_start); 169 db_putnchars(BACKUP, db_le - db_lc); 170 } 171 break; 172 case '\n': 173 case '\r': 174 *db_le++ = c; 175 return (1); 176 default: 177 if (db_le == db_lbuf_end) { 178 cnputc('\007'); 179 } 180 else if (c >= ' ' && c <= '~') { 181 register char *p; 182 183 for (p = db_le; p > db_lc; p--) 184 *p = *(p-1); 185 *db_lc++ = c; 186 db_le++; 187 cnputc(c); 188 db_putstring(db_lc, db_le - db_lc); 189 db_putnchars(BACKUP, db_le - db_lc); 190 } 191 break; 192 } 193 return (0); 194 } 195 196 int 197 db_readline(lstart, lsize) 198 char * lstart; 199 int lsize; 200 { 201 db_force_whitespace(); /* synch output position */ 202 203 db_lbuf_start = lstart; 204 db_lbuf_end = lstart + lsize; 205 db_lc = lstart; 206 db_le = lstart; 207 208 while (!db_inputchar(cngetc())) 209 continue; 210 211 db_putchar('\n'); /* synch output position */ 212 213 *db_le = 0; 214 return (db_le - db_lbuf_start); 215 } 216 217 void 218 db_check_interrupt() 219 { 220 register int c; 221 222 c = cnmaygetc(); 223 switch (c) { 224 case -1: /* no character */ 225 return; 226 227 case CTRL('c'): 228 db_error((char *)0); 229 /*NOTREACHED*/ 230 231 case CTRL('s'): 232 do { 233 c = cnmaygetc(); 234 if (c == CTRL('c')) 235 db_error((char *)0); 236 } while (c != CTRL('q')); 237 break; 238 239 default: 240 /* drop on floor */ 241 break; 242 } 243 } 244 245 int 246 cnmaygetc (void) 247 { 248 return (-1); 249 } 250 251 /* called from kdb_trap in db_interface.c */ 252 void 253 cnpollc (flag) 254 int flag; 255 { 256 } 257