Annotation of sys/ddb/db_lex.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: db_lex.c,v 1.9 2006/03/13 06:23:20 jsg Exp $ */
2: /* $NetBSD: db_lex.c,v 1.8 1996/02/05 01:57:05 christos Exp $ */
3:
4: /*
5: * Mach Operating System
6: * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
7: * All Rights Reserved.
8: *
9: * Permission to use, copy, modify and distribute this software and its
10: * documentation is hereby granted, provided that both the copyright
11: * notice and this permission notice appear in all copies of the
12: * software, derivative works or modified versions, and any portions
13: * thereof, and that both notices appear in supporting documentation.
14: *
15: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie Mellon
27: * the rights to redistribute these changes.
28: *
29: * Author: David B. Golub, Carnegie Mellon University
30: * Date: 7/90
31: */
32:
33: /*
34: * Lexical analyzer.
35: */
36: #include <sys/param.h>
37: #include <sys/proc.h>
38:
39: #include <uvm/uvm_extern.h>
40:
41: #include <machine/db_machdep.h>
42:
43: #include <ddb/db_lex.h>
44: #include <ddb/db_output.h>
45: #include <ddb/db_command.h>
46: #include <ddb/db_sym.h>
47: #include <ddb/db_extern.h>
48: #include <ddb/db_var.h>
49:
50: char db_line[120];
51: char * db_lp, *db_endlp;
52:
53: db_expr_t db_tok_number;
54: char db_tok_string[TOK_STRING_SIZE];
55:
56: int
57: db_read_line(void)
58: {
59: int i;
60:
61: i = db_readline(db_line, sizeof(db_line));
62: if (i == 0)
63: return (0); /* EOI */
64: db_lp = db_line;
65: db_endlp = db_lp + i;
66: return (i);
67: }
68:
69: void
70: db_flush_line(void)
71: {
72: db_lp = db_line;
73: db_endlp = db_line;
74: }
75:
76: int db_look_char = 0;
77:
78: int
79: db_read_char(void)
80: {
81: int c;
82:
83: if (db_look_char != 0) {
84: c = db_look_char;
85: db_look_char = 0;
86: }
87: else if (db_lp >= db_endlp)
88: c = -1;
89: else
90: c = *db_lp++;
91: return (c);
92: }
93:
94: void
95: db_unread_char(int c)
96: {
97: db_look_char = c;
98: }
99:
100: int db_look_token = 0;
101:
102: void
103: db_unread_token(int t)
104: {
105: db_look_token = t;
106: }
107:
108: int
109: db_read_token(void)
110: {
111: int t;
112:
113: if (db_look_token) {
114: t = db_look_token;
115: db_look_token = 0;
116: }
117: else
118: t = db_lex();
119: return (t);
120: }
121:
122: void
123: db_flush_lex(void)
124: {
125: db_flush_line();
126: db_look_char = 0;
127: db_look_token = 0;
128: }
129:
130: int
131: db_lex(void)
132: {
133: int c;
134:
135: c = db_read_char();
136: while (c <= ' ' || c > '~') {
137: if (c == '\n' || c == -1)
138: return (tEOL);
139: c = db_read_char();
140: }
141:
142: if (c >= '0' && c <= '9') {
143: /* number */
144: int r, digit = 0;
145:
146: if (c > '0')
147: r = db_radix;
148: else {
149: c = db_read_char();
150: if (c == 'O' || c == 'o')
151: r = 8;
152: else if (c == 'T' || c == 't')
153: r = 10;
154: else if (c == 'X' || c == 'x')
155: r = 16;
156: else {
157: r = db_radix;
158: db_unread_char(c);
159: }
160: c = db_read_char();
161: }
162: db_tok_number = 0;
163: for (;;) {
164: if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
165: digit = c - '0';
166: else if (r == 16 && ((c >= 'A' && c <= 'F') ||
167: (c >= 'a' && c <= 'f'))) {
168: if (c >= 'a')
169: digit = c - 'a' + 10;
170: else if (c >= 'A')
171: digit = c - 'A' + 10;
172: }
173: else
174: break;
175: db_tok_number = db_tok_number * r + digit;
176: c = db_read_char();
177: }
178: if ((c >= '0' && c <= '9') ||
179: (c >= 'A' && c <= 'Z') ||
180: (c >= 'a' && c <= 'z') ||
181: (c == '_'))
182: {
183: db_error("Bad character in number\n");
184: /*NOTREACHED*/
185: }
186: db_unread_char(c);
187: return (tNUMBER);
188: }
189: if ((c >= 'A' && c <= 'Z') ||
190: (c >= 'a' && c <= 'z') ||
191: c == '_' || c == '\\')
192: {
193: /* string */
194: char *cp;
195:
196: cp = db_tok_string;
197: if (c == '\\') {
198: c = db_read_char();
199: if (c == '\n' || c == -1) {
200: db_error("Bad escape\n");
201: /*NOTREACHED*/
202: }
203: }
204: *cp++ = c;
205: while (1) {
206: c = db_read_char();
207: if ((c >= 'A' && c <= 'Z') ||
208: (c >= 'a' && c <= 'z') ||
209: (c >= '0' && c <= '9') ||
210: c == '_' || c == '\\' || c == ':')
211: {
212: if (c == '\\') {
213: c = db_read_char();
214: if (c == '\n' || c == -1) {
215: db_error("Bad escape\n");
216: /*NOTREACHED*/
217: }
218: }
219: *cp++ = c;
220: if (cp == db_tok_string+sizeof(db_tok_string)) {
221: db_error("String too long\n");
222: /*NOTREACHED*/
223: }
224: continue;
225: }
226: else {
227: *cp = '\0';
228: break;
229: }
230: }
231: db_unread_char(c);
232: return (tIDENT);
233: }
234:
235: switch (c) {
236: case '+':
237: return (tPLUS);
238: case '-':
239: return (tMINUS);
240: case '.':
241: c = db_read_char();
242: if (c == '.')
243: return (tDOTDOT);
244: db_unread_char(c);
245: return (tDOT);
246: case '*':
247: return (tSTAR);
248: case '/':
249: return (tSLASH);
250: case '=':
251: return (tEQ);
252: case '%':
253: return (tPCT);
254: case '#':
255: return (tHASH);
256: case '(':
257: return (tLPAREN);
258: case ')':
259: return (tRPAREN);
260: case ',':
261: return (tCOMMA);
262: case '"':
263: return (tDITTO);
264: case '$':
265: return (tDOLLAR);
266: case '!':
267: return (tEXCL);
268: case '<':
269: c = db_read_char();
270: if (c == '<')
271: return (tSHIFT_L);
272: db_unread_char(c);
273: break;
274: case '>':
275: c = db_read_char();
276: if (c == '>')
277: return (tSHIFT_R);
278: db_unread_char(c);
279: break;
280: case -1:
281: return (tEOF);
282: }
283: db_printf("Bad character\n");
284: db_flush_lex();
285: return (tEOF);
286: }
CVSweb