17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California.
37c478bdstevel@tonic-gate * All rights reserved.
47c478bdstevel@tonic-gate *
57c478bdstevel@tonic-gate * Redistribution and use in source and binary forms are permitted
67c478bdstevel@tonic-gate * provided that the above copyright notice and this paragraph are
77c478bdstevel@tonic-gate * duplicated in all such forms and that any documentation,
87c478bdstevel@tonic-gate * advertising materials, and other materials related to such
97c478bdstevel@tonic-gate * distribution and use acknowledge that the software was developed
107c478bdstevel@tonic-gate * by the University of California, Berkeley.  The name of the
117c478bdstevel@tonic-gate * University may not be used to endorse or promote products derived
127c478bdstevel@tonic-gate * from this software without specific prior written permission.
137c478bdstevel@tonic-gate *
14740638cbw * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
15740638cbw * Use is subject to license terms.
167c478bdstevel@tonic-gate */
177c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
187c478bdstevel@tonic-gate
197c478bdstevel@tonic-gate#include "defs.h"
207c478bdstevel@tonic-gate
217c478bdstevel@tonic-gate	/* symbol types */
227c478bdstevel@tonic-gate#define VAR	1
237c478bdstevel@tonic-gate#define CONST	2
247c478bdstevel@tonic-gate
257c478bdstevel@tonic-gatestruct syment {
267c478bdstevel@tonic-gate	int	s_type;
277c478bdstevel@tonic-gate	char	*s_name;
287c478bdstevel@tonic-gate	struct	namelist *s_value;
297c478bdstevel@tonic-gate	struct	syment *s_next;
307c478bdstevel@tonic-gate};
317c478bdstevel@tonic-gate
327c478bdstevel@tonic-gatestatic struct syment *hashtab[HASHSIZE];
337c478bdstevel@tonic-gate
347c478bdstevel@tonic-gate/*
357c478bdstevel@tonic-gate * Define a variable from a command line argument.
367c478bdstevel@tonic-gate */
37740638cbwvoid
387c478bdstevel@tonic-gatedefine(name)
397c478bdstevel@tonic-gate	char *name;
407c478bdstevel@tonic-gate{
417c478bdstevel@tonic-gate	register char *cp, *s;
427c478bdstevel@tonic-gate	register struct namelist *nl;
437c478bdstevel@tonic-gate	struct namelist *value;
447c478bdstevel@tonic-gate
457c478bdstevel@tonic-gate	if (debug)
467c478bdstevel@tonic-gate		printf("define(%s)\n", name);
477c478bdstevel@tonic-gate
487c478bdstevel@tonic-gate	cp = index(name, '=');
497c478bdstevel@tonic-gate	if (cp == NULL)
507c478bdstevel@tonic-gate		value = NULL;
517c478bdstevel@tonic-gate	else if (cp[1] == '\0') {
527c478bdstevel@tonic-gate		*cp = '\0';
537c478bdstevel@tonic-gate		value = NULL;
547c478bdstevel@tonic-gate	} else if (cp[1] != '(') {
557c478bdstevel@tonic-gate		*cp++ = '\0';
567c478bdstevel@tonic-gate		value = makenl(cp);
577c478bdstevel@tonic-gate	} else {
587c478bdstevel@tonic-gate		nl = NULL;
597c478bdstevel@tonic-gate		*cp++ = '\0';
607c478bdstevel@tonic-gate		do
617c478bdstevel@tonic-gate			cp++;
627c478bdstevel@tonic-gate		while (*cp == ' ' || *cp == '\t');
637c478bdstevel@tonic-gate		for (s = cp; ; s++) {
647c478bdstevel@tonic-gate			switch (*s) {
657c478bdstevel@tonic-gate			case ')':
667c478bdstevel@tonic-gate				*s = '\0';
677c478bdstevel@tonic-gate			case '\0':
687c478bdstevel@tonic-gate				break;
697c478bdstevel@tonic-gate			case ' ':
707c478bdstevel@tonic-gate			case '\t':
717c478bdstevel@tonic-gate				*s++ = '\0';
727c478bdstevel@tonic-gate				while (*s == ' ' || *s == '\t')
737c478bdstevel@tonic-gate					s++;
747c478bdstevel@tonic-gate				if (*s == ')')
757c478bdstevel@tonic-gate					*s = '\0';
767c478bdstevel@tonic-gate				break;
777c478bdstevel@tonic-gate			default:
787c478bdstevel@tonic-gate				continue;
797c478bdstevel@tonic-gate			}
807c478bdstevel@tonic-gate			if (nl == NULL)
817c478bdstevel@tonic-gate				value = nl = makenl(cp);
827c478bdstevel@tonic-gate			else {
837c478bdstevel@tonic-gate				nl->n_next = makenl(cp);
847c478bdstevel@tonic-gate				nl = nl->n_next;
857c478bdstevel@tonic-gate			}
867c478bdstevel@tonic-gate			if (*s == '\0')
877c478bdstevel@tonic-gate				break;
887c478bdstevel@tonic-gate			cp = s;
897c478bdstevel@tonic-gate		}
907c478bdstevel@tonic-gate	}
917c478bdstevel@tonic-gate	(void) lookup(name, REPLACE, value);
927c478bdstevel@tonic-gate}
937c478bdstevel@tonic-gate
947c478bdstevel@tonic-gate/*
957c478bdstevel@tonic-gate * Lookup name in the table and return a pointer to it.
967c478bdstevel@tonic-gate * LOOKUP - just do lookup, return NULL if not found.
977c478bdstevel@tonic-gate * INSERT - insert name with value, error if already defined.
987c478bdstevel@tonic-gate * REPLACE - insert or replace name with value.
997c478bdstevel@tonic-gate */
1007c478bdstevel@tonic-gate
1017c478bdstevel@tonic-gatestruct namelist *
1027c478bdstevel@tonic-gatelookup(name, action, value)
1037c478bdstevel@tonic-gate	char *name;
1047c478bdstevel@tonic-gate	int action;
1057c478bdstevel@tonic-gate	struct namelist *value;
1067c478bdstevel@tonic-gate{
1077c478bdstevel@tonic-gate	register unsigned n;
1087c478bdstevel@tonic-gate	register char *cp;
1097c478bdstevel@tonic-gate	register struct syment *s;
1107c478bdstevel@tonic-gate	char buf[256];
1117c478bdstevel@tonic-gate
1127c478bdstevel@tonic-gate	if (debug)
1137c478bdstevel@tonic-gate		printf("lookup(%s, %d, %x)\n", name, action, value);
1147c478bdstevel@tonic-gate
1157c478bdstevel@tonic-gate	n = 0;
1167c478bdstevel@tonic-gate	for (cp = name; *cp; )
1177c478bdstevel@tonic-gate		n += *cp++;
1187c478bdstevel@tonic-gate	n %= HASHSIZE;
1197c478bdstevel@tonic-gate
1207c478bdstevel@tonic-gate	for (s = hashtab[n]; s != NULL; s = s->s_next) {
1217c478bdstevel@tonic-gate		if (strcmp(name, s->s_name))
1227c478bdstevel@tonic-gate			continue;
1237c478bdstevel@tonic-gate		if (action != LOOKUP) {
1247c478bdstevel@tonic-gate			if (action != INSERT || s->s_type != CONST) {
1257c478bdstevel@tonic-gate				(void)sprintf(buf, "%.*s redefined",
1267c478bdstevel@tonic-gate				      sizeof(buf) - sizeof(" redefined"), name);
1277c478bdstevel@tonic-gate				yyerror(buf);
1287c478bdstevel@tonic-gate			}
1297c478bdstevel@tonic-gate		}
1307c478bdstevel@tonic-gate		return(s->s_value);
1317c478bdstevel@tonic-gate	}
1327c478bdstevel@tonic-gate
1337c478bdstevel@tonic-gate	if (action == LOOKUP) {
1347c478bdstevel@tonic-gate		(void)sprintf(buf, "%.*s undefined",
1357c478bdstevel@tonic-gate			sizeof(buf) - sizeof(" undefined"), name);
1367c478bdstevel@tonic-gate		yyerror(buf);
1377c478bdstevel@tonic-gate		return(NULL);
1387c478bdstevel@tonic-gate	}
1397c478bdstevel@tonic-gate
1407c478bdstevel@tonic-gate	s = ALLOC(syment);
1417c478bdstevel@tonic-gate	if (s == NULL)
1427c478bdstevel@tonic-gate		fatal("ran out of memory\n");
1437c478bdstevel@tonic-gate	s->s_next = hashtab[n];
1447c478bdstevel@tonic-gate	hashtab[n] = s;
1457c478bdstevel@tonic-gate	s->s_type = action == INSERT ? VAR : CONST;
1467c478bdstevel@tonic-gate	s->s_name = name;
1477c478bdstevel@tonic-gate	s->s_value = value;
1487c478bdstevel@tonic-gate	return(value);
1497c478bdstevel@tonic-gate}
150