pcheader.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,179 行 · 第 1/3 页

C
1,179
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/

#include "plusplus.h"

#include <stddef.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <setjmp.h>
#include <limits.h>
#include <share.h>

#include "errdefns.h"
#include "memmgr.h"
#include "carve.h"
#include "hfile.h"
#include "preproc.h"
#include "cgdata.h"
#include "stats.h"
#include "initdefs.h"
#include "name.h"
#include "pcheader.h"
#include "cgiobuff.h"
#include "brinfo.h"

#if defined(__UNIX__)
 #include <dirent.h>
 #define _FILENAME_CMP  strcmp
#else
 #include <direct.h>
 #define _FILENAME_CMP  stricmp
#endif

static pch_status (*readFunctions[])( void ) = {
#define PCH_EXEC( s, g )        PCHRead##g,
#include "pcregdef.h"
};
static pch_status (*writeFunctions[])( void ) = {
#define PCH_EXEC( s, g )        PCHWrite##g,
#include "pcregdef.h"
};

static pch_status (*initFunctions[])( boolean ) = {
#define PCH_EXEC( s, g )        PCHInit##g,
#include "pcregdef.h"
};
static pch_status (*finiFunctions[])( boolean ) = {
#define PCH_EXEC( s, g )        PCHFini##g,
#include "pcregdef.h"
};
static pch_status (*relocFunctions[])( char *, size_t ) = {
#define PCH_RELOC( s, g )       PCHReloc##g,
#include "pcregdef.h"
};

ExtraRptCtr( ctr_pch_length );
ExtraRptCtr( ctr_pch_waste );
ExtraRptTable( ctr_pchw_region, PCHRW_MAX+1, 1 );

static pch_reloc_info relocInfo[ PCHRELOC_MAX ];

static char *pchName;
static char *pchDebugInfoName;
static int pchFile;

#ifndef NDEBUG
#define IO_BUFFER_SIZE  1024
#else
#define IO_BUFFER_SIZE  65536
#endif
static int amountLeft;
static char *ioBuffer;
static char *bufferCursor;
//static char *bufferEnd;
static fpos_t bufferPosition;

#define pch_buff_cur CompInfo.pch_buff_cursor
#define pch_buff_eob CompInfo.pch_buff_end

static jmp_buf *abortData;

#ifndef NDEBUG
static clock_t start_parse;
void PCHActivate( void )
{
    start_parse = clock();
}
#else
void PCHActivate( void )
/**********************/
{
}
#endif


void PCHSetFileName( char *name )
/*******************************/
{
    CMemFreePtr( &pchName );
    pchName = name;
}

char *PCHFileName( void )
{
    if( pchName != NULL ) {
        return( pchName );
    }
    return( PCH_DEFAULT_FILE_NAME );
}

static void fail( void )
{
    longjmp( abortData, 1 );
}

static void dumpHeader( void )
{
    auto precompiled_header_header header;

    memcpy( header.text_header, PHH_TEXT_HEADER, TEXT_HEADER_SIZE );
    header.signature[0] = PHH_SIGNATURE_0;
    header.signature[1] = PHH_SIGNATURE_1;
    header.signature[2] = PHH_SIGNATURE_2;
    header.signature[3] = PHH_SIGNATURE_3;
    header.major_version = PHH_MAJOR;
    header.minor_version = PHH_MINOR;
    header.target_architecture = PHH_TARG_ARCHITECTURE;
    header.host_system = PHH_HOST_SYSTEM;
    header.host_architecture = PHH_HOST_ARCHITECTURE;
    header.corrupted = PHH_CORRUPTED_YES;
    header.browse_info = 0;
    PCHWrite( &header, sizeof( header ) );
}

static void setOKHeader( unsigned long brinf_posn )
{
    auto precompiled_header_header header;


    if( lseek( pchFile, 0, SEEK_SET ) != 0 ) {
        fail();
    }
    if( read( pchFile, &header, sizeof( header ) ) != sizeof( header ) ) {
        fail();
    }
    header.browse_info = brinf_posn;
    header.corrupted = PHH_CORRUPTED_NO;
    if( lseek( pchFile, 0, SEEK_SET ) != 0 ) {
        fail();
    }
    if( write( pchFile, &header, sizeof( header ) ) != sizeof( header ) ) {
        fail();
    }
}

static void dumpFileString( char *str )
{
    size_t len;

    len = strlen( str ) + 1;
    PCHWriteUInt( len );
    PCHWrite( str, len );
}

static void* readFileStringLocate( char *buff )
{
    size_t len;

    // assumes 'buff' is at least _MAX_PATH bytes
    len = PCHReadUInt();
    return PCHReadLocate( buff, len );
}

static void* readFileString( char *buff )
{
    size_t len;

    // assumes 'buff' is at least _MAX_PATH bytes
    len = PCHReadUInt();
    return PCHRead( buff, len );
}

