📄 pchdr.c
字号:
/****************************************************************************
*
* 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 + -