|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_COPYRIGHT@
24: */
25: /*
26: * HISTORY
27: *
28: * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
29: * Import of Mac OS X kernel (~semeria)
30: *
31: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
32: * Import of OSF Mach kernel (~mburg)
33: *
34: * Revision 1.3.10.2 1994/09/23 01:19:37 ezf
35: * change marker to not FREE
36: * [1994/09/22 21:10:05 ezf]
37: *
38: * Revision 1.3.10.1 1994/06/11 21:11:48 bolinger
39: * Merge up to NMK17.2.
40: * [1994/06/11 20:01:41 bolinger]
41: *
42: * Revision 1.3.8.2 1994/02/11 14:21:41 paire
43: * Added string.h header file for strlen declaration.
44: * [94/02/09 paire]
45: *
46: * Revision 1.3.8.1 1994/02/08 10:57:55 bernadat
47: * Added db_auto_completion variable.
48: * [93/08/17 paire]
49: *
50: * Added support of symbol completion by typing '\t'.
51: * [93/08/14 paire]
52: * [94/02/07 bernadat]
53: *
54: * Revision 1.3.2.4 1993/08/11 20:37:51 elliston
55: * Add ANSI Prototypes. CR #9523.
56: * [1993/08/11 03:33:21 elliston]
57: *
58: * Revision 1.3.2.3 1993/07/27 18:27:30 elliston
59: * Add ANSI prototypes. CR #9523.
60: * [1993/07/27 18:12:01 elliston]
61: *
62: * Revision 1.3.2.2 1993/06/09 02:20:13 gm
63: * CR9176 - ANSI C violations: trailing tokens on CPP
64: * directives, extra semicolons after decl_ ..., asm keywords
65: * [1993/06/07 18:57:14 jeffc]
66: *
67: * Added to OSF/1 R1.3 from NMK15.0.
68: * [1993/06/02 20:56:26 jeffc]
69: *
70: * Revision 1.3 1993/04/19 16:02:17 devrcs
71: * Replaced ^R (redraw) with ^L [[email protected]]
72: *
73: * Added ^R and ^S commands for history search commands
74: * ^U does not erase end of the line anymore. (only erases
75: * from the beginning of the line to current position).
76: * [[email protected]]
77: *
78: * ^C now erases the entire line. [[email protected]]
79: * [92/12/03 bernadat]
80: *
81: * Fixed history management: Do not store repeated typed
82: * command. Null terminate current command in case it is a
83: * substring of the last command.
84: * [92/10/02 bernadat]
85: *
86: * Revision 1.2 1992/11/25 01:04:24 robert
87: * integrate changes for norma_14 below
88: *
89: * Philippe Bernadat (bernadat) at gr.osf.org 02-Oct-92
90: * Fixed history management: Do not store repeated typed
91: * command. Null terminate current command in case it is a
92: * substring of the last command.
93: * [1992/11/20 00:56:07 robert]
94: *
95: * integrate changes below for norma_14
96: * [1992/11/13 19:21:34 robert]
97: *
98: * Revision 1.1 1992/09/30 02:01:08 robert
99: * Initial revision
100: *
101: * $EndLog$
102: */
103: /* CMU_HIST */
104: /*
105: * Revision 2.7.3.2 92/09/15 17:14:26 jeffreyh
106: * Fixed history code. (Only one char. out of 2 was checked to
107: * compare to last command)
108: * [[email protected]]
109: *
110: * Revision 2.7.3.1 92/03/03 16:13:30 jeffreyh
111: * Pick up changes from TRUNK
112: * [92/02/26 10:59:36 jeffreyh]
113: *
114: * Revision 2.8 92/02/19 15:07:44 elf
115: * Added delete_line (Ctrl-U).
116: * [92/02/17 kivinen]
117: *
118: * Added command line history. Ctrl-P = previous, Ctrl-N = next. If
119: * DB_HISTORY_SIZE is 0 then command history is disabled.
120: * [92/02/17 kivinen]
121: *
122: * Revision 2.7 91/10/09 16:00:03 af
123: * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh
124: * Fixed incorrect db_lbuf_end setting.
125: * [91/08/29 tak]
126: *
127: * Revision 2.6.2.1 91/10/05 13:06:12 jeffreyh
128: * Fixed incorrect db_lbuf_end setting.
129: * [91/08/29 tak]
130: *
131: * Revision 2.6 91/07/09 23:15:49 danner
132: * Add include of machine/db_machdep.h to allow machine-specific
133: * overrides via defines.
134: * [91/07/08 danner]
135: *
136: * Revision 2.5 91/05/14 15:34:03 mrt
137: * Correcting copyright
138: *
139: * Revision 2.4 91/02/14 14:41:53 mrt
140: * Add input line editing.
141: * [90/11/11 dbg]
142: *
143: * Revision 2.3 91/02/05 17:06:32 mrt
144: * Changed to new Mach copyright
145: * [91/01/31 16:18:13 mrt]
146: *
147: * Revision 2.2 90/08/27 21:51:03 dbg
148: * Reduce lint.
149: * [90/08/07 dbg]
150: * Created.
151: * [90/07/25 dbg]
152: *
153: */
154: /* CMU_ENDHIST */
155: /*
156: * Mach Operating System
157: * Copyright (c) 1991,1990 Carnegie Mellon University
158: * All Rights Reserved.
159: *
160: * Permission to use, copy, modify and distribute this software and its
161: * documentation is hereby granted, provided that both the copyright
162: * notice and this permission notice appear in all copies of the
163: * software, derivative works or modified versions, and any portions
164: * thereof, and that both notices appear in supporting documentation.
165: *
166: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
167: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
168: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
169: *
170: * Carnegie Mellon requests users of this software to return to
171: *
172: * Software Distribution Coordinator or [email protected]
173: * School of Computer Science
174: * Carnegie Mellon University
175: * Pittsburgh PA 15213-3890
176: *
177: * any improvements or extensions that they make and grant Carnegie Mellon
178: * the rights to redistribute these changes.
179: */
180: /*
181: */
182: /*
183: * Author: David B. Golub, Carnegie Mellon University
184: * Date: 7/90
185: */
186:
187: #include <string.h>
188: #include <mach/boolean.h>
189: #include <machine/db_machdep.h>
190: #include <kern/misc_protos.h>
191: #include <ddb/db_output.h>
192: #include <ddb/db_lex.h>
193: #include <ddb/db_command.h>
194: #include <ddb/db_input.h>
195: #include <ddb/db_sym.h>
196:
197: #ifndef DB_HISTORY_SIZE
198: #define DB_HISTORY_SIZE 4000
199: #endif /* DB_HISTORY_SIZE */
200:
201: /*
202: * Character input and editing.
203: */
204:
205: /*
206: * We don't track output position while editing input,
207: * since input always ends with a new-line. We just
208: * reset the line position at the end.
209: */
210: char * db_lbuf_start; /* start of input line buffer */
211: char * db_lbuf_end; /* end of input line buffer */
212: char * db_lc; /* current character */
213: char * db_le; /* one past last character */
214: int db_completion; /* number of incomplete symbols matched */
215: int db_auto_completion = 10; /* number of line to display without asking */
216: #if DB_HISTORY_SIZE != 0
217: char db_history[DB_HISTORY_SIZE]; /* start of history buffer */
218: int db_history_size = DB_HISTORY_SIZE;/* size of history buffer */
219: char * db_history_curr = db_history; /* start of current line */
220: char * db_history_last = db_history; /* start of last line */
221: char * db_history_prev = (char *) 0; /* start of previous line */
222: int db_hist_unmodified = 0; /* unmodified line from history */
223: int db_hist_search = 0; /* are we in hist search mode ? */
224: char db_hist_search_string[DB_LEX_LINE_SIZE];/* the string to look for */
225: int db_hist_ignore_dups = 0; /* don't duplicate commands in hist */
226: #endif
227:
228: #define CTRL(c) ((c) & 0x1f)
229: #define isspace(c) ((c) == ' ' || (c) == '\t')
230: #define BLANK ' '
231: #define BACKUP '\b'
232:
233:
234:
235: /* Prototypes for functions local to this file. XXX -- should be static!
236: */
237: void db_putstring(
238: char *s,
239: int count);
240:
241: void db_putnchars(
242: int c,
243: int count);
244:
245: void db_delete(
246: int n,
247: int bwd);
248:
249: void db_delete_line(void);
250:
251: boolean_t db_hist_substring(
252: char *string,
253: char *substring);
254:
255: boolean_t db_inputchar(int c);
256:
257: extern jmp_buf_t *db_recover;
258:
259: void
260: db_putstring(
261: char *s,
262: int count)
263: {
264: while (--count >= 0)
265: cnputc(*s++);
266: }
267:
268: void
269: db_putnchars(
270: int c,
271: int count)
272: {
273: while (--count >= 0)
274: cnputc(c);
275: }
276:
277: /*
278: * Delete N characters, forward or backward
279: */
280: #define DEL_FWD 0
281: #define DEL_BWD 1
282: void
283: db_delete(
284: int n,
285: int bwd)
286: {
287: register char *p;
288:
289: if (bwd) {
290: db_lc -= n;
291: db_putnchars(BACKUP, n);
292: }
293: for (p = db_lc; p < db_le-n; p++) {
294: *p = *(p+n);
295: cnputc(*p);
296: }
297: db_putnchars(BLANK, n);
298: db_putnchars(BACKUP, db_le - db_lc);
299: db_le -= n;
300: }
301:
302: void
303: db_delete_line(void)
304: {
305: db_delete(db_le - db_lc, DEL_FWD);
306: db_delete(db_lc - db_lbuf_start, DEL_BWD);
307: db_le = db_lc = db_lbuf_start;
308: }
309:
310: #if DB_HISTORY_SIZE != 0
311: #define INC_DB_CURR() \
312: do { \
313: db_history_curr++; \
314: if (db_history_curr > \
315: db_history + db_history_size - 1) \
316: db_history_curr = db_history; \
317: } while (0)
318: #define DEC_DB_CURR() \
319: do { \
320: db_history_curr--; \
321: if (db_history_curr < db_history) \
322: db_history_curr = db_history + \
323: db_history_size - 1; \
324: } while (0)
325: #endif
326:
327: /* returs TRUE if "substring" is a substring of "string" */
328: boolean_t
329: db_hist_substring(
330: char *string,
331: char *substring)
332: {
333: register char *cp1, *cp2;
334:
335: cp1 = string;
336: while (*cp1)
337: cp1++;
338: cp2 = substring;
339: while (*cp2)
340: cp2++;
341:
342: while (cp2 > substring) {
343: cp1--; cp2--;
344: }
345:
346: while (cp1 >= string) {
347: register char *cp3;
348:
349: cp2 = substring;
350: cp3 = cp1;
351: while (*cp2 && *cp2 == *cp3) {
352: cp2++; cp3++;
353: }
354: if (*cp2 == '\0') {
355: return TRUE;
356: }
357: cp1--;
358: }
359: return FALSE;
360: }
361:
362: /* returns TRUE at end-of-line */
363: boolean_t
364: db_inputchar(int c)
365: {
366: char *sym;
367: char *start;
368: char *restart;
369: jmp_buf_t db_jmpbuf;
370: jmp_buf_t *db_prev;
371: char *p;
372: int len;
373:
374: switch(db_completion) {
375: case -1:
376: db_putchar('\n');
377: db_prev = db_recover;
378: if (_setjmp(db_recover = &db_jmpbuf) == 0 &&
379: (c == 'y' || c == ' ' || c == '\t'))
380: db_print_completion(db_tok_string);
381: db_recover = db_prev;
382: db_completion = 0;
383: db_reset_more();
384: db_output_prompt();
385: if (db_le > db_lbuf_start) {
386: for (start = db_lbuf_start; start < db_le; start++)
387: db_putchar(*start);
388: db_putnchars(BACKUP, db_le - db_lc);
389: }
390: return(FALSE);
391:
392: case 0:
393: break;
394:
395: default:
396: if (c == '\t') {
397: db_printf("\nThere are %d possibilities. ", db_completion);
398: db_printf("Do you really wish to see them all [n] ? ");
399: db_force_whitespace();
400: db_completion = -1;
401: db_reset_more();
402: return(FALSE);
403: }
404: db_completion = 0;
405: break;
406: }
407:
408: switch (c) {
409: case '\t':
410: /* symbol completion */
411: if (db_lc == db_lbuf_start || db_auto_completion == 0)
412: break;
413: if (db_le == db_lbuf_end) {
414: cnputc('\007');
415: break;
416: }
417: start = db_lc - 1;
418: while (start >= db_lbuf_start &&
419: ((*start >= 'A' && *start <= 'Z') ||
420: (*start >= 'a' && *start <= 'z') ||
421: (*start >= '0' && *start <= '9') ||
422: *start == '_' || *start == ':'))
423: start--;
424: if (start == db_lc - 1)
425: break;
426: if (start > db_lbuf_start && *start == '$') {
427: cnputc('\007');
428: break;
429: }
430: sym = db_tok_string;
431: restart = ++start;
432: do {
433: *sym++ = *start++;
434: } while (start != db_lc &&
435: sym != db_tok_string + sizeof(db_tok_string));
436: if (sym == db_tok_string + sizeof(db_tok_string)) {
437: cnputc('\007');
438: break;
439: }
440: *sym = '\0';
441: db_completion = db_lookup_incomplete(db_tok_string,
442: sizeof(db_tok_string));
443: if (db_completion == 0) {
444: /* symbol unknown */
445: cnputc('\007');
446: break;
447: }
448:
449: len = strlen(db_tok_string) - (start - restart);
450: if (db_completion == 1 &&
451: (db_le == db_lc ||
452: (db_le > db_lc) && *db_lc != ' '))
453: len++;
454: for (p = db_le - 1; p >= db_lc; p--)
455: *(p + len) = *p;
456: db_le += len;
457: for (sym = &db_tok_string[start - restart];
458: *sym != '\0'; sym++)
459: *db_lc++ = *sym;
460:
461: if (db_completion == 1 || db_completion > db_auto_completion) {
462: for (sym = &db_tok_string[start - restart];
463: *sym != '\0'; sym++)
464: cnputc(*sym);
465: if (db_completion == 1) {
466: if (db_le == db_lc ||
467: (db_le > db_lc) && *db_lc != ' ') {
468: cnputc(' ');
469: *db_lc++ = ' ';
470: }
471: db_completion = 0;
472: }
473: db_putstring(db_lc, db_le - db_lc);
474: db_putnchars(BACKUP, db_le - db_lc);
475: }
476:
477: if (db_completion > 1) {
478: cnputc('\007');
479: if (db_completion <= db_auto_completion) {
480: db_putchar('\n');
481: db_print_completion(db_tok_string);
482: db_completion = 0;
483: db_reset_more();
484: db_output_prompt();
485: if (db_le > db_lbuf_start) {
486: for (start = db_lbuf_start; start < db_le; start++)
487: db_putchar(*start);
488: db_putnchars(BACKUP, db_le - db_lc);
489: }
490: }
491: }
492: break;
493:
494: case CTRL('b'):
495: /* back up one character */
496: if (db_lc > db_lbuf_start) {
497: cnputc(BACKUP);
498: db_lc--;
499: }
500: break;
501: case CTRL('f'):
502: /* forward one character */
503: if (db_lc < db_le) {
504: cnputc(*db_lc);
505: db_lc++;
506: }
507: break;
508: case CTRL('a'):
509: /* beginning of line */
510: while (db_lc > db_lbuf_start) {
511: cnputc(BACKUP);
512: db_lc--;
513: }
514: break;
515: case CTRL('e'):
516: /* end of line */
517: while (db_lc < db_le) {
518: cnputc(*db_lc);
519: db_lc++;
520: }
521: break;
522: case CTRL('h'):
523: case 0177:
524: /* erase previous character */
525: if (db_lc > db_lbuf_start)
526: db_delete(1, DEL_BWD);
527: break;
528: case CTRL('d'):
529: /* erase next character */
530: if (db_lc < db_le)
531: db_delete(1, DEL_FWD);
532: break;
533: case CTRL('k'):
534: /* delete to end of line */
535: if (db_lc < db_le)
536: db_delete(db_le - db_lc, DEL_FWD);
537: break;
538: case CTRL('u'):
539: /* delete to beginning of line */
540: if (db_lc > db_lbuf_start)
541: db_delete(db_lc - db_lbuf_start, DEL_BWD);
542: break;
543: case CTRL('t'):
544: /* twiddle last 2 characters */
545: if (db_lc >= db_lbuf_start + 2) {
546: c = db_lc[-2];
547: db_lc[-2] = db_lc[-1];
548: db_lc[-1] = c;
549: cnputc(BACKUP);
550: cnputc(BACKUP);
551: cnputc(db_lc[-2]);
552: cnputc(db_lc[-1]);
553: }
554: break;
555: case CTRL('c'):
556: case CTRL('g'):
557: db_delete_line();
558: #if DB_HISTORY_SIZE != 0
559: db_history_curr = db_history_last;
560: if (c == CTRL('g') && db_hist_search) {
561: char *p;
562: for (p = db_hist_search_string, db_le = db_lbuf_start;
563: *p; ) {
564: *db_le++ = *p++;
565: }
566: db_lc = db_le;
567: *db_le = '\0';
568: db_putstring(db_lbuf_start, db_le - db_lbuf_start);
569: }
570: #endif
571: break;
572: #if DB_HISTORY_SIZE != 0
573: case CTRL('r'):
574: if (db_hist_search++ == 0) {
575: /* starting an history lookup */
576: register char *cp1, *cp2;
577: for (cp1 = db_lbuf_start, cp2 = db_hist_search_string;
578: cp1 < db_le;
579: cp1++, cp2++)
580: *cp2 = *cp1;
581: *cp2 = '\0';
582: db_hist_search++;
583: }
584: /* FALL THROUGH */
585: case CTRL('p'):
586: {
587: char * old_history_curr = db_history_curr;
588:
589: if (db_hist_unmodified++ == 0)
590: db_hist_unmodified++;
591: DEC_DB_CURR();
592: while (db_history_curr != db_history_last) {
593: DEC_DB_CURR();
594: if (*db_history_curr == '\0') {
595: INC_DB_CURR();
596: if (db_hist_search <= 1) {
597: if (*db_history_curr == '\0')
598: cnputc('\007');
599: else
600: DEC_DB_CURR();
601: break;
602: }
603: if (*db_history_curr == '\0') {
604: cnputc('\007');
605: db_history_curr = old_history_curr;
606: DEC_DB_CURR();
607: break;
608: }
609: if (db_history_curr != db_history_last &&
610: db_hist_substring(db_history_curr,
611: db_hist_search_string)) {
612: DEC_DB_CURR();
613: break;
614: }
615: DEC_DB_CURR();
616: }
617: }
618: if (db_history_curr == db_history_last) {
619: cnputc('\007');
620: db_history_curr = old_history_curr;
621: } else {
622: register char *p;
623: INC_DB_CURR();
624: db_delete_line();
625: for (p = db_history_curr, db_le = db_lbuf_start;
626: *p; ) {
627: *db_le++ = *p++;
628: if (p == db_history + db_history_size) {
629: p = db_history;
630: }
631: }
632: db_lc = db_le;
633: *db_le = '\0';
634: db_putstring(db_lbuf_start, db_le - db_lbuf_start);
635: }
636: break;
637: }
638: case CTRL('s'):
639: if (db_hist_search++ == 0) {
640: /* starting an history lookup */
641: register char *cp1, *cp2;
642: for (cp1 = db_lbuf_start, cp2 = db_hist_search_string;
643: cp1 < db_le;
644: cp1++, cp2++)
645: *cp2 = *cp1;
646: *cp2 = '\0';
647: db_hist_search++;
648: }
649: /* FALL THROUGH */
650: case CTRL('n'):
651: {
652: char *old_history_curr = db_history_curr;
653:
654: if (db_hist_unmodified++ == 0)
655: db_hist_unmodified++;
656: while (db_history_curr != db_history_last) {
657: if (*db_history_curr == '\0') {
658: if (db_hist_search <= 1)
659: break;
660: INC_DB_CURR();
661: if (db_history_curr != db_history_last &&
662: db_hist_substring(db_history_curr,
663: db_hist_search_string)) {
664: DEC_DB_CURR();
665: break;
666: }
667: DEC_DB_CURR();
668: }
669: INC_DB_CURR();
670: }
671: if (db_history_curr != db_history_last) {
672: INC_DB_CURR();
673: if (db_history_curr != db_history_last) {
674: register char *p;
675: db_delete_line();
676: for (p = db_history_curr,
677: db_le = db_lbuf_start; *p;) {
678: *db_le++ = *p++;
679: if (p == db_history +
680: db_history_size) {
681: p = db_history;
682: }
683: }
684: db_lc = db_le;
685: *db_le = '\0';
686: db_putstring(db_lbuf_start,
687: db_le - db_lbuf_start);
688: } else {
689: cnputc('\007');
690: db_history_curr = old_history_curr;
691: }
692: } else {
693: cnputc('\007');
694: db_history_curr = old_history_curr;
695: }
696: break;
697: }
698: #endif
699: /* refresh the command line */
700: case CTRL('l'):
701: db_putstring("^L\n", 3);
702: if (db_le > db_lbuf_start) {
703: db_putstring(db_lbuf_start, db_le - db_lbuf_start);
704: db_putnchars(BACKUP, db_le - db_lc);
705: }
706: break;
707: case '\n':
708: case '\r':
709: #if DB_HISTORY_SIZE != 0
710: /* Check if it same than previous line */
711: if (db_history_prev) {
712: register char *pp, *pc;
713:
714: /* Is it unmodified */
715: for (p = db_history_prev, pc = db_lbuf_start;
716: pc != db_le && *p;) {
717: if (*p != *pc)
718: break;
719: if (++p == db_history + db_history_size) {
720: p = db_history;
721: }
722: if (++pc == db_history + db_history_size) {
723: pc = db_history;
724: }
725: }
726: if (!*p && pc == db_le) {
727: /* Repeted previous line, not saved */
728: db_history_curr = db_history_last;
729: *db_le++ = c;
730: db_hist_search = 0;
731: db_hist_unmodified = 0;
732: return (TRUE);
733: }
734: }
735: if (db_le != db_lbuf_start &&
736: (db_hist_unmodified == 0 || !db_hist_ignore_dups)) {
737: db_history_prev = db_history_last;
738: for (p = db_lbuf_start; p != db_le; p++) {
739: *db_history_last++ = *p;
740: if (db_history_last == db_history +
741: db_history_size) {
742: db_history_last = db_history;
743: }
744: }
745: *db_history_last++ = '\0';
746: }
747: db_history_curr = db_history_last;
748: #endif
749: *db_le++ = c;
750: db_hist_search = 0;
751: db_hist_unmodified = 0;
752: return (TRUE);
753: default:
754: if (db_le == db_lbuf_end) {
755: cnputc('\007');
756: }
757: else if (c >= ' ' && c <= '~') {
758: for (p = db_le; p > db_lc; p--)
759: *p = *(p-1);
760: *db_lc++ = c;
761: db_le++;
762: cnputc(c);
763: db_putstring(db_lc, db_le - db_lc);
764: db_putnchars(BACKUP, db_le - db_lc);
765: }
766: break;
767: }
768: if (db_hist_search)
769: db_hist_search--;
770: if (db_hist_unmodified)
771: db_hist_unmodified--;
772: return (FALSE);
773: }
774:
775: int
776: db_readline(
777: char * lstart,
778: int lsize)
779: {
780: db_force_whitespace(); /* synch output position */
781:
782: db_lbuf_start = lstart;
783: db_lbuf_end = lstart + lsize - 1;
784: db_lc = lstart;
785: db_le = lstart;
786:
787: while (!db_inputchar(cngetc()))
788: continue;
789:
790: db_putchar('\n'); /* synch output position */
791:
792: *db_le = 0;
793: return (db_le - db_lbuf_start);
794: }
795:
796: void
797: db_check_interrupt(void)
798: {
799: register int c;
800:
801: c = cnmaygetc();
802: switch (c) {
803: case -1: /* no character */
804: return;
805:
806: case CTRL('c'):
807: db_error((char *)0);
808: /*NOTREACHED*/
809:
810: case CTRL('s'):
811: do {
812: c = cnmaygetc();
813: if (c == CTRL('c'))
814: db_error((char *)0);
815: } while (c != CTRL('q'));
816: break;
817:
818: default:
819: /* drop on floor */
820: break;
821: }
822: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.