xref: /csrg-svn/old/dbx/keywords.c (revision 38105)
121604Sdist /*
2*38105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
3*38105Sbostic  * All rights reserved.
4*38105Sbostic  *
5*38105Sbostic  * Redistribution and use in source and binary forms are permitted
6*38105Sbostic  * provided that the above copyright notice and this paragraph are
7*38105Sbostic  * duplicated in all such forms and that any documentation,
8*38105Sbostic  * advertising materials, and other materials related to such
9*38105Sbostic  * distribution and use acknowledge that the software was developed
10*38105Sbostic  * by the University of California, Berkeley.  The name of the
11*38105Sbostic  * University may not be used to endorse or promote products derived
12*38105Sbostic  * from this software without specific prior written permission.
13*38105Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38105Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38105Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621604Sdist  */
179664Slinton 
1821604Sdist #ifndef lint
19*38105Sbostic static char sccsid[] = "@(#)keywords.c	5.3 (Berkeley) 05/23/89";
20*38105Sbostic #endif /* not lint */
219664Slinton 
229664Slinton /*
2318220Slinton  * Keywords, variables, and aliases (oh my!).
249664Slinton  */
259664Slinton 
269664Slinton #include "defs.h"
279664Slinton #include "keywords.h"
289664Slinton #include "scanner.h"
299664Slinton #include "names.h"
309664Slinton #include "symbols.h"
319664Slinton #include "tree.h"
3218220Slinton #include "lists.h"
3318220Slinton #include "main.h"
349664Slinton #include "y.tab.h"
359664Slinton 
369664Slinton #ifndef public
3718220Slinton 
389664Slinton #include "scanner.h"
3918220Slinton #include "tree.h"
4018220Slinton 
419664Slinton #endif
429664Slinton 
439664Slinton private String reserved[] ={
449664Slinton     "alias", "and", "assign", "at", "call", "catch", "cont",
4516611Ssam     "debug", "delete", "div", "down", "dump", "edit", "file", "func",
469664Slinton     "gripe", "help", "if", "ignore", "in",
479664Slinton     "list", "mod", "next", "nexti", "nil", "not", "or",
4816611Ssam     "print", "psym", "quit", "rerun", "return", "run",
4918220Slinton     "set", "sh", "skip", "source", "status", "step", "stepi",
5018220Slinton     "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use",
5118220Slinton     "whatis", "when", "where", "whereis", "which",
5218220Slinton     "INT", "CHAR", "REAL", "NAME", "STRING", "->"
539664Slinton };
549664Slinton 
559664Slinton /*
569664Slinton  * The keyword table is a traditional hash table with collisions
579664Slinton  * resolved by chaining.
589664Slinton  */
5918220Slinton 
6018220Slinton #define HASHTABLESIZE 1007
6118220Slinton 
6218220Slinton typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType;
6318220Slinton 
649664Slinton typedef struct Keyword {
659664Slinton     Name name;
6618220Slinton     KeywordType class : 16;
6718220Slinton     union {
6818220Slinton 	/* ISKEYWORD: */
6918220Slinton 	    Token toknum;
7018220Slinton 
7118220Slinton 	/* ISALIAS: */
7218220Slinton 	    struct {
7318220Slinton 		List paramlist;
7418220Slinton 		String expansion;
7518220Slinton 	    } alias;
7618220Slinton 
7718220Slinton 	/* ISVAR: */
7818220Slinton 	    Node var;
7918220Slinton     } value;
809664Slinton     struct Keyword *chain;
819664Slinton } *Keyword;
829664Slinton 
839664Slinton typedef unsigned int Hashvalue;
849664Slinton 
8518220Slinton private Keyword hashtab[HASHTABLESIZE];
869664Slinton 
8718220Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE)
889664Slinton 
899664Slinton /*
909664Slinton  * Enter all the reserved words into the keyword table.
9118220Slinton  *
9218220Slinton  * If the vaddrs flag is set (through the -k command line option) then
9318220Slinton  * set the special "$mapaddrs" variable.  This assumes that the
9418220Slinton  * command line arguments are scanned before this routine is called.
959664Slinton  */
9618220Slinton 
979664Slinton public enterkeywords()
989664Slinton {
9918220Slinton     register integer i;
1009664Slinton 
10118220Slinton     for (i = ALIAS; i <= WHICH; i++) {
10216928Ssam 	keyword(reserved[ord(i) - ord(ALIAS)], i);
10318220Slinton     }
10418220Slinton     defalias("c", "cont");
10518220Slinton     defalias("d", "delete");
10618220Slinton     defalias("h", "help");
10718220Slinton     defalias("e", "edit");
10818220Slinton     defalias("l", "list");
10918220Slinton     defalias("n", "next");
11018220Slinton     defalias("p", "print");
11118220Slinton     defalias("q", "quit");
11218220Slinton     defalias("r", "run");
11318220Slinton     defalias("s", "step");
11418220Slinton     defalias("st", "stop");
11518220Slinton     defalias("j", "status");
11618220Slinton     defalias("t", "where");
11718220Slinton     if (vaddrs) {
11818220Slinton 	defvar(identname("$mapaddrs", true), nil);
11918220Slinton     }
1209664Slinton }
1219664Slinton 
1229664Slinton /*
12318220Slinton  * Deallocate the keyword table.
1249664Slinton  */
12518220Slinton 
1269664Slinton public keywords_free()
1279664Slinton {
1289664Slinton     register Integer i;
1299664Slinton     register Keyword k, nextk;
1309664Slinton 
13118220Slinton     for (i = 0; i < HASHTABLESIZE; i++) {
13218220Slinton 	k = hashtab[i];
13318220Slinton 	while (k != nil) {
1349664Slinton 	    nextk = k->chain;
1359664Slinton 	    dispose(k);
13618220Slinton 	    k = nextk;
1379664Slinton 	}
1389664Slinton 	hashtab[i] = nil;
1399664Slinton     }
14018220Slinton }
14118220Slinton 
14218220Slinton /*
14318220Slinton  * Insert a name into the keyword table and return the keyword for it.
14418220Slinton  */
14518220Slinton 
14618220Slinton private Keyword keywords_insert (n)
14718220Slinton Name n;
14818220Slinton {
14918220Slinton     Hashvalue h;
15018220Slinton     Keyword k;
15118220Slinton 
15218220Slinton     h = hash(n);
15318220Slinton     k = new(Keyword);
15418220Slinton     k->name = n;
15518220Slinton     k->chain = hashtab[h];
15618220Slinton     hashtab[h] = k;
15718220Slinton     return k;
15818220Slinton }
15918220Slinton 
16018220Slinton /*
16118220Slinton  * Find the keyword associated with the given name.
16218220Slinton  */
16318220Slinton 
16418220Slinton private Keyword keywords_lookup (n)
16518220Slinton Name n;
16618220Slinton {
16718220Slinton     Hashvalue h;
16818220Slinton     register Keyword k;
16918220Slinton 
17018220Slinton     h = hash(n);
17118220Slinton     k = hashtab[h];
17218220Slinton     while (k != nil and k->name != n) {
17318220Slinton 	k = k->chain;
17418220Slinton     }
17518220Slinton     return k;
17618220Slinton }
17718220Slinton 
17818220Slinton /*
17918220Slinton  * Delete the given keyword of the given class.
18018220Slinton  */
18118220Slinton 
18218220Slinton private boolean keywords_delete (n, class)
18318220Slinton Name n;
18418220Slinton KeywordType class;
18518220Slinton {
18618220Slinton     Hashvalue h;
18718220Slinton     register Keyword k, prevk;
18818220Slinton     boolean b;
18918220Slinton 
19018220Slinton     h = hash(n);
19118220Slinton     k = hashtab[h];
19218220Slinton     prevk = nil;
19318220Slinton     while (k != nil and (k->name != n or k->class != class)) {
19418220Slinton 	prevk = k;
19518220Slinton 	k = k->chain;
19618220Slinton     }
19718220Slinton     if (k != nil) {
19818220Slinton 	b = true;
19918220Slinton 	if (prevk == nil) {
20018220Slinton 	    hashtab[h] = k->chain;
20118220Slinton 	} else {
20218220Slinton 	    prevk->chain = k->chain;
20316928Ssam 	}
20418220Slinton 	dispose(k);
20518220Slinton     } else {
20618220Slinton 	b = false;
20716928Ssam     }
20818220Slinton     return b;
2099664Slinton }
2109664Slinton 
2119664Slinton /*
21218220Slinton  * Enter a keyword into the table.  It is assumed to not be there already.
2139664Slinton  * The string is assumed to be statically allocated.
2149664Slinton  */
21518220Slinton 
21618220Slinton private keyword (s, t)
2179664Slinton String s;
2189664Slinton Token t;
2199664Slinton {
22018220Slinton     Keyword k;
2219664Slinton     Name n;
2229664Slinton 
2239664Slinton     n = identname(s, true);
22418220Slinton     k = keywords_insert(n);
22518220Slinton     k->class = ISKEYWORD;
22618220Slinton     k->value.toknum = t;
2279664Slinton }
2289664Slinton 
2299664Slinton /*
23018220Slinton  * Define a builtin command name alias.
2319664Slinton  */
23218220Slinton 
23318220Slinton private defalias (s1, s2)
23418220Slinton String s1, s2;
2359664Slinton {
23618220Slinton     alias(identname(s1, true), nil, s2);
2379664Slinton }
2389664Slinton 
2399664Slinton /*
24018220Slinton  * Look for a word of a particular class.
2419664Slinton  */
2429664Slinton 
24318220Slinton private Keyword findword (n, class)
2449664Slinton Name n;
24518220Slinton KeywordType class;
2469664Slinton {
2479664Slinton     register Keyword k;
2489664Slinton 
24918220Slinton     k = keywords_lookup(n);
25018220Slinton     while (k != nil and (k->name != n or k->class != class)) {
25118220Slinton 	k = k->chain;
25218220Slinton     }
25318220Slinton     return k;
25416611Ssam }
25516611Ssam 
25618220Slinton /*
25718220Slinton  * Return the token associated with a given keyword string.
25818220Slinton  * If there is none, return the given default value.
25918220Slinton  */
26018220Slinton 
26118220Slinton public Token findkeyword (n, def)
26216611Ssam Name n;
26318220Slinton Token def;
26416611Ssam {
26518220Slinton     Keyword k;
26618220Slinton     Token t;
26716611Ssam 
26818220Slinton     k = findword(n, ISKEYWORD);
26918220Slinton     if (k == nil) {
27018220Slinton 	t = def;
27118220Slinton     } else {
27218220Slinton 	t = k->value.toknum;
27318220Slinton     }
27418220Slinton     return t;
2759664Slinton }
2769664Slinton 
2779664Slinton /*
27818220Slinton  * Return the associated string if there is an alias with the given name.
2799664Slinton  */
28018220Slinton 
28118220Slinton public boolean findalias (n, pl, str)
28218220Slinton Name n;
28318220Slinton List *pl;
28418220Slinton String *str;
28518220Slinton {
28618220Slinton     Keyword k;
28718220Slinton     boolean b;
28818220Slinton 
28918220Slinton     k = findword(n, ISALIAS);
29018220Slinton     if (k == nil) {
29118220Slinton 	b = false;
29218220Slinton     } else {
29318220Slinton 	*pl = k->value.alias.paramlist;
29418220Slinton 	*str = k->value.alias.expansion;
29522017Ssam 	b = true;
29618220Slinton     }
29718220Slinton     return b;
29818220Slinton }
29918220Slinton 
30018220Slinton /*
30118220Slinton  * Return the string associated with a token corresponding to a keyword.
30218220Slinton  */
30318220Slinton 
30418220Slinton public String keywdstring (t)
30518220Slinton Token t;
30618220Slinton {
30718220Slinton     return reserved[ord(t) - ord(ALIAS)];
30818220Slinton }
30918220Slinton 
31018220Slinton /*
31118220Slinton  * Process an alias command, either entering a new alias or printing out
31218220Slinton  * an existing one.
31318220Slinton  */
31418220Slinton 
31518220Slinton public alias (newcmd, args, str)
31618220Slinton Name newcmd;
31718220Slinton List args;
31818220Slinton String str;
31918220Slinton {
32018220Slinton     Keyword k;
32118220Slinton 
32218220Slinton     if (str == nil) {
32318220Slinton 	print_alias(newcmd);
32418220Slinton     } else {
32518220Slinton 	k = findword(newcmd, ISALIAS);
32618220Slinton 	if (k == nil) {
32718220Slinton 	    k = keywords_insert(newcmd);
32818220Slinton 	}
32918220Slinton 	k->class = ISALIAS;
33018220Slinton 	k->value.alias.paramlist = args;
33118220Slinton 	k->value.alias.expansion = str;
33218220Slinton     }
33318220Slinton }
33418220Slinton 
33518220Slinton /*
33618220Slinton  * Print out an alias.
33718220Slinton  */
33818220Slinton 
33918220Slinton private print_alias (cmd)
34016928Ssam Name cmd;
3419664Slinton {
34218220Slinton     register Keyword k;
34318220Slinton     register Integer i;
34416928Ssam     Name n;
3459664Slinton 
34618220Slinton     if (cmd == nil) {
34718220Slinton 	for (i = 0; i < HASHTABLESIZE; i++) {
34818220Slinton 	    for (k = hashtab[i]; k != nil; k = k->chain) {
34918220Slinton 		if (k->class == ISALIAS) {
35018220Slinton 		    if (isredirected()) {
35118220Slinton 			printf("alias %s", ident(k->name));
35218220Slinton 			printparams(k->value.alias.paramlist);
35318220Slinton 			printf("\t\"%s\"\n", k->value.alias.expansion);
35418220Slinton 		    } else {
35518220Slinton 			printf("%s", ident(k->name));
35618220Slinton 			printparams(k->value.alias.paramlist);
35718220Slinton 			printf("\t%s\n", k->value.alias.expansion);
35818220Slinton 		    }
35918220Slinton 		}
36018220Slinton 	    }
36118220Slinton 	}
36218220Slinton     } else {
36318220Slinton 	k = findword(cmd, ISALIAS);
36418220Slinton 	if (k == nil) {
36518220Slinton 	    printf("\n");
36618220Slinton 	} else {
36718220Slinton 	    printparams(k->value.alias.paramlist);
36818220Slinton 	    printf("%s\n", k->value.alias.expansion);
36918220Slinton 	}
3709664Slinton     }
3719664Slinton }
3729664Slinton 
37318220Slinton private printparams (pl)
37418220Slinton List pl;
37516928Ssam {
37618220Slinton     Name n;
37716928Ssam 
37818220Slinton     if (pl != nil) {
37918220Slinton 	printf("(");
38018220Slinton 	foreach(Name, n, pl)
38118220Slinton 	    printf("%s", ident(n));
38218220Slinton 	    if (not list_islast()) {
38318220Slinton 		printf(", ");
38418220Slinton 	    }
38518220Slinton 	endfor
38618220Slinton 	printf(")");
38716928Ssam     }
38818220Slinton }
38918220Slinton 
39018220Slinton /*
39118220Slinton  * Remove an alias.
39218220Slinton  */
39318220Slinton 
39418220Slinton public unalias (n)
39518220Slinton Name n;
39618220Slinton {
39718220Slinton     if (not keywords_delete(n, ISALIAS)) {
39818220Slinton 	error("%s is not aliased", ident(n));
39916949Ssam     }
40016928Ssam }
40116928Ssam 
40218220Slinton /*
40318220Slinton  * Define a variable.
40418220Slinton  */
40518220Slinton 
40618220Slinton public defvar (n, val)
40718220Slinton Name n;
40818220Slinton Node val;
40916949Ssam {
41018220Slinton     Keyword k;
41116949Ssam 
41218220Slinton     if (n == nil) {
41318220Slinton 	print_vars();
41418220Slinton     } else {
41518220Slinton 	if (lookup(n) != nil) {
41618220Slinton 	    error("\"%s\" is a program symbol -- use assign", ident(n));
41718220Slinton 	}
41818220Slinton 	k = findword(n, ISVAR);
41918220Slinton 	if (k == nil) {
42018220Slinton 	    k = keywords_insert(n);
42118220Slinton 	}
42218220Slinton 	k->class = ISVAR;
42318220Slinton 	k->value.var = val;
42418220Slinton 	if (n == identname("$mapaddrs", true)) {
42518220Slinton 	    vaddrs = true;
42618220Slinton 	}
42718220Slinton     }
42816949Ssam }
42916949Ssam 
4309664Slinton /*
43118220Slinton  * Return the value associated with a variable.
4329664Slinton  */
43318220Slinton 
43418220Slinton public Node findvar (n)
43518220Slinton Name n;
4369664Slinton {
43718220Slinton     Keyword k;
43818220Slinton     Node val;
4399664Slinton 
44018220Slinton     k = findword(n, ISVAR);
44118220Slinton     if (k == nil) {
44218220Slinton 	val = nil;
44318220Slinton     } else {
44418220Slinton 	val = k->value.var;
44516928Ssam     }
44618220Slinton     return val;
44718220Slinton }
44818220Slinton 
44918220Slinton /*
45018220Slinton  * Return whether or not a variable is set.
45118220Slinton  */
45218220Slinton 
45318220Slinton public boolean varIsSet (s)
45418220Slinton String s;
45518220Slinton {
45618220Slinton     return (boolean) (findword(identname(s, false), ISVAR) != nil);
45718220Slinton }
45818220Slinton 
45918220Slinton /*
46018220Slinton  * Delete a variable.
46118220Slinton  */
46218220Slinton 
46318220Slinton public undefvar (n)
46418220Slinton Name n;
46518220Slinton {
46618220Slinton     if (not keywords_delete(n, ISVAR)) {
46718220Slinton 	error("%s is not set", ident(n));
46818220Slinton     }
46918220Slinton     if (n == identname("$mapaddrs", true)) {
47018220Slinton 	vaddrs = false;
47118220Slinton     }
47218220Slinton }
47318220Slinton 
47418220Slinton /*
47518220Slinton  * Print out all the values of set variables.
47618220Slinton  */
47718220Slinton 
47818220Slinton private print_vars ()
47918220Slinton {
48018220Slinton     register integer i;
48118220Slinton     register Keyword k;
48218220Slinton 
48318220Slinton     for (i = 0; i < HASHTABLESIZE; i++) {
48418220Slinton 	for (k = hashtab[i]; k != nil; k = k->chain) {
48518220Slinton 	    if (k->class == ISVAR) {
48618220Slinton 		if (isredirected()) {
48718220Slinton 		    printf("set ");
48818220Slinton 		}
48918220Slinton 		printf("%s", ident(k->name));
49018220Slinton 		if (k->value.var != nil) {
49118220Slinton 		    printf("\t");
49218220Slinton 		    prtree(stdout, k->value.var);
49318220Slinton 		}
49418220Slinton 		printf("\n");
49518220Slinton 	    }
4969664Slinton 	}
4979664Slinton     }
4989664Slinton }
499