/* sym - symbol table routines */
* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Vern Paxson of Lawrence Berkeley Laboratory.
* The United States Government has rights in this work pursuant
* to contract no. DE-AC03-76SF00098 between the United States
* Department of Energy and the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)sym.c 5.2 (Berkeley) 6/18/90";
/* declare functions that have forward references */
int hashfunct
PROTO((register char[], int));
struct hash_entry
*ndtbl
[NAME_TABLE_HASH_SIZE
];
struct hash_entry
*sctbl
[START_COND_HASH_SIZE
];
struct hash_entry
*ccltab
[CCL_HASH_SIZE
];
struct hash_entry
*findsym();
/* addsym - add symbol and definitions to symbol table
* 0 / -1 = addsym( sym, def, int_def, table, table_size );
* -1 is returned if the symbol already exists, and the change not made.
int addsym( sym
, str_def
, int_def
, table
, table_size
)
int hash_val
= hashfunct( sym
, table_size
);
register struct hash_entry
*sym_entry
= table
[hash_val
];
register struct hash_entry
*new_entry
;
register struct hash_entry
*successor
;
if ( ! strcmp( sym
, sym_entry
->name
) )
{ /* entry already exists */
sym_entry
= sym_entry
->next
;
new_entry
= (struct hash_entry
*) malloc( sizeof( struct hash_entry
) );
flexfatal( "symbol table memory allocation failed" );
if ( (successor
= table
[hash_val
]) )
new_entry
->next
= successor
;
successor
->prev
= new_entry
;
new_entry
->str_val
= str_def
;
new_entry
->int_val
= int_def
;
table
[hash_val
] = new_entry
;
/* cclinstal - save the text of a character class
* cclinstal( ccltxt, cclnum );
void cclinstal( ccltxt
, cclnum
)
/* we don't bother checking the return status because we are not called
* unless the symbol is new
Char
*copy_unsigned_string();
(void) addsym( (char *) copy_unsigned_string( ccltxt
), (char *) 0, cclnum
,
/* ccllookup - lookup the number associated with character class text
* cclval/0 = ccllookup( ccltxt );
return ( findsym( (char *) ccltxt
, ccltab
, CCL_HASH_SIZE
)->int_val
);
/* findsym - find symbol in symbol table
* struct hash_entry *sym_entry, *findsym();
* sym_entry = findsym( sym, table, table_size );
struct hash_entry
*findsym( sym
, table
, table_size
)
register struct hash_entry
*sym_entry
= table
[hashfunct( sym
, table_size
)];
static struct hash_entry empty_entry
=
(struct hash_entry
*) 0, (struct hash_entry
*) 0, NULL
, NULL
, 0,
if ( ! strcmp( sym
, sym_entry
->name
) )
sym_entry
= sym_entry
->next
;
/* hashfunct - compute the hash value for "str" and hash size "hash_size"
* int hash_size, hash_val;
* hash_val = hashfunct( str, hash_size );
int hashfunct( str
, hash_size
)
hashval
= ((hashval
<< 1) + str
[locstr
++]) % hash_size
;
/* ndinstal - install a name definition
Char
*copy_unsigned_string();
if ( addsym( copy_string( nd
), (char *) copy_unsigned_string( def
), 0,
ndtbl
, NAME_TABLE_HASH_SIZE
) )
synerr( "name defined twice" );
/* ndlookup - lookup a name definition
* def/NULL = ndlookup( nd );
return ( (Char
*) findsym( nd
, ndtbl
, NAME_TABLE_HASH_SIZE
)->str_val
);
/* scinstal - make a start condition
* scinstal( str, xcluflg );
* the start condition is Exclusive if xcluflg is true
void scinstal( str
, xcluflg
)
/* bit of a hack. We know how the default start-condition is
* declared, and don't put out a define for it, because it
* would come out as "#define 0 1"
/* actually, this is no longer the case. The default start-condition
* is now called "INITIAL". But we keep the following for the sake
if ( strcmp( str
, "0" ) )
printf( "#define %s %d\n", str
, lastsc
);
if ( ++lastsc
>= current_max_scs
)
current_max_scs
+= MAX_SCS_INCREMENT
;
scset
= reallocate_integer_array( scset
, current_max_scs
);
scbol
= reallocate_integer_array( scbol
, current_max_scs
);
scxclu
= reallocate_integer_array( scxclu
, current_max_scs
);
sceof
= reallocate_integer_array( sceof
, current_max_scs
);
scname
= reallocate_char_ptr_array( scname
, current_max_scs
);
actvsc
= reallocate_integer_array( actvsc
, current_max_scs
);
scname
[lastsc
] = copy_string( str
);
if ( addsym( scname
[lastsc
], (char *) 0, lastsc
,
sctbl
, START_COND_HASH_SIZE
) )
format_pinpoint_message( "start condition %s declared twice", str
);
scset
[lastsc
] = mkstate( SYM_EPSILON
);
scbol
[lastsc
] = mkstate( SYM_EPSILON
);
scxclu
[lastsc
] = xcluflg
;
/* sclookup - lookup the number associated with a start condition
* scnum/0 = sclookup( str );
return ( findsym( str
, sctbl
, START_COND_HASH_SIZE
)->int_val
);