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 7#ifndef lint
8d7bc982 8static char sccsid[] = "@(#)keywords.c 5.2 (Berkeley) %G%";
2a24676e 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;
8d7bc982 286 b = true;
0022c355
ML
287 }
288 return b;
289}
290
291/*
292 * Return the string associated with a token corresponding to a keyword.
293 */
294
295public String keywdstring (t)
296Token t;
297{
298 return reserved[ord(t) - ord(ALIAS)];
299}
300
301/*
302 * Process an alias command, either entering a new alias or printing out
303 * an existing one.
304 */
305
306public alias (newcmd, args, str)
307Name newcmd;
308List args;
309String str;
2fd0f574 310{
0022c355 311 Keyword k;
2fd0f574 312
0022c355
ML
313 if (str == nil) {
314 print_alias(newcmd);
315 } else {
316 k = findword(newcmd, ISALIAS);
317 if (k == nil) {
318 k = keywords_insert(newcmd);
319 }
320 k->class = ISALIAS;
321 k->value.alias.paramlist = args;
322 k->value.alias.expansion = str;
323 }
9a3f3b7b
ML
324}
325
326/*
0022c355 327 * Print out an alias.
9a3f3b7b 328 */
0022c355
ML
329
330private print_alias (cmd)
f7adfe8e 331Name cmd;
9a3f3b7b 332{
0022c355
ML
333 register Keyword k;
334 register Integer i;
f7adfe8e
SL
335 Name n;
336
0022c355
ML
337 if (cmd == nil) {
338 for (i = 0; i < HASHTABLESIZE; i++) {
339 for (k = hashtab[i]; k != nil; k = k->chain) {
340 if (k->class == ISALIAS) {
341 if (isredirected()) {
342 printf("alias %s", ident(k->name));
343 printparams(k->value.alias.paramlist);
344 printf("\t\"%s\"\n", k->value.alias.expansion);
345 } else {
346 printf("%s", ident(k->name));
347 printparams(k->value.alias.paramlist);
348 printf("\t%s\n", k->value.alias.expansion);
349 }
350 }
351 }
352 }
353 } else {
354 k = findword(cmd, ISALIAS);
355 if (k == nil) {
356 printf("\n");
357 } else {
358 printparams(k->value.alias.paramlist);
359 printf("%s\n", k->value.alias.expansion);
360 }
9a3f3b7b 361 }
f7adfe8e
SL
362}
363
0022c355
ML
364private printparams (pl)
365List pl;
f7adfe8e 366{
0022c355 367 Name n;
f7adfe8e 368
0022c355
ML
369 if (pl != nil) {
370 printf("(");
371 foreach(Name, n, pl)
372 printf("%s", ident(n));
373 if (not list_islast()) {
374 printf(", ");
375 }
376 endfor
377 printf(")");
f7adfe8e 378 }
0022c355
ML
379}
380
381/*
382 * Remove an alias.
383 */
384
385public unalias (n)
386Name n;
387{
388 if (not keywords_delete(n, ISALIAS)) {
389 error("%s is not aliased", ident(n));
59475aff
SL
390 }
391}
392
0022c355
ML
393/*
394 * Define a variable.
395 */
396
397public defvar (n, val)
398Name n;
399Node val;
59475aff 400{
0022c355 401 Keyword k;
59475aff 402
0022c355
ML
403 if (n == nil) {
404 print_vars();
405 } else {
406 if (lookup(n) != nil) {
407 error("\"%s\" is a program symbol -- use assign", ident(n));
408 }
409 k = findword(n, ISVAR);
410 if (k == nil) {
411 k = keywords_insert(n);
412 }
413 k->class = ISVAR;
414 k->value.var = val;
415 if (n == identname("$mapaddrs", true)) {
416 vaddrs = true;
417 }
418 }
9a3f3b7b
ML
419}
420
421/*
0022c355 422 * Return the value associated with a variable.
9a3f3b7b 423 */
0022c355
ML
424
425public Node findvar (n)
426Name n;
9a3f3b7b 427{
0022c355
ML
428 Keyword k;
429 Node val;
9a3f3b7b 430
0022c355
ML
431 k = findword(n, ISVAR);
432 if (k == nil) {
433 val = nil;
434 } else {
435 val = k->value.var;
f7adfe8e 436 }
0022c355
ML
437 return val;
438}
439
440/*
441 * Return whether or not a variable is set.
442 */
443
444public boolean varIsSet (s)
445String s;
446{
447 return (boolean) (findword(identname(s, false), ISVAR) != nil);
448}
449
450/*
451 * Delete a variable.
452 */
453
454public undefvar (n)
455Name n;
456{
457 if (not keywords_delete(n, ISVAR)) {
458 error("%s is not set", ident(n));
459 }
460 if (n == identname("$mapaddrs", true)) {
461 vaddrs = false;
462 }
463}
464
465/*
466 * Print out all the values of set variables.
467 */
468
469private print_vars ()
470{
471 register integer i;
472 register Keyword k;
473
474 for (i = 0; i < HASHTABLESIZE; i++) {
475 for (k = hashtab[i]; k != nil; k = k->chain) {
476 if (k->class == ISVAR) {
477 if (isredirected()) {
478 printf("set ");
479 }
480 printf("%s", ident(k->name));
481 if (k->value.var != nil) {
482 printf("\t");
483 prtree(stdout, k->value.var);
484 }
485 printf("\n");
486 }
9a3f3b7b
ML
487 }
488 }
489}