|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 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.
1.1.1.2 root 11: *
1.1 root 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 7/90
29: */
1.1.1.3 ! root 30:
1.1 root 31: #if MACH_KDB
32:
33: /*
34: * Lexical analyzer.
35: */
1.1.1.3 ! root 36: #include <string.h>
1.1 root 37: #include <machine/db_machdep.h>
1.1.1.3 ! root 38: #include <ddb/db_command.h>
! 39: #include <ddb/db_examine.h>
! 40: #include <ddb/db_input.h>
1.1 root 41: #include <ddb/db_lex.h>
1.1.1.3 ! root 42: #include <ddb/db_output.h>
1.1 root 43:
44: char db_line[DB_LEX_LINE_SIZE];
45: char db_last_line[DB_LEX_LINE_SIZE];
46: char *db_lp, *db_endlp;
47: char *db_last_lp;
48: int db_look_char = 0;
49: db_expr_t db_look_token = 0;
50:
51: int
52: db_read_line(repeat_last)
53: char *repeat_last;
54: {
55: int i;
56:
57: i = db_readline(db_line, sizeof(db_line));
58: if (i == 0)
59: return (0); /* EOI */
60: if (repeat_last) {
61: if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) {
62: db_strcpy(db_line, db_last_line);
63: db_printf("%s", db_line);
64: i = strlen(db_line);
65: } else if (db_line[0] != '\n' && db_line[0] != 0)
66: db_strcpy(db_last_line, db_line);
67: }
68: db_lp = db_line;
69: db_endlp = db_lp + i;
70: db_last_lp = db_lp;
71: db_look_char = 0;
72: db_look_token = 0;
73: return (i);
74: }
75:
76: void
1.1.1.3 ! root 77: db_flush_line(void)
1.1 root 78: {
79: db_lp = db_line;
80: db_last_lp = db_lp;
81: db_endlp = db_line;
82: }
83:
84: void
85: db_switch_input(buffer, size)
86: char *buffer;
87: int size;
88: {
89: db_lp = buffer;
90: db_last_lp = db_lp;
91: db_endlp = buffer + size;
92: db_look_char = 0;
93: db_look_token = 0;
94: }
95:
96: void
97: db_save_lex_context(lp)
98: register struct db_lex_context *lp;
99: {
100: lp->l_ptr = db_lp;
101: lp->l_eptr = db_endlp;
102: lp->l_char = db_look_char;
103: lp->l_token = db_look_token;
104: }
105:
106: void
107: db_restore_lex_context(lp)
108: register struct db_lex_context *lp;
109: {
110: db_lp = lp->l_ptr;
111: db_last_lp = db_lp;
112: db_endlp = lp->l_eptr;
113: db_look_char = lp->l_char;
114: db_look_token = lp->l_token;
115: }
116:
117: int
1.1.1.3 ! root 118: db_read_char(void)
1.1 root 119: {
120: int c;
121:
122: if (db_look_char != 0) {
123: c = db_look_char;
124: db_look_char = 0;
125: }
126: else if (db_lp >= db_endlp)
127: c = -1;
1.1.1.2 root 128: else
1.1 root 129: c = *db_lp++;
130: return (c);
131: }
132:
133: void
134: db_unread_char(c)
135: int c;
136: {
137: db_look_char = c;
138: }
139:
140: void
141: db_unread_token(t)
142: int t;
143: {
144: db_look_token = t;
145: }
146:
147: int
1.1.1.3 ! root 148: db_read_token(void)
1.1 root 149: {
150: int t;
151:
152: if (db_look_token) {
153: t = db_look_token;
154: db_look_token = 0;
155: }
156: else {
157: db_last_lp = db_lp;
158: if (db_look_char)
159: db_last_lp--;
160: t = db_lex();
161: }
162: return (t);
163: }
164:
165: db_expr_t db_tok_number;
166: char db_tok_string[TOK_STRING_SIZE];
167: db_expr_t db_radix = 16;
168:
169: void
1.1.1.3 ! root 170: db_flush_lex(void)
1.1 root 171: {
172: db_flush_line();
173: db_look_char = 0;
174: db_look_token = 0;
175: }
176:
177: #define DB_DISP_SKIP 40 /* number of chars to display skip */
178:
179: void
1.1.1.3 ! root 180: db_skip_to_eol(void)
1.1 root 181: {
1.1.1.3 ! root 182: register int skip;
! 183: register int t;
! 184: register int n;
1.1 root 185: register char *p;
186:
187: t = db_read_token();
188: p = db_last_lp;
189: for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
190: t = db_read_token();
191: if (t == tSEMI_COLON)
192: db_unread_token(t);
193: if (skip != 0) {
194: while (p < db_last_lp && (*p == ' ' || *p == '\t'))
195: p++;
196: db_printf("Warning: Skipped input data \"");
197: for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
198: db_printf("%c", *p++);
199: if (n >= DB_DISP_SKIP)
200: db_printf("....");
201: db_printf("\"\n");
202: }
203: }
204:
205: int
1.1.1.3 ! root 206: db_lex(void)
1.1 root 207: {
208: register char *cp;
1.1.1.3 ! root 209: register int c;
1.1 root 210:
211: c = db_read_char();
212: while (c <= ' ' || c > '~') {
213: if (c == '\n' || c == -1)
214: return (tEOL);
215: c = db_read_char();
216: }
217:
218: cp = db_tok_string;
219: *cp++ = c;
220:
221: if (c >= '0' && c <= '9') {
222: /* number */
223: int r, digit;
224:
225: if (c > '0')
226: r = db_radix;
227: else {
228: c = db_read_char();
229: if (c == 'O' || c == 'o')
230: r = 8;
231: else if (c == 'T' || c == 't')
232: r = 10;
233: else if (c == 'X' || c == 'x')
234: r = 16;
235: else {
236: cp--;
237: r = db_radix;
238: db_unread_char(c);
239: }
240: c = db_read_char();
241: *cp++ = c;
242: }
243: db_tok_number = 0;
244: for (;;) {
245: if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
246: digit = c - '0';
247: else if (r == 16 && ((c >= 'A' && c <= 'F') ||
248: (c >= 'a' && c <= 'f'))) {
249: if (c >= 'a')
250: digit = c - 'a' + 10;
251: else
252: digit = c - 'A' + 10;
253: }
254: else
255: break;
256: db_tok_number = db_tok_number * r + digit;
257: c = db_read_char();
258: if (cp < &db_tok_string[sizeof(db_tok_string)-1])
259: *cp++ = c;
260: }
261: cp[-1] = 0;
262: if ((c >= '0' && c <= '9') ||
263: (c >= 'A' && c <= 'Z') ||
264: (c >= 'a' && c <= 'z') ||
265: (c == '_'))
266: {
1.1.1.2 root 267: db_printf("Bad character '%c' after number %s\n",
1.1 root 268: c, db_tok_string);
269: db_error(0);
270: db_flush_lex();
271: return (tEOF);
272: }
273: db_unread_char(c);
274: return (tNUMBER);
275: }
276: if ((c >= 'A' && c <= 'Z') ||
277: (c >= 'a' && c <= 'z') ||
278: c == '_' || c == '\\' || c == ':')
279: {
280: /* identifier */
281: if (c == '\\') {
282: c = db_read_char();
283: if (c == '\n' || c == -1)
284: db_error("Bad '\\' at the end of line\n");
285: cp[-1] = c;
286: }
287: while (1) {
288: c = db_read_char();
289: if ((c >= 'A' && c <= 'Z') ||
290: (c >= 'a' && c <= 'z') ||
291: (c >= '0' && c <= '9') ||
292: c == '_' || c == '\\' || c == ':' || c == '.')
293: {
294: if (c == '\\') {
295: c = db_read_char();
296: if (c == '\n' || c == -1)
297: db_error("Bad '\\' at the end of line\n");
298: }
299: *cp++ = c;
300: if (cp == db_tok_string+sizeof(db_tok_string)) {
301: db_error("String too long\n");
302: db_flush_lex();
303: return (tEOF);
304: }
305: continue;
306: }
307: else {
308: *cp = '\0';
309: break;
310: }
311: }
312: db_unread_char(c);
313: return (tIDENT);
314: }
315:
316: *cp = 0;
317: switch (c) {
318: case '+':
319: return (tPLUS);
320: case '-':
321: return (tMINUS);
322: case '.':
323: c = db_read_char();
324: if (c == '.') {
325: *cp++ = c;
326: *cp = 0;
327: return (tDOTDOT);
328: }
329: db_unread_char(c);
330: return (tDOT);
331: case '*':
332: return (tSTAR);
333: case '/':
334: return (tSLASH);
335: case '=':
336: c = db_read_char();
337: if (c == '=') {
338: *cp++ = c;
339: *cp = 0;
340: return(tLOG_EQ);
341: }
342: db_unread_char(c);
343: return (tEQ);
344: case '%':
345: return (tPCT);
346: case '#':
347: return (tHASH);
348: case '(':
349: return (tLPAREN);
350: case ')':
351: return (tRPAREN);
352: case ',':
353: return (tCOMMA);
354: case '\'':
355: return (tQUOTE);
356: case '"':
357: /* string */
358: cp = db_tok_string;
359: c = db_read_char();
360: while (c != '"' && c > 0 && c != '\n') {
361: if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
362: db_error("Too long string\n");
363: db_flush_lex();
364: return (tEOF);
365: }
366: if (c == '\\') {
367: c = db_read_char();
368: switch(c) {
369: case 'n':
370: c = '\n'; break;
371: case 't':
372: c = '\t'; break;
373: case '\\':
374: case '"':
375: break;
376: default:
377: db_printf("Bad escape sequence '\\%c'\n", c);
378: db_error(0);
379: db_flush_lex();
380: return (tEOF);
381: }
382: }
383: *cp++ = c;
384: c = db_read_char();
385: }
386: *cp = 0;
387: if (c != '"') {
388: db_error("Non terminated string constant\n");
389: db_flush_lex();
390: return (tEOF);
391: }
392: return (tSTRING);
393: case '$':
394: return (tDOLLAR);
395: case '!':
396: c = db_read_char();
397: if (c == '=') {
398: *cp++ = c;
399: *cp = 0;
400: return(tLOG_NOT_EQ);
401: }
402: db_unread_char(c);
403: return (tEXCL);
404: case '&':
405: c = db_read_char();
406: if (c == '&') {
407: *cp++ = c;
408: *cp = 0;
409: return(tLOG_AND);
410: }
411: db_unread_char(c);
412: return(tBIT_AND);
413: case '|':
414: c = db_read_char();
415: if (c == '|') {
416: *cp++ = c;
417: *cp = 0;
418: return(tLOG_OR);
419: }
420: db_unread_char(c);
421: return(tBIT_OR);
422: case '<':
423: c = db_read_char();
424: *cp++ = c;
425: *cp = 0;
426: if (c == '<')
427: return (tSHIFT_L);
428: if (c == '=')
429: return (tLESS_EQ);
430: cp[-1] = 0;
431: db_unread_char(c);
432: return(tLESS);
433: break;
434: case '>':
435: c = db_read_char();
436: *cp++ = c;
437: *cp = 0;
438: if (c == '>')
439: return (tSHIFT_R);
440: if (c == '=')
441: return (tGREATER_EQ);
442: cp[-1] = 0;
443: db_unread_char(c);
444: return (tGREATER);
445: break;
446: case ';':
447: return (tSEMI_COLON);
448: case '?':
449: return (tQUESTION);
450: case -1:
451: db_strcpy(db_tok_string, "<EOL>");
452: return (tEOF);
453: }
454: db_printf("Bad character '%c'\n", c);
455: db_flush_lex();
456: return (tEOF);
457: }
458:
1.1.1.2 root 459: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.