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