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

📄 pchdr.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Code to handle pre-compiled header files.
*
****************************************************************************/


#include "cvars.h"
#include "pragdefn.h"
#include "autodept.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef __WATCOMC__
#if (_OS != _QNX) && (_OS != _LINUX)
    #include <direct.h>
#endif
    #include <share.h>
#endif
#if (_OS == _QNX) || (_OS == _LINUX)
    #define PMODE       S_IRUSR+S_IWUSR+S_IRGRP+S_IWGRP+S_IROTH+S_IWOTH
#else
    #define PMODE       S_IRWXU
#endif
#ifndef O_BINARY
    #define O_BINARY  0
#endif
#if defined(SH_DENYWR) && !defined(SOPEN_DEFINED)
    #define sopen4 sopen
#else
    #define sopen4(a,b,c,d) open((a),(b),(d))
//    #define sopen(a,b,c) open((a),(b))
#endif

extern  TAGPTR  TagHash[TAG_HASH_SIZE + 1];

#define PH_BUF_SIZE     32768
#define PCH_SIGNATURE   (unsigned long) 'WPCH'
#define PCH_VERSION     ((_HOST << 16) | 0x0196)

static  jmp_buf         PH_jmpbuf;
static  int             PH_handle;
static  char            *PH_Buffer;
static  char            *PH_BufPtr;
static  unsigned        PH_BufSize;
static  MEPTR           *PCHMacroHash;
static  MEPTR           PCHUndefMacroList;
static  TYPEPTR         TypeArray;
static  TAGPTR          *TagArray;
static  FNAMEPTR        FNameList;
static  struct textsegment **TextSegArray;
static  unsigned        PH_SymHashCount;
static  unsigned        PH_FileCount;
static  unsigned        PH_RDirCount;
static  unsigned        PH_IncFileCount;
static  unsigned        PH_LibraryCount;
static  unsigned        PH_SegCount;
static  unsigned        PH_MacroCount;
static  unsigned        PH_UndefMacroCount;
static  unsigned        PH_TypeCount;
static  unsigned        PH_TagCount;
static  unsigned        PH_PragmaCount;
static  unsigned        PH_size;
static  unsigned        PH_MacroSize;
static  unsigned        PH_cwd_len;
static  char            PH_computing_size;

static  struct  rdir_list *PCHRDirNames;  /* list of read only directorys */

struct  pheader {
    unsigned long       signature;      //  'WPCH'
    unsigned            version;
    unsigned            size_of_header;
    unsigned            size_of_int;
    unsigned            pack_amount;    // PackAmount
    unsigned long       gen_switches;   // GenSwitches
    unsigned long       target_switches;// TargetSwitches
    int                 toggles;        // Toggles
    unsigned            size;
    unsigned            macro_size;
    unsigned            file_count;
    unsigned            rdir_count;
    unsigned            incfile_count;
    unsigned            incline_count;  // IncLineCount
    unsigned            library_count;  // # of pragma library(s)
    unsigned            seg_count;
    unsigned            macro_count;
    unsigned            undef_macro_count;
    unsigned            type_count;
    unsigned            tag_count;
    unsigned            pragma_count;
    unsigned            symhash_count;
    unsigned            symbol_count;
    unsigned            specialsyms_count;
    unsigned            cwd_len;        // length of current working directory
    unsigned            msgflags_len;   // length of MsgFlags array
};

#if _MACHINE == _PC
static struct aux_info *BuiltinInfos[] = {
        &DefaultInfo,
        &CdeclInfo,
        &PascalInfo,
        &FortranInfo,
        &SyscallInfo,
        &StdcallInfo,
        &OptlinkInfo,
        &FastCallInfo,
        NULL
};
#endif

static int FixupDataStructures( char *p, struct pheader *pch );

void InitDebugTypes( void );

//========================================================================
//      This portion of the code creates the pre-compiled header.
//========================================================================

