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