1/* 2 * Copyright (c) 1992 OMRON Corporation. 3 * Copyright (c) 1992 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)getline.c-big 8.2 (Berkeley) 03/21/94 12 */ 13 14/* 15 * getline -- getline function with EMACS like key operation 16 * by A.Fujita, FEB-01-1992 17 */ 18 19#define MAXLINE 80 20 21struct key_bind_table { 22 int (*func)(); 23}; 24 25char linebuff[MAXLINE]; 26int lineleft; 27int lineright = MAXLINE - 1; 28int cursole; 29int endline; 30 31int 32nil_operation(c) 33 char c; 34{ 35 return(1); 36} 37 38int 39self_insert(c) 40 char c; 41{ 42 register int n; 43 44 if (cursole <= endline) { 45 linebuff[cursole++] = c; 46 47 cnputc(c); 48 49 for (n = endline; n < MAXLINE; n++) 50 cnputc(linebuff[n]); 51 for (n = endline + 1; n < MAXLINE; n++) 52 cnputc('\x08'); /* le: move the cursor left one column */ 53 } 54 55 return(1); 56} 57 58/* 59int 60self_insert(c) 61 char c; 62{ 63 register int n; 64 65 if (cursole <= endline) { 66 linebuff[cursole++] = c; 67 68 cnputc('\x1b'); 69 cnputc('['); 70 cnputc('4'); 71 cnputc('h'); 72 73 cnputc(c); 74 75 cnputc('\x1b'); 76 cnputc('['); 77 cnputc('4'); 78 cnputc('l'); 79 } 80 81 return(1); 82} 83 */ 84 85int 86accept_line(c) 87 char c; 88{ 89 cnputc('\r'); 90 cnputc('\n'); 91 92 return(0); 93} 94 95int 96beginning_of_line(c) 97 char c; 98{ 99 while (cursole > lineleft) { 100 linebuff[endline--] = linebuff[--cursole]; 101 cnputc('\x08'); /* le: move the cursor left one column */ 102 } 103 104 return(1); 105} 106 107int 108end_of_line(c) 109 char c; 110{ 111 while (endline < lineright) { 112 linebuff[cursole++] = linebuff[++endline]; 113 cnputc('\x1b'); /* nd: move the cursor right one column */ 114 cnputc('['); 115 cnputc('C'); 116 } 117 118 return(1); 119} 120 121int 122forward_char(c) 123 char c; 124{ 125 if (endline < lineright) { 126 linebuff[cursole++] = linebuff[++endline]; 127 cnputc('\x1b'); /* nd: move the cursor right one column */ 128 cnputc('['); 129 cnputc('C'); 130 } 131 132 return(1); 133} 134 135int 136backward_char(c) 137 char c; 138{ 139 if (cursole > lineleft) { 140 linebuff[endline--] = linebuff[--cursole]; 141 cnputc('\x08'); 142 } 143 144 return(1); 145} 146 147int 148delete_char(c) 149 char c; 150{ 151 register int n; 152 153 if (cursole > lineleft || endline < lineright) { 154 endline++; 155 cnputc('\x1b'); /* dc: delete one character position at the cursor */ 156 cnputc('['); 157 cnputc('P'); 158 } 159} 160 161int 162backward_delete_char(c) 163 char c; 164{ 165 if (cursole > lineleft) { 166 cursole--; 167 cnputc('\x08'); /* le: move the cursor left one column */ 168 cnputc('\x1b'); /* dc: delete one character position at the cursor */ 169 cnputc('['); 170 cnputc('P'); 171 } 172 173 return(1); 174} 175 176int 177kill_line(c) 178{ 179 register int n = lineright - endline; 180 181 while(endline < lineright) { 182 endline++; 183 cnputc('\x1b'); /* dc: delete one character position at the cursor */ 184 cnputc('['); 185 cnputc('P'); 186 } 187 188 return(1); 189} 190 191struct key_bind_table keybind[] = { 192{ nil_operation }, /* 0x00 NUL */ 193{ beginning_of_line }, /* 0x01 SOH */ 194{ backward_char }, /* 0x02 STX */ 195{ nil_operation }, /* 0x03 ETX */ 196{ delete_char }, /* 0x04 EOT */ 197{ end_of_line }, /* 0x05 ENQ */ 198{ forward_char }, /* 0x06 ACK */ 199{ nil_operation }, /* 0x07 BEL */ 200{ backward_delete_char }, /* 0x08 BS */ 201{ nil_operation }, /* 0x09 HT */ 202{ accept_line }, /* 0x0A NL */ 203{ kill_line }, /* 0x0B VT */ 204{ nil_operation }, /* 0x0C NP */ 205{ accept_line }, /* 0x0D CR */ 206{ nil_operation }, /* 0x0E SO */ 207{ nil_operation }, /* 0x0F SI */ 208{ nil_operation }, /* 0x10 DLE */ 209{ nil_operation }, /* 0x11 DC1 */ 210{ nil_operation }, /* 0x12 DC2 */ 211{ nil_operation }, /* 0x13 DC3 */ 212{ nil_operation }, /* 0x14 DC4 */ 213{ nil_operation }, /* 0x15 NAK */ 214{ nil_operation }, /* 0x16 SYN */ 215{ nil_operation }, /* 0x17 ETB */ 216{ nil_operation }, /* 0x18 CAN */ 217{ nil_operation }, /* 0x19 EM */ 218{ nil_operation }, /* 0x1A SUB */ 219{ nil_operation }, /* 0x1B ESC */ 220{ nil_operation }, /* 0x1C FS */ 221{ nil_operation }, /* 0x1D GS */ 222{ nil_operation }, /* 0x1E RS */ 223{ nil_operation }, /* 0x1F US */ 224{ self_insert }, /* 0x20 ( ) */ 225{ self_insert }, /* 0x21 (!) */ 226{ self_insert }, /* 0x22 (") */ 227{ self_insert }, /* 0x23 (#) */ 228{ self_insert }, /* 0x24 ($) */ 229{ self_insert }, /* 0x25 (%) */ 230{ self_insert }, /* 0x26 (&) */ 231{ self_insert }, /* 0x27 (') */ 232{ self_insert }, /* 0x28 (() */ 233{ self_insert }, /* 0x29 ()) */ 234{ self_insert }, /* 0x2A (*) */ 235{ self_insert }, /* 0x2B (+) */ 236{ self_insert }, /* 0x2C (,) */ 237{ self_insert }, /* 0x2D (-) */ 238{ self_insert }, /* 0x2E (.) */ 239{ self_insert }, /* 0x2F (/) */ 240{ self_insert }, /* 0x30 (0) */ 241{ self_insert }, /* 0x31 (1) */ 242{ self_insert }, /* 0x32 (2) */ 243{ self_insert }, /* 0x33 (3) */ 244{ self_insert }, /* 0x34 (4) */ 245{ self_insert }, /* 0x35 (5) */ 246{ self_insert }, /* 0x36 (6) */ 247{ self_insert }, /* 0x37 (7) */ 248{ self_insert }, /* 0x38 (8) */ 249{ self_insert }, /* 0x39 (9) */ 250{ self_insert }, /* 0x3A (:) */ 251{ self_insert }, /* 0x3B (;) */ 252{ self_insert }, /* 0x3C (<) */ 253{ self_insert }, /* 0x3D (=) */ 254{ self_insert }, /* 0x3E (>) */ 255{ self_insert }, /* 0x3F (?) */ 256{ self_insert }, /* 0x40 (@) */ 257{ self_insert }, /* 0x41 (A) */ 258{ self_insert }, /* 0x42 (B) */ 259{ self_insert }, /* 0x43 (C) */ 260{ self_insert }, /* 0x44 (D) */ 261{ self_insert }, /* 0x45 (E) */ 262{ self_insert }, /* 0x46 (F) */ 263{ self_insert }, /* 0x47 (G) */ 264{ self_insert }, /* 0x48 (H) */ 265{ self_insert }, /* 0x49 (I) */ 266{ self_insert }, /* 0x4A (J) */ 267{ self_insert }, /* 0x4B (K) */ 268{ self_insert }, /* 0x4C (L) */ 269{ self_insert }, /* 0x4D (M) */ 270{ self_insert }, /* 0x4E (N) */ 271{ self_insert }, /* 0x4F (O) */ 272{ self_insert }, /* 0x50 (P) */ 273{ self_insert }, /* 0x51 (Q) */ 274{ self_insert }, /* 0x52 (R) */ 275{ self_insert }, /* 0x53 (S) */ 276{ self_insert }, /* 0x54 (T) */ 277{ self_insert }, /* 0x55 (U) */ 278{ self_insert }, /* 0x56 (V) */ 279{ self_insert }, /* 0x57 (W) */ 280{ self_insert }, /* 0x58 (X) */ 281{ self_insert }, /* 0x59 (W) */ 282{ self_insert }, /* 0x5A (Z) */ 283{ self_insert }, /* 0x5B ([) */ 284{ self_insert }, /* 0x5C (\) */ 285{ self_insert }, /* 0x5D (]) */ 286{ self_insert }, /* 0x5E (^) */ 287{ self_insert }, /* 0x5F (_) */ 288{ self_insert }, /* 0x60 (`) */ 289{ self_insert }, /* 0x61 (a) */ 290{ self_insert }, /* 0x62 (b) */ 291{ self_insert }, /* 0x63 (c) */ 292{ self_insert }, /* 0x64 (d) */ 293{ self_insert }, /* 0x65 (e) */ 294{ self_insert }, /* 0x66 (f) */ 295{ self_insert }, /* 0x67 (g) */ 296{ self_insert }, /* 0x68 (h) */ 297{ self_insert }, /* 0x69 (i) */ 298{ self_insert }, /* 0x6A (j) */ 299{ self_insert }, /* 0x6B (k) */ 300{ self_insert }, /* 0x6C (l) */ 301{ self_insert }, /* 0x6D (m) */ 302{ self_insert }, /* 0x6E (n) */ 303{ self_insert }, /* 0x6F (o) */ 304{ self_insert }, /* 0x70 (p) */ 305{ self_insert }, /* 0x71 (q) */ 306{ self_insert }, /* 0x72 (r) */ 307{ self_insert }, /* 0x73 (s) */ 308{ self_insert }, /* 0x74 (t) */ 309{ self_insert }, /* 0x75 (u) */ 310{ self_insert }, /* 0x76 (v) */ 311{ self_insert }, /* 0x77 (w) */ 312{ self_insert }, /* 0x78 (x) */ 313{ self_insert }, /* 0x79 (y) */ 314{ self_insert }, /* 0x7A (z) */ 315{ self_insert }, /* 0x7B ({) */ 316{ self_insert }, /* 0x7C (|) */ 317{ self_insert }, /* 0x7D (}) */ 318{ self_insert }, /* 0x7E (~) */ 319{ backward_delete_char }, /* 0x7F DEL */ 320}; 321 322int 323getline(prompt, buff) 324 char *prompt, *buff; 325{ 326 register int c; 327 328 bzero(linebuff, MAXLINE); 329 cursole = lineleft = strlen(prompt); 330 endline = lineright = MAXLINE - 1; 331 printf("%s", prompt); 332 333 do { 334 c = cngetc(); 335 c &= 0x7F; 336 } while((*keybind[c].func)(c)); 337 338 bcopy(&linebuff[lineleft], 339 &buff[0], cursole - lineleft); 340 bcopy(&linebuff[endline+1], 341 &buff[cursole - lineleft], lineright - endline); 342 343 return(strlen(buff)); 344} 345