static void InitPHVars( void ){
//*****************************
//Set vars to 0
//*****************************
    PH_SymHashCount=0;
    PH_FileCount=0;
    PH_RDirCount=0;
    PH_IncFileCount=0;
    PH_LibraryCount=0;
    PH_SegCount=0;
    PH_MacroCount=0;
    PH_UndefMacroCount=0;
    PH_TypeCount=0;
    PH_TagCount=0;
    PH_PragmaCount=0;
    PH_size=0;
    PH_MacroSize=0;
    PH_cwd_len=0;
    PH_computing_size=0;
}

static void CreatePHeader( char *filename )
{
    PH_handle = sopen4( filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, SH_DENYRW, PMODE );
    if( PH_handle == -1 ) {
        longjmp( PH_jmpbuf, 1 );
    }
}

static int WritePHeader( void *bufptr, unsigned len )
{
    unsigned    amt_written;
    char        *buf;

    buf = bufptr;
    if( PH_computing_size ) {
        PH_size += len;
    } else if( len != 0 ) {
        if( PH_Buffer != NULL ) {
            for(;;) {
                amt_written = len;
                if( amt_written > PH_BufSize )  amt_written = PH_BufSize;
                memcpy( PH_BufPtr, buf, amt_written );
                PH_BufSize -= amt_written;
                PH_BufPtr += amt_written;
                buf += amt_written;
                len -= amt_written;
                if( PH_BufSize == 0 ) {         // if buffer is full
                    PH_BufSize = PH_BUF_SIZE;
                    PH_BufPtr = PH_Buffer;
                    if( write( PH_handle, PH_Buffer, PH_BUF_SIZE ) !=
                                        PH_BUF_SIZE ) {
                        return( 1 );
                    }

                }
                if( len == 0 ) break;
            }
        } else {
            amt_written = write( PH_handle, buf, len );
            if( amt_written != len )  return( 1 );
        }
    }
    return( 0 );
}

static void FlushPHeader()
{
    unsigned    len;

    if( PH_BufSize != PH_BUF_SIZE ) {   // if buffer has some stuff in it
        len = PH_BUF_SIZE - PH_BufSize;
        if( write( PH_handle, PH_Buffer, len ) != len ) {
            longjmp( PH_jmpbuf, 1 );
        }
    }
}

static void ClosePHeader()
{
    close( PH_handle );
    PH_handle = -1;
}


