preproc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 404 行
C
404 行
/****************************************************************************
*
* 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 <process.h>
#include "memmgr.h"
#include "errdefns.h"
#include "iosupp.h"
#include "preproc.h"
#include "cppexit.h"
enum {
EL_NEW_LINE = 0x01,
EL_NULL = 0
};
static unsigned skipChars; // how many initial chars to skip
static unsigned maxLineSize; // how often to insert newline
static unsigned currLineSize; // insert newline periodically
static int prevChar; // previous char written out
typedef struct id_mangle IDMANGLE;
struct id_mangle {
IDMANGLE *next;
unsigned index;
char id[1];
};
static IDMANGLE *idList;
static unsigned idIndex;
void PpStartFile( // INDICATE START/CONTINUATION OF A FILE
void )
{
skipChars = 2;
}
unsigned PpVerifyWidth( // VERIFY WIDTH FOR PREPROCESSING
unsigned width ) // - new width
{
if( width != 0 ) {
if( width < 4 ) {
width = 4;
} else if( width > 8*1024 ) {
width = 8*1024;
}
}
return( width );
}
void PpSetWidth( // SET WIDTH FOR PREPROCESSING
unsigned width ) // - new width
{
maxLineSize = PpVerifyWidth( width );
}
#if 0
static void emitPoundLine( LINE_NO line, char *fname, unsigned control )
{
if( CompFlags.cpp_line_wanted ) {
if( CppPrinting() ) {
if( CompFlags.line_comments ) {
fputc( '/', CppFile );
fputc( '/', CppFile );
fputc( ' ', CppFile );
}
fprintf( CppFile, "#line %u \"%s\"", line, fname );
if( control & EL_NEW_LINE ) {
fputc( '\n', CppFile );
}
}
}
}
#else
static void emitPoundLine( LINE_NO line, char *fname, unsigned control )
{
if( CompFlags.cpp_line_wanted ) {
if( CppPrinting() ) {
if( CompFlags.line_comments ) {
if( control & EL_NEW_LINE ) {
// do zip: the correct position is immediately after comment
} else {
-- line;
}
if( line == 0 ) {
line = 1;
}
fprintf( CppFile
, "\n/*@lineinfo:filename=%s*/"
"/*@lineinfo:user-code*/"
"/*@lineinfo:%u^1*/"
, fname
, line );
} else {
if( line == 0 ) {
line = 1;
}
fprintf( CppFile, "#line %u \"%s\"", line, fname );
if( control & EL_NEW_LINE ) {
fputc( '\n', CppFile );
}
}
}
}
}
#endif
void EmitLine( // EMIT #LINE DIRECTIVE, IF REQ'D
LINE_NO line_num, // - line number
char *filename ) // - file name
{
emitPoundLine( line_num, filename, EL_NULL );
}
void EmitLineNL( // EMIT #LINE DIRECTIVE ON ITS OWN LINE, IF REQ'D
LINE_NO line_num, // - line number
char *filename ) // - file name
{
emitPoundLine( line_num, filename, EL_NEW_LINE );
}
void PpInit( // INITIALIZE PREPROCESSING
void )
{
maxLineSize = 128;
currLineSize = 0;
idIndex = 0;
idList = NULL;
prevChar = '\n';
PpStartFile(); // sets skipChars
CppFile = NULL;
PreProcChar = '#';
}
void PpOpen( // OPEN PREPROCESSOR OUTPUT
void )
{
char *name;
if( CompFlags.cpp_output_to_file ) { /* 29-sep-90 */
name = IoSuppOutFileName( OFT_PPO );
CppFile = SrcFileFOpen( name, SFO_WRITE_TEXT );
if( CppFile == NULL ) {
printf( "Unable to open '%s'\n", name );
CppExit( 1 );
} else {
IoSuppSetBuffering( CppFile, 512 );
}
} else {
CppFile = stdout;
}
}
static void prt_cpp_char( // PRINT CPP CHARACTER
int c ) // - character to be printed
{
if( c == '\n' ) {
if( c != prevChar || CompFlags.cpp_line_wanted ) {
fputc( c, CppFile );
}
currLineSize = 0;
} else {
fputc( c, CppFile );
currLineSize++;
if( maxLineSize != 0 ) {
if( currLineSize >= maxLineSize ) {
// output line splice
fputc( '\\', CppFile );
fputc( '\n', CppFile );
currLineSize = 0;
}
}
}
prevChar = c;
}
void PrtString( // PRINT CPP STRING
const char *str ) // - string to be printed
{
while( *str ) {
prt_cpp_char( *str );
str++;
}
}
void PrtChar( // PRINT PREPROC CHAR IF REQ'D
int c ) // - character to be printed
{
if( CppPrinting() ) {
if( skipChars ) {
--skipChars;
if( c != '\n' ) {
prt_cpp_char( c );
}
} else {
prt_cpp_char( c );
}
}
}
static void printMangledId( IDMANGLE *id )
{
auto char buff[32];
prt_cpp_char( '_' );
utoa( id->index, buff, 10 );
PrtString( buff );
prt_cpp_char( '_' );
}
static IDMANGLE *addNewId( IDMANGLE **head, IDMANGLE *next )
{
IDMANGLE *new_id;
size_t len;
len = strlen( Buffer );
new_id = CMemAlloc( sizeof( IDMANGLE ) + len );
new_id->next = next;
new_id->index = idIndex;
strcpy( new_id->id, Buffer );
*head = new_id;
++idIndex;
return( new_id );
}
static void idPrint( void )
{
IDMANGLE **head;
IDMANGLE *id;
int comp;
if( ! CompFlags.encrypt_preproc_output ) {
PrtString( Buffer );
return;
}
head = &idList;
for( id = *head; id != NULL; id = *head ) {
comp = strcmp( Buffer, id->id );
if( comp == 0 ) {
printMangledId( id );
return;
}
if( comp < 0 ) {
printMangledId( addNewId( head, id ) );
return;
}
head = &(id->next);
}
printMangledId( addNewId( head, NULL ) );
}
static void idMangleFini( void )
{
IDMANGLE *id;
IDMANGLE *next;
for( id = idList; id != NULL; id = next ) {
next = id->next;
CMemFree( id );
}
}
void PrtToken( // PRINT PREPROC TOKEN IF REQ'D
void )
{
if( CppPrinting() ) {
switch( CurToken ) {
case T_BAD_CHAR: /* 12-apr-89 */
case T_BAD_TOKEN: /* 12-apr-89 */
case T_CONSTANT:
PrtString( Buffer );
break;
case T_ID:
idPrint();
break;
case T_STRING:
prt_cpp_char( '\"' );
PrtString( Buffer );
prt_cpp_char( '\"' );
break;
case T_LSTRING:
prt_cpp_char( 'L' );
prt_cpp_char( '\"' );
PrtString( Buffer );
prt_cpp_char( '\"' );
break;
case T_EOF:
case T_NULL:
break;
default:
PrtString( Tokens[ CurToken ] );
}
}
}
void PpParse( // PARSE WHEN PREPROCESSING
void )
{
for(;;) {
GetNextToken();
if( CurToken == T_EOF ) break;
PrtToken();
}
idMangleFini();
}
char *TokenString( // RETURN A PRINTABLE STRING FOR CURRENT TOK
void )
{
char *token;
switch( CurToken ) {
case T_BAD_CHAR:
Buffer[1] = '\0';
case T_ID:
case T_STRING:
case T_CONSTANT:
case T_BAD_TOKEN:
token = Buffer;
break;
default:
token = Tokens[CurToken];
}
return( token );
}
void Expecting( // ISSUE EXPECTING ERROR FOR A TOKEN
char *a_token ) // - required token
{
CErr( ERR_EXPECTING_BUT_FOUND, a_token, TokenString() );
}
void MustRecog( // REQUIRE A SPECIFIC TOKEN AND SCAN NEXT
int this_token ) // - token to be recognized
{
int alt_token;
/* also accept alternative tokens (digraphs) */
if( this_token == T_LEFT_BRACKET ) {
alt_token = T_ALT_LEFT_BRACKET;
}
if( this_token == T_RIGHT_BRACKET ) {
alt_token = T_ALT_RIGHT_BRACKET;
}
if( this_token == T_LEFT_BRACE ) {
alt_token = T_ALT_LEFT_BRACE;
}
if( this_token == T_RIGHT_BRACE ) {
alt_token = T_ALT_RIGHT_BRACE;
} else {
alt_token = this_token;
}
if( ( CurToken != this_token ) && ( CurToken != alt_token ) ) {
Expecting( Tokens[ this_token ] );
if( CurToken != T_EOF ) {
NextToken();
}
} else {
NextToken();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?