rtld - do not allow both dynamic DTV index and static TLS offset
[dragonfly.git] / sys / ddb / db_lex.c
blobe6d21518b9659ef84747b9677d40276dd4dd328d
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
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.
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.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
26 * $FreeBSD: src/sys/ddb/db_lex.c,v 1.18 1999/08/28 00:41:08 peter Exp $
30 * Author: David B. Golub, Carnegie Mellon University
31 * Date: 7/90
34 * Lexical analyzer.
36 #include <sys/param.h>
37 #include <sys/systm.h>
39 #include <ddb/ddb.h>
40 #include <ddb/db_lex.h>
42 static char db_line[120];
43 static char * db_lp, *db_endlp;
45 static int db_lex (void);
46 static void db_flush_line (void);
47 static int db_read_char (void);
48 static void db_unread_char (int);
50 int
51 db_read_line(void)
53 int i;
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);
63 static void
64 db_flush_line(void)
66 db_lp = db_line;
67 db_endlp = db_line;
70 static int db_look_char = 0;
72 static int
73 db_read_char(void)
75 int c;
77 if (db_look_char != 0) {
78 c = db_look_char;
79 db_look_char = 0;
81 else if (db_lp >= db_endlp)
82 c = -1;
83 else
84 c = *db_lp++;
85 return (c);
88 static void
89 db_unread_char(int c)
91 db_look_char = c;
94 static int db_look_token = 0;
96 void
97 db_unread_token(int t)
99 db_look_token = t;
103 db_read_token(void)
105 int t;
107 if (db_look_token) {
108 t = db_look_token;
109 db_look_token = 0;
111 else
112 t = db_lex();
113 return (t);
116 db_expr_t db_tok_number;
117 char db_tok_string[TOK_STRING_SIZE];
119 db_expr_t db_radix = 16;
122 * Convert the number to a string in the current radix.
123 * This replaces the non-standard %r kprintf() format.
126 char *
127 db_num_to_str(db_expr_t val)
131 * 2 chars for "0x", 1 for a sign ("-")
132 * up to 21 chars for a 64-bit number:
133 * % echo 2^64 | bc | wc -c
134 * 21
135 * and 1 char for a terminal NUL
136 * 2+1+21+1 => 25
138 static char buf[25];
140 if (db_radix == 16)
141 ksnprintf(buf, sizeof(buf), "%" DDB_EXPR_FMT "x", val);
142 else if (db_radix == 8)
143 ksnprintf(buf, sizeof(buf), "%" DDB_EXPR_FMT "o", val);
144 else
145 ksnprintf(buf, sizeof(buf), "%" DDB_EXPR_FMT "u", val);
147 return (buf);
150 void
151 db_flush_lex(void)
153 db_flush_line();
154 db_look_char = 0;
155 db_look_token = 0;
158 static int
159 db_lex(void)
161 int c;
163 c = db_read_char();
164 while (c <= ' ' || c > '~') {
165 if (c == '\n' || c == -1)
166 return (tEOL);
167 c = db_read_char();
170 if (c >= '0' && c <= '9') {
171 /* number */
172 int r, digit = 0;
174 if (c > '0')
175 r = db_radix;
176 else {
177 c = db_read_char();
178 if (c == 'O' || c == 'o')
179 r = 8;
180 else if (c == 'T' || c == 't')
181 r = 10;
182 else if (c == 'X' || c == 'x')
183 r = 16;
184 else {
185 r = db_radix;
186 db_unread_char(c);
188 c = db_read_char();
190 db_tok_number = 0;
191 for (;;) {
192 if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
193 digit = c - '0';
194 else if (r == 16 && ((c >= 'A' && c <= 'F') ||
195 (c >= 'a' && c <= 'f'))) {
196 if (c >= 'a')
197 digit = c - 'a' + 10;
198 else if (c >= 'A')
199 digit = c - 'A' + 10;
201 else
202 break;
203 db_tok_number = db_tok_number * r + digit;
204 c = db_read_char();
206 if ((c >= '0' && c <= '9') ||
207 (c >= 'A' && c <= 'Z') ||
208 (c >= 'a' && c <= 'z') ||
209 (c == '_'))
211 db_error("Bad character in number\n");
212 db_flush_lex();
213 return (tEOF);
215 db_unread_char(c);
216 return (tNUMBER);
218 if ((c >= 'A' && c <= 'Z') ||
219 (c >= 'a' && c <= 'z') ||
220 c == '_' || c == '\\')
222 /* string */
223 char *cp;
225 cp = db_tok_string;
226 if (c == '\\') {
227 c = db_read_char();
228 if (c == '\n' || c == -1)
229 db_error("Bad escape\n");
231 *cp++ = c;
232 while (1) {
233 c = db_read_char();
234 if ((c >= 'A' && c <= 'Z') ||
235 (c >= 'a' && c <= 'z') ||
236 (c >= '0' && c <= '9') ||
237 c == '_' || c == '\\' || c == ':')
239 if (c == '\\') {
240 c = db_read_char();
241 if (c == '\n' || c == -1)
242 db_error("Bad escape\n");
244 *cp++ = c;
245 if (cp == db_tok_string+sizeof(db_tok_string)) {
246 db_error("String too long\n");
247 db_flush_lex();
248 return (tEOF);
250 continue;
252 else {
253 *cp = '\0';
254 break;
257 db_unread_char(c);
258 return (tIDENT);
261 switch (c) {
262 case '+':
263 return (tPLUS);
264 case '-':
265 return (tMINUS);
266 case '.':
267 c = db_read_char();
268 if (c == '.')
269 return (tDOTDOT);
270 db_unread_char(c);
271 return (tDOT);
272 case '*':
273 return (tSTAR);
274 case '/':
275 return (tSLASH);
276 case '=':
277 return (tEQ);
278 case '%':
279 return (tPCT);
280 case '#':
281 return (tHASH);
282 case '(':
283 return (tLPAREN);
284 case ')':
285 return (tRPAREN);
286 case ',':
287 return (tCOMMA);
288 case '"':
289 return (tDITTO);
290 case '$':
291 return (tDOLLAR);
292 case '!':
293 return (tEXCL);
294 case '<':
295 c = db_read_char();
296 if (c == '<')
297 return (tSHIFT_L);
298 db_unread_char(c);
299 break;
300 case '>':
301 c = db_read_char();
302 if (c == '>')
303 return (tSHIFT_R);
304 db_unread_char(c);
305 break;
306 case -1:
307 return (tEOF);
309 db_printf("Bad character\n");
310 db_flush_lex();
311 return (tEOF);