1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149#include <string.h>
150#include <ddb/db_lex.h>
151#include <ddb/db_command.h>
152#include <ddb/db_input.h>
153#include <ddb/db_output.h>
154
155char db_line[DB_LEX_LINE_SIZE];
156char db_last_line[DB_LEX_LINE_SIZE];
157char *db_lp, *db_endlp;
158char *db_last_lp;
159int db_look_char = 0;
160db_expr_t db_look_token = 0;
161
162
163
164
165void db_flush_line(void);
166void db_unread_char(int c);
167
168
169int
170db_read_line(char *repeat_last)
171{
172 int i;
173
174 i = db_readline(db_line, sizeof(db_line));
175 if (i == 0)
176 return (0);
177 if (repeat_last) {
178 if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) {
179 strcpy(db_line, db_last_line);
180 db_printf("%s", db_line);
181 i = strlen(db_line);
182 } else if (db_line[0] != '\n' && db_line[0] != 0)
183 strcpy(db_last_line, db_line);
184 }
185 db_lp = db_line;
186 db_endlp = db_lp + i;
187 db_last_lp = db_lp;
188 db_look_char = 0;
189 db_look_token = 0;
190 return (i);
191}
192
193void
194db_flush_line(void)
195{
196 db_lp = db_line;
197 db_last_lp = db_lp;
198 db_endlp = db_line;
199}
200
201void
202db_switch_input(
203 char *buffer,
204 int size)
205{
206 db_lp = buffer;
207 db_last_lp = db_lp;
208 db_endlp = buffer + size;
209 db_look_char = 0;
210 db_look_token = 0;
211}
212
213void
214db_save_lex_context(register struct db_lex_context *lp)
215{
216 lp->l_ptr = db_lp;
217 lp->l_eptr = db_endlp;
218 lp->l_char = db_look_char;
219 lp->l_token = db_look_token;
220}
221
222void
223db_restore_lex_context(register struct db_lex_context *lp)
224{
225 db_lp = lp->l_ptr;
226 db_last_lp = db_lp;
227 db_endlp = lp->l_eptr;
228 db_look_char = lp->l_char;
229 db_look_token = lp->l_token;
230}
231
232int
233db_read_char(void)
234{
235 int c;
236
237 if (db_look_char != 0) {
238 c = db_look_char;
239 db_look_char = 0;
240 }
241 else if (db_lp >= db_endlp)
242 c = -1;
243 else
244 c = *db_lp++;
245 return (c);
246}
247
248void
249db_unread_char(int c)
250{
251 db_look_char = c;
252}
253
254void
255db_unread_token(int t)
256{
257 db_look_token = t;
258}
259
260int
261db_read_token(void)
262{
263 int t;
264
265 if (db_look_token) {
266 t = db_look_token;
267 db_look_token = 0;
268 }
269 else {
270 db_last_lp = db_lp;
271 if (db_look_char)
272 db_last_lp--;
273 t = db_lex();
274 }
275 return (t);
276}
277
278db_expr_t db_tok_number;
279char db_tok_string[TOK_STRING_SIZE];
280
281db_expr_t db_radix = 16;
282
283void
284db_flush_lex(void)
285{
286 db_flush_line();
287 db_look_char = 0;
288 db_look_token = 0;
289}
290
291#define DB_DISP_SKIP 40
292
293void
294db_skip_to_eol(void)
295{
296 register int skip;
297 register int t;
298 register int n;
299 register char *p;
300
301 t = db_read_token();
302 p = db_last_lp;
303 for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++)
304 t = db_read_token();
305 if (t == tSEMI_COLON)
306 db_unread_token(t);
307 if (skip != 0) {
308 while (p < db_last_lp && (*p == ' ' || *p == '\t'))
309 p++;
310 db_printf("Warning: Skipped input data \"");
311 for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++)
312 db_printf("%c", *p++);
313 if (n >= DB_DISP_SKIP)
314 db_printf("....");
315 db_printf("\"\n");
316 }
317}
318
319int
320db_lex(void)
321{
322 register char *cp;
323 register int c;
324
325 c = db_read_char();
326 while (c <= ' ' || c > '~') {
327 if (c == '\n' || c == -1)
328 return (tEOL);
329 c = db_read_char();
330 }
331
332 cp = db_tok_string;
333 *cp++ = c;
334
335 if (c >= '0' && c <= '9') {
336
337 int r, digit;
338
339 if (c > '0')
340 r = db_radix;
341 else {
342 c = db_read_char();
343 if (c == 'O' || c == 'o')
344 r = 8;
345 else if (c == 'T' || c == 't')
346 r = 10;
347 else if (c == 'X' || c == 'x')
348 r = 16;
349 else {
350 cp--;
351 r = db_radix;
352 db_unread_char(c);
353 }
354 c = db_read_char();
355 *cp++ = c;
356 }
357 db_tok_number = 0;
358 for (;;) {
359 if (c >= '0' && c <= ((r == 8) ? '7' : '9'))
360 digit = c - '0';
361 else if (r == 16 && ((c >= 'A' && c <= 'F') ||
362 (c >= 'a' && c <= 'f'))) {
363 if (c >= 'a')
364 digit = c - 'a' + 10;
365 else
366 digit = c - 'A' + 10;
367 }
368 else
369 break;
370 db_tok_number = db_tok_number * r + digit;
371 c = db_read_char();
372 if (cp < &db_tok_string[sizeof(db_tok_string)-1])
373 *cp++ = c;
374 }
375 cp[-1] = 0;
376 if ((c >= '0' && c <= '9') ||
377 (c >= 'A' && c <= 'Z') ||
378 (c >= 'a' && c <= 'z') ||
379 (c == '_'))
380 {
381 db_printf("Bad character '%c' after number %s\n",
382 c, db_tok_string);
383 db_error(0);
384 db_flush_lex();
385 return (tEOF);
386 }
387 db_unread_char(c);
388 return (tNUMBER);
389 }
390 if ((c >= 'A' && c <= 'Z') ||
391 (c >= 'a' && c <= 'z') ||
392 c == '_' || c == '\\' || c == ':')
393 {
394
395 if (c == '\\') {
396 c = db_read_char();
397 if (c == '\n' || c == -1)
398 db_error("Bad '\\' at the end of line\n");
399 cp[-1] = c;
400 }
401 while (1) {
402 c = db_read_char();
403 if ((c >= 'A' && c <= 'Z') ||
404 (c >= 'a' && c <= 'z') ||
405 (c >= '0' && c <= '9') ||
406 c == '_' || c == '\\' || c == ':' || c == '.')
407 {
408 if (c == '\\') {
409 c = db_read_char();
410 if (c == '\n' || c == -1)
411 db_error("Bad '\\' at the end of line\n");
412 }
413 *cp++ = c;
414 if (cp == db_tok_string+sizeof(db_tok_string)) {
415 db_error("String too long\n");
416 db_flush_lex();
417 return (tEOF);
418 }
419 continue;
420 }
421 else {
422 *cp = '\0';
423 break;
424 }
425 }
426 db_unread_char(c);
427 return (tIDENT);
428 }
429
430 *cp = 0;
431 switch (c) {
432 case '+':
433 return (tPLUS);
434 case '-':
435 return (tMINUS);
436 case '.':
437 c = db_read_char();
438 if (c == '.') {
439 *cp++ = c;
440 *cp = 0;
441 return (tDOTDOT);
442 }
443 db_unread_char(c);
444 return (tDOT);
445 case '*':
446 return (tSTAR);
447 case '/':
448 return (tSLASH);
449 case '=':
450 c = db_read_char();
451 if (c == '=') {
452 *cp++ = c;
453 *cp = 0;
454 return(tLOG_EQ);
455 }
456 db_unread_char(c);
457 return (tEQ);
458 case '%':
459 return (tPCT);
460 case '#':
461 return (tHASH);
462 case '(':
463 return (tLPAREN);
464 case ')':
465 return (tRPAREN);
466 case ',':
467 return (tCOMMA);
468 case '\'':
469 return (tQUOTE);
470 case '"':
471
472 cp = db_tok_string;
473 c = db_read_char();
474 while (c != '"' && c > 0 && c != '\n') {
475 if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) {
476 db_error("Too long string\n");
477 db_flush_lex();
478 return (tEOF);
479 }
480 if (c == '\\') {
481 c = db_read_char();
482 switch(c) {
483 case 'n':
484 c = '\n'; break;
485 case 't':
486 c = '\t'; break;
487 case '\\':
488 case '"':
489 break;
490 default:
491 db_printf("Bad escape sequence '\\%c'\n", c);
492 db_error(0);
493 db_flush_lex();
494 return (tEOF);
495 }
496 }
497 *cp++ = c;
498 c = db_read_char();
499 }
500 *cp = 0;
501 if (c != '"') {
502 db_error("Non terminated string constant\n");
503 db_flush_lex();
504 return (tEOF);
505 }
506 return (tSTRING);
507 case '$':
508 return (tDOLLAR);
509 case '!':
510 c = db_read_char();
511 if (c == '=') {
512 *cp++ = c;
513 *cp = 0;
514 return(tLOG_NOT_EQ);
515 }
516 db_unread_char(c);
517 return (tEXCL);
518 case '&':
519 c = db_read_char();
520 if (c == '&') {
521 *cp++ = c;
522 *cp = 0;
523 return(tLOG_AND);
524 }
525 db_unread_char(c);
526 return(tBIT_AND);
527 case '|':
528 c = db_read_char();
529 if (c == '|') {
530 *cp++ = c;
531 *cp = 0;
532 return(tLOG_OR);
533 }
534 db_unread_char(c);
535 return(tBIT_OR);
536 case '<':
537 c = db_read_char();
538 *cp++ = c;
539 *cp = 0;
540 if (c == '<')
541 return (tSHIFT_L);
542 if (c == '=')
543 return (tLESS_EQ);
544 cp[-1] = 0;
545 db_unread_char(c);
546 return(tLESS);
547 break;
548 case '>':
549 c = db_read_char();
550 *cp++ = c;
551 *cp = 0;
552 if (c == '>')
553 return (tSHIFT_R);
554 if (c == '=')
555 return (tGREATER_EQ);
556 cp[-1] = 0;
557 db_unread_char(c);
558 return (tGREATER);
559 break;
560 case ';':
561 return (tSEMI_COLON);
562 case '?':
563 return (tQUESTION);
564 case -1:
565 strcpy(db_tok_string, "<EOL>");
566 return (tEOF);
567 }
568 db_printf("Bad character '%c'\n", c);
569 db_flush_lex();
570 return (tEOF);
571}
572