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

📄 pchdr.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -