Commit ba10055a authored by wanli's avatar wanli

update

parent f53f9e57
/*
* list.h - Definitions for list datastructures.
*
* Author: Russ Fish
* Computer Science Dept.
* University of Utah
* Date: 1 August 1980
*/
#ifndef LISTLINKS /* only once */
/*****************************************************************/
/* TAG( list LISTHDR TLISTHDR NULLPTR P N T_P T_N ) */
/* TAG( LISTLINKS TLISTLINKS ) */
typedef /* Generalized list header. */
struct listhdr
{
int t_tag; /* object type tag */
struct listhdr *next,*prev; /* Backward & forward pointers */
}
list;
/* LISTLINKS = a type tag, followed by a LISTHDR */
#define LISTLINKS int t_tag; struct tlist * next, * prev
#define TLISTLINKS(type) int t_tag; type * next, * prev
/* Access for List pointer manipulations. (Previous and Next.) */
#define P(node) ((node)->prev)
#define N(node) ((node)->next)
/* #define P(node) (((list *)(node))->prev)
* #define N(node) (((list *)(node))->next)
*/
/* Versions of P and N with cast on result to set list subtype properly. */
#define T_P(type,node) ((type *)(node)->prev)
#define T_N(type,node) ((type *)(node)->next)
/* *****************************************************************
* TAG( list_list LLIST NEW_LIST_LIST )
*
* list of lists data structure.
*/
typedef struct list_list
{
TLISTLINKS(struct list_list);
list * l_list;
} list_list;
#define LLIST(type,ll) (type *)ll->l_list /* get the list pointed to */
/*****************************************************************/
/* TAG( ADD INSERT REMOVE ) */
/* ADD links new members into a list, given a pointer to the new member, and
* a pointer to the first (left) element of the list.
*/
#define ADD(new,first) ( P(new) = NULL ,N(new) = (first),\
( ((first)!=NULL) ? (P(first)=(new), 0) :0 ),\
first = (new) )
/* INSERT links members into the middle of a list, given a pointer to the new
* member, and a pointer to the list element to insert after.
*/
#define INSERT(new,after) ( P(new) = (after),N(new) = N(after),\
( (N(after)!=NULL) ? (P(N(after))=(new), 0) :0),\
N(after) = (new) )
/* REMOVE unlinks a list element from a list, given a pointer to the element.
*/
#define REMOVE(elt) ( ( (P(elt)!=NULL) ? (N(P(elt))=N(elt), 0) :0 ),\
( (N(elt)!=NULL) ? (P(N(elt))=P(elt), 0) :0) )
/****************************************************************
* TAG( TRACE FREE_LIST FIRSTP ENDP )
*
* TRACE - Traces a linear list.
* FREE_LIST - Walks a list, freeing the elements.
* FIRSTP - Tests an element, TRUE if it is the first.
* ENDP - Tests an element, TRUE if it is the end.
*/
#define TRACE(t_var,ini) for((t_var)=(ini);(t_var)!=NULL;(t_var)=N(t_var))
#define FREE_LIST(lst) {while(N(lst)){lst=N(lst);free(P(lst));} free(lst);}
#define FIRSTP(ptr) (P(ptr) == NULL)
#define ENDP(ptr) (N(ptr) == NULL)
/****************************************************************
* TAGS( DEL )
* del deletes an element from a list, updating the base
* pointer of the list if necesary.
*/
#define DEL(elt,base) ( ( (P(elt)!=NULL) ? (N(P(elt)) = N(elt)) :0 ),\
( (N(elt)!=NULL) ? (P(N(elt)) = P(elt)) :0) ,\
( ((elt)==(base)) ? ((base)= N(base) ) :0) )
#endif LISTLINKS
# Makefile for opqcp.
CFLAGS = -g
OFILES = opqcp.o symtab.o new.o
opqcp: $(OFILES)
gcc -o opqcp $(CFLAGS) $(OFILES)
opqcp.o: misc.h symtab.h
symtab.o: misc.h symtab.h
new.o: misc.h
/*
* misc.h - Just the subset of defs needed for opqcp.
*
* Author: Russ Fish
* Computer Science Dept.
* University of Utah
* Date: 1 August 1980
*/
#ifndef MISCH /* Only once. */
#define MISCH
#include <stdio.h> /* Defines NULL. */
/*****************************************************************
* TAGS( string boolean fn byte address )
*
* Commonly used types.
*
*/
typedef char * string; /* Character Strings. */
typedef int boolean; /* Logical vars or values. */
typedef char byte; /* Byte is the unit of "sizeof". */
typedef char * address;
/*****************************************************************
* TAGS( TRUE FALSE )
*/
#define TRUE 1 /* Logical constants. */
#define FALSE 0
/*****************************************************************
* TAGS( NEW NEW_1 NEW_N new )
*
* NEW(type,size)
* Generalized allocation function, given an object type and size (in
* bytes) to be allocated.
*
* Variants:
* NEW_1(type) - Allocate a single object of the given type.
* NEW_N(type,n) - Allocate an array of N objects of the given type.
*/
extern address
new(); /* In-core allocator. */
/* ( size )
* int size;
*/
#define NEW(type,size) (type *)new(size) /* Macro with type cast. */
#define NEW_1(type) (type *)new(sizeof(type)) /* Single arg, fixed size. */
#define NEW_N(type,n) (type *)new((n)*sizeof(type)) /* Array of base type. */
/*****************************************************************
* TAGS( FREE free dispose )
*
* Macros to cast the argument to dispose().
*/
#define FREE( ptr ) dispose( (address)ptr )
#define free( ptr ) dispose( (address)ptr )
/*****************************************************************
* TAG( SIZE SIZE_N msize )
*
* SIZE returns the size (in bytes) of an allocated object.
*
* SIZE_N returns the number of objects of TYPE in ARRAY.
*/
extern long
msize();
/* ( obj )
* address obj;
*/
#define SIZE(obj) msize( (address)obj )
#define SIZE_N(type, array) (msize( (address)array ) / sizeof (type))
#endif
/*
* new.c - Generalized allocation function.
*
* Author: Russ Fish
* Computer Science Dept.
* University of Utah
* Date: 1 August 1980
*/
#include "misc.h"
typedef union
{
long mem_size; /* Someplace to stash the actual block size. */
/* Avoid messing up the double alignment of the block we are wrapping. */
double dummy;
} mem_hdr;
extern char * malloc(); /* Use the Std I/O Mem Alloc. */
/*****************************************************************
* TAG( new )
*
* Allocate a block of storage.
*
*/
address
new(size)
int size;
{
mem_hdr * retval;
if ( (retval = (mem_hdr *)
malloc( (unsigned) (size + sizeof(mem_hdr)) )) <= 0 )
{
fprintf( stderr, "\nNo Space in heap! %d bytes requested.\n", size);
exit( -1 );
}
/* Fill in the specified block size in a header word. The returned
* pointer points just AFTER the mem_hdr. Only "new", "dispose",
* "msize", and "expand" need to know about the mem_hdr.
*/
retval->mem_size = (long) size;
return (address)( retval + 1 );
}
/*****************************************************************
* TAG( msize )
*
* Report the size of a block of storage.
*/
long
msize( obj )
address obj;
{
return ( (mem_hdr *)obj - 1 )->mem_size;
}
/*****************************************************************
* TAG( dispose )
*
* Free a block of storage.
*/
dispose( obj )
address obj;
{
/* Get the "free" compatibility macro out of the way. This is the
* only place in the system where the real "free" function is visible.
*/
# undef free
if ( obj )
free( (char *) ((mem_hdr *)obj - 1) );
}
File added
/* opqcp - Makes opaque copies of a group of sources to support a flavor
* of distribution with the security of an object-only version but the ability
* to recompile on a variety of machines like a source distribution.
*
* The idea is that there is a lot of information in good sources which is
* not needed by the compiler or linker, but which conveys the meaning of the
* program to a programmer. We try to write the most understandable programs
* possible, opqcp aspires to translate them into the least understandable.
*
* Comments, #includes, #define'ed constants and macros - stripped or
* expanded by pouring the source through the C preprocessor.
*
* Global symbols - translated into unreadable equivalents or preserved
* if needed to link to the program or function. A global dictionary
* must have previously been derived from the .o file symbol tables.
* (All C reserved keywords are preserved automatically.)
*
* Local identifiers - Translated into unreadable equivalents within
* a single source file. This applies to everything not in the global
* table (variables, typedefs, struct fields, etc.)
*
* Indentation/Whitespace - The tokens are packed on screen-width lines with
* all whitespace removed.
*
* Arguments (dash args precede file and destdir args.):
* -d dictfile - (Optional, may be repeated.) Contains a wordlist that is
* entered into a symbol table of global names. Lines with just a name
* mark that identifier as a clear global to preserve in the output.
* (All C reserved words are automatically preserved in this way.)
* Lines with a name and its translation separated by a blank character
* denote an opaque global which is translated the same everywhere.
* All other symbols will be locally translated and may be different in
* each source file.
*
* -Idir - (Optional, may be repeated.) Include directory arguments passed
* on to the C preprocessor.
*
* -f - Filter mode, just opacifies stdin to stdout. File and
* directory arguments are ignored and the input must already have
* been run through "cc -E" if preprocessing is desired.
*
* -t - Token trace (for testing). Forces filter mode, prints token
* types and values.
*
* filenames.c - (Required except in filter mode, may be repeated.)
* Source files to obfuscate.
*
* destdir - (One required as the last argument except in filter mode.)
* Where to put the opaque copies of the source files.
* The copies have the same names as the originals, but opqcp
* refuses to overwrite a file with itself.
*/
#include "misc.h"
#include "symtab.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "ctype.h"
string c_keywords[] = /* From K&R, appendix A, section 2.3. */
{
"int", "char", "float", "double", "struct", "union", "enum", "long",
"short", "unsigned", "auto", "extern", "register", "typedef", "static",
"goto", "return", "sizeof", "break", "continue", "if", "else", "for",
"do", "while", "switch", "case", "default", "entry", "fortran", "asm",
"main", /* Reserved for main program functions. */
"void" /* Not in K&R, added since then. */
};
int n_keywords = sizeof c_keywords / sizeof( string );
main( argc, argv )
int argc;
string argv[];
{
boolean filter_mode = FALSE, token_trace = FALSE;
int i, j, k, l, arg_num;
hash_table * globals, * locals;
id * symbol;
string *name_ptr, *arg_ptr, arg;
static char I_args[BUFSIZ] = { '\0' };
char buffer[BUFSIZ], buffer2[BUFSIZ];
struct stat stat_buffer;
FILE * dict_in, * input, * output, * popen();
dev_t input_dev;
ino_t input_inode;
string directory, name, translation, index();
char chr, * chr_ptr , token[BUFSIZ], * token_end, string_type;
int token_length, line_length;
enum { NONE, SYMBOL, STRING, NUMBER, OTHER }
token_type, prev_token_type;
static string token_type_strings[] =
{ "none", "symbol", "string", "number", "other" };
boolean whitespace;
/* These characters will not be separated if they occur together. */
string op_diphthong_chars = "=!<>&|+-*/%&^";
/* Some simple macros to stream characters through the token recognizer. */
# define NEW_TOKEN ( token_end = token, *token_end = '\0' )
# define NEXT ( OUT, IN )
# define OUT ( *token_end++ = chr, *token_end = '\0' )
# define IN ( chr = getc( input ) )
# define NEW_LINE ( line_length = 0 )
int local_counter = 0;
# define NLOCALS 5000
static char local_names[NLOCALS][6];
/* Save a lot of hassle by putting the local name strings in a static
* array where they can be re-used. The var_value cells of the ids in
* a hashed symbol table are second class citizens in that they are not
* freed when the hash table is freed, although the var_name strings are.
*/
for ( i=0; i < NLOCALS/1000; i++ ) /* Initialize the local name strings. */
for ( j=0; j<=9; j++ )
for ( k=0; k<=9; k++ )
for ( l=0; l<=9; l++ )
{
chr_ptr = local_names[local_counter++];
*chr_ptr++ = 'l'; /* Leading letter. */
if ( i ) *chr_ptr++ = '0' + i; /* Thousands. */
if ( i || j ) *chr_ptr++ = '0' + j; /* Hundreds. */
if ( i || j || k ) *chr_ptr++ = '0' + k; /* Tens. */
*chr_ptr++ = '0' + l; /* Ones. */
*chr_ptr = '\0';
}
/* Start out the global dictionary with the C keywords. */
globals = new_hash_table( 1000 );
for ( i=0, name_ptr = c_keywords; i < n_keywords; i++, name_ptr++ )
new_symbol( *name_ptr, globals );
/* Process dash arguments. */
for ( arg_num=1, arg_ptr = &argv[1], arg = *arg_ptr;
arg_num < argc;
arg_num++, arg_ptr++, arg = *arg_ptr )
{
if ( arg[0] != '-' )
break; /* Only do dash args here. */
/* Process -d (global dictionary) args. */
if ( strcmp( arg, "-d" ) == 0 )
{
if ( ++arg_num >= argc-1 ) break; /* Ignore -d at the end. */
arg = *++arg_ptr;
if ( (dict_in = fopen( arg, "r" )) == NULL )
{
sprintf( buffer, "opqcp: Can't open dictionary %s\n", arg );
perror( buffer );
exit( 1 );
}
while( fgets( buffer, BUFSIZ, dict_in ) != NULL )
{
/* Trash the newline fgets puts in the buffer. */
buffer[ strlen(buffer)-1 ] = '\0';
/* Optional translation is separated from name by a blank. */
if ( (translation = index( buffer, ' ' )) != NULL )
*translation++ = '\0'; /* Terminate the name string. */
/* Link in a copy of the name string. */
name = NEW( char, strlen(buffer)+1 );
strcpy( name, buffer );
symbol = new_symbol( name, globals );
/* Translation will be NULL if symbol is to be left alone. */
if ( translation != NULL )
{
/* Link in a copy of the translation string. */
symbol->var_value = NEW( char, strlen(translation)+1 );
strcpy( symbol->var_value, translation );
}
}
fclose( dict_in );
}
/* Process -Idir (cpp include directory) argument(s). */
else if ( strncmp( arg, "-I", 2 ) == 0 )
{
strcat( I_args, " " );
strcat( I_args, arg );
}
/* Process a -t (token trace) argument. */
else if ( strcmp( arg, "-t" ) == 0 )
{
token_trace = TRUE; /* For testing. */
goto filter; /* Forces filter mode. */
}
/* Process a -f (filter mode) argument. */
else if ( strcmp( arg, "-f" ) == 0 )
{
filter:
filter_mode = TRUE; /* No-ops all of the file handling. */
input = stdin;
output = stdout;
}
else
break; /* Out if invalid dash arg. */
}
/* Usage message if bad dash flag or no file and dir args . */
if ( arg[0] == '-' || !filter_mode && argc-arg_num < 2 )
{
fprintf( stderr, "%s\n%s\n",
"usage: opqcp [-d dict]* [-Idir]* [srcfile]+ destdir",
" or opqcp [-d dict]* -f" );
exit( 2 );
}
/* Check that the last argument is a directory. */
if ( !filter_mode )
{
if ( stat( directory = argv[argc-1], &stat_buffer ) == -1 )
{
sprintf( buffer, "opqcp: Can't stat directory %s\n", directory );
perror( buffer );
exit( 1 );
}
if ( ! (stat_buffer.st_mode & S_IFDIR) )
{
fprintf( stderr, "opqcp: %s is not a directory.\n", directory );
exit( 1 );
}
}
/* Loop through the file arguments. */
for ( ; filter_mode || arg_num < argc-1; arg_num++, arg_ptr++ )
{
if ( filter_mode )
arg = "(stdin)";
else
{
arg = *arg_ptr;
/* Before opening the output file, check that it isn't the same
* as the input file. (This would result in clearing the file
* before it was read!)
*/
if ( stat( arg, &stat_buffer ) == -1 )
{
sprintf( buffer, "opqcp: Can't stat input file %s\n", arg );
perror( buffer );
continue; /* Go do next file arg. */
}
/* Might as well check that it's a plain file while we're here. */
if ( ! (stat_buffer.st_mode & S_IFREG) )
{
fprintf( stderr, "opqcp: %s is not a plain file.\n", arg );
continue; /* Go do next file arg. */
}
input_dev = stat_buffer.st_dev;
input_inode = stat_buffer.st_ino;
sprintf( buffer, "%s/%s", directory, arg ); /* Output file path. */
if ( stat( buffer, &stat_buffer ) == 0 )
{ /* We can only stat an already existing output file. */
/* Check for inode collision to guard against overwriting. */
if ( stat_buffer.st_dev == input_dev &&
stat_buffer.st_ino == input_inode )
{
fprintf( stderr, "opqcp: Can't copy file %s to itself.\n",
arg );
continue; /* Go on to next file arg. */
}
/* Check that it's a plain file while we're here. */
if ( ! (stat_buffer.st_mode & S_IFREG) )
{
fprintf( stderr, "opqcp: %s is not a plain file.\n",
buffer );
continue; /* Go on to next file arg. */
}
}
/* Open the opaque source file on the destination directory. */
if ( (output = fopen( buffer, "w" )) == NULL )
{
sprintf( buffer, "opqcp: Can't write file %s",arg );
perror( buffer );
continue; /* Go on to the next file. */
}
/* Copyright notice. */
fputs( "/* Licensed material, Copyright ", output );
fputs( "(c) 1985, University of Utah. */\n", output );
/* Read the source file through the C preprocessor. */
sprintf( buffer2, "cc -E %s %s", I_args, arg );
if ( (input = popen( buffer2, "r" )) == NULL )
{
sprintf( buffer2, "opqcp: Couldn't start cpp on %s.",arg );
perror( buffer2 );
fclose( output ); /* It was already opened. */
unlink( buffer ); /* Wipe out the empty output file. */
continue; /* Go on to the next file. */
}
}
/* Local dictionary lasts only through a single source file. */
locals = new_hash_table( 1000 );
local_counter = 0;
/* Transfer tokens from the cpp stream to a packed output file. */
chr = '\n'; /* In effect, the end of the line before the first line. */
NEW_LINE; /* Start first line of output. */
prev_token_type = NONE;
/* Back here at the beginning of each token. */
while( chr != EOF )
{
NEW_TOKEN; /* Set up to collect a token. */
token_type = NONE;
whitespace = FALSE;
/* Flush whitespace before a token. */
while( isspace( chr ) )
{
whitespace = TRUE;
if ( chr != '\n' )
IN; /* Character after blank or tab. */
else
{
IN; /* First character on a line. */
if ( chr == '#' )
{
/* Flush C preprocessor linenumber statements. */
while ( chr != '\n' && chr != EOF )
IN; /* Go until the newline is found. */
}
}
}
/* Identifiers, keywords, etc. Underscore is a letter. */
if ( isalpha( chr ) || chr == '_' )
{
token_type = SYMBOL;
/* Grab the alpha and then alphanumeric characters. */
NEXT;
while ( isalnum( chr ) || chr == '_' ) NEXT;
/* Look the symbol up in the global dictionary. */
if ( (symbol = find_symbol( token, globals )) != NULL )
{
/* Substitute a global translation if there is one. */
if ( symbol->var_value != NULL )
{
strcpy( token, symbol->var_value );
}
}
else
{
/* Look the symbol up in the local dictionary. */
if ( (symbol = find_symbol( token, locals )) == NULL )
{
/* New symbol, assign a local translation. */
name = NEW( char, strlen(token)+1 );
strcpy( name, token );
symbol = new_symbol( name, locals );
symbol->var_value = local_names[++local_counter];
}
/* Translate symbol to the local equivalent. */
strcpy( token, symbol->var_value );
}
}
/* Character constants and strings. */
else if ( chr == '"' || chr == '\'' )
{
token_type = STRING;
string_type = chr; /* Remember which kind of quote. */
NEXT; /* Stash quote, get first char of string. */
while ( chr != string_type )
{
if ( chr != '\\' )
NEXT; /* Stash non-backslash char, go ahead. */
else
/* Handle backslash escapes. */
{
NEXT; /* Stash backslash, go to escaped char. */
if ( string_type != '"' || chr != '\n' )
NEXT; /* Stash escaped char, go ahead. */
else
{
/* Weird special case. Strings can be
* continued onto the next line if they
* precede the newline with a backslash.
*/
NEXT; /* Stash escaped newline, go ahead. */
if ( strlen(token) + line_length > 77 )
fputs( "\n", output ); /* Break before. */
/* Put out the string with escaped newline. */
fputs( token, output );
/* Start a new line and a new token. */
NEW_LINE; NEW_TOKEN;
}
}
}
NEXT; /* Stash closing quote. */
}
/* Numbers. (This can be a bit simplified over a real
* lexical analyzer, since it only has to correctly
* recognize all valid number forms, not detect subtle
* syntax errors.)
*/
else if ( isdigit( chr ) )
{
number:
token_type = NUMBER;
/* Initial numeric part. */
if ( chr == '0' )
{ /* Could be an octal or hex constant, or just a "0". */
NEXT;
if ( chr == 'x' || chr == 'X' )
{
NEXT; /* Get first char of hex constant. */
while( isdigit( chr ) || chr >= 'a' && chr <= 'f'
|| chr >= 'A' && chr <= 'F' )
NEXT; /* Read through hex constant. */
}
else /* Octal integer constant. */
while ( isdigit( chr ) ) NEXT;
}
else
/* Decimal integer, or part of a floating pt number. */
while ( isdigit( chr ) ) NEXT;
/* Optional integer "l" suffix, fraction, or exponent. */
if ( chr == 'l' || chr == 'L' )
NEXT;
else
{
/* Optional fractional part on floats. */
if ( chr == '.' )
{
NEXT; /* Get first char of fraction. */
while ( isdigit( chr ) ) NEXT;
}
/* Optional exponent. */
if ( chr == 'e' || chr == 'E' )
{
NEXT; /* Get first char of exponent. */
/* Optional sign on exponent. */
if ( chr == '+' || chr == '-' ) NEXT;
while ( isdigit( chr ) ) NEXT; /* Exponent. */
}
}
}
/* Operators and single-character tokens for punctuation. */
else if( chr != EOF )
{
token_type = OTHER;
/* Dot may be either a leading decimal point on a number,
* or a structure access operator. We have a number if the
* following character is a digit.
*/
if ( chr == '.' )
{
NEXT;
if ( isdigit( chr ) )
goto number; /* Yep, leading decimal point. */
}
else /* Everything other than dots. */
{
/* Keep operator diphthongs contiguous. */
if ( index( op_diphthong_chars, chr ) != NULL )
while ( index( op_diphthong_chars, chr ) != NULL )
NEXT; /* Collect diphthong characters. */
else
NEXT; /* Single-character token. */
}
}
if ( token_trace )
fprintf( output, "type = %s, token = `",
token_type_strings[ (int)token_type ] );
/* Got a token in the buffer, pack it onto an output line. */
token_length = strlen( token );
if ( token_length + line_length > 77 ) /* Time for line break? */
{
fputs( "\n", output ); /* Line break. */
NEW_LINE; /* Start next line. */
}
/* Need to preserve blanks between symbols or numbers, and
* between operators next to = signs so they don't run together.
*/
else if ( (prev_token_type==SYMBOL || prev_token_type==NUMBER) &&
(token_type==SYMBOL || token_type==NUMBER) ||
token[0] == '=' && whitespace ) /* Space before =. */
{
fputs( " ", output );
line_length++;
}
/* Add token to the output stream. */
fputs( token, output );
line_length += token_length;
if ( token[token_length-1] == '=' && isspace( chr ) )
{
fputs( " ", output ); /* Space after = sign. */
line_length++;
}
if ( token_trace )
fprintf( output, "'\n" );
prev_token_type = token_type;
}
/* EOF. */
fputs( "\n", output ); /* End of line at end of file. */
if ( filter_mode )
exit( 0 ); /* Done. */
else
{
pclose( input );
fclose( output );
fr_hash_table( locals );
}
} /* Next file. */
}
/* Licensed material, Copyright (c) 1985, University of Utah. */
extern struct l1{int l2;char*l3;char*l4;int l5;short l6;char l7;}l8[];struct
l1*l9();struct l1*l10();struct l1*l11();struct l1*l12();long l13();char*l14()
;char*l15();char*l16();typedef char*l17;typedef int l18;typedef char l19;
typedef char*l20;extern l20 l21();extern long l22();typedef struct l23{int l24
;struct l23*l25,*l26;}l27;typedef struct l28{int l24;struct l28*l25,*l26;l27*
l29;}l28;typedef struct l30 l31;struct l30{int l24;l31*l25,*l26;l17 l32;l20
l33;};extern l31*l34();extern l31*l35();typedef struct{int l36;l31*l37[1];}
l38;extern l38*l39();extern l31**l40();extern l41();extern l42();typedef
unsigned char l43;typedef unsigned short l44;typedef unsigned int l45;typedef
unsigned long l46;typedef unsigned short l47;typedef struct l48{short l49[1];
}*l50;typedef struct l51{int l52[15];}l51;typedef struct l53{long l52[2];}l54
;typedef long l55;typedef char*l56;typedef long*l57;typedef l46 l58;typedef
long l59;typedef long l60;typedef long l61;typedef short l62;typedef long l63
;typedef l44 l64;typedef l44 l65;typedef l46 l66;typedef long l67;typedef
struct l68{l67 l69[(((256)+(((sizeof(l67)*8))-1))/((sizeof(l67)*8)))];}l68;
struct l70{l62 l71;l58 l72;unsigned short l73;short l74;l64 l75;l65 l76;l62
l77;l63 l78;l61 l79;int l80;l61 l81;int l82;l61 l83;int l84;long l85;long l86
;long l87[2];};extern char l88[];l17 l89[] = {"int","char","float","double",
"struct","union","enum","long","short","unsigned","auto","extern","register",
"typedef","static","goto","return","sizeof","break","continue","if","else",
"for","do","while","switch","case","default","entry","fortran","asm","main",
"void"};int l90 = sizeof l89/sizeof(l17);main(l91,l92)int l91;l17 l92[];{l18
l93 = 0,l94 = 0;int l95,l96,l97,l98,l99;l38*l100,*l101;l31*l102;l17*l103,*
l104,l105;static char l106[1024] = {'\0'};char l107[1024],l108[1024];struct
l70 l109;struct l1*l110,*l111,*l112,*l12();l62 l113;l58 l114;l17 l115,l116,
l117,l118();char l119,*l120,l121[1024],*l122,l123;int l124,l125;enum{l126,
l127,l128,l129,l130}l131,l132;static l17 l133[] = {"none","symbol","string",
"number","other"};l18 l134;l17 l135 = "=!<>&|+-*/%&^";int l136 = 0;static char
l137[5000][6];for(l95=0;l95<5000/1000;l95++)for(l96=0;l96<=9;l96++)for(l97=0;
l97<=9;l97++)for(l98=0;l98<=9;l98++){l120 = l137[l136++];*l120++ = 'l';if(l95
)*l120++ = '0'+l95;if(l95||l96)*l120++ = '0'+l96;if(l95||l96||l97)*l120++ =
'0'+l97;*l120++ = '0'+l98;*l120 = '\0';}l100 = l39(1000);for(l95=0,l103 = l89
;l95<l90;l95++,l103++)l34(*l103,l100);for(l99=1,l104 = &l92[1],l105 = *l104;
l99<l91;l99++,l104++,l105 = *l104){if(l105[0]!= '-')break;if(l138(l105,"-d")
== 0){if(++l99>= l91-1)break;l105 = *++l104;if((l110 = l9(l105,"r")) == 0){
l16(l107,"opqcp: Can't open dictionary %s\n",l105);l139(l107);l140(1);}while(
l14(l107,1024,l110)!= 0){l107[l141(l107)-1] = '\0';if((l117 = l118(l107,' '))
!= 0)*l117++ = '\0';l116 = (char*)l21(l141(l107)+1);l142(l116,l107);l102 =
l34(l116,l100);if(l117!= 0){l102->l33 = (char*)l21(l141(l117)+1);l142(l102->
l33,l117);}}l143(l110);}else if(l144(l105,"-I",2) == 0){l145(l106," ");l145(
l106,l105);}else if(l138(l105,"-t") == 0){l94 = 1;goto l146;}else if(l138(
l105,"-f") == 0){l146:l93 = 1;l111 = (&l8[0]);l112 = (&l8[1]);}else break;}if
(l105[0] == '-'||!l93&&l91-l99<2){l147((&l8[2]),"%s\n%s\n",
"usage: opqcp [-d dict]* [-Idir]* [srcfile]+ destdir",
" or opqcp [-d dict]* -f");l140(2);}if(!l93){if(l70(l115 = l92[l91-1],&
l109) == -1){l16(l107,"opqcp: Can't stat directory %s\n",l115);l139(l107);
l140(1);}if(!(l109.l73&0040000)){l147((&l8[2]),
"opqcp: %s is not a directory.\n",l115);l140(1);}}for(;l93||l99<l91-1;l99++,
l104++){if(l93)l105 = "(stdin)";else{l105 = *l104;if(l70(l105,&l109) == -1){
l16(l107,"opqcp: Can't stat input file %s\n",l105);l139(l107);continue;}if(!(
l109.l73&0100000)){l147((&l8[2]),"opqcp: %s is not a plain file.\n",l105);
continue;}l113 = l109.l71;l114 = l109.l72;l16(l107,"%s/%s",l115,l105);if(l70(
l107,&l109) == 0){if(l109.l71 == l113&&l109.l72 == l114){l147((&l8[2]),
"opqcp: Can't copy file %s to itself.\n",l105);continue;}if(!(l109.l73&
0100000)){l147((&l8[2]),"opqcp: %s is not a plain file.\n",l107);continue;}}
if((l112 = l9(l107,"w")) == 0){l16(l107,"opqcp: Can't write file %s",l105);
l139(l107);continue;}l148("/* Licensed material, Copyright ",l112);l148(
"(c) 1985, University of Utah. */\n",l112);l16(l108,"cc -E %s %s",l106,l105);
if((l111 = l12(l108,"r")) == 0){l16(l108,"opqcp: Couldn't start cpp on %s.",
l105);l139(l108);l143(l112);l149(l107);continue;}}l101 = l39(1000);l136 = 0;
l119 = '\n';(l125 = 0);l132 = l126;while(l119!= (-1)){(l122 = l121,*l122 =
'\0');l131 = l126;l134 = 0;while(((l88+1)[l119]&010)){l134 = 1;if(l119!= '\n'
)(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111)));
else{(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111)
));if(l119 == '#'){while(l119!= '\n'&&l119!= (-1))(l119 = (--(l111)->l2>=0?(
int)(*(unsigned char*)(l111)->l3++):l150(l111)));}}}if(((l88+1)[l119]&(01|02)
)||l119 == '_'){l131 = l127;((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)
->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));while(((l88+1)[
l119]&(01|02|04))||l119 == '_')((*l122++ = l119,*l122 = '\0'),(l119 = (--(
l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));if((l102 =
l35(l121,l100))!= 0){if(l102->l33!= 0){l142(l121,l102->l33);}}else{if((l102 =
l35(l121,l101)) == 0){l116 = (char*)l21(l141(l121)+1);l142(l116,l121);l102 =
l34(l116,l101);l102->l33 = l137[++l136];}l142(l121,l102->l33);}}else if(l119
== '"'||l119 == '\''){l131 = l128;l123 = l119;((*l122++ = l119,*l122 = '\0'),
(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));
while(l119!= l123){if(l119!= '\\')((*l122++ = l119,*l122 = '\0'),(l119 = (--(
l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));else{((*l122
++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111
)->l3++):l150(l111))));if(l123!= '"'||l119!= '\n')((*l122++ = l119,*l122 =
'\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111
))));else{((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(
unsigned char*)(l111)->l3++):l150(l111))));if(l141(l121)+l125>77)l148("\n",
l112);l148(l121,l112);(l125 = 0);(l122 = l121,*l122 = '\0');}}}((*l122++ =
l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3
++):l150(l111))));}else if(((l88+1)[l119]&04)){l151:l131 = l129;if(l119 ==
'0'){((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned
char*)(l111)->l3++):l150(l111))));if(l119 == 'x'||l119 == 'X'){((*l122++ =
l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3
++):l150(l111))));while(((l88+1)[l119]&04)||l119>= 'a'&&l119<= 'f'||l119>=
'A'&&l119<= 'F')((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)
(*(unsigned char*)(l111)->l3++):l150(l111))));}else while(((l88+1)[l119]&04))
((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char
*)(l111)->l3++):l150(l111))));}else while(((l88+1)[l119]&04))((*l122++ = l119
,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):
l150(l111))));if(l119 == 'l'||l119 == 'L')((*l122++ = l119,*l122 = '\0'),(
l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));
else{if(l119 == '.'){((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?
(int)(*(unsigned char*)(l111)->l3++):l150(l111))));while(((l88+1)[l119]&04))(
(*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*
)(l111)->l3++):l150(l111))));}if(l119 == 'e'||l119 == 'E'){((*l122++ = l119,*
l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):
l150(l111))));if(l119 == '+'||l119 == '-')((*l122++ = l119,*l122 = '\0'),(
l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));
while(((l88+1)[l119]&04))((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2
>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));}}}else if(l119!= (-1)
){l131 = l130;if(l119 == '.'){((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111
)->l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));if(((l88+1)[l119]
&04))goto l151;}else{if(l118(l135,l119)!= 0)while(l118(l135,l119)!= 0)((*l122
++ = l119,*l122 = '\0'),(l119 = (--(l111)->l2>=0?(int)(*(unsigned char*)(l111
)->l3++):l150(l111))));else((*l122++ = l119,*l122 = '\0'),(l119 = (--(l111)->
l2>=0?(int)(*(unsigned char*)(l111)->l3++):l150(l111))));}}if(l94)l147(l112,
"type = %s, token = `",l133[(int)l131]);l124 = l141(l121);if(l124+l125>77){
l148("\n",l112);(l125 = 0);}else if((l132==l127||l132==l129)&&(l131==l127||
l131==l129)||l121[0] == '='&&l134){l148(" ",l112);l125++;}l148(l121,l112);
l125+= l124;if(l121[l124-1] == '='&&((l88+1)[l119]&010)){l148(" ",l112);l125
++;}if(l94)l147(l112,"'\n");l132 = l131;}l148("\n",l112);if(l93)l140(0);else{
l152(l111);l143(l112);l42(l101);}}}
/* Licensed material, Copyright (c) 1985, University of Utah. */
typedef long unsigned int l1;
typedef l2 l3;
typedef unsigned char l4;
typedef unsigned short int l5;
typedef unsigned int l6;
typedef unsigned long int l7;
typedef l8 char l9;
typedef unsigned char l10;
typedef l8 short int l11;
typedef unsigned short int l12;
typedef l8 int l13;
typedef unsigned int l14;
typedef l8 long int l15;
typedef unsigned long int l16;
typedef l9 l17;
typedef l10 l18;
typedef l11 l19;
typedef l12 l20;
typedef l13 l21;
typedef l14 l22;
typedef l15
l23;
typedef l16 l24;
typedef long int l25;
typedef unsigned long int l26;
typedef long int l27;
typedef unsigned long int l28;
typedef unsigned long int
l29;
typedef unsigned int l30;
typedef unsigned int l31;
typedef unsigned long int l32;
typedef unsigned long int l33;
typedef unsigned int l34;
typedef unsigned long int l35;
typedef long int l36;
typedef long int l37;
typedef int
l38;
typedef struct
{
int l39[2];
} l40;
typedef long int l41;
typedef unsigned long int l42;
typedef unsigned long int l43;
typedef unsigned int l44;
typedef long int l45;
typedef unsigned int l46;
typedef long int l47;
typedef int l48;
typedef int l49;
typedef int l50;
typedef void *l51;
typedef long int l52;
typedef long int
l53;
typedef long int l54;
typedef unsigned long int l55;
typedef unsigned long int l56;
typedef unsigned long int l57;
typedef unsigned long int l58;
typedef long int l59;
typedef long int l60;
typedef long int l61;
typedef unsigned long int l62;
typedef l37 l63;
typedef char *l64;
typedef long int l65;
typedef unsigned int l66;
typedef int l67;
typedef struct
{
int l68;
union
{
unsigned int l69;
char l70
[4];
} l71;
} l72;
typedef struct l73
{
l36 l74;
l72 l75;
} l76;
typedef struct l77
{
l37
l74;
l72 l75;
} l78;
struct l79;
typedef struct l79 l80;
struct l79;
typedef struct
l79 l81;
struct l79;
struct l82;
struct l83;
struct l84;
typedef void l85;
struct
l79
{
int l86;
char *l87;
char *l88;
char *l89;
char *l90;
char *l91;
char *l92;
char *l93;
char *l94;
char *l95;
char *l96;
char *l97;
struct l82 *l98;
struct l79 *l99;
int l100;
int l101;
l36 l102;
unsigned short l103;
l8 char l104;
char l105[1];
l85 *l106;
l37
l107;
struct l83 *l108;
struct l84 *l109;
struct l79 *l110;
void *l111;
l1 l112;
int
l113;
char l114[15 * sizeof(int) - 4 * sizeof(void *) - sizeof(l1)];
};
typedef l3 l115;
typedef l36 l116;
typedef l60 l117;
typedef l76 l118;
extern l81 *l119;
extern l81
*l120;
extern l81 *l121;
extern int l122(l123 char *l124) l125((l126, l127));
extern int l128(l123 char *l129, l123 char *l130) l125((l126, l127));
extern int l131(int
l132,
l123 char *l129, int l133, l123 char *l130) l125((l126, l127));
extern l81 *l134(void);
extern char *l135(char *l136) l125((l126, l127));
extern char *l137(char *
l136) l125((l126, l127));
extern char *l138(l123 char *l139, l123 char *l140) l125((
l126, l127)) l125((l141));
extern int l142(l81 *l143);
extern int l144(l81 *l143);
extern int l145(l81 *l143);
extern l81 *l146(l123 char *l147 l124, l123 char *l147
l148);
extern l81 *l149(l123 char *l147 l124, l123 char *l147 l148, l81 *l147 l143);
extern l81 *l150(int l151, l123 char *l148) l125((l126, l127));
extern l81 *l152(
void *l136, l1 l153, l123 char *l148) l125((l126, l127));
extern l81 *l154(char **l155, l1 *l156) l125((l126, l127));
extern void l157(l81 *l147 l143, char *l147 l158) l125((l126, l127));
extern int l159(l81 *l147 l143, char *l147 l158, int l148, l1 l160)
l125((l126, l127));
extern void l161(l81 *l147 l143, char *l147 l158, l1 l162) l125(
(l126, l127));
extern void l163(l81 *l143) l125((l126, l127));
extern int l164(l81 *
l147 l143,
l123 char *l147 l165, ...);
extern int l166(l123 char *l147 l165, ...);
extern int l167(char *l147 l136, l123 char *l147 l165, ...) l125((l126));
extern int
l168(l81 *l147 l136, l123 char *l147 l165, l3 l169);
extern int l170(l123 char *
l147 l165,
l3 l169);
extern int l171(char *l147 l136, l123 char *l147 l165, l3 l169) l125((l126));
extern int l172(char *l147 l136, l1 l173, l123 char *l147 l165, ...)
l125((l126)) l125((l174(l175, 3, 4)));
extern int l176(char *l147 l136, l1 l173,
l123 char *l147 l165, l3 l169) l125((l126)) l125((l174(l175, 3, 0)));
extern int l177(int l151, l123 char *l147 l178, l3 l169) l125((l174(l175, 2, 0)));
extern int l179(
int l151, l123 char *l147 l178, ...) l125((l174(l175, 2, 3)));
extern int l180(l81 *
l147 l143,
l123 char *l147 l165, ...);
extern int l181(l123 char *l147 l165, ...);
extern int l182(l123 char *l147 l136, l123 char *l147 l165, ...) l125((l126, l127));
extern int l180(l81 *l147 l143, l123 char *l147 l165, ...) l183(""
"__isoc99_fscanf");
extern int l181(l123 char *l147 l165, ...) l183(""
"__isoc99_scanf");
extern int l182(l123 char *l147 l136, l123 char *l147 l165, ...) l183(""
"__isoc99_sscanf") l125((l126, l127));
extern int l184(l81 *l147 l136,
l123 char *l147 l165, l3 l169) l125((l174(l185, 2, 0)));
extern int l186(l123 char *
l147 l165,
l3 l169) l125((l174(l185, 1, 0)));
extern int l187(l123 char *l147 l136,
l123 char *l147 l165, l3 l169) l125((l126, l127)) l125((l174(l185, 2, 0)));
extern int
l184(l81 *l147 l136, l123 char *l147 l165, l3 l169) l183(""
"__isoc99_vfscanf") l125((l174(l185, 2, 0)));
extern int l186(l123 char *l147 l165, l3 l169) l183(""
"__isoc99_vscanf") l125((l174(l185, 1, 0)));
extern int l187(l123 char *l147 l136,
l123 char *l147 l165, l3 l169) l183(""
"__isoc99_vsscanf") l125((l126, l127)) l125((l174(l185, 2, 0)));
extern int l188(l81 *l143);
extern int l189(l81 *l143);
extern int l190(void);
extern int l191(l81 *l143);
extern int l192(void);
extern int l193(l81 *l143);
extern int l194(int l195, l81 *l143);
extern int l196(int l195, l81 *
l143);
extern int l197(int l195);
extern int l198(int l195, l81 *l143);
extern int
l199(int l195, l81 *l143);
extern int l200(int l195);
extern int l201(l81 *l143);
extern int l202(int l203, l81 *l143);
extern char *l204(char *l147 l136, int l160,
l81 *l147 l143);
extern l60 l205(char **l147 l206, l1 *l147 l160, int l207, l81 *l147 l143);
extern l60 l208(char **l147 l206, l1 *l147 l160, int l207, l81 *l147 l143);
extern l60 l209(char **l147 l206, l1 *l147 l160, l81 *l147 l143);
extern int l210(
l123 char *l147 l136, l81 *l147 l143);
extern int l211(l123 char *l136);
extern int
l212(int l195, l81 *l143);
extern l1 l213(void *l147 l214, l1 l162, l1 l160, l81 *l147 l143);
extern l1 l215(l123 void *l147 l214, l1 l162, l1 l160, l81 *l147 l136);
extern l1 l216(void *l147 l214, l1 l162, l1 l160, l81 *l147 l143);
extern l1 l217(
l123 void *l147 l214, l1 l162, l1 l160, l81 *l147 l143);
extern int l218(l81 *l143,
long int l219, int l220);
extern long int l221(l81 *l143);
extern void l222(l81 *
l143);
extern int l223(l81 *l143, l36 l219, int l220);
extern l36 l224(l81 *l143);
extern int l225(l81 *l147 l143, l118 *l147 l74);
extern int l226(l81 *l143, l123
l118 *l74);
extern void l227(l81 *l143) l125((l126, l127));
extern int l228(l81 *
l143) l125((l126, l127));
extern int l229(l81 *l143) l125((l126, l127));
extern void
l230(l81 *l143) l125((l126, l127));
extern int l231(l81 *l143) l125((l126, l127));
extern int l232(l81 *l143) l125((l126, l127));
extern void l233(l123 char *l136);
extern int l234;
extern l123 char *l123 l235[];
extern int l236(l81 *l143) l125((
l126, l127));
extern int l237(l81 *l143) l125((l126, l127));
extern l81 *l238(l123 char *l239, l123 char *l148);
extern int l240(l81 *l143);
extern char *l241(char *
l136) l125((l126, l127));
extern void l242(l81 *l143) l125((l126, l127));
extern int
l243(l81 *l143) l125((l126, l127));
extern void l244(l81 *l143) l125((l126, l127));
extern int l245(l81 *);
extern int l246(l81 *, int);
typedef char *l247;
typedef int
l248;
typedef char l249;
typedef char *l250;
extern l250 l251();
extern long l252();
typedef union
{
long l253;
double l254;
} l255;
extern char *l256();
l250 l251(l257) int l257;
{
l255 *l258;
if ((l258 = (l255 *)l256((unsigned)(l257 + sizeof(l255)))) <=
0)
{
l164(l121, "\nNo Space in heap! %d bytes requested.\n", l257);
l259(-1);
}
l258
->l253 = (long)l257;
return (l250)(l258 + 1);
}
long l252(l260) l250 l260;
{
return ((
l255 *)l260 -
1)
->l253;
}
l261(l260) l250 l260;
{
if (l260)
l262((char *)((l255 *)l260 - 1));
}
/*
* symtab.c - Symbol Table package routines.
* ( Descriptions in file symtab.h .)
*
* Author: Russ Fish
* Computer Science Dept.
* University of Utah
* Date: 3 September 1981
*/
#include "misc.h"
#include "symtab.h"
/*****************************************************************
* TAG( new_symbol )
*/
id * /* Constructor. */
new_symbol( sym_name, table )
string sym_name;
hash_table * table;
{
id * ret, * * slot;
/* Allocate id node and link into symbol table at hashed location. */
ret = NEW_1( id );
slot = hash( sym_name, table );
ADD( ret, *slot );
ret->var_name = sym_name; /* Link to name string from id. */
ret->var_value = NULL; /* No value cell or fn ptr yet. */
return( ret );
}
/*****************************************************************
* TAG( find_symbol )
*/
id * /* Locator, NULL if not found. */
find_symbol( sym_name, table )
string sym_name;
hash_table * table;
{
register id * sym; /* Symbol list traversal ptr. */
/* Search list to which symbol hashes. */
TRACE( sym, *hash( sym_name, table ) )
{
/* Break out of search loop when matching name is found. */
if ( strcmp( sym_name, sym->var_name ) == 0 ) break;
} /* sym is NULL if trace loop exits. */
return( sym );
}
/*****************************************************************
* TAG( new_hash_table )
*/
hash_table * /* Constructor. */
new_hash_table( n_entries )
int n_entries;
{
hash_table * ret;
id ** ent; /* Entries of table are bases of id lists. */
int i;
ret = NEW( hash_table, sizeof( hash_table ) + n_entries * sizeof( id * ) );
ret->hash_size = n_entries; /* Remember the size, for hash comp. */
for ( i = 0, ent = & ret->hash_id[0]; /* Clear the entries. */
i < n_entries;
i++ )
*ent++ = NULL; /* Empty list pointers. */
return( ret );
}
/*****************************************************************
* TAG( hash )
*/
id * * /* Hashing algorithm, returns ptr to base of an id list in table. */
hash( sym_name, table )
string sym_name;
hash_table * table;
{
register char * c;
register int i, n, hash_val;
/* Hash is the total of the character codes, modulo number of entries. */
for ( i = 0, n = strlen( sym_name ), c = (char *)sym_name, hash_val = 0;
i < n;
i++ )
hash_val += *c++;
return( & table->hash_id[ hash_val % table->hash_size ] );
}
/*****************************************************************
* TAG( ld_table )
*
* Links a vector of already initialiazed id's into a hash table.
* NULL var_name terminates the vector.
*/
ld_table( id_vec, table )
id id_vec[];
hash_table * table;
{
id * sym; /* Vector traversal ptr. */
id * * slot;
for ( sym = & id_vec[0]; sym->var_name != NULL; sym++ )
{
/* Link id node into symbol table at hashed location. */
slot = hash( sym->var_name, table );
ADD( sym, *slot );
}
}
/*****************************************************************
* TAG( fr_hash_table )
*
* Dispose of a hash table.
*/
fr_hash_table( table )
hash_table * table;
{
id ** ent; /* Entries of table are bases of id lists. */
id * ids;
int i;
for ( i = 0, ent = & table->hash_id[0]; /* Clear the entries. */
i < table->hash_size;
i++, ent++ )
if ( ids = *ent )
FREE_LIST( ids );
FREE( table );
}
/*
* symtab.h - Declarations for using Symbol Table package.
*
* Author: Russ Fish
* Computer Science Dept.
* University of Utah
* Date: 28 August 1981
*/
/*****************************************************************
* TAG( symtab )
*
* Simple symbol table package. Hash on name string gives buckets within
* hash table, which are bases of lists of id's, rather than reprobing
* within table. Multiple dictionaries are supported.
*/
#ifndef _SYM_TAB /* Only once. */
#define _SYM_TAB
#include "list.h" /* Needs list package. */
/*****************************************************************
* TAG( id )
*
* id - Identifier datatype.
*/
typedef struct _id id;
struct _id
{
TLISTLINKS(id); /* Linked lists within hash buckets. */
string var_name; /* Character string name of id. */
address var_value; /* Ptr to value of variable id. */
};
/*****************************************************************
* TAG( new_symbol find_symbol )
*/
extern id *
new_symbol(); /* Constructor. */
/* ( sym_name, table )
* string sym_name;
* hash_table * table;
*/
extern id *
find_symbol(); /* Locator, NULL if not found. */
/* ( sym_name, table )
* string sym_name;
* hash_table * table;
*/
/*****************************************************************
* TAG( hash_table new_hash_table hash )
*
* Datatype for hash dictionaries.
*/
typedef struct
{
int hash_size; /* Number of entries in table. */
id * hash_id[1]; /* Base of id list on entry. */
}
hash_table;
extern hash_table *
new_hash_table(); /* Constructor, returns cleared table. */
/* ( n_entries )
* int n_entries;
*/
extern id * *
hash(); /* Hashing algorithm, returns ptr to base of an id list in table. */
/* ( sym_name, table )
* string sym_name;
* hash_table * table;
*/
/*****************************************************************
* TAG( ld_table )
*
* Links a vector of already initialiazed id's into a hash table.
* NULL var_name terminates the vector.
*/
extern
ld_table();
/* ( id_vec, table )
* id id_vec[];
* hash_table * table;
*/
/*****************************************************************
* TAG( fr_hash_table )
*
* Dispose of a hash table.
*/
extern
fr_hash_table();
/* ( table )
* hash_table * table;
*/
/* Macros to aid in initializing symbol vectors. */
#define NULLS NULL,NULL
#define VAR_SYM(name_string,var_name) { NULLS, name_string,&var_name, NULL }
#define FN_SYM(name_string,fn_name) { NULLS, name_string, NULL, fn_name }
#endif _SYM_TAB
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment