📄 pchdr.c
字号:
int index;
struct array_info *array;
union parmtype {
TYPEPTR parm_typ;
int type_index;
} *parm_list;
InitTypeHashTables();
typ = (TYPEPTR)p;
TypeArray = typ - 1;
while( type_count != 0 ) {
if( typ->decl_type == TYPE_FUNCTION ) break;
if( typ->object_index != 0 ) {
typ->object = &TypeArray[ typ->object_index ];
}
if( typ->decl_type == TYPE_ARRAY ) {
array = (struct array_info *)CMemAlloc(sizeof(struct array_info));
array->dimension = typ->u.array_dimension;
typ->u.array = array;
}
AddTypeHash( typ );
++typ;
--type_count;
}
parm_list = (union parmtype *)(typ + type_count);
while( type_count != 0 ) {
index = typ->u.parm_index;
typ->next_type = FuncTypeHead[ index ];
FuncTypeHead[ index ] = typ;
if( typ->object_index != 0 ) {
typ->object = &TypeArray[ typ->object_index ];
}
if( parm_list->type_index == -1 ) {
typ->u.parms = NULL;
} else {
typ->u.parms = (TYPEPTR *)parm_list;
for(;;) {
index = parm_list->type_index;
if( index == -1 ) break;
parm_list->parm_typ = TypeArray + index;
parm_list++;
}
parm_list->parm_typ = NULL;
}
parm_list++;
++typ;
--type_count;
}
FixupTypeIndexes( (struct type_indices *)parm_list );
return( (char *)parm_list + sizeof(struct type_indices) );
}
static char *FixupEnums( char *p, TAGPTR parent )
{
ENUMPTR ep;
for(;;) {
ep = (ENUMPTR)p;
p += ep->enum_len;
ep->parent = parent; // parent is union'ed with enum_len
ep->next_enum = EnumTable[ ep->hash ];
EnumTable[ ep->hash ] = ep;
if( ep->thread == NULL ) break;
ep->thread = (ENUMPTR)p;
}
return( p );
}
static char *FixupFields( char *p )
{
FIELDPTR field;
int len;
for(;;) {
field = (FIELDPTR)p;
field->field_type = TypeArray + field->field_type_index;
len = field->field_len;
p += len;
field->next_field = (FIELDPTR)p;
if( len < 0 ) break;
}
field->next_field = NULL;
p -= len + len;
return( p );
}
static void FixupTag( TYPEPTR typ )
{
switch( typ->decl_type ) {
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENUM:
typ->u.tag = TagArray[ typ->u.tag_index ];
break;
default:
break;
}
}
static void FixupTagPointers()
{
WalkTypeList( FixupTag );
}
static char *FixupTags( char *p, unsigned tag_count )
{
TAGPTR tag;
TAGPTR prevtag;
TAGPTR nexttag;
TYPEPTR typ;
unsigned len;
if( tag_count != 0 ) {
TagArray = (TAGPTR *)CMemAlloc( tag_count * sizeof(TAGPTR) );
}
tag = NULL;
prevtag = NULL;
while( tag_count != 0 ) {
tag = (TAGPTR)p;
TagArray[ tag->tag_index ] = tag;
typ = TypeArray + tag->sym_type_index;
tag->sym_type = typ;
len = strlen( tag->name ) + sizeof(TAGDEFN);
len = (len + (sizeof(int) - 1)) & - sizeof(int);
p += len;
if( typ->decl_type == TYPE_ENUM ) {
if( tag->u.enum_list != NULL ) {
tag->u.enum_list = (ENUMPTR)p;
p = FixupEnums( p, tag );
}
} else {
if( tag->u.field_list != NULL ) {
tag->u.field_list = (FIELDPTR)p;
p = FixupFields( p );
}
}
tag->next_tag = prevtag;
prevtag = tag;
--tag_count;
}
for( tag = prevtag; tag; tag = nexttag ) {
nexttag = tag->next_tag;
tag->next_tag = TagHash[ tag->hash ];
TagHash[ tag->hash ] = tag;
}
FixupTagPointers();
return( p );
}
#if _MACHINE == _PC
static char *FixupAuxInfo( char *p, struct aux_info *info )
{
unsigned len;
unsigned codelen;
p += sizeof( struct aux_info );
len = info->parms_size;
if( len != 0 ) {
info->parms = (hw_reg_set *)p;
p += len;
}
len = info->objname_size;
if( len != 0 ) {
info->objname = (char *)p;
p += len;
}
codelen = info->code_size;
if( codelen != 0 ) {
info->code = (byte_seq *)p;
p += codelen;
}
len += codelen;
p += ((len + (sizeof(int) - 1)) & - sizeof(int)) - len;
return( p );
}
static char *FixupPragmaInfo( char *p, unsigned pragma_count )
{
struct aux_entry *ent;
struct aux_info *info;
struct aux_info **info_array;
int index;
unsigned len;
for( index = 0; (info = BuiltinInfos[index]); ++index ) {
memcpy( info, p, sizeof(struct aux_info) );
p = FixupAuxInfo( p, info );
}
if( pragma_count == 0 ) return( p );
info_array = (struct aux_info **)
CMemAlloc( pragma_count * sizeof(struct aux_info *) );
index = 0;
while( pragma_count != 0 ) {
info = (struct aux_info *)p;
info_array[index++] = info;
p = FixupAuxInfo( p, info );
--pragma_count;
}
AuxList = (struct aux_entry *)p;
for(;;) {
ent = (struct aux_entry *)p;
len = sizeof( struct aux_entry ) + strlen( ent->name );
len = (len + (sizeof(int) - 1)) & - sizeof(int);
p += len;
ent->info = info_array[ ent->aux_info_index ];
if( ent->next == NULL ) break;
ent->next = (struct aux_entry *)p;
}
CMemFree( info_array );
return( p );
}
#endif
void FixupFNames( void ){
FNAMEPTR *lnk;
FNAMEPTR flist;
lnk = &FNames;
while( (flist = *lnk) != NULL ){
lnk = &flist->next;
}
*lnk = FNameList;
}
int ValidHeader( struct pheader *pch )
{
if( pch->signature == PCH_SIGNATURE &&
pch->version == PCH_VERSION &&
pch->size_of_header == sizeof(struct pheader) &&
pch->size_of_int == TARGET_INT &&
pch->specialsyms_count == SpecialSyms &&
pch->pack_amount == PackAmount ) {
return( 1 );
}
return( 0 ); // indicate unusable pre-compiled header
}
int LoadPreCompiledHeader( char *p, struct pheader *pch )
{
int rc;
rc = FixupDataStructures( p, pch );
CMemFree( TagArray );
CMemFree( TextSegArray );
CMemFree( PCHMacroHash );
return( rc );
}
static int FixupDataStructures( char *p, struct pheader *pch )
{
p = FixupLibrarys( p, pch->library_count );
p = FixupSegInfo( p, pch->seg_count );
p = FixupTypes( p, pch->type_count );
p = FixupTags( p, pch->tag_count );
#if _MACHINE == _PC
p = FixupPragmaInfo( p, pch->pragma_count );
#endif
p = FixupSymHashTable( p, pch->symhash_count );
p = FixupSymbols( p, pch->symbol_count );
if( pch->msgflags_len != 0 ) { /* 06-jul-94 */
MsgFlags = p;
p += pch->msgflags_len;
}
PCH_MaxSymHandle = pch->symbol_count;
NextSymHandle = pch->symbol_count - 1;
IncLineCount = pch->incline_count;
Toggles = pch->toggles;
FixupFNames();
InitDebugTypes();
InitDebugTags();
return( 0 );
}
int SameCWD( char *p )
{
char *cwd;
int same;
char buf[_MAX_PATH];
cwd = getcwd( buf, _MAX_PATH );
same = strcmp( cwd, p );
return( same == 0 );
}
void FreePreCompiledHeader( void ){
FEfree( PCH_Start );
FEfree( PCH_Macros );
FEfree( PCH_SymArray );
}
void AbortPreCompiledHeader( void )
{
FreePreCompiledHeader();
CMemFree( TagArray );
CMemFree( TextSegArray );
CMemFree( PCHMacroHash );
PCH_Start = NULL;
PCH_End = NULL;
PCH_Macros = NULL;
PCH_SymArray = NULL;
PCH_MaxSymHandle = 0;
TagArray = NULL;
TextSegArray = NULL;
FNameList = NULL;
IncFileList = NULL;
PCHMacroHash = NULL;
CompFlags.make_precompiled_header = 1; // force new PCH to be created
}
//========================================================================
// This portion of the code checks to see if we can use the
// existing pre-compiled header.
// - all the predefined macros have the same definition
// - all the include files are the same and have not been modified
//========================================================================
int UsePreCompiledHeader( char *filename )
{
int handle;
unsigned len;
char *p;
struct pheader pch;
handle = sopen( PCH_FileName, O_RDONLY|O_BINARY, SH_DENYWR );
if( handle == -1 ) {
CompFlags.make_precompiled_header = 1;
return( -1 );
}
PCH_Start = NULL;
TextSegArray = NULL;
TagArray = NULL;
PCHMacroHash = NULL;
len = read( handle, &pch, sizeof(struct pheader) );
if( len != sizeof(struct pheader) ) {
close( handle );
PCHNote( PCHDR_READ_ERROR );
AbortPreCompiledHeader();
return( -1 );
}
if( !ValidHeader( &pch ) ) {
close( handle );
PCHNote( PCHDR_INVALID_HEADER );
AbortPreCompiledHeader();
return( -1 );
}
if( pch.gen_switches != GenSwitches ||
pch.target_switches != TargetSwitches ) {
close( handle );
PCHNote( PCHDR_DIFFERENT_OPTIONS );
AbortPreCompiledHeader();
return( -1 );
}
p = FEmalloc( pch.size ); // allocate big memory block
PCH_Start = p;
PCH_End = p + pch.size;
PH_size = read( handle, p, pch.size ); // read rest of the file
PCH_Macros = FEmalloc( pch.macro_size );
len = read( handle, PCH_Macros, pch.macro_size );
close( handle );
PCH_SymArray = (SYMPTR *)FEmalloc( pch.symbol_count * sizeof(SYMPTR) );
if( PH_size != pch.size || len != pch.macro_size ) {
PCHNote( PCHDR_READ_ERROR );
AbortPreCompiledHeader();
return( -1 );
}
if( ! SameCWD( p ) ) {
PCHNote( PCHDR_DIFFERENT_CWD );
AbortPreCompiledHeader();
return( -1 );
}
p = FixupIncludes( p + pch.cwd_len, pch.file_count );
p = FixupRoDirList( p, pch.rdir_count );
if( VerifyIncludes() ){
AbortPreCompiledHeader();
return( -1 );
}
len = strlen( p ) + 1; // get length of saved HFileList
len = (len + sizeof(int) - 1) & - sizeof(int);
if((( HFileList == NULL ) && ( strlen( p ) > 0 ))
|| (( HFileList != NULL ) && ( strcmp( p, HFileList ) != 0 ))) {
PCHNote( PCHDR_INCFILE_DIFFERENT );
AbortPreCompiledHeader();
return( -1 );
}
p = FixupIncFileList( p + len, pch.incfile_count );
if( strcmp( filename, IncFileList->filename ) != 0 ) {
PCHNote( PCHDR_INCPATH_CHANGED );
AbortPreCompiledHeader();
return( -1 ); // can't use PCH
}
if( VerifyMacros(PCH_Macros,pch.macro_count,pch.undef_macro_count) != 0) {
PCHNote( PCHDR_MACRO_CHANGED );
AbortPreCompiledHeader();
return( -1 );
}
LoadPreCompiledHeader( p, &pch );
PCH_FileName = NULL;
return( 0 );
}
void SetDebugType( TYPEPTR typ )
{
typ->debug_type = DBG_NIL_TYPE;
}
void SetFuncDebugType( TYPEPTR typ, int index )
{
// index; /* unused */
typ->debug_type = DBG_NIL_TYPE;
}
void InitDebugTypes( void )
{
WalkTypeList( SetDebugType );
WalkFuncTypeList( SetFuncDebugType );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -