|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1991,1990 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 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. 1.1.1.2 ! root 11: * 1.1 root 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. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 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; 1.1.1.2 ! root 124: else 1.1 root 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: { 1.1.1.2 ! root 263: db_printf("Bad character '%c' after number %s\n", 1.1 root 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: 1.1.1.2 ! root 455: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.