|
|
1.1 ! root 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 "AS IS" ! 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 [email protected] ! 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 Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * Author: David B. Golub, Carnegie Mellon University ! 28: * Date: 7/90 ! 29: */ ! 30: #include "mach_kdb.h" ! 31: #if MACH_KDB ! 32: ! 33: /* ! 34: * Lexical analyzer. ! 35: */ ! 36: #include <machine/db_machdep.h> ! 37: #include <kern/strings.h> ! 38: #include <ddb/db_lex.h> ! 39: ! 40: char db_line[DB_LEX_LINE_SIZE]; ! 41: char db_last_line[DB_LEX_LINE_SIZE]; ! 42: char *db_lp, *db_endlp; ! 43: char *db_last_lp; ! 44: int db_look_char = 0; ! 45: db_expr_t db_look_token = 0; ! 46: ! 47: int ! 48: db_read_line(repeat_last) ! 49: char *repeat_last; ! 50: { ! 51: int i; ! 52: ! 53: i = db_readline(db_line, sizeof(db_line)); ! 54: if (i == 0) ! 55: return (0); /* EOI */ ! 56: if (repeat_last) { ! 57: if (strncmp(db_line, repeat_last, strlen(repeat_last)) == 0) { ! 58: db_strcpy(db_line, db_last_line); ! 59: db_printf("%s", db_line); ! 60: i = strlen(db_line); ! 61: } else if (db_line[0] != '\n' && db_line[0] != 0) ! 62: db_strcpy(db_last_line, db_line); ! 63: } ! 64: db_lp = db_line; ! 65: db_endlp = db_lp + i; ! 66: db_last_lp = db_lp; ! 67: db_look_char = 0; ! 68: db_look_token = 0; ! 69: return (i); ! 70: } ! 71: ! 72: void ! 73: db_flush_line() ! 74: { ! 75: db_lp = db_line; ! 76: db_last_lp = db_lp; ! 77: db_endlp = db_line; ! 78: } ! 79: ! 80: void ! 81: db_switch_input(buffer, size) ! 82: char *buffer; ! 83: int size; ! 84: { ! 85: db_lp = buffer; ! 86: db_last_lp = db_lp; ! 87: db_endlp = buffer + size; ! 88: db_look_char = 0; ! 89: db_look_token = 0; ! 90: } ! 91: ! 92: void ! 93: db_save_lex_context(lp) ! 94: register struct db_lex_context *lp; ! 95: { ! 96: lp->l_ptr = db_lp; ! 97: lp->l_eptr = db_endlp; ! 98: lp->l_char = db_look_char; ! 99: lp->l_token = db_look_token; ! 100: } ! 101: ! 102: void ! 103: db_restore_lex_context(lp) ! 104: register struct db_lex_context *lp; ! 105: { ! 106: db_lp = lp->l_ptr; ! 107: db_last_lp = db_lp; ! 108: db_endlp = lp->l_eptr; ! 109: db_look_char = lp->l_char; ! 110: db_look_token = lp->l_token; ! 111: } ! 112: ! 113: int ! 114: db_read_char() ! 115: { ! 116: int c; ! 117: ! 118: if (db_look_char != 0) { ! 119: c = db_look_char; ! 120: db_look_char = 0; ! 121: } ! 122: else if (db_lp >= db_endlp) ! 123: c = -1; ! 124: else ! 125: c = *db_lp++; ! 126: return (c); ! 127: } ! 128: ! 129: void ! 130: db_unread_char(c) ! 131: int c; ! 132: { ! 133: db_look_char = c; ! 134: } ! 135: ! 136: void ! 137: db_unread_token(t) ! 138: int t; ! 139: { ! 140: db_look_token = t; ! 141: } ! 142: ! 143: int ! 144: db_read_token() ! 145: { ! 146: int t; ! 147: ! 148: if (db_look_token) { ! 149: t = db_look_token; ! 150: db_look_token = 0; ! 151: } ! 152: else { ! 153: db_last_lp = db_lp; ! 154: if (db_look_char) ! 155: db_last_lp--; ! 156: t = db_lex(); ! 157: } ! 158: return (t); ! 159: } ! 160: ! 161: db_expr_t db_tok_number; ! 162: char db_tok_string[TOK_STRING_SIZE]; ! 163: db_expr_t db_radix = 16; ! 164: ! 165: void ! 166: db_flush_lex() ! 167: { ! 168: db_flush_line(); ! 169: db_look_char = 0; ! 170: db_look_token = 0; ! 171: } ! 172: ! 173: #define DB_DISP_SKIP 40 /* number of chars to display skip */ ! 174: ! 175: void ! 176: db_skip_to_eol() ! 177: { ! 178: register skip; ! 179: register t; ! 180: register n; ! 181: register char *p; ! 182: ! 183: t = db_read_token(); ! 184: p = db_last_lp; ! 185: for (skip = 0; t != tEOL && t != tSEMI_COLON && t != tEOF; skip++) ! 186: t = db_read_token(); ! 187: if (t == tSEMI_COLON) ! 188: db_unread_token(t); ! 189: if (skip != 0) { ! 190: while (p < db_last_lp && (*p == ' ' || *p == '\t')) ! 191: p++; ! 192: db_printf("Warning: Skipped input data \""); ! 193: for (n = 0; n < DB_DISP_SKIP && p < db_last_lp; n++) ! 194: db_printf("%c", *p++); ! 195: if (n >= DB_DISP_SKIP) ! 196: db_printf("...."); ! 197: db_printf("\"\n"); ! 198: } ! 199: } ! 200: ! 201: int ! 202: db_lex() ! 203: { ! 204: register char *cp; ! 205: register c; ! 206: ! 207: c = db_read_char(); ! 208: while (c <= ' ' || c > '~') { ! 209: if (c == '\n' || c == -1) ! 210: return (tEOL); ! 211: c = db_read_char(); ! 212: } ! 213: ! 214: cp = db_tok_string; ! 215: *cp++ = c; ! 216: ! 217: if (c >= '0' && c <= '9') { ! 218: /* number */ ! 219: int r, digit; ! 220: ! 221: if (c > '0') ! 222: r = db_radix; ! 223: else { ! 224: c = db_read_char(); ! 225: if (c == 'O' || c == 'o') ! 226: r = 8; ! 227: else if (c == 'T' || c == 't') ! 228: r = 10; ! 229: else if (c == 'X' || c == 'x') ! 230: r = 16; ! 231: else { ! 232: cp--; ! 233: r = db_radix; ! 234: db_unread_char(c); ! 235: } ! 236: c = db_read_char(); ! 237: *cp++ = c; ! 238: } ! 239: db_tok_number = 0; ! 240: for (;;) { ! 241: if (c >= '0' && c <= ((r == 8) ? '7' : '9')) ! 242: digit = c - '0'; ! 243: else if (r == 16 && ((c >= 'A' && c <= 'F') || ! 244: (c >= 'a' && c <= 'f'))) { ! 245: if (c >= 'a') ! 246: digit = c - 'a' + 10; ! 247: else ! 248: digit = c - 'A' + 10; ! 249: } ! 250: else ! 251: break; ! 252: db_tok_number = db_tok_number * r + digit; ! 253: c = db_read_char(); ! 254: if (cp < &db_tok_string[sizeof(db_tok_string)-1]) ! 255: *cp++ = c; ! 256: } ! 257: cp[-1] = 0; ! 258: if ((c >= '0' && c <= '9') || ! 259: (c >= 'A' && c <= 'Z') || ! 260: (c >= 'a' && c <= 'z') || ! 261: (c == '_')) ! 262: { ! 263: db_printf("Bad character '%c' after number %s\n", ! 264: c, db_tok_string); ! 265: db_error(0); ! 266: db_flush_lex(); ! 267: return (tEOF); ! 268: } ! 269: db_unread_char(c); ! 270: return (tNUMBER); ! 271: } ! 272: if ((c >= 'A' && c <= 'Z') || ! 273: (c >= 'a' && c <= 'z') || ! 274: c == '_' || c == '\\' || c == ':') ! 275: { ! 276: /* identifier */ ! 277: if (c == '\\') { ! 278: c = db_read_char(); ! 279: if (c == '\n' || c == -1) ! 280: db_error("Bad '\\' at the end of line\n"); ! 281: cp[-1] = c; ! 282: } ! 283: while (1) { ! 284: c = db_read_char(); ! 285: if ((c >= 'A' && c <= 'Z') || ! 286: (c >= 'a' && c <= 'z') || ! 287: (c >= '0' && c <= '9') || ! 288: c == '_' || c == '\\' || c == ':' || c == '.') ! 289: { ! 290: if (c == '\\') { ! 291: c = db_read_char(); ! 292: if (c == '\n' || c == -1) ! 293: db_error("Bad '\\' at the end of line\n"); ! 294: } ! 295: *cp++ = c; ! 296: if (cp == db_tok_string+sizeof(db_tok_string)) { ! 297: db_error("String too long\n"); ! 298: db_flush_lex(); ! 299: return (tEOF); ! 300: } ! 301: continue; ! 302: } ! 303: else { ! 304: *cp = '\0'; ! 305: break; ! 306: } ! 307: } ! 308: db_unread_char(c); ! 309: return (tIDENT); ! 310: } ! 311: ! 312: *cp = 0; ! 313: switch (c) { ! 314: case '+': ! 315: return (tPLUS); ! 316: case '-': ! 317: return (tMINUS); ! 318: case '.': ! 319: c = db_read_char(); ! 320: if (c == '.') { ! 321: *cp++ = c; ! 322: *cp = 0; ! 323: return (tDOTDOT); ! 324: } ! 325: db_unread_char(c); ! 326: return (tDOT); ! 327: case '*': ! 328: return (tSTAR); ! 329: case '/': ! 330: return (tSLASH); ! 331: case '=': ! 332: c = db_read_char(); ! 333: if (c == '=') { ! 334: *cp++ = c; ! 335: *cp = 0; ! 336: return(tLOG_EQ); ! 337: } ! 338: db_unread_char(c); ! 339: return (tEQ); ! 340: case '%': ! 341: return (tPCT); ! 342: case '#': ! 343: return (tHASH); ! 344: case '(': ! 345: return (tLPAREN); ! 346: case ')': ! 347: return (tRPAREN); ! 348: case ',': ! 349: return (tCOMMA); ! 350: case '\'': ! 351: return (tQUOTE); ! 352: case '"': ! 353: /* string */ ! 354: cp = db_tok_string; ! 355: c = db_read_char(); ! 356: while (c != '"' && c > 0 && c != '\n') { ! 357: if (cp >= &db_tok_string[sizeof(db_tok_string)-1]) { ! 358: db_error("Too long string\n"); ! 359: db_flush_lex(); ! 360: return (tEOF); ! 361: } ! 362: if (c == '\\') { ! 363: c = db_read_char(); ! 364: switch(c) { ! 365: case 'n': ! 366: c = '\n'; break; ! 367: case 't': ! 368: c = '\t'; break; ! 369: case '\\': ! 370: case '"': ! 371: break; ! 372: default: ! 373: db_printf("Bad escape sequence '\\%c'\n", c); ! 374: db_error(0); ! 375: db_flush_lex(); ! 376: return (tEOF); ! 377: } ! 378: } ! 379: *cp++ = c; ! 380: c = db_read_char(); ! 381: } ! 382: *cp = 0; ! 383: if (c != '"') { ! 384: db_error("Non terminated string constant\n"); ! 385: db_flush_lex(); ! 386: return (tEOF); ! 387: } ! 388: return (tSTRING); ! 389: case '$': ! 390: return (tDOLLAR); ! 391: case '!': ! 392: c = db_read_char(); ! 393: if (c == '=') { ! 394: *cp++ = c; ! 395: *cp = 0; ! 396: return(tLOG_NOT_EQ); ! 397: } ! 398: db_unread_char(c); ! 399: return (tEXCL); ! 400: case '&': ! 401: c = db_read_char(); ! 402: if (c == '&') { ! 403: *cp++ = c; ! 404: *cp = 0; ! 405: return(tLOG_AND); ! 406: } ! 407: db_unread_char(c); ! 408: return(tBIT_AND); ! 409: case '|': ! 410: c = db_read_char(); ! 411: if (c == '|') { ! 412: *cp++ = c; ! 413: *cp = 0; ! 414: return(tLOG_OR); ! 415: } ! 416: db_unread_char(c); ! 417: return(tBIT_OR); ! 418: case '<': ! 419: c = db_read_char(); ! 420: *cp++ = c; ! 421: *cp = 0; ! 422: if (c == '<') ! 423: return (tSHIFT_L); ! 424: if (c == '=') ! 425: return (tLESS_EQ); ! 426: cp[-1] = 0; ! 427: db_unread_char(c); ! 428: return(tLESS); ! 429: break; ! 430: case '>': ! 431: c = db_read_char(); ! 432: *cp++ = c; ! 433: *cp = 0; ! 434: if (c == '>') ! 435: return (tSHIFT_R); ! 436: if (c == '=') ! 437: return (tGREATER_EQ); ! 438: cp[-1] = 0; ! 439: db_unread_char(c); ! 440: return (tGREATER); ! 441: break; ! 442: case ';': ! 443: return (tSEMI_COLON); ! 444: case '?': ! 445: return (tQUESTION); ! 446: case -1: ! 447: db_strcpy(db_tok_string, "<EOL>"); ! 448: return (tEOF); ! 449: } ! 450: db_printf("Bad character '%c'\n", c); ! 451: db_flush_lex(); ! 452: return (tEOF); ! 453: } ! 454: ! 455: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.