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.8 1995/11/24 14:13:36 bde Exp $ 27 */ 28 29 /* 30 * Author: David B. Golub, Carnegie Mellon University 31 * Date: 7/90 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/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 static int cnmaygetc __P((void)); 61 static void db_delete __P((int n, int bwd)); 62 static int db_inputchar __P((int c)); 63 static void db_putnchars __P((int c, int count)); 64 static void db_putstring __P((char *s, int count)); 65 66 void 67 db_putstring(s, count) 68 char *s; 69 int count; 70 { 71 while (--count >= 0) 72 cnputc(*s++); 73 } 74 75 void 76 db_putnchars(c, count) 77 int c; 78 int count; 79 { 80 while (--count >= 0) 81 cnputc(c); 82 } 83 84 /* 85 * Delete N characters, forward or backward 86 */ 87 #define DEL_FWD 0 88 #define DEL_BWD 1 89 void 90 db_delete(n, bwd) 91 int n; 92 int bwd; 93 { 94 register char *p; 95 96 if (bwd) { 97 db_lc -= n; 98 db_putnchars(BACKUP, n); 99 } 100 for (p = db_lc; p < db_le-n; p++) { 101 *p = *(p+n); 102 cnputc(*p); 103 } 104 db_putnchars(BLANK, n); 105 db_putnchars(BACKUP, db_le - db_lc); 106 db_le -= n; 107 } 108 109 /* returns TRUE at end-of-line */ 110 int 111 db_inputchar(c) 112 int c; 113 { 114 switch (c) { 115 case CTRL('b'): 116 /* back up one character */ 117 if (db_lc > db_lbuf_start) { 118 cnputc(BACKUP); 119 db_lc--; 120 } 121 break; 122 case CTRL('f'): 123 /* forward one character */ 124 if (db_lc < db_le) { 125 cnputc(*db_lc); 126 db_lc++; 127 } 128 break; 129 case CTRL('a'): 130 /* beginning of line */ 131 while (db_lc > db_lbuf_start) { 132 cnputc(BACKUP); 133 db_lc--; 134 } 135 break; 136 case CTRL('e'): 137 /* end of line */ 138 while (db_lc < db_le) { 139 cnputc(*db_lc); 140 db_lc++; 141 } 142 break; 143 case CTRL('h'): 144 case 0177: 145 /* erase previous character */ 146 if (db_lc > db_lbuf_start) 147 db_delete(1, DEL_BWD); 148 break; 149 case CTRL('d'): 150 /* erase next character */ 151 if (db_lc < db_le) 152 db_delete(1, DEL_FWD); 153 break; 154 case CTRL('k'): 155 /* delete to end of line */ 156 if (db_lc < db_le) 157 db_delete(db_le - db_lc, DEL_FWD); 158 break; 159 case CTRL('t'): 160 /* twiddle last 2 characters */ 161 if (db_lc >= db_lbuf_start + 2) { 162 c = db_lc[-2]; 163 db_lc[-2] = db_lc[-1]; 164 db_lc[-1] = c; 165 cnputc(BACKUP); 166 cnputc(BACKUP); 167 cnputc(db_lc[-2]); 168 cnputc(db_lc[-1]); 169 } 170 break; 171 case CTRL('r'): 172 db_putstring("^R\n", 3); 173 if (db_le > db_lbuf_start) { 174 db_putstring(db_lbuf_start, db_le - db_lbuf_start); 175 db_putnchars(BACKUP, db_le - db_lc); 176 } 177 break; 178 case '\n': 179 case '\r': 180 *db_le++ = c; 181 return (1); 182 default: 183 if (db_le == db_lbuf_end) { 184 cnputc('\007'); 185 } 186 else if (c >= ' ' && c <= '~') { 187 register char *p; 188 189 for (p = db_le; p > db_lc; p--) 190 *p = *(p-1); 191 *db_lc++ = c; 192 db_le++; 193 cnputc(c); 194 db_putstring(db_lc, db_le - db_lc); 195 db_putnchars(BACKUP, db_le - db_lc); 196 } 197 break; 198 } 199 return (0); 200 } 201 202 int 203 cnmaygetc() 204 { 205 return (-1); 206 } 207 208 int 209 db_readline(lstart, lsize) 210 char * lstart; 211 int lsize; 212 { 213 db_force_whitespace(); /* synch output position */ 214 215 db_lbuf_start = lstart; 216 db_lbuf_end = lstart + lsize; 217 db_lc = lstart; 218 db_le = lstart; 219 220 while (!db_inputchar(cngetc())) 221 continue; 222 223 db_putchar('\n'); /* synch output position */ 224 225 *db_le = 0; 226 return (db_le - db_lbuf_start); 227 } 228 229 void 230 db_check_interrupt() 231 { 232 register int c; 233 234 c = cnmaygetc(); 235 switch (c) { 236 case -1: /* no character */ 237 return; 238 239 case CTRL('c'): 240 db_error((char *)0); 241 /*NOTREACHED*/ 242 243 case CTRL('s'): 244 do { 245 c = cnmaygetc(); 246 if (c == CTRL('c')) 247 db_error((char *)0); 248 } while (c != CTRL('q')); 249 break; 250 251 default: 252 /* drop on floor */ 253 break; 254 } 255 } 256 257 /* called from kdb_trap in db_interface.c */ 258 void 259 cnpollc (flag) 260 int flag; 261 { 262 } 263