|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * HISTORY ! 27: * ! 28: * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez ! 29: * Import of Mac OS X kernel (~semeria) ! 30: * ! 31: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez ! 32: * Import of OSF Mach kernel (~mburg) ! 33: * ! 34: * Revision 1.1.11.3 1996/01/09 19:15:49 devrcs ! 35: * Change 'register foo' to 'register int foo'. ! 36: * [1995/12/01 21:42:12 jfraser] ! 37: * ! 38: * Merged '64-bit safe' changes from DEC alpha port. ! 39: * [1995/11/21 18:03:11 jfraser] ! 40: * ! 41: * Revision 1.1.11.2 1995/01/06 19:10:21 devrcs ! 42: * mk6 CR668 - 1.3b26 merge ! 43: * * Revision 1.1.4.6 1994/05/06 18:39:20 tmt ! 44: * Merged osc1.3dec/shared with osc1.3b19 ! 45: * Merge Alpha changes into osc1.312b source code. ! 46: * String protos. ! 47: * 64bit cleanup. ! 48: * Cleanup to quiet gcc warnings. ! 49: * * End1.3merge ! 50: * [1994/11/04 08:49:35 dwm] ! 51: * ! 52: * Revision 1.1.11.1 1994/09/23 01:19:59 ezf ! 53: * change marker to not FREE ! 54: * [1994/09/22 21:10:14 ezf] ! 55: * ! 56: * Revision 1.1.4.4 1993/08/11 20:37:55 elliston ! 57: * Add ANSI Prototypes. CR #9523. ! 58: * [1993/08/11 03:33:26 elliston] ! 59: * ! 60: * Revision 1.1.4.3 1993/07/27 18:27:38 elliston ! 61: * Add ANSI prototypes. CR #9523. ! 62: * [1993/07/27 18:12:13 elliston] ! 63: * ! 64: * Revision 1.1.4.2 1993/06/02 23:11:27 jeffc ! 65: * Added to OSF/1 R1.3 from NMK15.0. ! 66: * [1993/06/02 20:56:32 jeffc] ! 67: * ! 68: * Revision 1.1 1992/09/30 02:01:10 robert ! 69: * Initial revision ! 70: * ! 71: * $EndLog$ ! 72: */ ! 73: /* CMU_HIST */ ! 74: /* ! 75: * Revision 2.5 91/10/09 16:00:20 af ! 76: * Revision 2.4.3.1 91/10/05 13:06:25 jeffreyh ! 77: * Added relational operator tokens and string constant etc. ! 78: * Added input switching functions for macro and conditional command. ! 79: * Moved skip_to_eol() from db_command.c and added db_last_lp to print ! 80: * skipped input data as a warning message. ! 81: * Added last input repetition support to db_read_line. ! 82: * Changed db_lex() to always set db_tok_string for error message. ! 83: * [91/08/29 tak] ! 84: * ! 85: * Revision 2.4.3.1 91/10/05 13:06:25 jeffreyh ! 86: * Added relational operator tokens and string constant etc. ! 87: * Added input switching functions for macro and conditional command. ! 88: * Moved skip_to_eol() from db_command.c and added db_last_lp to print ! 89: * skipped input data as a warning message. ! 90: * Added last input repetition support to db_read_line. ! 91: * Changed db_lex() to always set db_tok_string for error message. ! 92: * [91/08/29 tak] ! 93: * ! 94: * Revision 2.4 91/05/14 15:34:23 mrt ! 95: * Correcting copyright ! 96: * ! 97: * Revision 2.3 91/02/05 17:06:36 mrt ! 98: * Changed to new Mach copyright ! 99: * [91/01/31 16:18:20 mrt] ! 100: * ! 101: * Revision 2.2 90/08/27 21:51:10 dbg ! 102: * Add 'dotdot' token. ! 103: * [90/08/22 dbg] ! 104: * ! 105: * Allow backslash to quote any character into an identifier. ! 106: * Allow colon in identifier for symbol table qualification. ! 107: * [90/08/16 dbg] ! 108: * Reduce lint. ! 109: * [90/08/07 dbg] ! 110: * Created. ! 111: * [90/07/25 dbg] ! 112: * ! 113: */ ! 114: /* CMU_ENDHIST */ ! 115: /* ! 116: * Mach Operating System ! 117: * Copyright (c) 1991,1990 Carnegie Mellon University ! 118: * All Rights Reserved. ! 119: * ! 120: * Permission to use, copy, modify and distribute this software and its ! 121: * documentation is hereby granted, provided that both the copyright ! 122: * notice and this permission notice appear in all copies of the ! 123: * software, derivative works or modified versions, and any portions ! 124: * thereof, and that both notices appear in supporting documentation. ! 125: * ! 126: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 127: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 128: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 129: * ! 130: * Carnegie Mellon requests users of this software to return to ! 131: * ! 132: * Software Distribution Coordinator or [email protected] ! 133: * School of Computer Science ! 134: * Carnegie Mellon University ! 135: * Pittsburgh PA 15213-3890 ! 136: * ! 137: * any improvements or extensions that they make and grant Carnegie Mellon ! 138: * the rights to redistribute these changes. ! 139: */ ! 140: /* ! 141: */ ! 142: /* ! 143: * Author: David B. Golub, Carnegie Mellon University ! 144: * Date: 7/90 ! 145: */ ! 146: /* ! 147: * Lexical analyzer. ! 148: */ ! 149: #include <string.h> /* For strcpy(), strncmp(), strlen() */ ! 150: #include <ddb/db_lex.h> ! 151: #include <ddb/db_command.h> ! 152: #include <ddb/db_input.h> ! 153: #include <ddb/db_output.h> /* For db_printf() */ ! 154: ! 155: char db_line[DB_LEX_LINE_SIZE]; ! 156: char db_last_line[DB_LEX_LINE_SIZE]; ! 157: char *db_lp, *db_endlp; ! 158: char *db_last_lp; ! 159: int db_look_char = 0; ! 160: db_expr_t db_look_token = 0; ! 161: ! 162: ! 163: /* Prototypes for functions local to this file. XXX -- should be static! ! 164: */ ! 165: void db_flush_line(void); ! 166: void db_unread_char(int c); ! 167: ! 168: ! 169: int ! 170: db_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); /* EOI */ ! 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: ! 193: void ! 194: db_flush_line(void) ! 195: { ! 196: db_lp = db_line; ! 197: db_last_lp = db_lp; ! 198: db_endlp = db_line; ! 199: } ! 200: ! 201: void ! 202: db_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: ! 213: void ! 214: db_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: ! 222: void ! 223: db_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: ! 232: int ! 233: db_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: ! 248: void ! 249: db_unread_char(int c) ! 250: { ! 251: db_look_char = c; ! 252: } ! 253: ! 254: void ! 255: db_unread_token(int t) ! 256: { ! 257: db_look_token = t; ! 258: } ! 259: ! 260: int ! 261: db_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: ! 278: db_expr_t db_tok_number; ! 279: char db_tok_string[TOK_STRING_SIZE]; ! 280: ! 281: db_expr_t db_radix = 16; ! 282: ! 283: void ! 284: db_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 /* number of chars to display skip */ ! 292: ! 293: void ! 294: db_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: ! 319: int ! 320: db_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: /* number */ ! 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: /* identifier */ ! 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: /* string */ ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.