xref: /netbsd-src/external/bsd/flex/dist/src/sym.c (revision 7977e68669c3b784eb65c933a2bd99785638ae00)
1*7977e686Schristos /*	$NetBSD: sym.c,v 1.3 2017/01/02 17:45:27 christos Exp $	*/
2a11deec2Schristos 
330da1778Schristos /* sym - symbol table routines */
430da1778Schristos 
530da1778Schristos /*  Copyright (c) 1990 The Regents of the University of California. */
630da1778Schristos /*  All rights reserved. */
730da1778Schristos 
830da1778Schristos /*  This code is derived from software contributed to Berkeley by */
930da1778Schristos /*  Vern Paxson. */
1030da1778Schristos 
1130da1778Schristos /*  The United States Government has rights in this work pursuant */
1230da1778Schristos /*  to contract no. DE-AC03-76SF00098 between the United States */
1330da1778Schristos /*  Department of Energy and the University of California. */
1430da1778Schristos 
1530da1778Schristos /*  This file is part of flex. */
1630da1778Schristos 
1730da1778Schristos /*  Redistribution and use in source and binary forms, with or without */
1830da1778Schristos /*  modification, are permitted provided that the following conditions */
1930da1778Schristos /*  are met: */
2030da1778Schristos 
2130da1778Schristos /*  1. Redistributions of source code must retain the above copyright */
2230da1778Schristos /*     notice, this list of conditions and the following disclaimer. */
2330da1778Schristos /*  2. Redistributions in binary form must reproduce the above copyright */
2430da1778Schristos /*     notice, this list of conditions and the following disclaimer in the */
2530da1778Schristos /*     documentation and/or other materials provided with the distribution. */
2630da1778Schristos 
2730da1778Schristos /*  Neither the name of the University nor the names of its contributors */
2830da1778Schristos /*  may be used to endorse or promote products derived from this software */
2930da1778Schristos /*  without specific prior written permission. */
3030da1778Schristos 
3130da1778Schristos /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
3230da1778Schristos /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
3330da1778Schristos /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
3430da1778Schristos /*  PURPOSE. */
3530da1778Schristos #include "flexdef.h"
36*7977e686Schristos __RCSID("$NetBSD: sym.c,v 1.3 2017/01/02 17:45:27 christos Exp $");
37a11deec2Schristos 
3830da1778Schristos 
3930da1778Schristos /* Variables for symbol tables:
4030da1778Schristos  * sctbl - start-condition symbol table
4130da1778Schristos  * ndtbl - name-definition symbol table
4230da1778Schristos  * ccltab - character class text symbol table
4330da1778Schristos  */
4430da1778Schristos 
4530da1778Schristos struct hash_entry {
4630da1778Schristos 	struct hash_entry *prev, *next;
4730da1778Schristos 	char   *name;
4830da1778Schristos 	char   *str_val;
4930da1778Schristos 	int     int_val;
5030da1778Schristos };
5130da1778Schristos 
5230da1778Schristos typedef struct hash_entry **hash_table;
5330da1778Schristos 
5430da1778Schristos #define NAME_TABLE_HASH_SIZE 101
5530da1778Schristos #define START_COND_HASH_SIZE 101
5630da1778Schristos #define CCL_HASH_SIZE 101
5730da1778Schristos 
5830da1778Schristos static struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
5930da1778Schristos static struct hash_entry *sctbl[START_COND_HASH_SIZE];
6030da1778Schristos static struct hash_entry *ccltab[CCL_HASH_SIZE];
6130da1778Schristos 
6230da1778Schristos 
6330da1778Schristos /* declare functions that have forward references */
6430da1778Schristos 
65*7977e686Schristos static int addsym(char[], char *, int, hash_table, int);
66*7977e686Schristos static struct hash_entry *findsym (const char *sym, hash_table table,
67*7977e686Schristos 				   int table_size);
68*7977e686Schristos static int hashfunct(const char *, int);
6930da1778Schristos 
7030da1778Schristos 
7130da1778Schristos /* addsym - add symbol and definitions to symbol table
7230da1778Schristos  *
7330da1778Schristos  * -1 is returned if the symbol already exists, and the change not made.
7430da1778Schristos  */
7530da1778Schristos 
addsym(char sym[],char * str_def,int int_def,hash_table table,int table_size)76*7977e686Schristos static int addsym (char sym[], char *str_def, int int_def, hash_table table, int table_size)
7730da1778Schristos {
7830da1778Schristos 	int    hash_val = hashfunct (sym, table_size);
7930da1778Schristos 	struct hash_entry *sym_entry = table[hash_val];
8030da1778Schristos 	struct hash_entry *new_entry;
8130da1778Schristos 	struct hash_entry *successor;
8230da1778Schristos 
8330da1778Schristos 	while (sym_entry) {
8430da1778Schristos 		if (!strcmp (sym, sym_entry->name)) {	/* entry already exists */
8530da1778Schristos 			return -1;
8630da1778Schristos 		}
8730da1778Schristos 
8830da1778Schristos 		sym_entry = sym_entry->next;
8930da1778Schristos 	}
9030da1778Schristos 
9130da1778Schristos 	/* create new entry */
92*7977e686Schristos 	new_entry = malloc(sizeof(struct hash_entry));
9330da1778Schristos 
9430da1778Schristos 	if (new_entry == NULL)
9530da1778Schristos 		flexfatal (_("symbol table memory allocation failed"));
9630da1778Schristos 
9730da1778Schristos 	if ((successor = table[hash_val]) != 0) {
9830da1778Schristos 		new_entry->next = successor;
9930da1778Schristos 		successor->prev = new_entry;
10030da1778Schristos 	}
10130da1778Schristos 	else
10230da1778Schristos 		new_entry->next = NULL;
10330da1778Schristos 
10430da1778Schristos 	new_entry->prev = NULL;
10530da1778Schristos 	new_entry->name = sym;
10630da1778Schristos 	new_entry->str_val = str_def;
10730da1778Schristos 	new_entry->int_val = int_def;
10830da1778Schristos 
10930da1778Schristos 	table[hash_val] = new_entry;
11030da1778Schristos 
11130da1778Schristos 	return 0;
11230da1778Schristos }
11330da1778Schristos 
11430da1778Schristos 
11530da1778Schristos /* cclinstal - save the text of a character class */
11630da1778Schristos 
cclinstal(char ccltxt[],int cclnum)117*7977e686Schristos void    cclinstal (char ccltxt[], int cclnum)
11830da1778Schristos {
11930da1778Schristos 	/* We don't bother checking the return status because we are not
12030da1778Schristos 	 * called unless the symbol is new.
12130da1778Schristos 	 */
12230da1778Schristos 
123*7977e686Schristos 	(void) addsym (xstrdup(ccltxt),
12430da1778Schristos 		       (char *) 0, cclnum, ccltab, CCL_HASH_SIZE);
12530da1778Schristos }
12630da1778Schristos 
12730da1778Schristos 
12830da1778Schristos /* ccllookup - lookup the number associated with character class text
12930da1778Schristos  *
13030da1778Schristos  * Returns 0 if there's no CCL associated with the text.
13130da1778Schristos  */
13230da1778Schristos 
ccllookup(char ccltxt[])133*7977e686Schristos int     ccllookup (char ccltxt[])
13430da1778Schristos {
135*7977e686Schristos 	return findsym (ccltxt, ccltab, CCL_HASH_SIZE)->int_val;
13630da1778Schristos }
13730da1778Schristos 
13830da1778Schristos 
13930da1778Schristos /* findsym - find symbol in symbol table */
14030da1778Schristos 
findsym(const char * sym,hash_table table,int table_size)141*7977e686Schristos static struct hash_entry *findsym (const char *sym, hash_table table, int table_size)
14230da1778Schristos {
14330da1778Schristos 	static struct hash_entry empty_entry = {
144*7977e686Schristos 		NULL, NULL, NULL, NULL, 0,
14530da1778Schristos 	};
14630da1778Schristos 	struct hash_entry *sym_entry =
14730da1778Schristos 
14830da1778Schristos 		table[hashfunct (sym, table_size)];
14930da1778Schristos 
15030da1778Schristos 	while (sym_entry) {
15130da1778Schristos 		if (!strcmp (sym, sym_entry->name))
15230da1778Schristos 			return sym_entry;
15330da1778Schristos 		sym_entry = sym_entry->next;
15430da1778Schristos 	}
15530da1778Schristos 
15630da1778Schristos 	return &empty_entry;
15730da1778Schristos }
15830da1778Schristos 
15930da1778Schristos /* hashfunct - compute the hash value for "str" and hash size "hash_size" */
16030da1778Schristos 
hashfunct(const char * str,int hash_size)161*7977e686Schristos static int hashfunct (const char *str, int hash_size)
16230da1778Schristos {
16330da1778Schristos 	int hashval;
16430da1778Schristos 	int locstr;
16530da1778Schristos 
16630da1778Schristos 	hashval = 0;
16730da1778Schristos 	locstr = 0;
16830da1778Schristos 
16930da1778Schristos 	while (str[locstr]) {
17030da1778Schristos 		hashval = (hashval << 1) + (unsigned char) str[locstr++];
17130da1778Schristos 		hashval %= hash_size;
17230da1778Schristos 	}
17330da1778Schristos 
17430da1778Schristos 	return hashval;
17530da1778Schristos }
17630da1778Schristos 
17730da1778Schristos 
17830da1778Schristos /* ndinstal - install a name definition */
17930da1778Schristos 
ndinstal(const char * name,char definition[])180*7977e686Schristos void    ndinstal (const char *name, char definition[])
18130da1778Schristos {
18230da1778Schristos 
183*7977e686Schristos 	if (addsym (xstrdup(name),
184*7977e686Schristos 		    xstrdup(definition), 0,
18530da1778Schristos 		    ndtbl, NAME_TABLE_HASH_SIZE))
18630da1778Schristos 			synerr (_("name defined twice"));
18730da1778Schristos }
18830da1778Schristos 
18930da1778Schristos 
19030da1778Schristos /* ndlookup - lookup a name definition
19130da1778Schristos  *
19230da1778Schristos  * Returns a nil pointer if the name definition does not exist.
19330da1778Schristos  */
19430da1778Schristos 
ndlookup(const char * nd)195*7977e686Schristos char   *ndlookup (const char *nd)
19630da1778Schristos {
197*7977e686Schristos 	return findsym (nd, ndtbl, NAME_TABLE_HASH_SIZE)->str_val;
19830da1778Schristos }
19930da1778Schristos 
20030da1778Schristos 
20130da1778Schristos /* scextend - increase the maximum number of start conditions */
20230da1778Schristos 
scextend(void)203*7977e686Schristos void    scextend (void)
20430da1778Schristos {
20530da1778Schristos 	current_max_scs += MAX_SCS_INCREMENT;
20630da1778Schristos 
20730da1778Schristos 	++num_reallocs;
20830da1778Schristos 
20930da1778Schristos 	scset = reallocate_integer_array (scset, current_max_scs);
21030da1778Schristos 	scbol = reallocate_integer_array (scbol, current_max_scs);
21130da1778Schristos 	scxclu = reallocate_integer_array (scxclu, current_max_scs);
21230da1778Schristos 	sceof = reallocate_integer_array (sceof, current_max_scs);
21330da1778Schristos 	scname = reallocate_char_ptr_array (scname, current_max_scs);
21430da1778Schristos }
21530da1778Schristos 
21630da1778Schristos 
21730da1778Schristos /* scinstal - make a start condition
21830da1778Schristos  *
21930da1778Schristos  * NOTE
22030da1778Schristos  *    The start condition is "exclusive" if xcluflg is true.
22130da1778Schristos  */
22230da1778Schristos 
scinstal(const char * str,int xcluflg)223*7977e686Schristos void    scinstal (const char *str, int xcluflg)
22430da1778Schristos {
22530da1778Schristos 
22630da1778Schristos 	if (++lastsc >= current_max_scs)
22730da1778Schristos 		scextend ();
22830da1778Schristos 
229*7977e686Schristos 	scname[lastsc] = xstrdup(str);
23030da1778Schristos 
231*7977e686Schristos 	if (addsym(scname[lastsc], NULL, lastsc,
23230da1778Schristos 		    sctbl, START_COND_HASH_SIZE))
23330da1778Schristos 			format_pinpoint_message (_
23430da1778Schristos 						 ("start condition %s declared twice"),
23530da1778Schristos str);
23630da1778Schristos 
23730da1778Schristos 	scset[lastsc] = mkstate (SYM_EPSILON);
23830da1778Schristos 	scbol[lastsc] = mkstate (SYM_EPSILON);
23930da1778Schristos 	scxclu[lastsc] = xcluflg;
24030da1778Schristos 	sceof[lastsc] = false;
24130da1778Schristos }
24230da1778Schristos 
24330da1778Schristos 
24430da1778Schristos /* sclookup - lookup the number associated with a start condition
24530da1778Schristos  *
24630da1778Schristos  * Returns 0 if no such start condition.
24730da1778Schristos  */
24830da1778Schristos 
sclookup(const char * str)249*7977e686Schristos int     sclookup (const char *str)
25030da1778Schristos {
25130da1778Schristos 	return findsym (str, sctbl, START_COND_HASH_SIZE)->int_val;
25230da1778Schristos }
253