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