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 + -
显示快捷键?