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