Add copyright
[unix-history] / usr / src / old / dbx / keywords.c
CommitLineData
2a24676e
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
9a3f3b7b 6
2a24676e
DF
7#ifndef lint
8static char sccsid[] = "@(#)keywords.c 5.1 (Berkeley) %G%";
9#endif not lint
0022c355
ML
10
11static char rcsid[] = "$Header: keywords.c,v 1.5 84/12/26 10:39:45 linton Exp $";
9a3f3b7b
ML
12
13/*
0022c355 14 * Keywords, variables, and aliases (oh my!).
9a3f3b7b
ML
15 */
16
17#include "defs.h"
18#include "keywords.h"
19#include "scanner.h"
20#include "names.h"
21#include "symbols.h"
22#include "tree.h"
0022c355
ML
23#include "lists.h"
24#include "main.h"
9a3f3b7b
ML
25#include "y.tab.h"
26
27#ifndef public
0022c355 28
9a3f3b7b 29#include "scanner.h"
0022c355
ML
30#include "tree.h"
31
9a3f3b7b
ML
32#endif
33
34private String reserved[] ={
35 "alias", "and", "assign", "at", "call", "catch", "cont",
2fd0f574 36 "debug", "delete", "div", "down", "dump", "edit", "file", "func",
9a3f3b7b
ML
37 "gripe", "help", "if", "ignore", "in",
38 "list", "mod", "next", "nexti", "nil", "not", "or",
2fd0f574 39 "print", "psym", "quit", "rerun", "return", "run",
0022c355
ML
40 "set", "sh", "skip", "source", "status", "step", "stepi",
41 "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use",
42 "whatis", "when", "where", "whereis", "which",
43 "INT", "CHAR", "REAL", "NAME", "STRING", "->"
9a3f3b7b
ML
44};
45
46/*
47 * The keyword table is a traditional hash table with collisions
48 * resolved by chaining.
49 */
0022c355
ML
50
51#define HASHTABLESIZE 1007
52
53typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType;
54
9a3f3b7b
ML
55typedef struct Keyword {
56 Name name;
0022c355
ML
57 KeywordType class : 16;
58 union {
59 /* ISKEYWORD: */
60 Token toknum;
61
62 /* ISALIAS: */
63 struct {
64 List paramlist;
65 String expansion;
66 } alias;
67
68 /* ISVAR: */
69 Node var;
70 } value;
9a3f3b7b
ML
71 struct Keyword *chain;
72} *Keyword;
73
74typedef unsigned int Hashvalue;
75
0022c355 76private Keyword hashtab[HASHTABLESIZE];
f7adfe8e 77
0022c355 78#define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE)
9a3f3b7b
ML
79
80/*
81 * Enter all the reserved words into the keyword table.
0022c355
ML
82 *
83 * If the vaddrs flag is set (through the -k command line option) then
84 * set the special "$mapaddrs" variable. This assumes that the
85 * command line arguments are scanned before this routine is called.
9a3f3b7b 86 */
0022c355 87
9a3f3b7b
ML
88public enterkeywords()
89{
0022c355 90 register integer i;
9a3f3b7b 91
0022c355 92 for (i = ALIAS; i <= WHICH; i++) {
f7adfe8e 93 keyword(reserved[ord(i) - ord(ALIAS)], i);
0022c355
ML
94 }
95 defalias("c", "cont");
96 defalias("d", "delete");
97 defalias("h", "help");
98 defalias("e", "edit");
99 defalias("l", "list");
100 defalias("n", "next");
101 defalias("p", "print");
102 defalias("q", "quit");
103 defalias("r", "run");
104 defalias("s", "step");
105 defalias("st", "stop");
106 defalias("j", "status");
107 defalias("t", "where");
108 if (vaddrs) {
109 defvar(identname("$mapaddrs", true), nil);
110 }
9a3f3b7b
ML
111}
112
113/*
0022c355 114 * Deallocate the keyword table.
9a3f3b7b 115 */
0022c355 116
9a3f3b7b
ML
117public keywords_free()
118{
119 register Integer i;
120 register Keyword k, nextk;
121
0022c355
ML
122 for (i = 0; i < HASHTABLESIZE; i++) {
123 k = hashtab[i];
124 while (k != nil) {
9a3f3b7b
ML
125 nextk = k->chain;
126 dispose(k);
0022c355 127 k = nextk;
9a3f3b7b
ML
128 }
129 hashtab[i] = nil;
130 }
0022c355
ML
131}
132
133/*
134 * Insert a name into the keyword table and return the keyword for it.
135 */
136
137private Keyword keywords_insert (n)
138Name n;
139{
140 Hashvalue h;
141 Keyword k;
142
143 h = hash(n);
144 k = new(Keyword);
145 k->name = n;
146 k->chain = hashtab[h];
147 hashtab[h] = k;
148 return k;
149}
150
151/*
152 * Find the keyword associated with the given name.
153 */
154
155private Keyword keywords_lookup (n)
156Name n;
157{
158 Hashvalue h;
159 register Keyword k;
160
161 h = hash(n);
162 k = hashtab[h];
163 while (k != nil and k->name != n) {
164 k = k->chain;
165 }
166 return k;
167}
168
169/*
170 * Delete the given keyword of the given class.
171 */
172
173private boolean keywords_delete (n, class)
174Name n;
175KeywordType class;
176{
177 Hashvalue h;
178 register Keyword k, prevk;
179 boolean b;
180
181 h = hash(n);
182 k = hashtab[h];
183 prevk = nil;
184 while (k != nil and (k->name != n or k->class != class)) {
185 prevk = k;
186 k = k->chain;
187 }
188 if (k != nil) {
189 b = true;
190 if (prevk == nil) {
191 hashtab[h] = k->chain;
192 } else {
193 prevk->chain = k->chain;
f7adfe8e 194 }
0022c355
ML
195 dispose(k);
196 } else {
197 b = false;
f7adfe8e 198 }
0022c355 199 return b;
9a3f3b7b
ML
200}
201
202/*
0022c355 203 * Enter a keyword into the table. It is assumed to not be there already.
9a3f3b7b
ML
204 * The string is assumed to be statically allocated.
205 */
0022c355
ML
206
207private keyword (s, t)
9a3f3b7b
ML
208String s;
209Token t;
9a3f3b7b 210{
0022c355 211 Keyword k;
9a3f3b7b
ML
212 Name n;
213
214 n = identname(s, true);
0022c355
ML
215 k = keywords_insert(n);
216 k->class = ISKEYWORD;
217 k->value.toknum = t;
9a3f3b7b
ML
218}
219
220/*
0022c355 221 * Define a builtin command name alias.
9a3f3b7b 222 */
0022c355
ML
223
224private defalias (s1, s2)
225String s1, s2;
9a3f3b7b 226{
0022c355 227 alias(identname(s1, true), nil, s2);
9a3f3b7b
ML
228}
229
230/*
0022c355 231 * Look for a word of a particular class.
9a3f3b7b
ML
232 */
233
0022c355 234private Keyword findword (n, class)
9a3f3b7b 235Name n;
0022c355 236KeywordType class;
9a3f3b7b 237{
9a3f3b7b 238 register Keyword k;
9a3f3b7b 239
0022c355
ML
240 k = keywords_lookup(n);
241 while (k != nil and (k->name != n or k->class != class)) {
242 k = k->chain;
243 }
244 return k;
245}
246
247/*
248 * Return the token associated with a given keyword string.
249 * If there is none, return the given default value.
250 */
251
252public Token findkeyword (n, def)
253Name n;
254Token def;
255{
256 Keyword k;
257 Token t;
258
259 k = findword(n, ISKEYWORD);
260 if (k == nil) {
261 t = def;
262 } else {
263 t = k->value.toknum;
264 }
265 return t;
2fd0f574
SL
266}
267
0022c355
ML
268/*
269 * Return the associated string if there is an alias with the given name.
270 */
271
272public boolean findalias (n, pl, str)
2fd0f574 273Name n;
0022c355
ML
274List *pl;
275String *str;
276{
277 Keyword k;
278 boolean b;
279
280 k = findword(n, ISALIAS);
281 if (k == nil) {
282 b = false;
283 } else {
284 *pl = k->value.alias.paramlist;
285 *str = k->value.alias.expansion;
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}