static void OutPutHeader()
{
    int                 rc;
    struct pheader      pch;

    pch.signature       = PCH_SIGNATURE;
    pch.version         = PCH_VERSION;
    pch.size_of_header  = sizeof(struct pheader);
    pch.size_of_int     = TARGET_INT;
    pch.pack_amount     = PackAmount;
    pch.gen_switches    = GenSwitches;
    pch.target_switches = TargetSwitches;
    pch.toggles         = Toggles;
    pch.size            = PH_size - PH_MacroSize;
    pch.macro_size      = PH_MacroSize;
    pch.file_count      = PH_FileCount;
    pch.rdir_count      = PH_RDirCount;
    pch.incfile_count   = PH_IncFileCount;
    pch.incline_count   = IncLineCount;
    pch.library_count   = PH_LibraryCount;
    pch.seg_count       = PH_SegCount;
    pch.macro_count     = PH_MacroCount;
    pch.undef_macro_count=PH_UndefMacroCount;
    pch.type_count      = PH_TypeCount;
    pch.tag_count       = PH_TagCount;
    pch.pragma_count    = PH_PragmaCount;
    pch.symhash_count   = PH_SymHashCount;
    pch.symbol_count    = NextSymHandle + 1;
    pch.specialsyms_count  = SpecialSyms;
    pch.cwd_len         = PH_cwd_len;
    if( MsgFlags != NULL ) {                            /* 06-jul-94 */
        pch.msgflags_len = ((HIGHEST_MESSAGE_NUMBER + 7) / 8)
                                + (sizeof(int) - 1) & - sizeof(int);
    } else {
        pch.msgflags_len = 0;
    }
    rc = WritePHeader( &pch, sizeof(struct pheader) );
    rc |= WritePHeader( PH_Buffer + sizeof(struct pheader), pch.cwd_len );
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutHFileList()           // output include paths
{
    int         rc;
    unsigned    len;

    if( HFileList == NULL ) {
        rc = 0;
        rc = WritePHeader( &rc, sizeof(int) );
    } else {
        len = strlen( HFileList ) + 1;
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        rc = WritePHeader( HFileList, len );
    }
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutIncFileList()         // output primary include files
{
    int         rc;
    unsigned    len;
    INCFILE     *ifile;

    for( ifile = IncFileList; ifile; ifile = ifile->nextfile ) {
        len = sizeof(INCFILE) + ifile->len;
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        rc = WritePHeader( ifile, len );
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        PH_IncFileCount++;
    }
}

static void OutPutLibrarys()
{
    int                 rc;
    unsigned            len;
    struct library_list *lib;

    for( lib = HeadLibs; lib; lib = lib->next ) {
        len = sizeof(struct library_list) + strlen( lib->name );
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        rc = WritePHeader( lib, len );
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        PH_LibraryCount++;
    }
}

static void OutPutMsgFlags()
{
    int         rc;

    if( MsgFlags != NULL ) {                            /* 06-jul-94 */
        rc = WritePHeader( MsgFlags, (HIGHEST_MESSAGE_NUMBER + 7) / 8 );
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutIncludes()
{
    FNAMEPTR    flist;
    FNAMEPTR    next_flist;
    unsigned    len;
    int         rc;

    flist = FNames;
    // don't want to include the primary source file
    while( flist != NULL ){
        if( strcmp( flist->name, SrcFile->src_name ) == 0 ){
            flist = flist->next;
            break;
        }
        flist = flist->next;
    }
    while( flist != NULL ) {
        next_flist = flist->next;
        len = strlen( flist->name ) + sizeof(struct fname_list);
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        flist->fname_len = len;
        rc = WritePHeader( flist, len );
        flist->next = next_flist;
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        flist = next_flist;
        PH_FileCount++;
    }
}

static void OutPutRoDirList()
{
    RDIRPTR   dirlist;
    RDIRPTR   next_dirlist;
    unsigned    len;
    int         rc;

    dirlist = PCHRDirNames;
    while( dirlist != NULL ) {
        next_dirlist = dirlist->next;
        len = strlen( dirlist->name ) + sizeof(struct rdir_list);
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        dirlist->name_len = len;
        rc = WritePHeader( dirlist, len );
        dirlist->next = next_dirlist;
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        dirlist = next_dirlist;
        PH_RDirCount++;
    }
}

static void OutPutSegInfo()
{
    struct textsegment  *seg;
    struct textsegment  *next;
    int                 rc;
    unsigned            len;

    for( seg = TextSegList; seg; seg = seg->next ) {
        ++PH_SegCount;
        seg->index = PH_SegCount;
        len = strlen( seg->segname );           // segment name
        len += strlen( &seg->segname[len+1] );  // class name
        len += sizeof(struct textsegment) + 1;
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        next = seg->next;                       // save next pointer
        seg->textsegment_len = len;             // replace with len
        rc = WritePHeader( seg, len );
        seg->next = next;                       // restore next pointer
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutEnums( ENUMPTR ep, TAGPTR parent )
{
    int         rc;
    unsigned    len;

    for( ; ep; ep = ep->thread ) {
        len = strlen( ep->name ) + sizeof(ENUMDEFN);
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        ep->enum_len = len;
        rc = WritePHeader( ep, len );
        ep->parent = parent;            // enum_len is union'ed with parent
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutFields( FIELDPTR field )
{
    int         rc;
    int         len;
    FIELDPTR    next_field;
    TYPEPTR     typ;

⌨️ 快捷键说明

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