📄 pchdr.c
字号:
#endif
OutPutSymHashTable();
OutPutSymbols();
OutPutMsgFlags();
OutPutMacros();
}
void InitBuildPreCompiledHeader( void )
//Save any before info when building pre compiled headers
{
struct rdir_list *start;
start = RDirNames;
if( start != NULL ){
start = start->next;
}
PCHRDirNames = start;
}
void BuildPreCompiledHeader( char *filename )
{
int rc;
char *cwd;
if( FirstStmt != 0 || DataQuadSegIndex != -1 ) {
PCHNote( PCHDR_NO_OBJECT );
return;
}
InitPHVars();
PH_Buffer = FEmalloc( PH_BUF_SIZE );
PH_BufPtr = PH_Buffer;
PH_BufSize = PH_BUF_SIZE;
cwd = getcwd( PH_Buffer + sizeof(struct pheader),
PH_BUF_SIZE - sizeof(struct pheader) );
rc = setjmp( PH_jmpbuf );
if( rc == 0 ) {
CreatePHeader( filename );
PH_cwd_len = ((strlen(cwd) + 1) + sizeof(int) - 1)
& - sizeof(int);
PH_size = PH_cwd_len;
PH_computing_size = 1;
OutPutEverything();
PH_computing_size = 0;
OutPutHeader();
OutPutEverything();
FlushPHeader();
ClosePHeader();
} else { // error creating pre-compiled header
if( PH_handle != -1 ) {
ClosePHeader(); // close the file
remove( filename ); // delete the pre-compiled header
}
}
InitDebugTypes();
InitDebugTags();
FEfree( PH_Buffer );
PCH_FileName = NULL;
CompFlags.make_precompiled_header = 0;
}
//========================================================================
// This portion of the code loads the pre-compiled header and
// rebuilds the data structures by replacing all the indices with
// pointers, reconstructing hash tables, etc.
//========================================================================
static char *FixupIncFileList( char *p, unsigned incfile_count )
{
INCFILE *ifile;
unsigned len;
IncFileList = NULL;
if( incfile_count != 0 ) {
IncFileList = (INCFILE *)p;
for(;;) {
ifile = (INCFILE *)p;
len = sizeof(INCFILE) + ifile->len;
len = (len + (sizeof(int) - 1)) & - sizeof(int);
p += len;
--incfile_count;
if( incfile_count == 0 ) break;
ifile->nextfile = (INCFILE *)p;
}
}
return( p );
}
static char *FixupIncludes( char *p, unsigned file_count )
{
FNAMEPTR flist;
unsigned len;
FNameList = NULL;
if( file_count != 0 ) {
FNameList = (FNAMEPTR)p;
for(;;) {
flist = (FNAMEPTR)p;
len = flist->fname_len;
flist->fullpath = NULL;
p += len;
flist->next = (FNAMEPTR)p;
--file_count;
if( file_count == 0 ) break;
}
flist->next = NULL;
}
return( p );
}
static char *FixupRoDirList( char *p, unsigned list_count )
{
RDIRPTR dirlist;
RDIRPTR *lnk;
unsigned len;
lnk = &RDirNames;
while( (dirlist = *lnk) != NULL ) {
lnk = &dirlist->next;
}
while( list_count != 0 ) {
dirlist = (RDIRPTR)p;
len = dirlist->name_len;
p += len;
*lnk = dirlist;
lnk = &dirlist->next;
--list_count;
}
*lnk = NULL;
return( p );
}
static int VerifyIncludes()
{
FNAMEPTR flist;
time_t mtime;
bool failed;
failed = FALSE;
for( flist = FNameList; flist; flist = flist->next ) {
if( flist->rwflag ){
if( SrcFileInRDir( flist ) ){
flist->rwflag = FALSE;
}
}
if( flist->rwflag ){
mtime = _getFilenameTimeStamp( flist->name );
if( flist->mtime != mtime || mtime == 0 ){
PCHNote( PCHDR_INCFILE_CHANGED, flist->name );
#if 0
printf( "%s old %d new %d\n",flist->name, flist->mtime, mtime );
#endif
failed = TRUE;
}
}
}
return( failed );
}
static char *FixupLibrarys( char *p, unsigned library_count )
{
struct library_list *lib;
unsigned len;
HeadLibs = NULL;
if( library_count != 0 ) {
lib = (struct library_list *)p;
HeadLibs = lib;
for(;;) {
len = sizeof(struct library_list) + strlen( lib->name );
len = (len + (sizeof(int) - 1)) & - sizeof(int);
p += len;
lib->next = (struct library_list *)p;
--library_count;
if( library_count == 0 ) break;
lib = (struct library_list *)p;
}
lib->next = NULL;
}
return( p );
}
static char *FixupSegInfo( char *p, unsigned seg_count )
{
struct textsegment *seg;
unsigned len;
TextSegArray = (struct textsegment **)CMemAlloc( (seg_count+1) *
sizeof(struct textsegment *) );
TextSegArray[0] = NULL;
if( seg_count != 0 ) {
while( seg_count != 0 ) {
seg = (struct textsegment *)p;
TextSegArray[ seg->index + 1 ] = seg;
len = seg->textsegment_len;
p += len;
seg->next = (struct textsegment *)p;
--seg_count;
}
seg->next = NULL;
}
return( p );
}
static char *FixupMacros( char *p, unsigned macro_count )
{
int i;
MEPTR mentry;
unsigned mentry_len;
while( macro_count != 0 ) {
mentry = (MEPTR)p;
i = mentry->macro_index; // get hash index
mentry->next_macro = PCHMacroHash[i];
PCHMacroHash[i] = mentry;
mentry_len = (mentry->macro_len + (sizeof(int) - 1)) & - sizeof(int);
p += mentry_len;
--macro_count;
}
return( p );
}
static char *FixupUndefMacros( char *p, unsigned undef_macro_count )
{ // Read in as written out
MEPTR mentry, *lnk;
unsigned mentry_len;
PCHUndefMacroList = NULL;
lnk = &PCHUndefMacroList;
while( undef_macro_count != 0 ) {
mentry = (MEPTR)p;
*lnk = mentry;
lnk = &mentry->next_macro;
mentry_len = (mentry->macro_len + (sizeof(int) - 1)) & - sizeof(int);
p += mentry_len;
--undef_macro_count;
}
*lnk = NULL;
return( p );
}
static int VerifyMacros( char *p, unsigned macro_count, unsigned undef_count )
{
int i;
MEPTR mpch;
MEPTR mcur;
int macro_compare;
PCHMacroHash = (MEPTR *)CMemAlloc( MACRO_HASH_SIZE * sizeof(MEPTR) );
p = FixupMacros( p, macro_count );
p = FixupUndefMacros( p, undef_count );
for( i = 0; i < MACRO_HASH_SIZE; ++i ) {
MEPTR prev_mpch;
prev_mpch = NULL;
for( mpch = PCHMacroHash[i]; mpch; mpch = mpch->next_macro ) {
if( mpch->macro_flags & MACRO_DEFINED_BEFORE_FIRST_INCLUDE ) {
mcur = MacHash[ i ];
while( mcur != NULL ) {
if( strcmp( mcur->macro_name, mpch->macro_name ) == 0 ) {
macro_compare = MacroCompare( mpch, mcur );
if( mpch->macro_flags & MACRO_REFERENCED ) {
if( macro_compare == 0 ) break;
return( -1 ); // abort: macros different
}
if( macro_compare != 0 ) { /* if different */
/* delete macro from pch, add new one */
if( prev_mpch == NULL ) {
PCHMacroHash[i] = mpch->next_macro;
} else {
prev_mpch->next_macro = mpch->next_macro;
}
}
break;
}
mcur = mcur->next_macro;
}
if( mcur == NULL ) { /* macro not found in current compile */
if( mpch->macro_flags & MACRO_REFERENCED ) {
return( -1 ); // abort: macro definition required
}
// delete macro from PCH list
if( prev_mpch == NULL ) {
PCHMacroHash[i] = mpch->next_macro;
} else {
prev_mpch->next_macro = mpch->next_macro;
}
}
}
prev_mpch = mpch;
}
}
// check if any user-defined macros have been defined that were not
// defined when the pre-compiled header file was created
//
// for all macros in current compilation unit
// - if it is present in the PCH header file set of macros
// -- if not defined before first include
// --- abort:
// -- endif
// - else macro NOT in PCH
// -- if the macro is a user-defined macro
// --- abort:
// -- endif
// - endif
// endloop
for( i = 0; i < MACRO_HASH_SIZE; ++i ) {
for( mcur = MacHash[i]; mcur; mcur = mcur->next_macro ) {
for( mpch = PCHMacroHash[i]; mpch; mpch = mpch->next_macro ) {
if( strcmp( mpch->macro_name, mcur->macro_name ) == 0 ) break;
}
if( mpch == NULL || !(mpch->macro_flags & MACRO_DEFINED_BEFORE_FIRST_INCLUDE) ){
// macro may either have been undef'd (mpch == NULL ) or undef'd and defined
if( mcur->macro_flags & MACRO_USER_DEFINED ){ //compiler defined macros not saved on undefs
for( mpch = PCHUndefMacroList; mpch; mpch = mpch->next_macro ) {
if( strcmp(mpch->macro_name,mcur->macro_name) == 0 ){
if( MacroCompare( mpch, mcur ) != 0 ){
return( -1 );
}else{
break;
}
}
}
if( mpch == NULL ) {
// abort: macro wasn't defined before include
return( -1 );
}
}
}
}
}
for( i = 0; i < MACRO_HASH_SIZE; ++i ) {
MEPTR next_mcur;
for( mcur = MacHash[i]; mcur; mcur = next_mcur ) {
for( mpch = PCHMacroHash[i]; mpch; mpch = mpch->next_macro ) {
if( strcmp( mpch->macro_name, mcur->macro_name ) == 0 ) break;
}
next_mcur = mcur->next_macro;
if( mpch == NULL ) { // if this macro not found in PCH
mcur->next_macro = PCHMacroHash[i]; // add it to PCH
PCHMacroHash[i] = mcur;
}
}
}
memcpy( MacHash, PCHMacroHash, MACRO_HASH_SIZE * sizeof(MEPTR) );
CMemFree( PCHMacroHash );
PCHMacroHash = NULL;
UndefMacroList = PCHUndefMacroList;
return( 0 );
}
static char *FixupSymHashTable( char *p, unsigned symhash_count )
{
SYM_HASHPTR hsym;
int i;
unsigned len;
while( symhash_count != 0 ) {
hsym = (SYM_HASHPTR)p;
i = hsym->hash_index;
hsym->next_sym = HashTab[i];
HashTab[i] = hsym;
if( hsym->sym_type_index != 0 ) {
hsym->sym_type = TypeArray + hsym->sym_type_index;
}
len = strlen( hsym->name ) + sizeof(struct sym_hash_entry);
len = (len + (sizeof(int) - 1)) & - sizeof(int);
p += len;
--symhash_count;
}
return( p );
}
static char *FixupSymbols( char *p, unsigned symbol_count )
{
SYMPTR symptr;
SYM_ENTRY sym;
SYM_HANDLE sym_handle;
sym_handle = 0;
while( symbol_count != 0 ) {
symptr = (SYMPTR)p;
if( symptr->sym_type_index != 0 ) {
symptr->sym_type = TypeArray + symptr->sym_type_index;
}
symptr->seginfo = TextSegArray[ symptr->seginfo_index ];
PCH_SymArray[ sym_handle ] = symptr;
p += sizeof(SYM_ENTRY);
++sym_handle;
--symbol_count;
}
for( sym_handle = 0; sym_handle < SpecialSyms; sym_handle++ ) {
SymGet( &sym, sym_handle ); // Redo special syms
symptr = PCH_SymArray[ sym_handle ];
*symptr = sym;
}
return( p );
}
static void FixupTypeIndexes( struct type_indices *typ_index ) /* 02-jan-95 */
{
int i;
int index;
for( i = TYPE_CHAR; i < TYPE_LAST_ENTRY; i++ ) {
index = typ_index->basetype_index[i];
if( index != 0 ) {
BaseTypes[i] = TypeArray + index;
}
}
VoidParmList[0] = BaseTypes[TYPE_VOID];
StringType = TypeArray + typ_index->stringtype_index;
ConstCharType = TypeArray + typ_index->constchartype_index;
}
static char *FixupTypes( char *p, unsigned type_count )
{
TYPEPTR typ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -