xref: /csrg-svn/old/dbx/keywords.c (revision 18220)
19664Slinton /* Copyright (c) 1982 Regents of the University of California */
29664Slinton 
3*18220Slinton static	char sccsid[] = "@(#)keywords.c	1.7 (Berkeley) 03/01/85";
49664Slinton 
5*18220Slinton static char rcsid[] = "$Header: keywords.c,v 1.5 84/12/26 10:39:45 linton Exp $";
6*18220Slinton 
79664Slinton /*
8*18220Slinton  * Keywords, variables, and aliases (oh my!).
99664Slinton  */
109664Slinton 
119664Slinton #include "defs.h"
129664Slinton #include "keywords.h"
139664Slinton #include "scanner.h"
149664Slinton #include "names.h"
159664Slinton #include "symbols.h"
169664Slinton #include "tree.h"
17*18220Slinton #include "lists.h"
18*18220Slinton #include "main.h"
199664Slinton #include "y.tab.h"
209664Slinton 
219664Slinton #ifndef public
22*18220Slinton 
239664Slinton #include "scanner.h"
24*18220Slinton #include "tree.h"
25*18220Slinton 
269664Slinton #endif
279664Slinton 
289664Slinton private String reserved[] ={
299664Slinton     "alias", "and", "assign", "at", "call", "catch", "cont",
3016611Ssam     "debug", "delete", "div", "down", "dump", "edit", "file", "func",
319664Slinton     "gripe", "help", "if", "ignore", "in",
329664Slinton     "list", "mod", "next", "nexti", "nil", "not", "or",
3316611Ssam     "print", "psym", "quit", "rerun", "return", "run",
34*18220Slinton     "set", "sh", "skip", "source", "status", "step", "stepi",
35*18220Slinton     "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use",
36*18220Slinton     "whatis", "when", "where", "whereis", "which",
37*18220Slinton     "INT", "CHAR", "REAL", "NAME", "STRING", "->"
389664Slinton };
399664Slinton 
409664Slinton /*
419664Slinton  * The keyword table is a traditional hash table with collisions
429664Slinton  * resolved by chaining.
439664Slinton  */
44*18220Slinton 
45*18220Slinton #define HASHTABLESIZE 1007
46*18220Slinton 
47*18220Slinton typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType;
48*18220Slinton 
499664Slinton typedef struct Keyword {
509664Slinton     Name name;
51*18220Slinton     KeywordType class : 16;
52*18220Slinton     union {
53*18220Slinton 	/* ISKEYWORD: */
54*18220Slinton 	    Token toknum;
55*18220Slinton 
56*18220Slinton 	/* ISALIAS: */
57*18220Slinton 	    struct {
58*18220Slinton 		List paramlist;
59*18220Slinton 		String expansion;
60*18220Slinton 	    } alias;
61*18220Slinton 
62*18220Slinton 	/* ISVAR: */
63*18220Slinton 	    Node var;
64*18220Slinton     } value;
659664Slinton     struct Keyword *chain;
669664Slinton } *Keyword;
679664Slinton 
689664Slinton typedef unsigned int Hashvalue;
699664Slinton 
70*18220Slinton private Keyword hashtab[HASHTABLESIZE];
719664Slinton 
72*18220Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE)
739664Slinton 
749664Slinton /*
759664Slinton  * Enter all the reserved words into the keyword table.
76*18220Slinton  *
77*18220Slinton  * If the vaddrs flag is set (through the -k command line option) then
78*18220Slinton  * set the special "$mapaddrs" variable.  This assumes that the
79*18220Slinton  * command line arguments are scanned before this routine is called.
809664Slinton  */
81*18220Slinton 
829664Slinton public enterkeywords()
839664Slinton {
84*18220Slinton     register integer i;
859664Slinton 
86*18220Slinton     for (i = ALIAS; i <= WHICH; i++) {
8716928Ssam 	keyword(reserved[ord(i) - ord(ALIAS)], i);
88*18220Slinton     }
89*18220Slinton     defalias("c", "cont");
90*18220Slinton     defalias("d", "delete");
91*18220Slinton     defalias("h", "help");
92*18220Slinton     defalias("e", "edit");
93*18220Slinton     defalias("l", "list");
94*18220Slinton     defalias("n", "next");
95*18220Slinton     defalias("p", "print");
96*18220Slinton     defalias("q", "quit");
97*18220Slinton     defalias("r", "run");
98*18220Slinton     defalias("s", "step");
99*18220Slinton     defalias("st", "stop");
100*18220Slinton     defalias("j", "status");
101*18220Slinton     defalias("t", "where");
102*18220Slinton     if (vaddrs) {
103*18220Slinton 	defvar(identname("$mapaddrs", true), nil);
104*18220Slinton     }
1059664Slinton }
1069664Slinton 
1079664Slinton /*
108*18220Slinton  * Deallocate the keyword table.
1099664Slinton  */
110*18220Slinton 
1119664Slinton public keywords_free()
1129664Slinton {
1139664Slinton     register Integer i;
1149664Slinton     register Keyword k, nextk;
1159664Slinton 
116*18220Slinton     for (i = 0; i < HASHTABLESIZE; i++) {
117*18220Slinton 	k = hashtab[i];
118*18220Slinton 	while (k != nil) {
1199664Slinton 	    nextk = k->chain;
1209664Slinton 	    dispose(k);
121*18220Slinton 	    k = nextk;
1229664Slinton 	}
1239664Slinton 	hashtab[i] = nil;
1249664Slinton     }
125*18220Slinton }
126*18220Slinton 
127*18220Slinton /*
128*18220Slinton  * Insert a name into the keyword table and return the keyword for it.
129*18220Slinton  */
130*18220Slinton 
131*18220Slinton private Keyword keywords_insert (n)
132*18220Slinton Name n;
133*18220Slinton {
134*18220Slinton     Hashvalue h;
135*18220Slinton     Keyword k;
136*18220Slinton 
137*18220Slinton     h = hash(n);
138*18220Slinton     k = new(Keyword);
139*18220Slinton     k->name = n;
140*18220Slinton     k->chain = hashtab[h];
141*18220Slinton     hashtab[h] = k;
142*18220Slinton     return k;
143*18220Slinton }
144*18220Slinton 
145*18220Slinton /*
146*18220Slinton  * Find the keyword associated with the given name.
147*18220Slinton  */
148*18220Slinton 
149*18220Slinton private Keyword keywords_lookup (n)
150*18220Slinton Name n;
151*18220Slinton {
152*18220Slinton     Hashvalue h;
153*18220Slinton     register Keyword k;
154*18220Slinton 
155*18220Slinton     h = hash(n);
156*18220Slinton     k = hashtab[h];
157*18220Slinton     while (k != nil and k->name != n) {
158*18220Slinton 	k = k->chain;
159*18220Slinton     }
160*18220Slinton     return k;
161*18220Slinton }
162*18220Slinton 
163*18220Slinton /*
164*18220Slinton  * Delete the given keyword of the given class.
165*18220Slinton  */
166*18220Slinton 
167*18220Slinton private boolean keywords_delete (n, class)
168*18220Slinton Name n;
169*18220Slinton KeywordType class;
170*18220Slinton {
171*18220Slinton     Hashvalue h;
172*18220Slinton     register Keyword k, prevk;
173*18220Slinton     boolean b;
174*18220Slinton 
175*18220Slinton     h = hash(n);
176*18220Slinton     k = hashtab[h];
177*18220Slinton     prevk = nil;
178*18220Slinton     while (k != nil and (k->name != n or k->class != class)) {
179*18220Slinton 	prevk = k;
180*18220Slinton 	k = k->chain;
181*18220Slinton     }
182*18220Slinton     if (k != nil) {
183*18220Slinton 	b = true;
184*18220Slinton 	if (prevk == nil) {
185*18220Slinton 	    hashtab[h] = k->chain;
186*18220Slinton 	} else {
187*18220Slinton 	    prevk->chain = k->chain;
18816928Ssam 	}
189*18220Slinton 	dispose(k);
190*18220Slinton     } else {
191*18220Slinton 	b = false;
19216928Ssam     }
193*18220Slinton     return b;
1949664Slinton }
1959664Slinton 
1969664Slinton /*
197*18220Slinton  * Enter a keyword into the table.  It is assumed to not be there already.
1989664Slinton  * The string is assumed to be statically allocated.
1999664Slinton  */
200*18220Slinton 
201*18220Slinton private keyword (s, t)
2029664Slinton String s;
2039664Slinton Token t;
2049664Slinton {
205*18220Slinton     Keyword k;
2069664Slinton     Name n;
2079664Slinton 
2089664Slinton     n = identname(s, true);
209*18220Slinton     k = keywords_insert(n);
210*18220Slinton     k->class = ISKEYWORD;
211*18220Slinton     k->value.toknum = t;
2129664Slinton }
2139664Slinton 
2149664Slinton /*
215*18220Slinton  * Define a builtin command name alias.
2169664Slinton  */
217*18220Slinton 
218*18220Slinton private defalias (s1, s2)
219*18220Slinton String s1, s2;
2209664Slinton {
221*18220Slinton     alias(identname(s1, true), nil, s2);
2229664Slinton }
2239664Slinton 
2249664Slinton /*
225*18220Slinton  * Look for a word of a particular class.
2269664Slinton  */
2279664Slinton 
228*18220Slinton private Keyword findword (n, class)
2299664Slinton Name n;
230*18220Slinton KeywordType class;
2319664Slinton {
2329664Slinton     register Keyword k;
2339664Slinton 
234*18220Slinton     k = keywords_lookup(n);
235*18220Slinton     while (k != nil and (k->name != n or k->class != class)) {
236*18220Slinton 	k = k->chain;
237*18220Slinton     }
238*18220Slinton     return k;
23916611Ssam }
24016611Ssam 
241*18220Slinton /*
242*18220Slinton  * Return the token associated with a given keyword string.
243*18220Slinton  * If there is none, return the given default value.
244*18220Slinton  */
245*18220Slinton 
246*18220Slinton public Token findkeyword (n, def)
24716611Ssam Name n;
248*18220Slinton Token def;
24916611Ssam {
250*18220Slinton     Keyword k;
251*18220Slinton     Token t;
25216611Ssam 
253*18220Slinton     k = findword(n, ISKEYWORD);
254*18220Slinton     if (k == nil) {
255*18220Slinton 	t = def;
256*18220Slinton     } else {
257*18220Slinton 	t = k->value.toknum;
258*18220Slinton     }
259*18220Slinton     return t;
2609664Slinton }
2619664Slinton 
2629664Slinton /*
263*18220Slinton  * Return the associated string if there is an alias with the given name.
2649664Slinton  */
265*18220Slinton 
266*18220Slinton public boolean findalias (n, pl, str)
267*18220Slinton Name n;
268*18220Slinton List *pl;
269*18220Slinton String *str;
270*18220Slinton {
271*18220Slinton     Keyword k;
272*18220Slinton     boolean b;
273*18220Slinton 
274*18220Slinton     k = findword(n, ISALIAS);
275*18220Slinton     if (k == nil) {
276*18220Slinton 	b = false;
277*18220Slinton     } else {
278*18220Slinton 	*pl = k->value.alias.paramlist;
279*18220Slinton 	*str = k->value.alias.expansion;
280*18220Slinton     }
281*18220Slinton     return b;
282*18220Slinton }
283*18220Slinton 
284*18220Slinton /*
285*18220Slinton  * Return the string associated with a token corresponding to a keyword.
286*18220Slinton  */
287*18220Slinton 
288*18220Slinton public String keywdstring (t)
289*18220Slinton Token t;
290*18220Slinton {
291*18220Slinton     return reserved[ord(t) - ord(ALIAS)];
292*18220Slinton }
293*18220Slinton 
294*18220Slinton /*
295*18220Slinton  * Process an alias command, either entering a new alias or printing out
296*18220Slinton  * an existing one.
297*18220Slinton  */
298*18220Slinton 
299*18220Slinton public alias (newcmd, args, str)
300*18220Slinton Name newcmd;
301*18220Slinton List args;
302*18220Slinton String str;
303*18220Slinton {
304*18220Slinton     Keyword k;
305*18220Slinton 
306*18220Slinton     if (str == nil) {
307*18220Slinton 	print_alias(newcmd);
308*18220Slinton     } else {
309*18220Slinton 	k = findword(newcmd, ISALIAS);
310*18220Slinton 	if (k == nil) {
311*18220Slinton 	    k = keywords_insert(newcmd);
312*18220Slinton 	}
313*18220Slinton 	k->class = ISALIAS;
314*18220Slinton 	k->value.alias.paramlist = args;
315*18220Slinton 	k->value.alias.expansion = str;
316*18220Slinton     }
317*18220Slinton }
318*18220Slinton 
319*18220Slinton /*
320*18220Slinton  * Print out an alias.
321*18220Slinton  */
322*18220Slinton 
323*18220Slinton private print_alias (cmd)
32416928Ssam Name cmd;
3259664Slinton {
326*18220Slinton     register Keyword k;
327*18220Slinton     register Integer i;
32816928Ssam     Name n;
3299664Slinton 
330*18220Slinton     if (cmd == nil) {
331*18220Slinton 	for (i = 0; i < HASHTABLESIZE; i++) {
332*18220Slinton 	    for (k = hashtab[i]; k != nil; k = k->chain) {
333*18220Slinton 		if (k->class == ISALIAS) {
334*18220Slinton 		    if (isredirected()) {
335*18220Slinton 			printf("alias %s", ident(k->name));
336*18220Slinton 			printparams(k->value.alias.paramlist);
337*18220Slinton 			printf("\t\"%s\"\n", k->value.alias.expansion);
338*18220Slinton 		    } else {
339*18220Slinton 			printf("%s", ident(k->name));
340*18220Slinton 			printparams(k->value.alias.paramlist);
341*18220Slinton 			printf("\t%s\n", k->value.alias.expansion);
342*18220Slinton 		    }
343*18220Slinton 		}
344*18220Slinton 	    }
345*18220Slinton 	}
346*18220Slinton     } else {
347*18220Slinton 	k = findword(cmd, ISALIAS);
348*18220Slinton 	if (k == nil) {
349*18220Slinton 	    printf("\n");
350*18220Slinton 	} else {
351*18220Slinton 	    printparams(k->value.alias.paramlist);
352*18220Slinton 	    printf("%s\n", k->value.alias.expansion);
353*18220Slinton 	}
3549664Slinton     }
3559664Slinton }
3569664Slinton 
357*18220Slinton private printparams (pl)
358*18220Slinton List pl;
35916928Ssam {
360*18220Slinton     Name n;
36116928Ssam 
362*18220Slinton     if (pl != nil) {
363*18220Slinton 	printf("(");
364*18220Slinton 	foreach(Name, n, pl)
365*18220Slinton 	    printf("%s", ident(n));
366*18220Slinton 	    if (not list_islast()) {
367*18220Slinton 		printf(", ");
368*18220Slinton 	    }
369*18220Slinton 	endfor
370*18220Slinton 	printf(")");
37116928Ssam     }
372*18220Slinton }
373*18220Slinton 
374*18220Slinton /*
375*18220Slinton  * Remove an alias.
376*18220Slinton  */
377*18220Slinton 
378*18220Slinton public unalias (n)
379*18220Slinton Name n;
380*18220Slinton {
381*18220Slinton     if (not keywords_delete(n, ISALIAS)) {
382*18220Slinton 	error("%s is not aliased", ident(n));
38316949Ssam     }
38416928Ssam }
38516928Ssam 
386*18220Slinton /*
387*18220Slinton  * Define a variable.
388*18220Slinton  */
389*18220Slinton 
390*18220Slinton public defvar (n, val)
391*18220Slinton Name n;
392*18220Slinton Node val;
39316949Ssam {
394*18220Slinton     Keyword k;
39516949Ssam 
396*18220Slinton     if (n == nil) {
397*18220Slinton 	print_vars();
398*18220Slinton     } else {
399*18220Slinton 	if (lookup(n) != nil) {
400*18220Slinton 	    error("\"%s\" is a program symbol -- use assign", ident(n));
401*18220Slinton 	}
402*18220Slinton 	k = findword(n, ISVAR);
403*18220Slinton 	if (k == nil) {
404*18220Slinton 	    k = keywords_insert(n);
405*18220Slinton 	}
406*18220Slinton 	k->class = ISVAR;
407*18220Slinton 	k->value.var = val;
408*18220Slinton 	if (n == identname("$mapaddrs", true)) {
409*18220Slinton 	    vaddrs = true;
410*18220Slinton 	}
411*18220Slinton     }
41216949Ssam }
41316949Ssam 
4149664Slinton /*
415*18220Slinton  * Return the value associated with a variable.
4169664Slinton  */
417*18220Slinton 
418*18220Slinton public Node findvar (n)
419*18220Slinton Name n;
4209664Slinton {
421*18220Slinton     Keyword k;
422*18220Slinton     Node val;
4239664Slinton 
424*18220Slinton     k = findword(n, ISVAR);
425*18220Slinton     if (k == nil) {
426*18220Slinton 	val = nil;
427*18220Slinton     } else {
428*18220Slinton 	val = k->value.var;
42916928Ssam     }
430*18220Slinton     return val;
431*18220Slinton }
432*18220Slinton 
433*18220Slinton /*
434*18220Slinton  * Return whether or not a variable is set.
435*18220Slinton  */
436*18220Slinton 
437*18220Slinton public boolean varIsSet (s)
438*18220Slinton String s;
439*18220Slinton {
440*18220Slinton     return (boolean) (findword(identname(s, false), ISVAR) != nil);
441*18220Slinton }
442*18220Slinton 
443*18220Slinton /*
444*18220Slinton  * Delete a variable.
445*18220Slinton  */
446*18220Slinton 
447*18220Slinton public undefvar (n)
448*18220Slinton Name n;
449*18220Slinton {
450*18220Slinton     if (not keywords_delete(n, ISVAR)) {
451*18220Slinton 	error("%s is not set", ident(n));
452*18220Slinton     }
453*18220Slinton     if (n == identname("$mapaddrs", true)) {
454*18220Slinton 	vaddrs = false;
455*18220Slinton     }
456*18220Slinton }
457*18220Slinton 
458*18220Slinton /*
459*18220Slinton  * Print out all the values of set variables.
460*18220Slinton  */
461*18220Slinton 
462*18220Slinton private print_vars ()
463*18220Slinton {
464*18220Slinton     register integer i;
465*18220Slinton     register Keyword k;
466*18220Slinton 
467*18220Slinton     for (i = 0; i < HASHTABLESIZE; i++) {
468*18220Slinton 	for (k = hashtab[i]; k != nil; k = k->chain) {
469*18220Slinton 	    if (k->class == ISVAR) {
470*18220Slinton 		if (isredirected()) {
471*18220Slinton 		    printf("set ");
472*18220Slinton 		}
473*18220Slinton 		printf("%s", ident(k->name));
474*18220Slinton 		if (k->value.var != nil) {
475*18220Slinton 		    printf("\t");
476*18220Slinton 		    prtree(stdout, k->value.var);
477*18220Slinton 		}
478*18220Slinton 		printf("\n");
479*18220Slinton 	    }
4809664Slinton 	}
4819664Slinton     }
4829664Slinton }
483