|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)keywords.c 5.4 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * Keywords, variables, and aliases (oh my!). ! 26: */ ! 27: ! 28: #include "defs.h" ! 29: #include "keywords.h" ! 30: #include "scanner.h" ! 31: #include "names.h" ! 32: #include "symbols.h" ! 33: #include "tree.h" ! 34: #include "lists.h" ! 35: #include "main.h" ! 36: #include "y.tab.h" ! 37: ! 38: #ifndef public ! 39: ! 40: #include "scanner.h" ! 41: #include "tree.h" ! 42: ! 43: #endif ! 44: ! 45: private String reserved[] ={ ! 46: "alias", "and", "assign", "at", "call", "catch", "cont", ! 47: "debug", "delete", "div", "down", "dump", "edit", "file", "func", ! 48: "gripe", "help", "if", "ignore", "in", ! 49: "list", "mod", "next", "nexti", "nil", "not", "or", ! 50: "print", "psym", "quit", "rerun", "return", "run", ! 51: "set", "sh", "skip", "source", "status", "step", "stepi", ! 52: "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use", ! 53: "whatis", "when", "where", "whereis", "which", ! 54: "INT", "CHAR", "REAL", "NAME", "STRING", "->" ! 55: }; ! 56: ! 57: /* ! 58: * The keyword table is a traditional hash table with collisions ! 59: * resolved by chaining. ! 60: */ ! 61: ! 62: #define HASHTABLESIZE 1007 ! 63: ! 64: typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType; ! 65: ! 66: typedef struct Keyword { ! 67: Name name; ! 68: KeywordType class : 16; ! 69: union { ! 70: /* ISKEYWORD: */ ! 71: Token toknum; ! 72: ! 73: /* ISALIAS: */ ! 74: struct { ! 75: List paramlist; ! 76: String expansion; ! 77: } alias; ! 78: ! 79: /* ISVAR: */ ! 80: Node var; ! 81: } value; ! 82: struct Keyword *chain; ! 83: } *Keyword; ! 84: ! 85: typedef unsigned int Hashvalue; ! 86: ! 87: private Keyword hashtab[HASHTABLESIZE]; ! 88: ! 89: #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE) ! 90: ! 91: /* ! 92: * Enter all the reserved words into the keyword table. ! 93: * ! 94: * If the vaddrs flag is set (through the -k command line option) then ! 95: * set the special "$mapaddrs" variable. This assumes that the ! 96: * command line arguments are scanned before this routine is called. ! 97: */ ! 98: ! 99: public enterkeywords() ! 100: { ! 101: register integer i; ! 102: ! 103: for (i = ALIAS; i <= WHICH; i++) { ! 104: keyword(reserved[ord(i) - ord(ALIAS)], i); ! 105: } ! 106: defalias("c", "cont"); ! 107: defalias("d", "delete"); ! 108: defalias("h", "help"); ! 109: defalias("e", "edit"); ! 110: defalias("l", "list"); ! 111: defalias("n", "next"); ! 112: defalias("p", "print"); ! 113: defalias("q", "quit"); ! 114: defalias("r", "run"); ! 115: defalias("s", "step"); ! 116: defalias("st", "stop"); ! 117: defalias("j", "status"); ! 118: defalias("t", "where"); ! 119: if (vaddrs) { ! 120: defvar(identname("$mapaddrs", true), nil); ! 121: } ! 122: } ! 123: ! 124: /* ! 125: * Deallocate the keyword table. ! 126: */ ! 127: ! 128: public keywords_free() ! 129: { ! 130: register Integer i; ! 131: register Keyword k, nextk; ! 132: ! 133: for (i = 0; i < HASHTABLESIZE; i++) { ! 134: k = hashtab[i]; ! 135: while (k != nil) { ! 136: nextk = k->chain; ! 137: dispose(k); ! 138: k = nextk; ! 139: } ! 140: hashtab[i] = nil; ! 141: } ! 142: } ! 143: ! 144: /* ! 145: * Insert a name into the keyword table and return the keyword for it. ! 146: */ ! 147: ! 148: private Keyword keywords_insert (n) ! 149: Name n; ! 150: { ! 151: Hashvalue h; ! 152: Keyword k; ! 153: ! 154: h = hash(n); ! 155: k = new(Keyword); ! 156: k->name = n; ! 157: k->chain = hashtab[h]; ! 158: hashtab[h] = k; ! 159: return k; ! 160: } ! 161: ! 162: /* ! 163: * Find the keyword associated with the given name. ! 164: */ ! 165: ! 166: private Keyword keywords_lookup (n) ! 167: Name n; ! 168: { ! 169: Hashvalue h; ! 170: register Keyword k; ! 171: ! 172: h = hash(n); ! 173: k = hashtab[h]; ! 174: while (k != nil and k->name != n) { ! 175: k = k->chain; ! 176: } ! 177: return k; ! 178: } ! 179: ! 180: /* ! 181: * Delete the given keyword of the given class. ! 182: */ ! 183: ! 184: private boolean keywords_delete (n, class) ! 185: Name n; ! 186: KeywordType class; ! 187: { ! 188: Hashvalue h; ! 189: register Keyword k, prevk; ! 190: boolean b; ! 191: ! 192: h = hash(n); ! 193: k = hashtab[h]; ! 194: prevk = nil; ! 195: while (k != nil and (k->name != n or k->class != class)) { ! 196: prevk = k; ! 197: k = k->chain; ! 198: } ! 199: if (k != nil) { ! 200: b = true; ! 201: if (prevk == nil) { ! 202: hashtab[h] = k->chain; ! 203: } else { ! 204: prevk->chain = k->chain; ! 205: } ! 206: dispose(k); ! 207: } else { ! 208: b = false; ! 209: } ! 210: return b; ! 211: } ! 212: ! 213: /* ! 214: * Enter a keyword into the table. It is assumed to not be there already. ! 215: * The string is assumed to be statically allocated. ! 216: */ ! 217: ! 218: private keyword (s, t) ! 219: String s; ! 220: Token t; ! 221: { ! 222: Keyword k; ! 223: Name n; ! 224: ! 225: n = identname(s, true); ! 226: k = keywords_insert(n); ! 227: k->class = ISKEYWORD; ! 228: k->value.toknum = t; ! 229: } ! 230: ! 231: /* ! 232: * Define a builtin command name alias. ! 233: */ ! 234: ! 235: private defalias (s1, s2) ! 236: String s1, s2; ! 237: { ! 238: alias(identname(s1, true), nil, s2); ! 239: } ! 240: ! 241: /* ! 242: * Look for a word of a particular class. ! 243: */ ! 244: ! 245: private Keyword findword (n, class) ! 246: Name n; ! 247: KeywordType class; ! 248: { ! 249: register Keyword k; ! 250: ! 251: k = keywords_lookup(n); ! 252: while (k != nil and (k->name != n or k->class != class)) { ! 253: k = k->chain; ! 254: } ! 255: return k; ! 256: } ! 257: ! 258: /* ! 259: * Return the token associated with a given keyword string. ! 260: * If there is none, return the given default value. ! 261: */ ! 262: ! 263: public Token findkeyword (n, def) ! 264: Name n; ! 265: Token def; ! 266: { ! 267: Keyword k; ! 268: Token t; ! 269: ! 270: k = findword(n, ISKEYWORD); ! 271: if (k == nil) { ! 272: t = def; ! 273: } else { ! 274: t = k->value.toknum; ! 275: } ! 276: return t; ! 277: } ! 278: ! 279: /* ! 280: * Return the associated string if there is an alias with the given name. ! 281: */ ! 282: ! 283: public boolean findalias (n, pl, str) ! 284: Name n; ! 285: List *pl; ! 286: String *str; ! 287: { ! 288: Keyword k; ! 289: boolean b; ! 290: ! 291: k = findword(n, ISALIAS); ! 292: if (k == nil) { ! 293: b = false; ! 294: } else { ! 295: *pl = k->value.alias.paramlist; ! 296: *str = k->value.alias.expansion; ! 297: b = true; ! 298: } ! 299: return b; ! 300: } ! 301: ! 302: /* ! 303: * Return the string associated with a token corresponding to a keyword. ! 304: */ ! 305: ! 306: public String keywdstring (t) ! 307: Token t; ! 308: { ! 309: return reserved[ord(t) - ord(ALIAS)]; ! 310: } ! 311: ! 312: /* ! 313: * Process an alias command, either entering a new alias or printing out ! 314: * an existing one. ! 315: */ ! 316: ! 317: public alias (newcmd, args, str) ! 318: Name newcmd; ! 319: List args; ! 320: String str; ! 321: { ! 322: Keyword k; ! 323: ! 324: if (str == nil) { ! 325: print_alias(newcmd); ! 326: } else { ! 327: k = findword(newcmd, ISALIAS); ! 328: if (k == nil) { ! 329: k = keywords_insert(newcmd); ! 330: } ! 331: k->class = ISALIAS; ! 332: k->value.alias.paramlist = args; ! 333: k->value.alias.expansion = str; ! 334: } ! 335: } ! 336: ! 337: /* ! 338: * Print out an alias. ! 339: */ ! 340: ! 341: private print_alias (cmd) ! 342: Name cmd; ! 343: { ! 344: register Keyword k; ! 345: register Integer i; ! 346: Name n; ! 347: ! 348: if (cmd == nil) { ! 349: for (i = 0; i < HASHTABLESIZE; i++) { ! 350: for (k = hashtab[i]; k != nil; k = k->chain) { ! 351: if (k->class == ISALIAS) { ! 352: if (isredirected()) { ! 353: printf("alias %s", ident(k->name)); ! 354: printparams(k->value.alias.paramlist); ! 355: printf("\t\"%s\"\n", k->value.alias.expansion); ! 356: } else { ! 357: printf("%s", ident(k->name)); ! 358: printparams(k->value.alias.paramlist); ! 359: printf("\t%s\n", k->value.alias.expansion); ! 360: } ! 361: } ! 362: } ! 363: } ! 364: } else { ! 365: k = findword(cmd, ISALIAS); ! 366: if (k == nil) { ! 367: printf("\n"); ! 368: } else { ! 369: printparams(k->value.alias.paramlist); ! 370: printf("%s\n", k->value.alias.expansion); ! 371: } ! 372: } ! 373: } ! 374: ! 375: private printparams (pl) ! 376: List pl; ! 377: { ! 378: Name n; ! 379: ! 380: if (pl != nil) { ! 381: printf("("); ! 382: foreach(Name, n, pl) ! 383: printf("%s", ident(n)); ! 384: if (not list_islast()) { ! 385: printf(", "); ! 386: } ! 387: endfor ! 388: printf(")"); ! 389: } ! 390: } ! 391: ! 392: /* ! 393: * Remove an alias. ! 394: */ ! 395: ! 396: public unalias (n) ! 397: Name n; ! 398: { ! 399: if (not keywords_delete(n, ISALIAS)) { ! 400: error("%s is not aliased", ident(n)); ! 401: } ! 402: } ! 403: ! 404: /* ! 405: * Define a variable. ! 406: */ ! 407: ! 408: public defvar (n, val) ! 409: Name n; ! 410: Node val; ! 411: { ! 412: Keyword k; ! 413: ! 414: if (n == nil) { ! 415: print_vars(); ! 416: } else { ! 417: if (lookup(n) != nil) { ! 418: error("\"%s\" is a program symbol -- use assign", ident(n)); ! 419: } ! 420: k = findword(n, ISVAR); ! 421: if (k == nil) { ! 422: k = keywords_insert(n); ! 423: } ! 424: k->class = ISVAR; ! 425: k->value.var = val; ! 426: if (n == identname("$mapaddrs", true)) { ! 427: vaddrs = true; ! 428: } ! 429: } ! 430: } ! 431: ! 432: /* ! 433: * Return the value associated with a variable. ! 434: */ ! 435: ! 436: public Node findvar (n) ! 437: Name n; ! 438: { ! 439: Keyword k; ! 440: Node val; ! 441: ! 442: k = findword(n, ISVAR); ! 443: if (k == nil) { ! 444: val = nil; ! 445: } else { ! 446: val = k->value.var; ! 447: } ! 448: return val; ! 449: } ! 450: ! 451: /* ! 452: * Return whether or not a variable is set. ! 453: */ ! 454: ! 455: public boolean varIsSet (s) ! 456: String s; ! 457: { ! 458: return (boolean) (findword(identname(s, false), ISVAR) != nil); ! 459: } ! 460: ! 461: /* ! 462: * Delete a variable. ! 463: */ ! 464: ! 465: public undefvar (n) ! 466: Name n; ! 467: { ! 468: if (not keywords_delete(n, ISVAR)) { ! 469: error("%s is not set", ident(n)); ! 470: } ! 471: if (n == identname("$mapaddrs", true)) { ! 472: vaddrs = false; ! 473: } ! 474: } ! 475: ! 476: /* ! 477: * Print out all the values of set variables. ! 478: */ ! 479: ! 480: private print_vars () ! 481: { ! 482: register integer i; ! 483: register Keyword k; ! 484: ! 485: for (i = 0; i < HASHTABLESIZE; i++) { ! 486: for (k = hashtab[i]; k != nil; k = k->chain) { ! 487: if (k->class == ISVAR) { ! 488: if (isredirected()) { ! 489: printf("set "); ! 490: } ! 491: printf("%s", ident(k->name)); ! 492: if (k->value.var != nil) { ! 493: printf("\t"); ! 494: prtree(stdout, k->value.var); ! 495: } ! 496: printf("\n"); ! 497: } ! 498: } ! 499: } ! 500: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.