121604Sdist /* 2*38105Sbostic * Copyright (c) 1983 The Regents of the University of California. 3*38105Sbostic * All rights reserved. 4*38105Sbostic * 5*38105Sbostic * Redistribution and use in source and binary forms are permitted 6*38105Sbostic * provided that the above copyright notice and this paragraph are 7*38105Sbostic * duplicated in all such forms and that any documentation, 8*38105Sbostic * advertising materials, and other materials related to such 9*38105Sbostic * distribution and use acknowledge that the software was developed 10*38105Sbostic * by the University of California, Berkeley. The name of the 11*38105Sbostic * University may not be used to endorse or promote products derived 12*38105Sbostic * from this software without specific prior written permission. 13*38105Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*38105Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*38105Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621604Sdist */ 179664Slinton 1821604Sdist #ifndef lint 19*38105Sbostic static char sccsid[] = "@(#)keywords.c 5.3 (Berkeley) 05/23/89"; 20*38105Sbostic #endif /* not lint */ 219664Slinton 229664Slinton /* 2318220Slinton * Keywords, variables, and aliases (oh my!). 249664Slinton */ 259664Slinton 269664Slinton #include "defs.h" 279664Slinton #include "keywords.h" 289664Slinton #include "scanner.h" 299664Slinton #include "names.h" 309664Slinton #include "symbols.h" 319664Slinton #include "tree.h" 3218220Slinton #include "lists.h" 3318220Slinton #include "main.h" 349664Slinton #include "y.tab.h" 359664Slinton 369664Slinton #ifndef public 3718220Slinton 389664Slinton #include "scanner.h" 3918220Slinton #include "tree.h" 4018220Slinton 419664Slinton #endif 429664Slinton 439664Slinton private String reserved[] ={ 449664Slinton "alias", "and", "assign", "at", "call", "catch", "cont", 4516611Ssam "debug", "delete", "div", "down", "dump", "edit", "file", "func", 469664Slinton "gripe", "help", "if", "ignore", "in", 479664Slinton "list", "mod", "next", "nexti", "nil", "not", "or", 4816611Ssam "print", "psym", "quit", "rerun", "return", "run", 4918220Slinton "set", "sh", "skip", "source", "status", "step", "stepi", 5018220Slinton "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use", 5118220Slinton "whatis", "when", "where", "whereis", "which", 5218220Slinton "INT", "CHAR", "REAL", "NAME", "STRING", "->" 539664Slinton }; 549664Slinton 559664Slinton /* 569664Slinton * The keyword table is a traditional hash table with collisions 579664Slinton * resolved by chaining. 589664Slinton */ 5918220Slinton 6018220Slinton #define HASHTABLESIZE 1007 6118220Slinton 6218220Slinton typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType; 6318220Slinton 649664Slinton typedef struct Keyword { 659664Slinton Name name; 6618220Slinton KeywordType class : 16; 6718220Slinton union { 6818220Slinton /* ISKEYWORD: */ 6918220Slinton Token toknum; 7018220Slinton 7118220Slinton /* ISALIAS: */ 7218220Slinton struct { 7318220Slinton List paramlist; 7418220Slinton String expansion; 7518220Slinton } alias; 7618220Slinton 7718220Slinton /* ISVAR: */ 7818220Slinton Node var; 7918220Slinton } value; 809664Slinton struct Keyword *chain; 819664Slinton } *Keyword; 829664Slinton 839664Slinton typedef unsigned int Hashvalue; 849664Slinton 8518220Slinton private Keyword hashtab[HASHTABLESIZE]; 869664Slinton 8718220Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE) 889664Slinton 899664Slinton /* 909664Slinton * Enter all the reserved words into the keyword table. 9118220Slinton * 9218220Slinton * If the vaddrs flag is set (through the -k command line option) then 9318220Slinton * set the special "$mapaddrs" variable. This assumes that the 9418220Slinton * command line arguments are scanned before this routine is called. 959664Slinton */ 9618220Slinton 979664Slinton public enterkeywords() 989664Slinton { 9918220Slinton register integer i; 1009664Slinton 10118220Slinton for (i = ALIAS; i <= WHICH; i++) { 10216928Ssam keyword(reserved[ord(i) - ord(ALIAS)], i); 10318220Slinton } 10418220Slinton defalias("c", "cont"); 10518220Slinton defalias("d", "delete"); 10618220Slinton defalias("h", "help"); 10718220Slinton defalias("e", "edit"); 10818220Slinton defalias("l", "list"); 10918220Slinton defalias("n", "next"); 11018220Slinton defalias("p", "print"); 11118220Slinton defalias("q", "quit"); 11218220Slinton defalias("r", "run"); 11318220Slinton defalias("s", "step"); 11418220Slinton defalias("st", "stop"); 11518220Slinton defalias("j", "status"); 11618220Slinton defalias("t", "where"); 11718220Slinton if (vaddrs) { 11818220Slinton defvar(identname("$mapaddrs", true), nil); 11918220Slinton } 1209664Slinton } 1219664Slinton 1229664Slinton /* 12318220Slinton * Deallocate the keyword table. 1249664Slinton */ 12518220Slinton 1269664Slinton public keywords_free() 1279664Slinton { 1289664Slinton register Integer i; 1299664Slinton register Keyword k, nextk; 1309664Slinton 13118220Slinton for (i = 0; i < HASHTABLESIZE; i++) { 13218220Slinton k = hashtab[i]; 13318220Slinton while (k != nil) { 1349664Slinton nextk = k->chain; 1359664Slinton dispose(k); 13618220Slinton k = nextk; 1379664Slinton } 1389664Slinton hashtab[i] = nil; 1399664Slinton } 14018220Slinton } 14118220Slinton 14218220Slinton /* 14318220Slinton * Insert a name into the keyword table and return the keyword for it. 14418220Slinton */ 14518220Slinton 14618220Slinton private Keyword keywords_insert (n) 14718220Slinton Name n; 14818220Slinton { 14918220Slinton Hashvalue h; 15018220Slinton Keyword k; 15118220Slinton 15218220Slinton h = hash(n); 15318220Slinton k = new(Keyword); 15418220Slinton k->name = n; 15518220Slinton k->chain = hashtab[h]; 15618220Slinton hashtab[h] = k; 15718220Slinton return k; 15818220Slinton } 15918220Slinton 16018220Slinton /* 16118220Slinton * Find the keyword associated with the given name. 16218220Slinton */ 16318220Slinton 16418220Slinton private Keyword keywords_lookup (n) 16518220Slinton Name n; 16618220Slinton { 16718220Slinton Hashvalue h; 16818220Slinton register Keyword k; 16918220Slinton 17018220Slinton h = hash(n); 17118220Slinton k = hashtab[h]; 17218220Slinton while (k != nil and k->name != n) { 17318220Slinton k = k->chain; 17418220Slinton } 17518220Slinton return k; 17618220Slinton } 17718220Slinton 17818220Slinton /* 17918220Slinton * Delete the given keyword of the given class. 18018220Slinton */ 18118220Slinton 18218220Slinton private boolean keywords_delete (n, class) 18318220Slinton Name n; 18418220Slinton KeywordType class; 18518220Slinton { 18618220Slinton Hashvalue h; 18718220Slinton register Keyword k, prevk; 18818220Slinton boolean b; 18918220Slinton 19018220Slinton h = hash(n); 19118220Slinton k = hashtab[h]; 19218220Slinton prevk = nil; 19318220Slinton while (k != nil and (k->name != n or k->class != class)) { 19418220Slinton prevk = k; 19518220Slinton k = k->chain; 19618220Slinton } 19718220Slinton if (k != nil) { 19818220Slinton b = true; 19918220Slinton if (prevk == nil) { 20018220Slinton hashtab[h] = k->chain; 20118220Slinton } else { 20218220Slinton prevk->chain = k->chain; 20316928Ssam } 20418220Slinton dispose(k); 20518220Slinton } else { 20618220Slinton b = false; 20716928Ssam } 20818220Slinton return b; 2099664Slinton } 2109664Slinton 2119664Slinton /* 21218220Slinton * Enter a keyword into the table. It is assumed to not be there already. 2139664Slinton * The string is assumed to be statically allocated. 2149664Slinton */ 21518220Slinton 21618220Slinton private keyword (s, t) 2179664Slinton String s; 2189664Slinton Token t; 2199664Slinton { 22018220Slinton Keyword k; 2219664Slinton Name n; 2229664Slinton 2239664Slinton n = identname(s, true); 22418220Slinton k = keywords_insert(n); 22518220Slinton k->class = ISKEYWORD; 22618220Slinton k->value.toknum = t; 2279664Slinton } 2289664Slinton 2299664Slinton /* 23018220Slinton * Define a builtin command name alias. 2319664Slinton */ 23218220Slinton 23318220Slinton private defalias (s1, s2) 23418220Slinton String s1, s2; 2359664Slinton { 23618220Slinton alias(identname(s1, true), nil, s2); 2379664Slinton } 2389664Slinton 2399664Slinton /* 24018220Slinton * Look for a word of a particular class. 2419664Slinton */ 2429664Slinton 24318220Slinton private Keyword findword (n, class) 2449664Slinton Name n; 24518220Slinton KeywordType class; 2469664Slinton { 2479664Slinton register Keyword k; 2489664Slinton 24918220Slinton k = keywords_lookup(n); 25018220Slinton while (k != nil and (k->name != n or k->class != class)) { 25118220Slinton k = k->chain; 25218220Slinton } 25318220Slinton return k; 25416611Ssam } 25516611Ssam 25618220Slinton /* 25718220Slinton * Return the token associated with a given keyword string. 25818220Slinton * If there is none, return the given default value. 25918220Slinton */ 26018220Slinton 26118220Slinton public Token findkeyword (n, def) 26216611Ssam Name n; 26318220Slinton Token def; 26416611Ssam { 26518220Slinton Keyword k; 26618220Slinton Token t; 26716611Ssam 26818220Slinton k = findword(n, ISKEYWORD); 26918220Slinton if (k == nil) { 27018220Slinton t = def; 27118220Slinton } else { 27218220Slinton t = k->value.toknum; 27318220Slinton } 27418220Slinton return t; 2759664Slinton } 2769664Slinton 2779664Slinton /* 27818220Slinton * Return the associated string if there is an alias with the given name. 2799664Slinton */ 28018220Slinton 28118220Slinton public boolean findalias (n, pl, str) 28218220Slinton Name n; 28318220Slinton List *pl; 28418220Slinton String *str; 28518220Slinton { 28618220Slinton Keyword k; 28718220Slinton boolean b; 28818220Slinton 28918220Slinton k = findword(n, ISALIAS); 29018220Slinton if (k == nil) { 29118220Slinton b = false; 29218220Slinton } else { 29318220Slinton *pl = k->value.alias.paramlist; 29418220Slinton *str = k->value.alias.expansion; 29522017Ssam b = true; 29618220Slinton } 29718220Slinton return b; 29818220Slinton } 29918220Slinton 30018220Slinton /* 30118220Slinton * Return the string associated with a token corresponding to a keyword. 30218220Slinton */ 30318220Slinton 30418220Slinton public String keywdstring (t) 30518220Slinton Token t; 30618220Slinton { 30718220Slinton return reserved[ord(t) - ord(ALIAS)]; 30818220Slinton } 30918220Slinton 31018220Slinton /* 31118220Slinton * Process an alias command, either entering a new alias or printing out 31218220Slinton * an existing one. 31318220Slinton */ 31418220Slinton 31518220Slinton public alias (newcmd, args, str) 31618220Slinton Name newcmd; 31718220Slinton List args; 31818220Slinton String str; 31918220Slinton { 32018220Slinton Keyword k; 32118220Slinton 32218220Slinton if (str == nil) { 32318220Slinton print_alias(newcmd); 32418220Slinton } else { 32518220Slinton k = findword(newcmd, ISALIAS); 32618220Slinton if (k == nil) { 32718220Slinton k = keywords_insert(newcmd); 32818220Slinton } 32918220Slinton k->class = ISALIAS; 33018220Slinton k->value.alias.paramlist = args; 33118220Slinton k->value.alias.expansion = str; 33218220Slinton } 33318220Slinton } 33418220Slinton 33518220Slinton /* 33618220Slinton * Print out an alias. 33718220Slinton */ 33818220Slinton 33918220Slinton private print_alias (cmd) 34016928Ssam Name cmd; 3419664Slinton { 34218220Slinton register Keyword k; 34318220Slinton register Integer i; 34416928Ssam Name n; 3459664Slinton 34618220Slinton if (cmd == nil) { 34718220Slinton for (i = 0; i < HASHTABLESIZE; i++) { 34818220Slinton for (k = hashtab[i]; k != nil; k = k->chain) { 34918220Slinton if (k->class == ISALIAS) { 35018220Slinton if (isredirected()) { 35118220Slinton printf("alias %s", ident(k->name)); 35218220Slinton printparams(k->value.alias.paramlist); 35318220Slinton printf("\t\"%s\"\n", k->value.alias.expansion); 35418220Slinton } else { 35518220Slinton printf("%s", ident(k->name)); 35618220Slinton printparams(k->value.alias.paramlist); 35718220Slinton printf("\t%s\n", k->value.alias.expansion); 35818220Slinton } 35918220Slinton } 36018220Slinton } 36118220Slinton } 36218220Slinton } else { 36318220Slinton k = findword(cmd, ISALIAS); 36418220Slinton if (k == nil) { 36518220Slinton printf("\n"); 36618220Slinton } else { 36718220Slinton printparams(k->value.alias.paramlist); 36818220Slinton printf("%s\n", k->value.alias.expansion); 36918220Slinton } 3709664Slinton } 3719664Slinton } 3729664Slinton 37318220Slinton private printparams (pl) 37418220Slinton List pl; 37516928Ssam { 37618220Slinton Name n; 37716928Ssam 37818220Slinton if (pl != nil) { 37918220Slinton printf("("); 38018220Slinton foreach(Name, n, pl) 38118220Slinton printf("%s", ident(n)); 38218220Slinton if (not list_islast()) { 38318220Slinton printf(", "); 38418220Slinton } 38518220Slinton endfor 38618220Slinton printf(")"); 38716928Ssam } 38818220Slinton } 38918220Slinton 39018220Slinton /* 39118220Slinton * Remove an alias. 39218220Slinton */ 39318220Slinton 39418220Slinton public unalias (n) 39518220Slinton Name n; 39618220Slinton { 39718220Slinton if (not keywords_delete(n, ISALIAS)) { 39818220Slinton error("%s is not aliased", ident(n)); 39916949Ssam } 40016928Ssam } 40116928Ssam 40218220Slinton /* 40318220Slinton * Define a variable. 40418220Slinton */ 40518220Slinton 40618220Slinton public defvar (n, val) 40718220Slinton Name n; 40818220Slinton Node val; 40916949Ssam { 41018220Slinton Keyword k; 41116949Ssam 41218220Slinton if (n == nil) { 41318220Slinton print_vars(); 41418220Slinton } else { 41518220Slinton if (lookup(n) != nil) { 41618220Slinton error("\"%s\" is a program symbol -- use assign", ident(n)); 41718220Slinton } 41818220Slinton k = findword(n, ISVAR); 41918220Slinton if (k == nil) { 42018220Slinton k = keywords_insert(n); 42118220Slinton } 42218220Slinton k->class = ISVAR; 42318220Slinton k->value.var = val; 42418220Slinton if (n == identname("$mapaddrs", true)) { 42518220Slinton vaddrs = true; 42618220Slinton } 42718220Slinton } 42816949Ssam } 42916949Ssam 4309664Slinton /* 43118220Slinton * Return the value associated with a variable. 4329664Slinton */ 43318220Slinton 43418220Slinton public Node findvar (n) 43518220Slinton Name n; 4369664Slinton { 43718220Slinton Keyword k; 43818220Slinton Node val; 4399664Slinton 44018220Slinton k = findword(n, ISVAR); 44118220Slinton if (k == nil) { 44218220Slinton val = nil; 44318220Slinton } else { 44418220Slinton val = k->value.var; 44516928Ssam } 44618220Slinton return val; 44718220Slinton } 44818220Slinton 44918220Slinton /* 45018220Slinton * Return whether or not a variable is set. 45118220Slinton */ 45218220Slinton 45318220Slinton public boolean varIsSet (s) 45418220Slinton String s; 45518220Slinton { 45618220Slinton return (boolean) (findword(identname(s, false), ISVAR) != nil); 45718220Slinton } 45818220Slinton 45918220Slinton /* 46018220Slinton * Delete a variable. 46118220Slinton */ 46218220Slinton 46318220Slinton public undefvar (n) 46418220Slinton Name n; 46518220Slinton { 46618220Slinton if (not keywords_delete(n, ISVAR)) { 46718220Slinton error("%s is not set", ident(n)); 46818220Slinton } 46918220Slinton if (n == identname("$mapaddrs", true)) { 47018220Slinton vaddrs = false; 47118220Slinton } 47218220Slinton } 47318220Slinton 47418220Slinton /* 47518220Slinton * Print out all the values of set variables. 47618220Slinton */ 47718220Slinton 47818220Slinton private print_vars () 47918220Slinton { 48018220Slinton register integer i; 48118220Slinton register Keyword k; 48218220Slinton 48318220Slinton for (i = 0; i < HASHTABLESIZE; i++) { 48418220Slinton for (k = hashtab[i]; k != nil; k = k->chain) { 48518220Slinton if (k->class == ISVAR) { 48618220Slinton if (isredirected()) { 48718220Slinton printf("set "); 48818220Slinton } 48918220Slinton printf("%s", ident(k->name)); 49018220Slinton if (k->value.var != nil) { 49118220Slinton printf("\t"); 49218220Slinton prtree(stdout, k->value.var); 49318220Slinton } 49418220Slinton printf("\n"); 49518220Slinton } 4969664Slinton } 4979664Slinton } 4989664Slinton } 499