int PP_Init2( const char *filename, unsigned flags, const char *include_path, const char *leadbytes ) { FILE *handle; int hash; for( hash = 0; hash < HASH_SIZE; hash++ ) { PPHashTable[hash] = NULL; } NestLevel = 0; SkipLevel = 0; PPFlags = flags; memset( MBCharLen, 0, 256 ); if( leadbytes != NULL ) { PP_SetLeadBytes( leadbytes ); } else if( flags & PPFLAG_DB_KANJI ) { SetRange( 0x81, 0x9f, 1 ); SetRange( 0xe0, 0xfc, 1 ); } else if( flags & PPFLAG_DB_CHINESE ) { SetRange( 0x81, 0xfc, 1 ); } else if( flags & PPFLAG_DB_KOREAN ) { SetRange( 0x81, 0xfd, 1 ); } else if( flags & PPFLAG_UTF8 ) { SetRange( 0xc0, 0xdf, 1 ); SetRange( 0xe0, 0xef, 2 ); SetRange( 0xf0, 0xf7, 3 ); SetRange( 0xf8, 0xfb, 4 ); SetRange( 0xfc, 0xfd, 5 ); } IncludePath2 = PP_Malloc( 1 ); *IncludePath2 = '\0'; IncludePath2 = AddIncludePath( IncludePath2, include_path ); if( (PPFlags & PPFLAG_IGNORE_INCLUDE) == 0 ) { IncludePath2 = AddIncludePath( IncludePath2, PP_GetEnv( "INCLUDE" ) ); } PP_AddMacro( "__LINE__", 8 ); PP_AddMacro( "__FILE__", 8 ); PP_AddMacro( "__DATE__", 8 ); PP_AddMacro( "__TIME__", 8 ); PP_AddMacro( "__STDC__", 8 ); PP_TimeInit(); handle = PP_Open( filename ); if( handle == NULL ) return( -1 ); PP_GenLine(); PPSavedChar = '\0'; PPTokenPtr = PPNextTokenPtr; return( 0 ); }
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 ); }