static void dumpCheckData( char *include_file )
{
    SRCFILE src;
    time_t stamp;
    auto char buff[_MAX_PATH];

    PCHWrite( &GenSwitches, sizeof( GenSwitches ) );
    PCHWrite( &TargetSwitches, sizeof( TargetSwitches ) );
    PCHWriteUInt( ErrPCHVersion() );
    PCHWriteUInt( TYPC_LAST );
    PCHWriteUInt( sizeof( COMP_FLAGS ) );
    PCHWrite( &CompFlags, sizeof( CompFlags ) );
    dumpFileString( WholeFName );
    include_file = IoSuppFullPath( include_file, buff, sizeof( buff ) );
    dumpFileString( include_file );
    getcwd( buff, sizeof( buff ) );
    dumpFileString( buff );
    HFileListStart();
    for( ; ; ) {
        HFileListNext( buff );
        dumpFileString( buff );
        if( buff[0] == '\0' ) break;
    }
    src = SrcFileNotReadOnly( SrcFileWalkInit() );
    for(;;) {
        if( src == NULL ) break;
        if( ! IsSrcFilePrimary( src ) ) {
            dumpFileString( SrcFileName( src ) );
            stamp = SrcFileTimeStamp( src );
            PCHWrite( &stamp, sizeof( stamp ) );
        }
        src = SrcFileNotReadOnly( SrcFileWalkNext( src ) );
    }
    buff[0] = '\0';
    dumpFileString( buff );
    PCHDumpMacroCheck();
}

static fpos_t cursorWriteFilePosition( void )
{
    fpos_t posn;

    posn = bufferPosition;
    posn += ( bufferCursor - ioBuffer );
    return( posn );
}

static void alignPCH( unsigned i, boolean writing )
{
    unsigned skip;
    unsigned dummy;

    if( writing ) {
        skip = - cursorWriteFilePosition();
        skip &= sizeof( unsigned ) - 1;
        PCHWriteUInt( skip );
        DbgAssert( skip == 0 );
        if( skip != 0 ) {
            PCHWrite( &dummy, skip );
        }
    } else {
        skip = PCHReadUInt();
        if( skip != 0 ) {
            PCHRead( &dummy, skip );
        }
    }
#ifndef NDEBUG
    if( writing ) {
        unsigned w = -i;
        PCHWriteUInt( w );
    } else {
        unsigned r;
        r = PCHReadUInt();
        if( r != -i ) {
            printf( "index = %u\n", i );
            CFatal( "pre-compiled header read/write out of synch" );
        }
    }
#else
    i = i;
#endif
}

static void execInitFunctions( boolean writing )
{
    int i;
    pch_status ist;

    for( i = 0; i < PCHRW_MAX; ++i ) {
        ist = (initFunctions[i])( writing );
        if( ist != PCHCB_OK ) {
            fail();
        }
        alignPCH( i, writing );
    }
}

static void execFiniFunctions( boolean writing )
{
    int i;
    pch_status fst;

    for( i = PCHRW_MAX-1; i >= 0; --i ) {
        fst = (finiFunctions[i])( writing );
        if( fst != PCHCB_OK ) {
            fail();
        }
        alignPCH( i, writing );
    }
}

static void execControlFunctions( boolean writing, pch_status (**tbl)( void ) )
{
    unsigned i;
    pch_status st;

    for( i = 0; i < PCHRW_MAX; ++i ) {
        ExtraRptTabSub( ctr_pchw_region, i, 0, (writing!=FALSE)*(ctr_pch_length+(IO_BUFFER_SIZE-amountLeft)) );
        ExtraRptTabSub( ctr_pchw_region, PCHRW_MAX, 0, (writing!=FALSE)*(ctr_pch_length+(IO_BUFFER_SIZE-amountLeft)) );
        st = (tbl[i])();
        ExtraRptTabAdd( ctr_pchw_region, i, 0, (writing!=FALSE)*(ctr_pch_length+(IO_BUFFER_SIZE-amountLeft)) );
        ExtraRptTabAdd( ctr_pchw_region, PCHRW_MAX, 0, (writing!=FALSE)*(ctr_pch_length+(IO_BUFFER_SIZE-amountLeft)) );
        if( st != PCHCB_OK ) {
            fail();
        }
        alignPCH( i, writing );
    }
}

void PCHFlushBuffer( void )
{
    size_t amount;
    size_t amt_written;

    if( amountLeft != IO_BUFFER_SIZE ) {
        amount = IO_BUFFER_SIZE - amountLeft;
        amt_written = write( pchFile, ioBuffer, amount );
        if( amt_written == -1 || amt_written != amount ) {
            fail();
        }
        ExtraRptAddtoCtr( ctr_pch_length, amt_written );
#if 1
        bufferPosition += amt_written;
        amountLeft = IO_BUFFER_SIZE;
        bufferCursor = ioBuffer;
#endif
    }
}


#ifndef NDEBUG
void PCHVerifyFile( int handle )    // DEBUG -- verify handle ok
{
    DbgVerify( handle == pchFile, "PCH handle is bad" );
}
#endif


#ifdef OPT_BR
long PCHSeek( long offset, int type )
{
    lseek( pchFile, offset, type );
    return tell( pchFile );
}
#endif


void PCHWrite( void const *p, size_t size )
/*****************************************/
{
    size_t aligned_size;
//  int amt_written;

    aligned_size = _pch_align_size( size );
    ExtraRptAddtoCtr( ctr_pch_waste, (aligned_size-size) );
    for(;;) {
        if( aligned_size <= amountLeft ) {
            memcpy( bufferCursor, p, size );
            bufferCursor += aligned_size;
            amountLeft -= aligned_size;
            break;
        }

⌨️ 快捷键说明

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