xref: /csrg-svn/old/dbx/keywords.c (revision 22017)
121604Sdist /*
221604Sdist  * Copyright (c) 1983 Regents of the University of California.
321604Sdist  * All rights reserved.  The Berkeley software License Agreement
421604Sdist  * specifies the terms and conditions for redistribution.
521604Sdist  */
69664Slinton 
721604Sdist #ifndef lint
8*22017Ssam static char sccsid[] = "@(#)keywords.c	5.2 (Berkeley) 06/04/85";
921604Sdist #endif not lint
109664Slinton 
1118220Slinton static char rcsid[] = "$Header: keywords.c,v 1.5 84/12/26 10:39:45 linton Exp $";
1218220Slinton 
139664Slinton /*
1418220Slinton  * Keywords, variables, and aliases (oh my!).
159664Slinton  */
169664Slinton 
179664Slinton #include "defs.h"
189664Slinton #include "keywords.h"
199664Slinton #include "scanner.h"
209664Slinton #include "names.h"
219664Slinton #include "symbols.h"
229664Slinton #include "tree.h"
2318220Slinton #include "lists.h"
2418220Slinton #include "main.h"
259664Slinton #include "y.tab.h"
269664Slinton 
279664Slinton #ifndef public
2818220Slinton 
299664Slinton #include "scanner.h"
3018220Slinton #include "tree.h"
3118220Slinton 
329664Slinton #endif
339664Slinton 
349664Slinton private String reserved[] ={
359664Slinton     "alias", "and", "assign", "at", "call", "catch", "cont",
3616611Ssam     "debug", "delete", "div", "down", "dump", "edit", "file", "func",
379664Slinton     "gripe", "help", "if", "ignore", "in",
389664Slinton     "list", "mod", "next", "nexti", "nil", "not", "or",
3916611Ssam     "print", "psym", "quit", "rerun", "return", "run",
4018220Slinton     "set", "sh", "skip", "source", "status", "step", "stepi",
4118220Slinton     "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use",
4218220Slinton     "whatis", "when", "where", "whereis", "which",
4318220Slinton     "INT", "CHAR", "REAL", "NAME", "STRING", "->"
449664Slinton };
459664Slinton 
469664Slinton /*
479664Slinton  * The keyword table is a traditional hash table with collisions
489664Slinton  * resolved by chaining.
499664Slinton  */
5018220Slinton 
5118220Slinton #define HASHTABLESIZE 1007
5218220Slinton 
5318220Slinton typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType;
5418220Slinton 
559664Slinton typedef struct Keyword {
569664Slinton     Name name;
5718220Slinton     KeywordType class : 16;
5818220Slinton     union {
5918220Slinton 	/* ISKEYWORD: */
6018220Slinton 	    Token toknum;
6118220Slinton 
6218220Slinton 	/* ISALIAS: */
6318220Slinton 	    struct {
6418220Slinton 		List paramlist;
6518220Slinton 		String expansion;
6618220Slinton 	    } alias;
6718220Slinton 
6818220Slinton 	/* ISVAR: */
6918220Slinton 	    Node var;
7018220Slinton     } value;
719664Slinton     struct Keyword *chain;
729664Slinton } *Keyword;
739664Slinton 
749664Slinton typedef unsigned int Hashvalue;
759664Slinton 
7618220Slinton private Keyword hashtab[HASHTABLESIZE];
779664Slinton 
7818220Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE)
799664Slinton 
809664Slinton /*
819664Slinton  * Enter all the reserved words into the keyword table.
8218220Slinton  *
8318220Slinton  * If the vaddrs flag is set (through the -k command line option) then
8418220Slinton  * set the special "$mapaddrs" variable.  This assumes that the
8518220Slinton  * command line arguments are scanned before this routine is called.
869664Slinton  */
8718220Slinton 
889664Slinton public enterkeywords()
899664Slinton {
9018220Slinton     register integer i;
919664Slinton 
9218220Slinton     for (i = ALIAS; i <= WHICH; i++) {
9316928Ssam 	keyword(reserved[ord(i) - ord(ALIAS)], i);
9418220Slinton     }
9518220Slinton     defalias("c", "cont");
9618220Slinton     defalias("d", "delete");
9718220Slinton     defalias("h", "help");
9818220Slinton     defalias("e", "edit");
9918220Slinton     defalias("l", "list");
10018220Slinton     defalias("n", "next");
10118220Slinton     defalias("p", "print");
10218220Slinton     defalias("q", "quit");
10318220Slinton     defalias("r", "run");
10418220Slinton     defalias("s", "step");
10518220Slinton     defalias("st", "stop");
10618220Slinton     defalias("j", "status");
10718220Slinton     defalias("t", "where");
10818220Slinton     if (vaddrs) {
10918220Slinton 	defvar(identname("$mapaddrs", true), nil);
11018220Slinton     }
1119664Slinton }
1129664Slinton 
1139664Slinton /*
11418220Slinton  * Deallocate the keyword table.
1159664Slinton  */
11618220Slinton 
1179664Slinton public keywords_free()
1189664Slinton {
1199664Slinton     register Integer i;
1209664Slinton     register Keyword k, nextk;
1219664Slinton 
12218220Slinton     for (i = 0; i < HASHTABLESIZE; i++) {
12318220Slinton 	k = hashtab[i];
12418220Slinton 	while (k != nil) {
1259664Slinton 	    nextk = k->chain;
1269664Slinton 	    dispose(k);
12718220Slinton 	    k = nextk;
1289664Slinton 	}
1299664Slinton 	hashtab[i] = nil;
1309664Slinton     }
13118220Slinton }
13218220Slinton 
13318220Slinton /*
13418220Slinton  * Insert a name into the keyword table and return the keyword for it.
13518220Slinton  */
13618220Slinton 
13718220Slinton private Keyword keywords_insert (n)
13818220Slinton Name n;
13918220Slinton {
14018220Slinton     Hashvalue h;
14118220Slinton     Keyword k;
14218220Slinton 
14318220Slinton     h = hash(n);
14418220Slinton     k = new(Keyword);
14518220Slinton     k->name = n;
14618220Slinton     k->chain = hashtab[h];
14718220Slinton     hashtab[h] = k;
14818220Slinton     return k;
14918220Slinton }
15018220Slinton 
15118220Slinton /*
15218220Slinton  * Find the keyword associated with the given name.
15318220Slinton  */
15418220Slinton 
15518220Slinton private Keyword keywords_lookup (n)
15618220Slinton Name n;
15718220Slinton {
15818220Slinton     Hashvalue h;
15918220Slinton     register Keyword k;
16018220Slinton 
16118220Slinton     h = hash(n);
16218220Slinton     k = hashtab[h];
16318220Slinton     while (k != nil and k->name != n) {
16418220Slinton 	k = k->chain;
16518220Slinton     }
16618220Slinton     return k;
16718220Slinton }
16818220Slinton 
16918220Slinton /*
17018220Slinton  * Delete the given keyword of the given class.
17118220Slinton  */
17218220Slinton 
17318220Slinton private boolean keywords_delete (n, class)
17418220Slinton Name n;
17518220Slinton KeywordType class;
17618220Slinton {
17718220Slinton     Hashvalue h;
17818220Slinton     register Keyword k, prevk;
17918220Slinton     boolean b;
18018220Slinton 
18118220Slinton     h = hash(n);
18218220Slinton     k = hashtab[h];
18318220Slinton     prevk = nil;
18418220Slinton     while (k != nil and (k->name != n or k->class != class)) {
18518220Slinton 	prevk = k;
18618220Slinton 	k = k->chain;
18718220Slinton     }
18818220Slinton     if (k != nil) {
18918220Slinton 	b = true;
19018220Slinton 	if (prevk == nil) {
19118220Slinton 	    hashtab[h] = k->chain;
19218220Slinton 	} else {
19318220Slinton 	    prevk->chain = k->chain;
19416928Ssam 	}
19518220Slinton 	dispose(k);
19618220Slinton     } else {
19718220Slinton 	b = false;
19816928Ssam     }
19918220Slinton     return b;
2009664Slinton }
2019664Slinton 
2029664Slinton /*
20318220Slinton  * Enter a keyword into the table.  It is assumed to not be there already.
2049664Slinton  * The string is assumed to be statically allocated.
2059664Slinton  */
20618220Slinton 
20718220Slinton private keyword (s, t)
2089664Slinton String s;
2099664Slinton Token t;
2109664Slinton {
21118220Slinton     Keyword k;
2129664Slinton     Name n;
2139664Slinton 
2149664Slinton     n = identname(s, true);
21518220Slinton     k = keywords_insert(n);
21618220Slinton     k->class = ISKEYWORD;
21718220Slinton     k->value.toknum = t;
2189664Slinton }
2199664Slinton 
2209664Slinton /*
22118220Slinton  * Define a builtin command name alias.
2229664Slinton  */
22318220Slinton 
22418220Slinton private defalias (s1, s2)
22518220Slinton String s1, s2;
2269664Slinton {
22718220Slinton     alias(identname(s1, true), nil, s2);
2289664Slinton }
2299664Slinton 
2309664Slinton /*
23118220Slinton  * Look for a word of a particular class.
2329664Slinton  */
2339664Slinton 
23418220Slinton private Keyword findword (n, class)
2359664Slinton Name n;
23618220Slinton KeywordType class;
2379664Slinton {
2389664Slinton     register Keyword k;
2399664Slinton 
24018220Slinton     k = keywords_lookup(n);
24118220Slinton     while (k != nil and (k->name != n or k->class != class)) {
24218220Slinton 	k = k->chain;
24318220Slinton     }
24418220Slinton     return k;
24516611Ssam }
24616611Ssam 
24718220Slinton /*
24818220Slinton  * Return the token associated with a given keyword string.
24918220Slinton  * If there is none, return the given default value.
25018220Slinton  */
25118220Slinton 
25218220Slinton public Token findkeyword (n, def)
25316611Ssam Name n;
25418220Slinton Token def;
25516611Ssam {
25618220Slinton     Keyword k;
25718220Slinton     Token t;
25816611Ssam 
25918220Slinton     k = findword(n, ISKEYWORD);
26018220Slinton     if (k == nil) {
26118220Slinton 	t = def;
26218220Slinton     } else {
26318220Slinton 	t = k->value.toknum;
26418220Slinton     }
26518220Slinton     return t;
2669664Slinton }
2679664Slinton 
2689664Slinton /*
26918220Slinton  * Return the associated string if there is an alias with the given name.
2709664Slinton  */
27118220Slinton 
27218220Slinton public boolean findalias (n, pl, str)
27318220Slinton Name n;
27418220Slinton List *pl;
27518220Slinton String *str;
27618220Slinton {
27718220Slinton     Keyword k;
27818220Slinton     boolean b;
27918220Slinton 
28018220Slinton     k = findword(n, ISALIAS);
28118220Slinton     if (k == nil) {
28218220Slinton 	b = false;
28318220Slinton     } else {
28418220Slinton 	*pl = k->value.alias.paramlist;
28518220Slinton 	*str = k->value.alias.expansion;
286*22017Ssam 	b = true;
28718220Slinton     }
28818220Slinton     return b;
28918220Slinton }
29018220Slinton 
29118220Slinton /*
29218220Slinton  * Return the string associated with a token corresponding to a keyword.
29318220Slinton  */
29418220Slinton 
29518220Slinton public String keywdstring (t)
29618220Slinton Token t;
29718220Slinton {
29818220Slinton     return reserved[ord(t) - ord(ALIAS)];
29918220Slinton }
30018220Slinton 
30118220Slinton /*
30218220Slinton  * Process an alias command, either entering a new alias or printing out
30318220Slinton  * an existing one.
30418220Slinton  */
30518220Slinton 
30618220Slinton public alias (newcmd, args, str)
30718220Slinton Name newcmd;
30818220Slinton List args;
30918220Slinton String str;
31018220Slinton {
31118220Slinton     Keyword k;
31218220Slinton 
31318220Slinton     if (str == nil) {
31418220Slinton 	print_alias(newcmd);
31518220Slinton     } else {
31618220Slinton 	k = findword(newcmd, ISALIAS);
31718220Slinton 	if (k == nil) {
31818220Slinton 	    k = keywords_insert(newcmd);
31918220Slinton 	}
32018220Slinton 	k->class = ISALIAS;
32118220Slinton 	k->value.alias.paramlist = args;
32218220Slinton 	k->value.alias.expansion = str;
32318220Slinton     }
32418220Slinton }
32518220Slinton 
32618220Slinton /*
32718220Slinton  * Print out an alias.
32818220Slinton  */
32918220Slinton 
33018220Slinton private print_alias (cmd)
33116928Ssam Name cmd;
3329664Slinton {
33318220Slinton     register Keyword k;
33418220Slinton     register Integer i;
33516928Ssam     Name n;
3369664Slinton 
33718220Slinton     if (cmd == nil) {
33818220Slinton 	for (i = 0; i < HASHTABLESIZE; i++) {
33918220Slinton 	    for (k = hashtab[i]; k != nil; k = k->chain) {
34018220Slinton 		if (k->class == ISALIAS) {
34118220Slinton 		    if (isredirected()) {
34218220Slinton 			printf("alias %s", ident(k->name));
34318220Slinton 			printparams(k->value.alias.paramlist);
34418220Slinton 			printf("\t\"%s\"\n", k->value.alias.expansion);
34518220Slinton 		    } else {
34618220Slinton 			printf("%s", ident(k->name));
34718220Slinton 			printparams(k->value.alias.paramlist);
34818220Slinton 			printf("\t%s\n", k->value.alias.expansion);
34918220Slinton 		    }
35018220Slinton 		}
35118220Slinton 	    }
35218220Slinton 	}
35318220Slinton     } else {
35418220Slinton 	k = findword(cmd, ISALIAS);
35518220Slinton 	if (k == nil) {
35618220Slinton 	    printf("\n");
35718220Slinton 	} else {
35818220Slinton 	    printparams(k->value.alias.paramlist);
35918220Slinton 	    printf("%s\n", k->value.alias.expansion);
36018220Slinton 	}
3619664Slinton     }
3629664Slinton }
3639664Slinton 
36418220Slinton private printparams (pl)
36518220Slinton List pl;
36616928Ssam {
36718220Slinton     Name n;
36816928Ssam 
36918220Slinton     if (pl != nil) {
37018220Slinton 	printf("(");
37118220Slinton 	foreach(Name, n, pl)
37218220Slinton 	    printf("%s", ident(n));
37318220Slinton 	    if (not list_islast()) {
37418220Slinton 		printf(", ");
37518220Slinton 	    }
37618220Slinton 	endfor
37718220Slinton 	printf(")");
37816928Ssam     }
37918220Slinton }
38018220Slinton 
38118220Slinton /*
38218220Slinton  * Remove an alias.
38318220Slinton  */
38418220Slinton 
38518220Slinton public unalias (n)
38618220Slinton Name n;
38718220Slinton {
38818220Slinton     if (not keywords_delete(n, ISALIAS)) {
38918220Slinton 	error("%s is not aliased", ident(n));
39016949Ssam     }
39116928Ssam }
39216928Ssam 
39318220Slinton /*
39418220Slinton  * Define a variable.
39518220Slinton  */
39618220Slinton 
39718220Slinton public defvar (n, val)
39818220Slinton Name n;
39918220Slinton Node val;
40016949Ssam {
40118220Slinton     Keyword k;
40216949Ssam 
40318220Slinton     if (n == nil) {
40418220Slinton 	print_vars();
40518220Slinton     } else {
40618220Slinton 	if (lookup(n) != nil) {
40718220Slinton 	    error("\"%s\" is a program symbol -- use assign", ident(n));
40818220Slinton 	}
40918220Slinton 	k = findword(n, ISVAR);
41018220Slinton 	if (k == nil) {
41118220Slinton 	    k = keywords_insert(n);
41218220Slinton 	}
41318220Slinton 	k->class = ISVAR;
41418220Slinton 	k->value.var = val;
41518220Slinton 	if (n == identname("$mapaddrs", true)) {
41618220Slinton 	    vaddrs = true;
41718220Slinton 	}
41818220Slinton     }
41916949Ssam }
42016949Ssam 
4219664Slinton /*
42218220Slinton  * Return the value associated with a variable.
4239664Slinton  */
42418220Slinton 
42518220Slinton public Node findvar (n)
42618220Slinton Name n;
4279664Slinton {
42818220Slinton     Keyword k;
42918220Slinton     Node val;
4309664Slinton 
43118220Slinton     k = findword(n, ISVAR);
43218220Slinton     if (k == nil) {
43318220Slinton 	val = nil;
43418220Slinton     } else {
43518220Slinton 	val = k->value.var;
43616928Ssam     }
43718220Slinton     return val;
43818220Slinton }
43918220Slinton 
44018220Slinton /*
44118220Slinton  * Return whether or not a variable is set.
44218220Slinton  */
44318220Slinton 
44418220Slinton public boolean varIsSet (s)
44518220Slinton String s;
44618220Slinton {
44718220Slinton     return (boolean) (findword(identname(s, false), ISVAR) != nil);
44818220Slinton }
44918220Slinton 
45018220Slinton /*
45118220Slinton  * Delete a variable.
45218220Slinton  */
45318220Slinton 
45418220Slinton public undefvar (n)
45518220Slinton Name n;
45618220Slinton {
45718220Slinton     if (not keywords_delete(n, ISVAR)) {
45818220Slinton 	error("%s is not set", ident(n));
45918220Slinton     }
46018220Slinton     if (n == identname("$mapaddrs", true)) {
46118220Slinton 	vaddrs = false;
46218220Slinton     }
46318220Slinton }
46418220Slinton 
46518220Slinton /*
46618220Slinton  * Print out all the values of set variables.
46718220Slinton  */
46818220Slinton 
46918220Slinton private print_vars ()
47018220Slinton {
47118220Slinton     register integer i;
47218220Slinton     register Keyword k;
47318220Slinton 
47418220Slinton     for (i = 0; i < HASHTABLESIZE; i++) {
47518220Slinton 	for (k = hashtab[i]; k != nil; k = k->chain) {
47618220Slinton 	    if (k->class == ISVAR) {
47718220Slinton 		if (isredirected()) {
47818220Slinton 		    printf("set ");
47918220Slinton 		}
48018220Slinton 		printf("%s", ident(k->name));
48118220Slinton 		if (k->value.var != nil) {
48218220Slinton 		    printf("\t");
48318220Slinton 		    prtree(stdout, k->value.var);
48418220Slinton 		}
48518220Slinton 		printf("\n");
48618220Slinton 	    }
4879664Slinton 	}
4889664Slinton     }
4899664Slinton }
490