Home | History | Annotate | Download | only in flex-2.5.4a
      1 /* sym - symbol table routines */
      2 
      3 /*-
      4  * Copyright (c) 1990 The Regents of the University of California.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Vern Paxson.
      9  *
     10  * The United States Government has rights in this work pursuant
     11  * to contract no. DE-AC03-76SF00098 between the United States
     12  * Department of Energy and the University of California.
     13  *
     14  * Redistribution and use in source and binary forms with or without
     15  * modification are permitted provided that: (1) source distributions retain
     16  * this entire copyright notice and comment, and (2) distributions including
     17  * binaries display the following acknowledgement:  ``This product includes
     18  * software developed by the University of California, Berkeley and its
     19  * contributors'' in the documentation or other materials provided with the
     20  * distribution and in all advertising materials mentioning features or use
     21  * of this software.  Neither the name of the University nor the names of
     22  * its contributors may be used to endorse or promote products derived from
     23  * this software without specific prior written permission.
     24  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
     25  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
     26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     27  */
     28 
     29 /* $Header: /home/daffy/u0/vern/flex/RCS/sym.c,v 2.19 95/03/04 16:11:04 vern Exp $ */
     30 
     31 #include "flexdef.h"
     32 
     33 
     34 /* declare functions that have forward references */
     35 
     36 int hashfunct PROTO((register char[], int));
     37 
     38 
     39 struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
     40 struct hash_entry *sctbl[START_COND_HASH_SIZE];
     41 struct hash_entry *ccltab[CCL_HASH_SIZE];
     42 
     43 struct hash_entry *findsym();
     44 
     45 
     46 /* addsym - add symbol and definitions to symbol table
     47  *
     48  * -1 is returned if the symbol already exists, and the change not made.
     49  */
     50 
     51 int addsym( sym, str_def, int_def, table, table_size )
     52 register char sym[];
     53 char *str_def;
     54 int int_def;
     55 hash_table table;
     56 int table_size;
     57 	{
     58 	int hash_val = hashfunct( sym, table_size );
     59 	register struct hash_entry *sym_entry = table[hash_val];
     60 	register struct hash_entry *new_entry;
     61 	register struct hash_entry *successor;
     62 
     63 	while ( sym_entry )
     64 		{
     65 		if ( ! strcmp( sym, sym_entry->name ) )
     66 			{ /* entry already exists */
     67 			return -1;
     68 			}
     69 
     70 		sym_entry = sym_entry->next;
     71 		}
     72 
     73 	/* create new entry */
     74 	new_entry = (struct hash_entry *)
     75 		flex_alloc( sizeof( struct hash_entry ) );
     76 
     77 	if ( new_entry == NULL )
     78 		flexfatal( _( "symbol table memory allocation failed" ) );
     79 
     80 	if ( (successor = table[hash_val]) != 0 )
     81 		{
     82 		new_entry->next = successor;
     83 		successor->prev = new_entry;
     84 		}
     85 	else
     86 		new_entry->next = NULL;
     87 
     88 	new_entry->prev = NULL;
     89 	new_entry->name = sym;
     90 	new_entry->str_val = str_def;
     91 	new_entry->int_val = int_def;
     92 
     93 	table[hash_val] = new_entry;
     94 
     95 	return 0;
     96 	}
     97 
     98 
     99 /* cclinstal - save the text of a character class */
    100 
    101 void cclinstal( ccltxt, cclnum )
    102 Char ccltxt[];
    103 int cclnum;
    104 	{
    105 	/* We don't bother checking the return status because we are not
    106 	 * called unless the symbol is new.
    107 	 */
    108 	Char *copy_unsigned_string();
    109 
    110 	(void) addsym( (char *) copy_unsigned_string( ccltxt ),
    111 			(char *) 0, cclnum,
    112 			ccltab, CCL_HASH_SIZE );
    113 	}
    114 
    115 
    116 /* ccllookup - lookup the number associated with character class text
    117  *
    118  * Returns 0 if there's no CCL associated with the text.
    119  */
    120 
    121 int ccllookup( ccltxt )
    122 Char ccltxt[];
    123 	{
    124 	return findsym( (char *) ccltxt, ccltab, CCL_HASH_SIZE )->int_val;
    125 	}
    126 
    127 
    128 /* findsym - find symbol in symbol table */
    129 
    130 struct hash_entry *findsym( sym, table, table_size )
    131 register char sym[];
    132 hash_table table;
    133 int table_size;
    134 	{
    135 	static struct hash_entry empty_entry =
    136 		{
    137 		(struct hash_entry *) 0, (struct hash_entry *) 0,
    138 		(char *) 0, (char *) 0, 0,
    139 		} ;
    140 	register struct hash_entry *sym_entry =
    141 		table[hashfunct( sym, table_size )];
    142 
    143 	while ( sym_entry )
    144 		{
    145 		if ( ! strcmp( sym, sym_entry->name ) )
    146 			return sym_entry;
    147 		sym_entry = sym_entry->next;
    148 		}
    149 
    150 	return &empty_entry;
    151 	}
    152 
    153 
    154 /* hashfunct - compute the hash value for "str" and hash size "hash_size" */
    155 
    156 int hashfunct( str, hash_size )
    157 register char str[];
    158 int hash_size;
    159 	{
    160 	register int hashval;
    161 	register int locstr;
    162 
    163 	hashval = 0;
    164 	locstr = 0;
    165 
    166 	while ( str[locstr] )
    167 		{
    168 		hashval = (hashval << 1) + (unsigned char) str[locstr++];
    169 		hashval %= hash_size;
    170 		}
    171 
    172 	return hashval;
    173 	}
    174 
    175 
    176 /* ndinstal - install a name definition */
    177 
    178 void ndinstal( name, definition )
    179 char name[];
    180 Char definition[];
    181 	{
    182 	char *copy_string();
    183 	Char *copy_unsigned_string();
    184 
    185 	if ( addsym( copy_string( name ),
    186 			(char *) copy_unsigned_string( definition ), 0,
    187 			ndtbl, NAME_TABLE_HASH_SIZE ) )
    188 		synerr( _( "name defined twice" ) );
    189 	}
    190 
    191 
    192 /* ndlookup - lookup a name definition
    193  *
    194  * Returns a nil pointer if the name definition does not exist.
    195  */
    196 
    197 Char *ndlookup( nd )
    198 char nd[];
    199 	{
    200 	return (Char *) findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val;
    201 	}
    202 
    203 
    204 /* scextend - increase the maximum number of start conditions */
    205 
    206 void scextend()
    207 	{
    208 	current_max_scs += MAX_SCS_INCREMENT;
    209 
    210 	++num_reallocs;
    211 
    212 	scset = reallocate_integer_array( scset, current_max_scs );
    213 	scbol = reallocate_integer_array( scbol, current_max_scs );
    214 	scxclu = reallocate_integer_array( scxclu, current_max_scs );
    215 	sceof = reallocate_integer_array( sceof, current_max_scs );
    216 	scname = reallocate_char_ptr_array( scname, current_max_scs );
    217 	}
    218 
    219 
    220 /* scinstal - make a start condition
    221  *
    222  * NOTE
    223  *    The start condition is "exclusive" if xcluflg is true.
    224  */
    225 
    226 void scinstal( str, xcluflg )
    227 char str[];
    228 int xcluflg;
    229 	{
    230 	char *copy_string();
    231 
    232 	/* Generate start condition definition, for use in BEGIN et al. */
    233 	action_define( str, lastsc );
    234 
    235 	if ( ++lastsc >= current_max_scs )
    236 		scextend();
    237 
    238 	scname[lastsc] = copy_string( str );
    239 
    240 	if ( addsym( scname[lastsc], (char *) 0, lastsc,
    241 			sctbl, START_COND_HASH_SIZE ) )
    242 		format_pinpoint_message(
    243 				_( "start condition %s declared twice" ),
    244 					str );
    245 
    246 	scset[lastsc] = mkstate( SYM_EPSILON );
    247 	scbol[lastsc] = mkstate( SYM_EPSILON );
    248 	scxclu[lastsc] = xcluflg;
    249 	sceof[lastsc] = false;
    250 	}
    251 
    252 
    253 /* sclookup - lookup the number associated with a start condition
    254  *
    255  * Returns 0 if no such start condition.
    256  */
    257 
    258 int sclookup( str )
    259 char str[];
    260 	{
    261 	return findsym( str, sctbl, START_COND_HASH_SIZE )->int_val;
    262 	}
    263