Remove some duplicate FreeBSD CVS IDs, move some IDs to better places.
[dragonfly.git] / sys / ddb / db_lex.c
CommitLineData
984263bc
MD
1/*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
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.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
25 *
26 * $FreeBSD: src/sys/ddb/db_lex.c,v 1.18 1999/08/28 00:41:08 peter Exp $
43f349ca 27 * $DragonFly: src/sys/ddb/db_lex.c,v 1.4 2005/02/01 17:53:01 eirikn Exp $
984263bc
MD
28 */
29
30/*
31 * Author: David B. Golub, Carnegie Mellon University
32 * Date: 7/90
33 */
34/*
35 * Lexical analyzer.
36 */
37#include <sys/param.h>
38
39#include <ddb/ddb.h>
40#include <ddb/db_lex.h>
41
42static char db_line[120];
43static char * db_lp, *db_endlp;
44
43c0ece6
RG
45static int db_lex (void);
46static void db_flush_line (void);
47static int db_read_char (void);
48static void db_unread_char (int);
984263bc
MD
49
50int
43f349ca 51db_read_line(void)
984263bc
MD
52{
53 int i;
54
55 i = db_readline(db_line, sizeof(db_line));
56 if (i == 0)
57 return (0); /* EOI */
58 db_lp = db_line;
59 db_endlp = db_lp + i;
60 return (i);
61}
62
63static void
43f349ca 64db_flush_line(void)
984263bc
MD
65{
66 db_lp = db_line;
67 db_endlp = db_line;
68}
69
70static int db_look_char = 0;
71
72static int
43f349ca 73db_read_char(void)
984263bc
MD
74{
75 int c;
76
77 if (db_look_char != 0) {
78 c = db_look_char;
79 db_look_char = 0;
80 }
81 else if (db_lp >= db_endlp)
82 c = -1;
83 else
84 c = *db_lp++;
85 return (c);
86}
87
88static void
89db_unread_char(c)
90 int c;
91{
92 db_look_char = c;
93}
94
95static int db_look_token = 0;
96
97void
43f349ca 98db_unread_token(int t)
984263bc
MD
99{
100 db_look_token = t;
101}
102
103int
43f349ca 104db_read_token(void)
984263bc
MD
105{
106 int t;
107
108 if (db_look_token) {
109 t = db_look_token;
110 db_look_token = 0;
111 }
112 else
113 t = db_lex();
114 return (t);
115}
116
117db_expr_t db_tok_number;
118char db_tok_string[TOK_STRING_SIZE];
119
120db_expr_t db_radix = 16;
121
122void
43f349ca 123db_flush_lex(void)
984263bc
MD
124{
125 db_flush_line();
126 db_look_char = 0;
127 db_look_token = 0;
128}
129
130static int
43f349ca 131db_lex(void)
984263bc
MD
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 db_flush_lex();
185 return (tEOF);
186 }
187 db_unread_char(c);
188 return (tNUMBER);
189 }
190 if ((c >= 'A' && c <= 'Z') ||
191 (c >= 'a' && c <= 'z') ||
192 c == '_' || c == '\\')
193 {
194 /* string */
195 char *cp;
196
197 cp = db_tok_string;
198 if (c == '\\') {
199 c = db_read_char();
200 if (c == '\n' || c == -1)
201 db_error("Bad escape\n");
202 }
203 *cp++ = c;
204 while (1) {
205 c = db_read_char();
206 if ((c >= 'A' && c <= 'Z') ||
207 (c >= 'a' && c <= 'z') ||
208 (c >= '0' && c <= '9') ||
209 c == '_' || c == '\\' || c == ':')
210 {
211 if (c == '\\') {
212 c = db_read_char();
213 if (c == '\n' || c == -1)
214 db_error("Bad escape\n");
215 }
216 *cp++ = c;
217 if (cp == db_tok_string+sizeof(db_tok_string)) {
218 db_error("String too long\n");
219 db_flush_lex();
220 return (tEOF);
221 }
222 continue;
223 }
224 else {
225 *cp = '\0';
226 break;
227 }
228 }
229 db_unread_char(c);
230 return (tIDENT);
231 }
232
233 switch (c) {
234 case '+':
235 return (tPLUS);
236 case '-':
237 return (tMINUS);
238 case '.':
239 c = db_read_char();
240 if (c == '.')
241 return (tDOTDOT);
242 db_unread_char(c);
243 return (tDOT);
244 case '*':
245 return (tSTAR);
246 case '/':
247 return (tSLASH);
248 case '=':
249 return (tEQ);
250 case '%':
251 return (tPCT);
252 case '#':
253 return (tHASH);
254 case '(':
255 return (tLPAREN);
256 case ')':
257 return (tRPAREN);
258 case ',':
259 return (tCOMMA);
260 case '"':
261 return (tDITTO);
262 case '$':
263 return (tDOLLAR);
264 case '!':
265 return (tEXCL);
266 case '<':
267 c = db_read_char();
268 if (c == '<')
269 return (tSHIFT_L);
270 db_unread_char(c);
271 break;
272 case '>':
273 c = db_read_char();
274 if (c == '>')
275 return (tSHIFT_R);
276 db_unread_char(c);
277 break;
278 case -1:
279 return (tEOF);
280 }
281 db_printf("Bad character\n");
282 db_flush_lex();
283 return (tEOF);
284}