date and time created 90/06/25 15:36:55 by bostic
[unix-history] / usr / src / old / dbx / keywords.c
CommitLineData
2a24676e 1/*
8a90f3aa
KB
2 * Copyright (c) 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
6ecf3d85 5 * %sccs.include.redist.c%
2a24676e 6 */
9a3f3b7b 7
2a24676e 8#ifndef lint
6ecf3d85 9static char sccsid[] = "@(#)keywords.c 5.4 (Berkeley) %G%";
8a90f3aa 10#endif /* not lint */
9a3f3b7b
ML
11
12/*
0022c355 13 * Keywords, variables, and aliases (oh my!).
9a3f3b7b
ML
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"
0022c355
ML
22#include "lists.h"
23#include "main.h"
9a3f3b7b
ML
24#include "y.tab.h"
25
26#ifndef public
0022c355 27
9a3f3b7b 28#include "scanner.h"
0022c355
ML
29#include "tree.h"
30
9a3f3b7b
ML
31#endif
32
33private String reserved[] ={
34 "alias", "and", "assign", "at", "call", "catch", "cont",
2fd0f574 35 "debug", "delete", "div", "down", "dump", "edit", "file", "func",
9a3f3b7b
ML
36 "gripe", "help", "if", "ignore", "in",
37 "list", "mod", "next", "nexti", "nil", "not", "or",
2fd0f574 38 "print", "psym", "quit", "rerun", "return", "run",
0022c355
ML
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", "->"
9a3f3b7b
ML
43};
44
45/*
46 * The keyword table is a traditional hash table with collisions
47 * resolved by chaining.
48 */
0022c355
ML
49
50#define HASHTABLESIZE 1007
51
52typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType;
53
9a3f3b7b
ML
54typedef struct Keyword {
55 Name name;
0022c355
ML
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;
9a3f3b7b
ML
70 struct Keyword *chain;
71} *Keyword;
72
73typedef unsigned int Hashvalue;
74
0022c355 75private Keyword hashtab[HASHTABLESIZE];
f7adfe8e 76
0022c355 77#define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE)
9a3f3b7b
ML
78
79/*
80 * Enter all the reserved words into the keyword table.
0022c355
ML
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.
9a3f3b7b 85 */
0022c355 86
9a3f3b7b
ML
87public enterkeywords()
88{
0022c355 89 register integer i;
9a3f3b7b 90
0022c355 91 for (i = ALIAS; i <= WHICH; i++) {
f7adfe8e 92 keyword(reserved[ord(i) - ord(ALIAS)], i);
0022c355
ML
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 }
9a3f3b7b
ML
110}
111
112/*
0022c355 113 * Deallocate the keyword table.
9a3f3b7b 114 */
0022c355 115
9a3f3b7b
ML
116public keywords_free()
117{
118 register Integer i;
119 register Keyword k, nextk;
120
0022c355
ML
121 for (i = 0; i < HASHTABLESIZE; i++) {
122 k = hashtab[i];
123 while (k != nil) {
9a3f3b7b
ML
124 nextk = k->chain;
125 dispose(k);
0022c355 126 k = nextk;
9a3f3b7b
ML
127 }
128 hashtab[i] = nil;
129 }
0022c355
ML
130}
131
132/*
133 * Insert a name into the keyword table and return the keyword for it.
134 */
135
136private Keyword keywords_insert (n)
137Name 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
154private Keyword keywords_lookup (n)
155Name 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
172private boolean keywords_delete (n, class)
173Name n;
174KeywordType 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;
f7adfe8e 193 }
0022c355
ML
194 dispose(k);
195 } else {
196 b = false;
f7adfe8e 197 }
0022c355 198 return b;
9a3f3b7b
ML
199}
200
201/*
0022c355 202 * Enter a keyword into the table. It is assumed to not be there already.
9a3f3b7b
ML
203 * The string is assumed to be statically allocated.
204 */
0022c355
ML
205
206private keyword (s, t)
9a3f3b7b
ML
207String s;
208Token t;
9a3f3b7b 209{
0022c355 210 Keyword k;
9a3f3b7b
ML
211 Name n;
212
213 n = identname(s, true);
0022c355
ML
214 k = keywords_insert(n);
215 k->class = ISKEYWORD;
216 k->value.toknum = t;
9a3f3b7b
ML
217}
218
219/*
0022c355 220 * Define a builtin command name alias.
9a3f3b7b 221 */
0022c355
ML
222
223private defalias (s1, s2)
224String s1, s2;
9a3f3b7b 225{
0022c355 226 alias(identname(s1, true), nil, s2);
9a3f3b7b
ML
227}
228
229/*
0022c355 230 * Look for a word of a particular class.
9a3f3b7b
ML
231 */
232
0022c355 233private Keyword findword (n, class)
9a3f3b7b 234Name n;
0022c355 235KeywordType class;
9a3f3b7b 236{
9a3f3b7b 237 register Keyword k;
9a3f3b7b 238
0022c355
ML
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
251public Token findkeyword (n, def)
252Name n;
253Token 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;
2fd0f574
SL
265}
266
0022c355
ML
267/*
268 * Return the associated string if there is an alias with the given name.
269 */
270
271public boolean findalias (n, pl, str)
2fd0f574 272Name n;
0022c355
ML
273List *pl;
274String *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;
8d7bc982 285 b = true;
0022c355
ML
286 }
287 return b;
288}
289
290/*
291 * Return the string associated with a token corresponding to a keyword.
292 */
293
294public String keywdstring (t)
295Token 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
305public alias (newcmd, args, str)
306Name newcmd;
307List args;
308String str;
2fd0f574 309{
0022c355 310 Keyword k;
2fd0f574 311
0022c355
ML
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 }
9a3f3b7b
ML
323}
324
325/*
0022c355 326 * Print out an alias.
9a3f3b7b 327 */
0022c355
ML
328
329private print_alias (cmd)
f7adfe8e 330Name cmd;
9a3f3b7b 331{
0022c355
ML
332 register Keyword k;
333 register Integer i;
f7adfe8e
SL
334 Name n;
335
0022c355
ML
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 }
9a3f3b7b 360 }
f7adfe8e
SL
361}
362
0022c355
ML
363private printparams (pl)
364List pl;
f7adfe8e 365{
0022c355 366 Name n;
f7adfe8e 367
0022c355
ML
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(")");
f7adfe8e 377 }
0022c355
ML
378}
379
380/*
381 * Remove an alias.
382 */
383
384public unalias (n)
385Name n;
386{
387 if (not keywords_delete(n, ISALIAS)) {
388 error("%s is not aliased", ident(n));
59475aff
SL
389 }
390}
391
0022c355
ML
392/*
393 * Define a variable.
394 */
395
396public defvar (n, val)
397Name n;
398Node val;
59475aff 399{
0022c355 400 Keyword k;
59475aff 401
0022c355
ML
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 }
9a3f3b7b
ML
418}
419
420/*
0022c355 421 * Return the value associated with a variable.
9a3f3b7b 422 */
0022c355
ML
423
424public Node findvar (n)
425Name n;
9a3f3b7b 426{
0022c355
ML
427 Keyword k;
428 Node val;
9a3f3b7b 429
0022c355
ML
430 k = findword(n, ISVAR);
431 if (k == nil) {
432 val = nil;
433 } else {
434 val = k->value.var;
f7adfe8e 435 }
0022c355
ML
436 return val;
437}
438
439/*
440 * Return whether or not a variable is set.
441 */
442
443public boolean varIsSet (s)
444String s;
445{
446 return (boolean) (findword(identname(s, false), ISVAR) != nil);
447}
448
449/*
450 * Delete a variable.
451 */
452
453public undefvar (n)
454Name 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
468private 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 }
9a3f3b7b
ML
486 }
487 }
488}