static int PreprocessInputFile( void ) /************************************/ { unsigned flags; char rcdefine[13]; char **cppargs; char *p; int rc; flags = PPFLAG_EMIT_LINE | PPFLAG_IGNORE_INCLUDE; if( CmdLineParms.IgnoreCWD ) { flags |= PPFLAG_IGNORE_CWD; } rc = PP_Init2( CmdLineParms.InFileName, flags, NULL, CharSetLen ); if( rc != 0 ) { RcError( ERR_CANT_OPEN_FILE, CmdLineParms.InFileName, strerror(errno) ); return( TRUE ); } strcpy( rcdefine, "RC_INVOKED 1" ); PP_Define( rcdefine ); if( !CmdLineParms.NoTargetDefine ) { if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ) { strcpy( rcdefine, "__WINDOWS__" ); PP_Define( rcdefine ); } else if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) { strcpy( rcdefine, "__NT__" ); PP_Define( rcdefine ); } else if( CmdLineParms.TargetOS == RC_TARGET_OS_OS2 ) { strcpy( rcdefine, "__OS2__" ); PP_Define( rcdefine ); } } cppargs = CmdLineParms.CPPArgs; if( cppargs != NULL ) { ++cppargs; for(;;) { p = *cppargs; if( p == NULL ) break; for(;;) { if( *p == '\0' ) break; if( *p == '=' ) { *p = ' '; break; } ++p; } p = *cppargs; PP_Define( p + 2 ); // skip over -d ++cppargs; } } return( FALSE ); // indicate no error }
int PP_Sharp( char *ptr ) { char *token; char c; while( *ptr == ' ' || *ptr == '\t' ) ++ptr; token = ptr; while( *ptr >= 'a' && *ptr <= 'z' ) ++ptr; c = *ptr; *ptr = '\0'; if( strcmp( token, "include" ) == 0 ) { *ptr = c; if( NestLevel == SkipLevel ) { PP_Include( ptr ); return( 0 ); } } else if( strcmp( token, "define" ) == 0 ) { *ptr = c; if( NestLevel == SkipLevel ) PP_Define( ptr ); } else if( strcmp( token, "undef" ) == 0 ) { *ptr = c; if( NestLevel == SkipLevel ) PP_Undef( ptr ); } else if( strcmp( token, "ifdef" ) == 0 ) { *ptr = c; PP_Ifdef( ptr ); } else if( strcmp( token, "ifndef" ) == 0 ) { *ptr = c; PP_Ifndef( ptr ); } else if( strcmp( token, "if" ) == 0 ) { *ptr = c; PP_If( ptr ); } else if( strcmp( token, "elif" ) == 0 ) { *ptr = c; PP_Elif( ptr ); } else if( strcmp( token, "else" ) == 0 ) { *ptr = c; PP_Else(); } else if( strcmp( token, "endif" ) == 0 ) { *ptr = c; PP_Endif(); } else { *ptr = c; if( PPFlags & PPFLAG_ASM_COMMENT ) { // # is also a line-comment char in MS's stupid assembler // so we just return 1 to say we recognized it and the rest // of this delightful preprocessor will take care of eating // the remainder of the line return( 1 ); } return( 0 ); // indicate unrecognized } return( 1 ); // indicate recognized }
extern void OptionsPPDefine( void ) { //*********************************** unsigned idx = 0; char *str; if( !ppDefines ) return; str = ppDefines[idx++]; while( str ) { PP_Define( str ); str = ppDefines[idx++]; } }
static int PP_Sharp( const char *ptr ) { const char *token; size_t len; while( *ptr == ' ' || *ptr == '\t' ) ++ptr; token = ptr; while( *ptr >= 'a' && *ptr <= 'z' ) ++ptr; len = ptr - token; if( len == 7 && memcmp( token, "include", 7 ) == 0 ) { if( NestLevel == SkipLevel ) { PP_Include( ptr ); return( 0 ); } } else if( len == 6 && memcmp( token, "define", 6 ) == 0 ) { if( NestLevel == SkipLevel ) { PP_Define( ptr ); } } else if( len == 5 && memcmp( token, "undef", 5 ) == 0 ) { if( NestLevel == SkipLevel ) { PP_Undef( ptr ); } } else if( len == 5 && memcmp( token, "ifdef", 5 ) == 0 ) { PP_Ifdef( ptr ); } else if( len == 6 && memcmp( token, "ifndef", 6 ) == 0 ) { PP_Ifndef( ptr ); } else if( len == 2 && memcmp( token, "if", 2 ) == 0 ) { PP_If( ptr ); } else if( len == 4 && memcmp( token, "elif", 4 ) == 0 ) { PP_Elif( ptr ); } else if( len == 4 && memcmp( token, "else", 4 ) == 0 ) { PP_Else(); } else if( len == 5 && memcmp( token, "endif", 5 ) == 0 ) { PP_Endif(); } else { if( PPFlags & PPFLAG_ASM_COMMENT ) { // # is also a line-comment char in MS's stupid assembler // so we just return 1 to say we recognized it and the rest // of this delightful preprocessor will take care of eating // the remainder of the line return( 1 ); } return( 0 ); // indicate unrecognized } return( 1 ); // indicate recognized }
static bool scanEnvVarOrFile( const char *name ) /**********************************************/ { /* * Pass nofilenames and analysis of getenv(name) into argc and argv * to doScanParams. Return view on usability of data. (true is usable.) * * Recursion is supported but circularity is rejected. */ typedef struct VarInfo { struct VarInfo *next; char *name; char **argv; /* points into buf */ char buf[1]; /* dynamic array */ } VarInfo; int argc; VarInfo *info; static VarInfo *stack = NULL; // Needed to detect recursion. size_t argvsize; size_t argbufsize; const char *optstring; size_t varlen; // size to hold name copy. bool result; // doScanParams Result. char fbuf[512]; optstring = PP_GetEnv( name ); if( optstring == NULL ) { FILE *fh; fh = fopen( name, "rt" ); if( fh == NULL ) { // RcWarning( ERR_ENV_VAR_NOT_FOUND, name ); return( true ); } fgets( fbuf, sizeof( fbuf ), fh ); fclose( fh ); optstring = fbuf; } // This used to cause stack overflow: set foo=@foo && wrc @foo. for( info = stack; info != NULL; info = info->next ) { #if defined( __UNIX__ ) if( strcmp( name, info->name ) == 0 ) { // Case-sensitive #else if( stricmp( name, info->name ) == 0 ) { // Case-insensitive #endif // RcFatalError( ERR_RCVARIABLE_RECURSIVE, name ); } } argc = ParseVariable( optstring, NULL, NULL ); // count parameters. argbufsize = strlen( optstring ) + 1 + argc; // inter-parameter spaces map to 0 argvsize = argc * sizeof( char * ); // sizeof argv[argc+1] varlen = strlen( name ) + 1; // Copy taken to detect recursion. info = malloc( sizeof( *info ) + argbufsize + argvsize + varlen ); info->next = stack; stack = info; // push info on stack info->argv = (char **)info->buf; ParseVariable( optstring, info->argv, info->buf + argvsize ); info->name = info->buf + argvsize + argbufsize; strcpy( info->name, name ); result = doScanParams( argc, info->argv ); stack = info->next; // pop stack free( info ); return( result ); } static bool doScanParams( int argc, char *argv[] ) /************************************************/ { const char *arg; int switchchar; bool contok; /* continue with main execution */ int currarg; contok = true; switchchar = _dos_switch_char(); for( currarg = 0; currarg < argc && contok; currarg++ ) { arg = argv[currarg]; if( *arg == switchchar || *arg == '-' ) { contok = ScanOptionsArg( arg + 1 ) && contok; } else if( *arg == '@' ) { contok = scanEnvVarOrFile( arg + 1 ) && contok; } else if( *arg == '?' ) { wcpp_quit( usageMsg, NULL ); // contok = false; } else { filenames = realloc( (void *)filenames, ( nofilenames + 1 ) * sizeof( char * ) ); filenames[nofilenames++] = my_strdup( arg ); } } return( contok ); } int main( int argc, char *argv[] ) { int ch; int i; int j; int rc; FILE *fo; if( argc < 2 ) { wcpp_quit( usageMsg, "No filename specified\n" ); } else if( argc == 2 ) { if( !strcmp( argv[1], "?" ) ) { wcpp_quit( usageMsg, NULL ); } } PP_IncludePathInit(); rc = EXIT_FAILURE; if( doScanParams( argc - 1, argv + 1 ) && nofilenames != 0 ) { PP_Init( '#' ); fo = stdout; if( out_filename != NULL ) { fo = fopen( out_filename, "wb" ); } rc = EXIT_SUCCESS; for( i = 0; i < nofilenames; ++i ) { if( PP_FileInit( filenames[i], flags, NULL ) != 0 ) { fprintf( stderr, "Unable to open '%s'\n", filenames[i] ); rc = EXIT_FAILURE; break; } for( j = 0; j < numdefs; j++ ) { PP_Define( defines[j] ); } for( ;; ) { ch = PP_Char(); if( ch == EOF ) break; #ifndef __UNIX__ if( ch == '\n' ) fputc( '\r', fo ); #endif fputc( ch, fo ); } PP_FileFini(); } if( fo == stdout ) { fflush( fo ); } else if( fo != NULL ) { fclose( fo ); } PP_Fini(); } if( out_filename != NULL ) { free( out_filename ); } for( i = 0; i < nofilenames; ++i ) { free( filenames[i] ); } free( (void *)filenames ); for( i = 0; i < numdefs; i++ ) { free( defines[i] ); } free( (void *)defines ); PP_IncludePathFini(); if( rc == EXIT_FAILURE && nofilenames == 0 ) { wcpp_quit( usageMsg, "No filename specified\n" ); } return( rc ); }