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