121604Sdist /*
238105Sbostic * Copyright (c) 1983 The Regents of the University of California.
338105Sbostic * All rights reserved.
438105Sbostic *
5*42683Sbostic * %sccs.include.redist.c%
621604Sdist */
79664Slinton
821604Sdist #ifndef lint
9*42683Sbostic static char sccsid[] = "@(#)keywords.c 5.4 (Berkeley) 06/01/90";
1038105Sbostic #endif /* not lint */
119664Slinton
129664Slinton /*
1318220Slinton * Keywords, variables, and aliases (oh my!).
149664Slinton */
159664Slinton
169664Slinton #include "defs.h"
179664Slinton #include "keywords.h"
189664Slinton #include "scanner.h"
199664Slinton #include "names.h"
209664Slinton #include "symbols.h"
219664Slinton #include "tree.h"
2218220Slinton #include "lists.h"
2318220Slinton #include "main.h"
249664Slinton #include "y.tab.h"
259664Slinton
269664Slinton #ifndef public
2718220Slinton
289664Slinton #include "scanner.h"
2918220Slinton #include "tree.h"
3018220Slinton
319664Slinton #endif
329664Slinton
339664Slinton private String reserved[] ={
349664Slinton "alias", "and", "assign", "at", "call", "catch", "cont",
3516611Ssam "debug", "delete", "div", "down", "dump", "edit", "file", "func",
369664Slinton "gripe", "help", "if", "ignore", "in",
379664Slinton "list", "mod", "next", "nexti", "nil", "not", "or",
3816611Ssam "print", "psym", "quit", "rerun", "return", "run",
3918220Slinton "set", "sh", "skip", "source", "status", "step", "stepi",
4018220Slinton "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use",
4118220Slinton "whatis", "when", "where", "whereis", "which",
4218220Slinton "INT", "CHAR", "REAL", "NAME", "STRING", "->"
439664Slinton };
449664Slinton
459664Slinton /*
469664Slinton * The keyword table is a traditional hash table with collisions
479664Slinton * resolved by chaining.
489664Slinton */
4918220Slinton
5018220Slinton #define HASHTABLESIZE 1007
5118220Slinton
5218220Slinton typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType;
5318220Slinton
549664Slinton typedef struct Keyword {
559664Slinton Name name;
5618220Slinton KeywordType class : 16;
5718220Slinton union {
5818220Slinton /* ISKEYWORD: */
5918220Slinton Token toknum;
6018220Slinton
6118220Slinton /* ISALIAS: */
6218220Slinton struct {
6318220Slinton List paramlist;
6418220Slinton String expansion;
6518220Slinton } alias;
6618220Slinton
6718220Slinton /* ISVAR: */
6818220Slinton Node var;
6918220Slinton } value;
709664Slinton struct Keyword *chain;
719664Slinton } *Keyword;
729664Slinton
739664Slinton typedef unsigned int Hashvalue;
749664Slinton
7518220Slinton private Keyword hashtab[HASHTABLESIZE];
769664Slinton
7718220Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE)
789664Slinton
799664Slinton /*
809664Slinton * Enter all the reserved words into the keyword table.
8118220Slinton *
8218220Slinton * If the vaddrs flag is set (through the -k command line option) then
8318220Slinton * set the special "$mapaddrs" variable. This assumes that the
8418220Slinton * command line arguments are scanned before this routine is called.
859664Slinton */
8618220Slinton
enterkeywords()879664Slinton public enterkeywords()
889664Slinton {
8918220Slinton register integer i;
909664Slinton
9118220Slinton for (i = ALIAS; i <= WHICH; i++) {
9216928Ssam keyword(reserved[ord(i) - ord(ALIAS)], i);
9318220Slinton }
9418220Slinton defalias("c", "cont");
9518220Slinton defalias("d", "delete");
9618220Slinton defalias("h", "help");
9718220Slinton defalias("e", "edit");
9818220Slinton defalias("l", "list");
9918220Slinton defalias("n", "next");
10018220Slinton defalias("p", "print");
10118220Slinton defalias("q", "quit");
10218220Slinton defalias("r", "run");
10318220Slinton defalias("s", "step");
10418220Slinton defalias("st", "stop");
10518220Slinton defalias("j", "status");
10618220Slinton defalias("t", "where");
10718220Slinton if (vaddrs) {
10818220Slinton defvar(identname("$mapaddrs", true), nil);
10918220Slinton }
1109664Slinton }
1119664Slinton
1129664Slinton /*
11318220Slinton * Deallocate the keyword table.
1149664Slinton */
11518220Slinton
keywords_free()1169664Slinton public keywords_free()
1179664Slinton {
1189664Slinton register Integer i;
1199664Slinton register Keyword k, nextk;
1209664Slinton
12118220Slinton for (i = 0; i < HASHTABLESIZE; i++) {
12218220Slinton k = hashtab[i];
12318220Slinton while (k != nil) {
1249664Slinton nextk = k->chain;
1259664Slinton dispose(k);
12618220Slinton k = nextk;
1279664Slinton }
1289664Slinton hashtab[i] = nil;
1299664Slinton }
13018220Slinton }
13118220Slinton
13218220Slinton /*
13318220Slinton * Insert a name into the keyword table and return the keyword for it.
13418220Slinton */
13518220Slinton
keywords_insert(n)13618220Slinton private Keyword keywords_insert (n)
13718220Slinton Name n;
13818220Slinton {
13918220Slinton Hashvalue h;
14018220Slinton Keyword k;
14118220Slinton
14218220Slinton h = hash(n);
14318220Slinton k = new(Keyword);
14418220Slinton k->name = n;
14518220Slinton k->chain = hashtab[h];
14618220Slinton hashtab[h] = k;
14718220Slinton return k;
14818220Slinton }
14918220Slinton
15018220Slinton /*
15118220Slinton * Find the keyword associated with the given name.
15218220Slinton */
15318220Slinton
keywords_lookup(n)15418220Slinton private Keyword keywords_lookup (n)
15518220Slinton Name n;
15618220Slinton {
15718220Slinton Hashvalue h;
15818220Slinton register Keyword k;
15918220Slinton
16018220Slinton h = hash(n);
16118220Slinton k = hashtab[h];
16218220Slinton while (k != nil and k->name != n) {
16318220Slinton k = k->chain;
16418220Slinton }
16518220Slinton return k;
16618220Slinton }
16718220Slinton
16818220Slinton /*
16918220Slinton * Delete the given keyword of the given class.
17018220Slinton */
17118220Slinton
keywords_delete(n,class)17218220Slinton private boolean keywords_delete (n, class)
17318220Slinton Name n;
17418220Slinton KeywordType class;
17518220Slinton {
17618220Slinton Hashvalue h;
17718220Slinton register Keyword k, prevk;
17818220Slinton boolean b;
17918220Slinton
18018220Slinton h = hash(n);
18118220Slinton k = hashtab[h];
18218220Slinton prevk = nil;
18318220Slinton while (k != nil and (k->name != n or k->class != class)) {
18418220Slinton prevk = k;
18518220Slinton k = k->chain;
18618220Slinton }
18718220Slinton if (k != nil) {
18818220Slinton b = true;
18918220Slinton if (prevk == nil) {
19018220Slinton hashtab[h] = k->chain;
19118220Slinton } else {
19218220Slinton prevk->chain = k->chain;
19316928Ssam }
19418220Slinton dispose(k);
19518220Slinton } else {
19618220Slinton b = false;
19716928Ssam }
19818220Slinton return b;
1999664Slinton }
2009664Slinton
2019664Slinton /*
20218220Slinton * Enter a keyword into the table. It is assumed to not be there already.
2039664Slinton * The string is assumed to be statically allocated.
2049664Slinton */
20518220Slinton
keyword(s,t)20618220Slinton private keyword (s, t)
2079664Slinton String s;
2089664Slinton Token t;
2099664Slinton {
21018220Slinton Keyword k;
2119664Slinton Name n;
2129664Slinton
2139664Slinton n = identname(s, true);
21418220Slinton k = keywords_insert(n);
21518220Slinton k->class = ISKEYWORD;
21618220Slinton k->value.toknum = t;
2179664Slinton }
2189664Slinton
2199664Slinton /*
22018220Slinton * Define a builtin command name alias.
2219664Slinton */
22218220Slinton
defalias(s1,s2)22318220Slinton private defalias (s1, s2)
22418220Slinton String s1, s2;
2259664Slinton {
22618220Slinton alias(identname(s1, true), nil, s2);
2279664Slinton }
2289664Slinton
2299664Slinton /*
23018220Slinton * Look for a word of a particular class.
2319664Slinton */
2329664Slinton
findword(n,class)23318220Slinton private Keyword findword (n, class)
2349664Slinton Name n;
23518220Slinton KeywordType class;
2369664Slinton {
2379664Slinton register Keyword k;
2389664Slinton
23918220Slinton k = keywords_lookup(n);
24018220Slinton while (k != nil and (k->name != n or k->class != class)) {
24118220Slinton k = k->chain;
24218220Slinton }
24318220Slinton return k;
24416611Ssam }
24516611Ssam
24618220Slinton /*
24718220Slinton * Return the token associated with a given keyword string.
24818220Slinton * If there is none, return the given default value.
24918220Slinton */
25018220Slinton
findkeyword(n,def)25118220Slinton public Token findkeyword (n, def)
25216611Ssam Name n;
25318220Slinton Token def;
25416611Ssam {
25518220Slinton Keyword k;
25618220Slinton Token t;
25716611Ssam
25818220Slinton k = findword(n, ISKEYWORD);
25918220Slinton if (k == nil) {
26018220Slinton t = def;
26118220Slinton } else {
26218220Slinton t = k->value.toknum;
26318220Slinton }
26418220Slinton return t;
2659664Slinton }
2669664Slinton
2679664Slinton /*
26818220Slinton * Return the associated string if there is an alias with the given name.
2699664Slinton */
27018220Slinton
findalias(n,pl,str)27118220Slinton public boolean findalias (n, pl, str)
27218220Slinton Name n;
27318220Slinton List *pl;
27418220Slinton String *str;
27518220Slinton {
27618220Slinton Keyword k;
27718220Slinton boolean b;
27818220Slinton
27918220Slinton k = findword(n, ISALIAS);
28018220Slinton if (k == nil) {
28118220Slinton b = false;
28218220Slinton } else {
28318220Slinton *pl = k->value.alias.paramlist;
28418220Slinton *str = k->value.alias.expansion;
28522017Ssam b = true;
28618220Slinton }
28718220Slinton return b;
28818220Slinton }
28918220Slinton
29018220Slinton /*
29118220Slinton * Return the string associated with a token corresponding to a keyword.
29218220Slinton */
29318220Slinton
keywdstring(t)29418220Slinton public String keywdstring (t)
29518220Slinton Token t;
29618220Slinton {
29718220Slinton return reserved[ord(t) - ord(ALIAS)];
29818220Slinton }
29918220Slinton
30018220Slinton /*
30118220Slinton * Process an alias command, either entering a new alias or printing out
30218220Slinton * an existing one.
30318220Slinton */
30418220Slinton
alias(newcmd,args,str)30518220Slinton public alias (newcmd, args, str)
30618220Slinton Name newcmd;
30718220Slinton List args;
30818220Slinton String str;
30918220Slinton {
31018220Slinton Keyword k;
31118220Slinton
31218220Slinton if (str == nil) {
31318220Slinton print_alias(newcmd);
31418220Slinton } else {
31518220Slinton k = findword(newcmd, ISALIAS);
31618220Slinton if (k == nil) {
31718220Slinton k = keywords_insert(newcmd);
31818220Slinton }
31918220Slinton k->class = ISALIAS;
32018220Slinton k->value.alias.paramlist = args;
32118220Slinton k->value.alias.expansion = str;
32218220Slinton }
32318220Slinton }
32418220Slinton
32518220Slinton /*
32618220Slinton * Print out an alias.
32718220Slinton */
32818220Slinton
print_alias(cmd)32918220Slinton private print_alias (cmd)
33016928Ssam Name cmd;
3319664Slinton {
33218220Slinton register Keyword k;
33318220Slinton register Integer i;
33416928Ssam Name n;
3359664Slinton
33618220Slinton if (cmd == nil) {
33718220Slinton for (i = 0; i < HASHTABLESIZE; i++) {
33818220Slinton for (k = hashtab[i]; k != nil; k = k->chain) {
33918220Slinton if (k->class == ISALIAS) {
34018220Slinton if (isredirected()) {
34118220Slinton printf("alias %s", ident(k->name));
34218220Slinton printparams(k->value.alias.paramlist);
34318220Slinton printf("\t\"%s\"\n", k->value.alias.expansion);
34418220Slinton } else {
34518220Slinton printf("%s", ident(k->name));
34618220Slinton printparams(k->value.alias.paramlist);
34718220Slinton printf("\t%s\n", k->value.alias.expansion);
34818220Slinton }
34918220Slinton }
35018220Slinton }
35118220Slinton }
35218220Slinton } else {
35318220Slinton k = findword(cmd, ISALIAS);
35418220Slinton if (k == nil) {
35518220Slinton printf("\n");
35618220Slinton } else {
35718220Slinton printparams(k->value.alias.paramlist);
35818220Slinton printf("%s\n", k->value.alias.expansion);
35918220Slinton }
3609664Slinton }
3619664Slinton }
3629664Slinton
printparams(pl)36318220Slinton private printparams (pl)
36418220Slinton List pl;
36516928Ssam {
36618220Slinton Name n;
36716928Ssam
36818220Slinton if (pl != nil) {
36918220Slinton printf("(");
37018220Slinton foreach(Name, n, pl)
37118220Slinton printf("%s", ident(n));
37218220Slinton if (not list_islast()) {
37318220Slinton printf(", ");
37418220Slinton }
37518220Slinton endfor
37618220Slinton printf(")");
37716928Ssam }
37818220Slinton }
37918220Slinton
38018220Slinton /*
38118220Slinton * Remove an alias.
38218220Slinton */
38318220Slinton
unalias(n)38418220Slinton public unalias (n)
38518220Slinton Name n;
38618220Slinton {
38718220Slinton if (not keywords_delete(n, ISALIAS)) {
38818220Slinton error("%s is not aliased", ident(n));
38916949Ssam }
39016928Ssam }
39116928Ssam
39218220Slinton /*
39318220Slinton * Define a variable.
39418220Slinton */
39518220Slinton
defvar(n,val)39618220Slinton public defvar (n, val)
39718220Slinton Name n;
39818220Slinton Node val;
39916949Ssam {
40018220Slinton Keyword k;
40116949Ssam
40218220Slinton if (n == nil) {
40318220Slinton print_vars();
40418220Slinton } else {
40518220Slinton if (lookup(n) != nil) {
40618220Slinton error("\"%s\" is a program symbol -- use assign", ident(n));
40718220Slinton }
40818220Slinton k = findword(n, ISVAR);
40918220Slinton if (k == nil) {
41018220Slinton k = keywords_insert(n);
41118220Slinton }
41218220Slinton k->class = ISVAR;
41318220Slinton k->value.var = val;
41418220Slinton if (n == identname("$mapaddrs", true)) {
41518220Slinton vaddrs = true;
41618220Slinton }
41718220Slinton }
41816949Ssam }
41916949Ssam
4209664Slinton /*
42118220Slinton * Return the value associated with a variable.
4229664Slinton */
42318220Slinton
findvar(n)42418220Slinton public Node findvar (n)
42518220Slinton Name n;
4269664Slinton {
42718220Slinton Keyword k;
42818220Slinton Node val;
4299664Slinton
43018220Slinton k = findword(n, ISVAR);
43118220Slinton if (k == nil) {
43218220Slinton val = nil;
43318220Slinton } else {
43418220Slinton val = k->value.var;
43516928Ssam }
43618220Slinton return val;
43718220Slinton }
43818220Slinton
43918220Slinton /*
44018220Slinton * Return whether or not a variable is set.
44118220Slinton */
44218220Slinton
varIsSet(s)44318220Slinton public boolean varIsSet (s)
44418220Slinton String s;
44518220Slinton {
44618220Slinton return (boolean) (findword(identname(s, false), ISVAR) != nil);
44718220Slinton }
44818220Slinton
44918220Slinton /*
45018220Slinton * Delete a variable.
45118220Slinton */
45218220Slinton
undefvar(n)45318220Slinton public undefvar (n)
45418220Slinton Name n;
45518220Slinton {
45618220Slinton if (not keywords_delete(n, ISVAR)) {
45718220Slinton error("%s is not set", ident(n));
45818220Slinton }
45918220Slinton if (n == identname("$mapaddrs", true)) {
46018220Slinton vaddrs = false;
46118220Slinton }
46218220Slinton }
46318220Slinton
46418220Slinton /*
46518220Slinton * Print out all the values of set variables.
46618220Slinton */
46718220Slinton
print_vars()46818220Slinton private print_vars ()
46918220Slinton {
47018220Slinton register integer i;
47118220Slinton register Keyword k;
47218220Slinton
47318220Slinton for (i = 0; i < HASHTABLESIZE; i++) {
47418220Slinton for (k = hashtab[i]; k != nil; k = k->chain) {
47518220Slinton if (k->class == ISVAR) {
47618220Slinton if (isredirected()) {
47718220Slinton printf("set ");
47818220Slinton }
47918220Slinton printf("%s", ident(k->name));
48018220Slinton if (k->value.var != nil) {
48118220Slinton printf("\t");
48218220Slinton prtree(stdout, k->value.var);
48318220Slinton }
48418220Slinton printf("\n");
48518220Slinton }
4869664Slinton }
4879664Slinton }
4889664Slinton }
489