date and time created 83/09/27 14:16:34 by ralph
authorRalph Campbell <ralph@ucbvax.Berkeley.EDU>
Wed, 28 Sep 1983 06:16:34 +0000 (22:16 -0800)
committerRalph Campbell <ralph@ucbvax.Berkeley.EDU>
Wed, 28 Sep 1983 06:16:34 +0000 (22:16 -0800)
SCCS-vsn: usr.bin/rdist/lookup.c 4.1

usr/src/usr.bin/rdist/lookup.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/rdist/lookup.c b/usr/src/usr.bin/rdist/lookup.c
new file mode 100644 (file)
index 0000000..08840e5
--- /dev/null
@@ -0,0 +1,146 @@
+#ifndef lint
+static char *sccsid = "@(#)lookup.c    4.1 (Berkeley) 83/09/27";
+#endif
+
+#include "defs.h"
+
+/*
+ * Define a variable from a command line argument.
+ */
+define(name)
+       char *name;
+{
+       register char *cp, *s;
+       register struct block *bp, *value;
+
+       if (debug)
+               printf("define(%s)\n", name);
+
+       cp = index(name, '=');
+       if (cp == NULL || cp[1] == '\0')
+               value = NULL;
+       else if (cp[1] != '(') {
+               *cp++ = '\0';
+               value = makeblock(NAME, cp);
+       } else {
+               bp = NULL;
+               *cp++ = '\0';
+               do
+                       cp++;
+               while (*cp == ' ' || *cp == '\t');
+               for (s = cp; ; s++) {
+                       switch (*s) {
+                       case ')':
+                               *s = '\0';
+                       case '\0':
+                               break;
+                       case ' ':
+                       case '\t':
+                               *s++ = '\0';
+                               while (*s == ' ' || *s == '\t')
+                                       s++;
+                               if (*s == ')')
+                                       *s = '\0';
+                               break;
+                       default:
+                               continue;
+                       }
+                       if (bp == NULL)
+                               value = bp = makeblock(NAME, cp);
+                       else {
+                               bp->b_next = makeblock(NAME, cp);
+                               bp = bp->b_next;
+                       }
+                       if (*s == '\0')
+                               break;
+                       cp = s;
+               }
+       }
+       bp = makeblock(VAR, name);
+       bp->b_args = value;
+       (void) lookup(bp->b_name, bp, 1);
+}
+
+static struct block *hashtab[HASHSIZE];
+
+/*
+ * Lookup name in the table and return a pointer to it.
+ * Insert == 0 - just do lookup, return NULL if not found.
+ * insert == 1 - insert name with value, error if already defined.
+ * insert == 2 - replace name with value if not entered with insert == 1.
+ */
+
+struct block *
+lookup(name, value, insert)
+       char *name;
+       struct block *value;
+       int insert;
+{
+       register unsigned n;
+       register char *cp;
+       register struct block *b, *f;
+
+       if (debug)
+               printf("lookup(%s, %x, %d)\n", name, value, insert);
+
+       n = 0;
+       for (cp = name; *cp; )
+               n += *cp++;
+       n %= HASHSIZE;
+
+       for (b = hashtab[n]; b != NULL; b = b->b_next) {
+               if (strcmp(name, b->b_name))
+                       continue;
+               if (insert) {
+                       if (b->b_type == NAME) {
+                               warn("%s redefined\n", name);
+                               f = b->b_args;
+                               b->b_args = value->b_args;
+                               value->b_args = f;
+                       } else if (value->b_type == VAR)
+                               fatal("%s redefined\n", name);
+                       while (f = value->b_next) {
+                               value->b_next = f->b_next;
+                               free(f->b_name);
+                               free(f);
+                       }
+                       free(value->b_name);
+                       free(value);
+               }
+               return(b);
+       }
+
+       if (!insert)
+               fatal("%s not defined", name);
+
+       value->b_next = hashtab[n];
+       hashtab[n] = value;
+       return(value);
+}
+
+/*
+ * Make a block for lists of variables, commands, etc.
+ */
+struct block *
+makeblock(type, name)
+       int type;
+       register char *name;
+{
+       register char *cp;
+       register struct block *bp;
+
+       bp = ALLOC(block);
+       if (bp == NULL)
+               fatal("ran out of memory\n");
+       bp->b_type = type;
+       bp->b_next = bp->b_args = NULL;
+       if (type == NAME || type == VAR) {
+               bp->b_name = cp = (char *) malloc(strlen(name) + 1);
+               if (cp == NULL)
+                       fatal("ran out of memory\n");
+               while (*cp++ = *name++)
+                       ;
+       } else
+               bp->b_name = NULL;
+       return(bp);
+}