⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc3.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			}			    /*			     *	something is wrong			     *	if it's not resolved, use the header file			     *	otherwise, it's just a regular error			     */			if ( symbolp -> sym_un.sym_str.rfilep == NIL ) {			    error( ERROR ,		    "%s, line %d: %s is already defined\n\t(%s, line %d)." ,				ifilep -> name , nlp -> n_value , 				nlp -> n_un.n_name , 				symbolp -> sym_un.sym_str.fromi -> name ,				symbolp -> sym_un.sym_str.iline );			    return;			}			break;		case N_PGFUNC:		case N_PGPROC:			    /*			     *	functions may not be seen more than once.			     *	the loader will complain about			     *	`multiply defined', but we can, too.			     */			break;		case N_PGLABEL:		case N_PGCONST:		case N_PGTYPE:		case N_PGVAR:			    /*			     *	labels, constants, types, variables			     *	and external declarations			     *	may be seen as many times as they want,			     *	as long as they come from the same include file.			     *	make it look like they come from this .p file.			     */included:			if (  nlp -> n_desc != symbolp -> desc			   || symbolp -> sym_un.sym_str.fromi != ifilep ) {			    break;			}			symbolp -> fromp = pfilep;			return;		case N_PLDATA:		case N_PLTEXT:			switch ( nlp -> n_desc ) {			    default:				error( FATAL , "pc3: unknown stab 0x%x"					, nlp -> n_desc );				return;			    case N_PSO:			    case N_PSOL:			    case N_PGCONST:			    case N_PGTYPE:				/* these won't conflict with library */				return;			    case N_PGLABEL:			    case N_PGVAR:			    case N_PGFUNC:			    case N_PGPROC:			    case N_PEFUNC:			    case N_PEPROC:			    case N_PLDATA:			    case N_PLTEXT:				errtype = WARNING;				break;			}			break;	    }		/*		 *	this is the breaks		 */	    error( errtype		, "%s, line %d: %s %s is already defined\n\t%s%s (%s, line %d)."		, ifilep -> name		, nlp -> n_value		, classify( nlp -> n_desc )		, nlp -> n_un.n_name		, ( symbolp -> desc == nlp -> n_desc ? "" : " as " )		, ( symbolp -> desc == nlp -> n_desc			? "" : article( symbolp -> desc ) )		, symbolp -> sym_un.sym_str.rfilep -> name		, symbolp -> sym_un.sym_str.rline );	}    }    /*     *	quadratically hashed symbol table.     *	things are never deleted from the hash symbol table.     *	as more hash table is needed,     *	a new one is alloc'ed and chained to the end.     *	search is by rehashing within each table,     *	traversing chains to next table if unsuccessful.     */struct symbol *entersymbol( name )    char	*name;    {	static struct symboltableinfo	symboltable;	char				*enteredname;	long				hashindex;	register struct symboltableinfo	*tablep;	register struct symbol		**herep;	register struct symbol		**limitp;	register long			increment;	enteredname = enterstring( name );	hashindex = SHORT_ABS( ( long ) enteredname ) % SYMBOLPRIME;	for ( tablep = &symboltable ; /*return*/ ; tablep = tablep -> chain ) {	    if ( tablep == NIL ) {#		ifdef SPACEDEBUG		    fprintf( stderr ,			    "[entersymbol] calloc'ing table for %d symbols\n" , 			    SYMBOLPRIME );#		endif SPACEDEBUG		for ( tablep = &symboltable		    ; tablep->chain != NIL		    ; tablep = tablep->chain ) {			continue;		}		tablep->chain = ( struct symboltableinfo * )			    calloc( 1 , sizeof ( struct symboltableinfo ) );		if ( tablep->chain == NIL ) {		    error( FATAL , "ran out of memory (entersymbol)" );		}		tablep = tablep->chain;	    }	    herep = &( tablep -> entry[ hashindex ] );	    limitp = &( tablep -> entry[ SYMBOLPRIME ] );	    increment = 1;	    do {		if ( *herep == NIL ) {			/* empty */		    if ( tablep -> used > ( ( SYMBOLPRIME / 4 ) * 3 ) ) {			    /* too full, break for next table */			break;		    }		    tablep -> used++;		    *herep = symbolalloc();		    ( *herep ) -> name = enteredname;		    ( *herep ) -> lookup = NEW;#		    ifdef HASHDEBUG			fprintf( stderr ,				"[entersymbol] name %s NEW after %d\n" ,				enteredname , increment / 2 );#		    endif HASHDEBUG		    return *herep;		}		    /* a find? */		if ( ( *herep ) -> name == enteredname ) {		    ( *herep ) -> lookup = OLD;#		    ifdef HASHDEBUG			fprintf( stderr , "[entersymbol] name %s OLD at %d\n" ,				enteredname , increment / 2 );#		    endif HASHDEBUG		    return *herep;		}		herep += increment;		if ( herep >= limitp ) {		    herep -= SYMBOLPRIME;		}		increment += 2;	    } while ( increment < SYMBOLPRIME );#	    ifdef HASHDEBUG		fprintf( stderr , "[entersymbol] next symboltable\n" );#	    endif HASHDEBUG	}    }    /*     *	allocate a symbol from the dynamically allocated symbol table.     */struct symbol *symbolalloc()    {	static struct symbol	*nextsymbol = NIL;	static long		symbolsleft = 0;	struct symbol		*newsymbol;	if ( symbolsleft <= 0 ) {#	    ifdef SPACEDEBUG		fprintf( stderr ,			"[symbolalloc] malloc space for %d symbols\n" ,			SYMBOLALLOC / sizeof( struct symbol ) );#	    endif SPACEDEBUG	    nextsymbol = ( struct symbol * ) malloc( SYMBOLALLOC );	    if ( nextsymbol == 0 ) {		error( FATAL , "ran out of memory (symbolalloc)" );	    }	    symbolsleft = SYMBOLALLOC / sizeof( struct symbol );	}	newsymbol = nextsymbol;	nextsymbol++;	symbolsleft--;	return newsymbol;    }    /*     *	hash a string based on all of its characters.     */longhashstring( string )    char	*string;    {	register char	*cp;	register long	value;	value = 0;	for ( cp = string ; *cp ; cp++ ) {	    value = ( value * 2 ) + *cp;	}	return value;    }    /*     *	quadratically hashed string table.     *	things are never deleted from the hash string table.     *	as more hash table is needed,     *	a new one is alloc'ed and chained to the end.     *	search is by rehashing within each table,     *	traversing chains to next table if unsuccessful.     */char *enterstring( string )    char	*string;    {	static struct stringtableinfo	stringtable;	long				hashindex;	register struct stringtableinfo	*tablep;	register char			**herep;	register char			**limitp;	register long			increment;	hashindex = SHORT_ABS( hashstring( string ) ) % STRINGPRIME;	for ( tablep = &stringtable ; /*return*/ ; tablep = tablep -> chain ) {	    if ( tablep == NIL ) {#		ifdef SPACEDEBUG		    fprintf( stderr ,			    "[enterstring] calloc space for %d strings\n" ,			    STRINGPRIME );#		endif SPACEDEBUG		for ( tablep = &stringtable		    ; tablep->chain != NIL		    ; tablep = tablep->chain ) {			continue;		}		tablep->chain = ( struct stringtableinfo * )			    calloc( 1 , sizeof ( struct stringtableinfo ) );		if ( tablep->chain == NIL ) {		    error( FATAL , "ran out of memory (enterstring)" );		}		tablep = tablep->chain;	    }	    herep = &( tablep -> entry[ hashindex ] );	    limitp = &( tablep -> entry[ STRINGPRIME ] );	    increment = 1;	    do {		if ( *herep == NIL ) {			/* empty */		    if ( tablep -> used > ( ( STRINGPRIME / 4 ) * 3 ) ) {			    /* too full, break for next table */			break;		    }		    tablep -> used++;		    *herep = charalloc( strlen( string ) );		    strcpy( *herep , string );#		    ifdef HASHDEBUG			fprintf( stderr ,				"[enterstring] string %s copied after %d\n" , 				*herep , increment / 2 );#		    endif HASHDEBUG		    return *herep;		}		    /* quick, check the first chars and then the rest */		if ( **herep == *string && strcmp( *herep , string ) == 0 ) {#		    ifdef HASHDEBUG			fprintf( stderr ,				"[enterstring] string %s found after %d\n" ,				*herep , increment / 2 );#		    endif HASHDEBUG		    return *herep;		}		herep += increment;		if ( herep >= limitp ) {		    herep -= STRINGPRIME;		}		increment += 2;	    } while ( increment < STRINGPRIME );#	    ifdef HASHDEBUG		fprintf( stderr , "[enterstring] next stringtable\n" );#	    endif HASHDEBUG	}    }    /*     *	copy a string to the dynamically allocated character table.     */char *charalloc( length )    register long	length;    {	static char	*nextchar = NIL;	static long	charsleft = 0;	register long	lengthplus1 = length + 1;	register long	askfor;	char		*newstring;	if ( charsleft < lengthplus1 ) {	    askfor = lengthplus1 > CHARALLOC ? lengthplus1 : CHARALLOC;#	    ifdef SPACEDEBUG		fprintf( stderr , "[charalloc] malloc space for %d chars\n" 			, askfor );#	    endif SPACEDEBUG	    nextchar = ( char * ) malloc( askfor );	    if ( nextchar == 0 ) {		error( FATAL , "no room for %d characters" , askfor );	    }	    charsleft = askfor;	}	newstring = nextchar;	nextchar += lengthplus1;	charsleft -= lengthplus1;	return newstring;    }    /*     *	read an archive header for the next element     *	and find the offset of the one after this.      */BOOLnextelement( ofilep )    struct fileinfo	*ofilep;    {	register char	*cp;	register long	red;	register off_t	arsize;	struct ar_hdr	archdr;	fseek( ofilep -> file , ofilep -> nextoffset , 0 );	red = fread( (char *) &archdr , 1 , sizeof archdr , ofilep -> file );	if ( red != sizeof archdr ) {	    return FALSE;	}	    /* null terminate the blank-padded name */	cp = &archdr.ar_name[ ( sizeof archdr.ar_name ) - 1 ];	*cp = '\0';	while ( *--cp == ' ' ) {	    *cp = '\0';	}	    /* set up the address of the beginning of next element */	arsize = atol( archdr.ar_size );	    /* archive elements are aligned on 0 mod 2 boundaries */	if ( arsize & 1 ) {	    arsize += 1;	}	ofilep -> nextoffset = ftell( ofilep -> file ) + arsize;	    /* say we had one */	return TRUE;    }    /*     *	variable number of arguments to error, like printf.     */error( type , message , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 )    int		type;    char	*message;    {	errors = type > errors ? type : errors;	if ( wflag && type == WARNING ) {	    return;	}	fprintf( stderr , "%s: " , program );	switch ( type ) {	    case WARNING:		    fprintf( stderr , "Warning: " );		    break;	    case ERROR:		    fprintf( stderr , "Error: " );		    break;	    case FATAL:		    fprintf( stderr , "Fatal: " );		    break;	    default:		    fprintf( stderr , "Ooops: " );		    break;	}	fprintf( stderr , message , arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 );	fprintf( stderr , "\n" );	if ( type == FATAL ) {	    exit( FATAL );	}    }char *classify( type )    unsigned char	type;    {	switch ( type ) {	    case N_PSO:		return "source file";	    case N_PSOL:		return "include file";	    case N_PGLABEL:		return "label";	    case N_PGCONST:		return "constant";	    case N_PGTYPE:		return "type";	    case N_PGVAR:		return "variable";	    case N_PGFUNC:		return "function";	    case N_PGPROC:		return "procedure";	    case N_PEFUNC:		return "external function";	    case N_PEPROC:		return "external procedure";	    case N_PLDATA:		return "library variable";	    case N_PLTEXT:		return "library routine";	    default:		return "unknown symbol";	}    }char *article( type )    unsigned char	type;    {	switch ( type ) {	    case N_PSO:		return "a source file";	    case N_PSOL:		return "an include file";	    case N_PGLABEL:		return "a label";	    case N_PGCONST:		return "a constant";	    case N_PGTYPE:		return "a type";	    case N_PGVAR:		return "a variable";	    case N_PGFUNC:		return "a function";	    case N_PGPROC:		return "a procedure";	    case N_PEFUNC:		return "an external function";	    case N_PEPROC:		return "an external procedure";	    case N_PLDATA:		return "a library variable";	    case N_PLTEXT:		return "a library routine";	    default:		return "an unknown symbol";	}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -