Changeset b87a5ed for driver/cc1.cc
- Timestamp:
- May 16, 2015, 3:36:19 PM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- a32b204
- Parents:
- b8508a2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
driver/cc1.cc
rb8508a2 rb87a5ed 1 // -*- Mode: C++ -*- 2 // 3 // CForall Version 1.0, Copyright (C) Peter A. Buhr 2005 4 // 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo 3 // 4 // The contents of this file are covered under the licence agreement in the 5 // file "LICENCE" distributed with Cforall. 6 // 5 7 // cc1.cc -- 6 // 7 // Author : Richard C. Bilson8 // 9 // Author : Peter A. Buhr 8 10 // Created On : Fri Aug 26 14:23:51 2005 9 11 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Thu May 14 13:24:45201511 // Update Count : 4 312 // Last Modified On : Sat May 16 07:42:14 2015 13 // Update Count : 49 12 14 // 13 14 15 15 16 #include <iostream> … … 18 19 #include <string> 19 20 using std::string; 20 #include <cstdio> // stderr, stdout, perror, fprintf21 #include <cstdlib> // getenv, exit, mkstemp22 #include <unistd.h> // execvp, fork, unlink23 #include <sys/wait.h> // wait24 25 #include "config.h" // configure info21 #include <cstdio> // stderr, stdout, perror, fprintf 22 #include <cstdlib> // getenv, exit, mkstemp 23 #include <unistd.h> // execvp, fork, unlink 24 #include <sys/wait.h> // wait 25 26 #include "config.h" // configure info 26 27 27 28 … … 29 30 30 31 31 string compiler_name( GCC_PATH ); 32 string compiler_name( GCC_PATH ); // path/name of C compiler 32 33 33 34 string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" ); … … 39 40 40 41 bool prefix( string arg, string pre ) { 41 42 return arg.substr( 0, pre.size() ) == pre; 42 43 } // prefix 43 44 44 45 45 46 void checkEnv( const char *args[], int &nargs ) { 46 char *value; 47 48 value = getenv( "__COMPILER__" ); 49 if ( value != NULL ) { 50 compiler_name = value; 51 #ifdef __DEBUG_H__ 52 cerr << "env arg:\"" << compiler_name << "\"" << endl; 53 #endif // __DEBUG_H__ 54 } // if 55 56 value = getenv( "__GCC_MACHINE__" ); 57 if ( value != NULL ) { 58 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along 59 #ifdef __DEBUG_H__ 60 cerr << "env arg:\"" << args[nargs] << "\"" << endl; 61 #endif // __DEBUG_H__ 47 char *value; 48 49 value = getenv( "__COMPILER__" ); 50 if ( value != NULL ) { 51 compiler_name = value; 52 #ifdef __DEBUG_H__ 53 cerr << "env arg:\"" << compiler_name << "\"" << endl; 54 #endif // __DEBUG_H__ 55 } // if 56 57 value = getenv( "__GCC_MACHINE__" ); 58 if ( value != NULL ) { 59 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along 60 #ifdef __DEBUG_H__ 61 cerr << "env arg:\"" << args[nargs] << "\"" << endl; 62 #endif // __DEBUG_H__ 63 nargs += 1; 64 } // if 65 66 value = getenv( "__GCC_VERSION__" ); 67 if ( value != NULL ) { 68 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along 69 #ifdef __DEBUG_H__ 70 cerr << "env arg:\"" << args[nargs] << "\"" << endl; 71 #endif // __DEBUG_H__ 72 nargs += 1; 73 } // if 74 } // checkEnv 75 76 77 void rmtmpfile() { 78 if ( unlink( tmpname ) == -1 ) { // remove tmpname 79 perror ( "CFA Translator error: cpp failed" ); 80 exit( EXIT_FAILURE ); 81 } // if 82 tmpfilefd = -1; // mark closed 83 } // rmtmpfile 84 85 86 void sigTermHandler( int signal ) { 87 if ( tmpfilefd != -1 ) { // RACE, file created ? 88 rmtmpfile(); // remove 89 exit( EXIT_FAILURE ); // terminate 90 } // if 91 } // sigTermHandler 92 93 94 void Stage1( const int argc, const char * const argv[] ) { 95 int code; 96 int i; 97 98 string arg; 99 string bprefix; 100 101 const char *cpp_in = NULL; 102 const char *cpp_out = NULL; 103 104 bool CFA_flag = false; 105 bool cpp_flag = false; 106 const char *o_name = NULL; 107 108 const char *args[argc + 100]; // leave space for 100 additional cpp command line values 109 int nargs = 1; // number of arguments in args list; 0 => command name 110 const char *uargs[20]; // leave space for 20 additional cfa-cpp command line values 111 int nuargs = 1; // 0 => command name 112 113 signal( SIGINT, sigTermHandler ); 114 signal( SIGTERM, sigTermHandler ); 115 116 // process all the arguments 117 118 checkEnv( args, nargs ); // arguments passed via environment variables 119 120 for ( i = 1; i < argc; i += 1 ) { 121 #ifdef __DEBUG_H__ 122 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; 123 #endif // __DEBUG_H__ 124 arg = argv[i]; 125 #ifdef __DEBUG_H__ 126 cerr << "arg:\"" << arg << "\"" << endl; 127 #endif // __DEBUG_H__ 128 if ( prefix( arg, "-" ) ) { 129 // strip g++ flags that are inappropriate or cause duplicates in subsequent passes 130 131 if ( arg == "-quiet" ) { 132 } else if ( arg == "-imultilib" || arg == "-imultiarch" ) { 133 i += 1; // and the argument 134 } else if ( prefix( arg, "-A" ) ) { 135 } else if ( prefix( arg, "-D__GNU" ) ) { 136 //******** 137 // GCC 5.6.0 SEPARATED THE -D FROM THE ARGUMENT! 138 //******** 139 } else if ( arg == "-D" && prefix( argv[i + 1], "__GNU" ) ) { 140 i += 1; // and the argument 141 142 // strip flags controlling cpp step 143 144 } else if ( arg == "-D__CPP__" ) { 145 cpp_flag = true; 146 } else if ( arg == "-D" && string( argv[i + 1] ) == "__CPP__" ) { 147 i += 1; // and the argument 148 cpp_flag = true; 149 } else if ( arg == "-D__CFA__" ) { 150 CFA_flag = true; 151 } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA__" ) { 152 i += 1; // and the argument 153 CFA_flag = true; 154 } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) { 155 uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str(); 156 nuargs += 1; 157 } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) { 158 uargs[nuargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str(); 159 nuargs += 1; 160 i += 1; // and the argument 161 } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) { 162 bprefix = arg.substr( D__GCC_BPREFIX__.size() ); 163 } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) { 164 bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 ); 165 i += 1; // and the argument 166 167 // all other flags 168 169 } else if ( arg == "-o" ) { 170 i += 1; 171 o_name = argv[i]; 172 } else { 173 args[nargs] = argv[i]; // pass the flag along 174 nargs += 1; 175 // CPP flags with an argument 176 if ( arg == "-D" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" || 177 arg == "-include" || arg == "-imacros" || arg == "-idirafter" || arg == "-iprefix" || 178 arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) { 179 i += 1; 180 args[nargs] = argv[i]; // pass the argument along 181 nargs += 1; 182 #ifdef __DEBUG_H__ 183 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; 184 #endif // __DEBUG_H__ 185 } else if ( arg == "-MD" || arg == "-MMD" ) { 186 args[nargs] = "-MF"; // insert before file 187 nargs += 1; 188 i += 1; 189 args[nargs] = argv[i]; // pass the argument along 190 nargs += 1; 191 #ifdef __DEBUG_H__ 192 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; 193 #endif // __DEBUG_H__ 194 } // if 195 } // if 196 } else { // obtain input and possibly output files 197 if ( cpp_in == NULL ) { 198 cpp_in = argv[i]; 199 #ifdef __DEBUG_H__ 200 cerr << "cpp_in:\"" << cpp_in << "\"" << endl; 201 #endif // __DEBUG_H__ 202 } else if ( cpp_out == NULL ) { 203 cpp_out = argv[i]; 204 #ifdef __DEBUG_H__ 205 cerr << "cpp_out:\"" << cpp_out << "\""<< endl; 206 #endif // __DEBUG_H__ 207 } else { 208 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl; 209 exit( EXIT_FAILURE ); 210 } // if 211 } // if 212 } // for 213 214 #ifdef __DEBUG_H__ 215 cerr << "args:"; 216 for ( i = 1; i < nargs; i += 1 ) { 217 cerr << " " << args[i]; 218 } // for 219 if ( cpp_in != NULL ) cerr << " " << cpp_in; 220 if ( cpp_out != NULL ) cerr << " " << cpp_out; 221 cerr << endl; 222 #endif // __DEBUG_H__ 223 224 if ( cpp_in == NULL ) { 225 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl; 226 exit( EXIT_FAILURE ); 227 } // if 228 229 if ( cpp_flag ) { 230 // The -E flag is specified on the cfa command so only run the preprocessor and output is written to standard 231 // output or -o. The call to cfa has a -E so it does not have to be added to the argument list. 232 233 args[0] = compiler_name.c_str(); 234 args[nargs] = cpp_in; 235 nargs += 1; 236 if ( o_name != NULL ) { // location for output 237 args[nargs] = "-o"; 238 nargs += 1; 239 args[nargs] = o_name; 240 nargs += 1; 241 } // if 242 args[nargs] = NULL; // terminate argument list 243 244 #ifdef __DEBUG_H__ 245 cerr << "nargs: " << nargs << endl; 246 for ( i = 0; args[i] != NULL; i += 1 ) { 247 cerr << args[i] << " "; 248 } // for 249 cerr << endl; 250 #endif // __DEBUG_H__ 251 252 execvp( args[0], (char *const *)args ); // should not return 253 perror( "CFA Translator error: cpp level, execvp" ); 254 exit( EXIT_FAILURE ); 255 } // if 256 257 // Create a temporary file to store output of the C preprocessor. 258 259 tmpfilefd = mkstemp( tmpname ); 260 if ( tmpfilefd == -1 ) { 261 perror( "CFA Translator error: cpp level, mkstemp" ); 262 exit( EXIT_FAILURE ); 263 } // if 264 265 #ifdef __DEBUG_H__ 266 cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl; 267 #endif // __DEBUG_H__ 268 269 // Run the C preprocessor and save the output in tmpfile. 270 271 if ( fork() == 0 ) { // child process ? 272 // -o xxx.ii cannot be used to write the output file from cpp because no output file is created if cpp detects 273 // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error, 274 // when cpp writes to stdout. Hence, stdout is redirected into the temporary file. 275 if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname 276 perror( "CFA Translator error: cpp level, freopen" ); 277 exit( EXIT_FAILURE ); 278 } // if 279 280 args[0] = compiler_name.c_str(); 281 args[nargs] = cpp_in; // input to cpp 282 nargs += 1; 283 args[nargs] = NULL; // terminate argument list 284 285 #ifdef __DEBUG_H__ 286 cerr << "cpp nargs: " << nargs << endl; 287 for ( i = 0; args[i] != NULL; i += 1 ) { 288 cerr << args[i] << " "; 289 } // for 290 cerr << endl; 291 #endif // __DEBUG_H__ 292 293 execvp( args[0], (char *const *)args ); // should not return 294 perror( "CFA Translator error: cpp level, execvp" ); 295 exit( EXIT_FAILURE ); 296 } // if 297 298 wait( &code ); // wait for child to finish 299 300 #ifdef __DEBUG_H__ 301 cerr << "return code from cpp:" << WEXITSTATUS(code) << endl; 302 #endif // __DEBUG_H__ 303 304 if ( WIFSIGNALED(code) != 0 ) { // child failed ? 305 rmtmpfile(); // remove tmpname 306 cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl; 307 exit( EXIT_FAILURE ); 308 } // if 309 310 if ( WEXITSTATUS(code) != 0 ) { // child error ? 311 rmtmpfile(); // remove tmpname 312 exit( WEXITSTATUS( code ) ); // do not continue 313 } // if 314 315 // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard 316 // output. Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file. 317 318 if ( fork() == 0 ) { // child runs CFA 319 uargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str(); 320 321 uargs[nuargs] = "-p"; 322 nuargs += 1; 323 324 uargs[nuargs] = tmpname; 325 nuargs += 1; 326 if ( o_name != NULL ) { 327 uargs[nuargs] = o_name; 328 nuargs += 1; 329 } else if ( ! CFA_flag ) { // run cfa-cpp ? 330 uargs[nuargs] = cpp_out; 331 nuargs += 1; 332 } // if 333 uargs[nuargs] = NULL; // terminate argument list 334 335 #ifdef __DEBUG_H__ 336 cerr << "cfa-cpp nuargs: " << o_name << " " << CFA_flag << " " << nuargs << endl; 337 for ( i = 0; uargs[i] != NULL; i += 1 ) { 338 cerr << uargs[i] << " "; 339 } // for 340 cerr << endl; 341 #endif // __DEBUG_H__ 342 343 execvp( uargs[0], (char * const *)uargs ); // should not return 344 perror( "CFA Translator error: cpp level, execvp" ); 345 exit( EXIT_FAILURE ); 346 } // if 347 348 wait( &code ); // wait for child to finish 349 350 #ifdef __DEBUG_H__ 351 cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl; 352 #endif // __DEBUG_H__ 353 354 // Must unlink here because file must exist across execvp. 355 rmtmpfile(); // remove tmpname 356 357 if ( WIFSIGNALED(code) ) { // child failed ? 358 cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl; 359 exit( EXIT_FAILURE ); 360 } // if 361 362 exit( WEXITSTATUS(code) ); 363 } // Stage1 364 365 366 void Stage2( const int argc, const char * const * argv ) { 367 int i; 368 369 string arg; 370 371 const char *cpp_in = NULL; 372 373 const char *args[argc + 100]; // leave space for 100 additional cfa command line values 374 int nargs = 1; // number of arguments in args list; 0 => command name 375 376 // process all the arguments 377 378 checkEnv( args, nargs ); // arguments passed via environment variables 379 380 for ( i = 1; i < argc; i += 1 ) { 381 #ifdef __DEBUG_H__ 382 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; 383 #endif // __DEBUG_H__ 384 arg = argv[i]; 385 #ifdef __DEBUG_H__ 386 cerr << "arg:\"" << arg << "\"" << endl; 387 #endif // __DEBUG_H__ 388 if ( prefix( arg, "-" ) ) { 389 // strip inappropriate flags 390 391 if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" || 392 // Currently CFA does not suppose precompiled .h files. 393 prefix( arg, "--output-pch" ) ) { 394 395 // strip inappropriate flags with an argument 396 397 } else if ( arg == "-auxbase" || arg == "-auxbase-strip" || arg == "-dumpbase" ) { 398 i += 1; 399 #ifdef __DEBUG_H__ 400 cerr << "arg:\"" << argv[i] << "\"" << endl; 401 #endif // __DEBUG_H__ 402 403 // all other flags 404 405 } else { 406 args[nargs] = argv[i]; // pass the flag along 407 nargs += 1; 408 if ( arg == "-o" ) { 409 i += 1; 410 args[nargs] = argv[i]; // pass the argument along 411 nargs += 1; 412 #ifdef __DEBUG_H__ 413 cerr << "arg:\"" << argv[i] << "\"" << endl; 414 #endif // __DEBUG_H__ 415 } // if 416 } // if 417 } else { // obtain input and possibly output files 418 if ( cpp_in == NULL ) { 419 cpp_in = argv[i]; 420 #ifdef __DEBUG_H__ 421 cerr << "cpp_in:\"" << cpp_in << "\"" << endl; 422 #endif // __DEBUG_H__ 423 } else { 424 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl; 425 exit( EXIT_FAILURE ); 426 } // if 427 } // if 428 } // for 429 430 #ifdef __DEBUG_H__ 431 cerr << "args:"; 432 for ( i = 1; i < nargs; i += 1 ) { 433 cerr << " " << args[i]; 434 } // for 435 cerr << endl; 436 if ( cpp_in != NULL ) cerr << " " << cpp_in; 437 #endif // __DEBUG_H__ 438 439 args[0] = compiler_name.c_str(); 440 args[nargs] = "-S"; // only compile and put assembler output in specified file 62 441 nargs += 1; 63 } // if64 65 value = getenv( "__GCC_VERSION__" );66 if ( value != NULL ) {67 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along68 #ifdef __DEBUG_H__69 cerr << "env arg:\"" << args[nargs] << "\"" << endl;70 #endif // __DEBUG_H__71 nargs += 1;72 } // if73 } // checkEnv74 75 76 void rmtmpfile() {77 if ( unlink( tmpname ) == -1 ) { // remove tmpname78 perror ( "CFA Translator error: cpp failed" );79 exit( EXIT_FAILURE );80 } // if81 tmpfilefd = -1; // mark closed82 } // rmtmpfile83 84 85 void sigTermHandler( int signal ) {86 if ( tmpfilefd != -1 ) { // RACE, file created ?87 rmtmpfile(); // remove88 exit( EXIT_FAILURE ); // terminate89 } // if90 } // sigTermHandler91 92 93 void Stage1( const int argc, const char * const argv[] ) {94 int code;95 int i;96 97 string arg;98 string bprefix;99 100 const char *cpp_in = NULL;101 const char *cpp_out = NULL;102 103 bool CFA_flag = false;104 bool cpp_flag = false;105 const char *o_name = NULL;106 107 const char *args[argc + 100]; // leave space for 100 additional cpp command line values108 int nargs = 1; // number of arguments in args list; 0 => command name109 const char *uargs[20]; // leave space for 20 additional cfa-cpp command line values110 int nuargs = 1; // 0 => command name111 112 signal( SIGINT, sigTermHandler );113 signal( SIGTERM, sigTermHandler );114 115 // process all the arguments116 117 checkEnv( args, nargs ); // arguments passed via environment variables118 119 for ( i = 1; i < argc; i += 1 ) {120 #ifdef __DEBUG_H__121 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;122 #endif // __DEBUG_H__123 arg = argv[i];124 #ifdef __DEBUG_H__125 cerr << "arg:\"" << arg << "\"" << endl;126 #endif // __DEBUG_H__127 if ( prefix( arg, "-" ) ) {128 // strip g++ flags that are inappropriate or cause duplicates in subsequent passes129 130 if ( arg == "-quiet" ) {131 } else if ( arg == "-imultilib" || arg == "-imultiarch" ) {132 i += 1; // and the argument133 } else if ( prefix( arg, "-A" ) ) {134 } else if ( prefix( arg, "-D__GNU" ) ) {135 //********136 // GCC 5.6.0 SEPARATED THE -D FROM THE ARGUMENT!137 //********138 } else if ( arg == "-D" && prefix( argv[i + 1], "__GNU" ) ) {139 i += 1; // and the argument140 141 // strip flags controlling cpp step142 143 } else if ( arg == "-D__CPP__" ) {144 cpp_flag = true;145 } else if ( arg == "-D" && string( argv[i + 1] ) == "__CPP__" ) {146 i += 1; // and the argument147 cpp_flag = true;148 } else if ( arg == "-D__CFA__" ) {149 CFA_flag = true;150 } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA__" ) {151 i += 1; // and the argument152 CFA_flag = true;153 } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {154 uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();155 nuargs += 1;156 } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {157 uargs[nuargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();158 nuargs += 1;159 i += 1; // and the argument160 } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {161 bprefix = arg.substr( D__GCC_BPREFIX__.size() );162 } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) {163 bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 );164 i += 1; // and the argument165 166 // all other flags167 168 } else if ( arg == "-o" ) {169 i += 1;170 o_name = argv[i];171 } else {172 args[nargs] = argv[i]; // pass the flag along173 nargs += 1;174 // CPP flags with an argument175 if ( arg == "-D" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" ||176 arg == "-include" || arg == "-imacros" || arg == "-idirafter" || arg == "-iprefix" ||177 arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) {178 i += 1;179 args[nargs] = argv[i]; // pass the argument along180 nargs += 1;181 #ifdef __DEBUG_H__182 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;183 #endif // __DEBUG_H__184 } else if ( arg == "-MD" || arg == "-MMD" ) {185 args[nargs] = "-MF"; // insert before file186 nargs += 1;187 i += 1;188 args[nargs] = argv[i]; // pass the argument along189 nargs += 1;190 #ifdef __DEBUG_H__191 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;192 #endif // __DEBUG_H__193 } // if194 } // if195 } else { // obtain input and possibly output files196 if ( cpp_in == NULL ) {197 cpp_in = argv[i];198 #ifdef __DEBUG_H__199 cerr << "cpp_in:\"" << cpp_in << "\"" << endl;200 #endif // __DEBUG_H__201 } else if ( cpp_out == NULL ) {202 cpp_out = argv[i];203 #ifdef __DEBUG_H__204 cerr << "cpp_out:\"" << cpp_out << "\""<< endl;205 #endif // __DEBUG_H__206 } else {207 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;208 exit( EXIT_FAILURE );209 } // if210 } // if211 } // for212 213 #ifdef __DEBUG_H__214 cerr << "args:";215 for ( i = 1; i < nargs; i += 1 ) {216 cerr << " " << args[i];217 } // for218 if ( cpp_in != NULL ) cerr << " " << cpp_in;219 if ( cpp_out != NULL ) cerr << " " << cpp_out;220 cerr << endl;221 #endif // __DEBUG_H__222 223 if ( cpp_in == NULL ) {224 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;225 exit( EXIT_FAILURE );226 } // if227 228 if ( cpp_flag ) {229 // The -E flag is specified on the cfa command so only run the preprocessor and output is written to standard230 // output or -o. The call to cfa has a -E so it does not have to be added to the argument list.231 232 args[0] = compiler_name.c_str();233 442 args[nargs] = cpp_in; 234 443 nargs += 1; 235 if ( o_name != NULL ) { // location for output 236 args[nargs] = "-o"; 237 nargs += 1; 238 args[nargs] = o_name; 239 nargs += 1; 240 } // if 241 args[nargs] = NULL; // terminate argument list 242 243 #ifdef __DEBUG_H__ 244 cerr << "nargs: " << nargs << endl; 444 args[nargs] = NULL; // terminate argument list 445 446 #ifdef __DEBUG_H__ 447 cerr << "stage2 nargs: " << nargs << endl; 245 448 for ( i = 0; args[i] != NULL; i += 1 ) { 246 449 cerr << args[i] << " "; 247 450 } // for 248 451 cerr << endl; 249 452 #endif // __DEBUG_H__ 250 453 251 execvp( args[0], (char * const *)args );// should not return454 execvp( args[0], (char * const *)args ); // should not return 252 455 perror( "CFA Translator error: cpp level, execvp" ); 253 exit( EXIT_FAILURE ); 254 } // if 255 256 // Create a temporary file to store output of the C preprocessor. 257 258 tmpfilefd = mkstemp( tmpname ); 259 if ( tmpfilefd == -1 ) { 260 perror( "CFA Translator error: cpp level, mkstemp" ); 261 exit( EXIT_FAILURE ); 262 } // if 263 264 #ifdef __DEBUG_H__ 265 cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl; 266 #endif // __DEBUG_H__ 267 268 // Run the C preprocessor and save the output in tmpfile. 269 270 if ( fork() == 0 ) { // child process ? 271 // -o xxx.ii cannot be used to write the output file from cpp because no output file is created if cpp detects 272 // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error, 273 // when cpp writes to stdout. Hence, stdout is redirected into the temporary file. 274 if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname 275 perror( "CFA Translator error: cpp level, freopen" ); 276 exit( EXIT_FAILURE ); 277 } // if 278 279 args[0] = compiler_name.c_str(); 280 args[nargs] = cpp_in; // input to cpp 281 nargs += 1; 282 args[nargs] = NULL; // terminate argument list 283 284 #ifdef __DEBUG_H__ 285 cerr << "cpp nargs: " << nargs << endl; 286 for ( i = 0; args[i] != NULL; i += 1 ) { 287 cerr << args[i] << " "; 288 } // for 289 cerr << endl; 290 #endif // __DEBUG_H__ 291 292 execvp( args[0], (char *const *)args ); // should not return 293 perror( "CFA Translator error: cpp level, execvp" ); 294 exit( EXIT_FAILURE ); 295 } // if 296 297 wait( &code ); // wait for child to finish 298 299 #ifdef __DEBUG_H__ 300 cerr << "return code from cpp:" << WEXITSTATUS(code) << endl; 301 #endif // __DEBUG_H__ 302 303 if ( WIFSIGNALED(code) != 0 ) { // child failed ? 304 rmtmpfile(); // remove tmpname 305 cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl; 306 exit( EXIT_FAILURE ); 307 } // if 308 309 if ( WEXITSTATUS(code) != 0 ) { // child error ? 310 rmtmpfile(); // remove tmpname 311 exit( WEXITSTATUS( code ) ); // do not continue 312 } // if 313 314 // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard 315 // output. Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file. 316 317 if ( fork() == 0 ) { // child runs CFA 318 uargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str(); 319 320 uargs[nuargs] = "-p"; 321 nuargs += 1; 322 323 uargs[nuargs] = tmpname; 324 nuargs += 1; 325 if ( o_name != NULL ) { 326 uargs[nuargs] = o_name; 327 nuargs += 1; 328 } else if ( ! CFA_flag ) { // run cfa-cpp ? 329 uargs[nuargs] = cpp_out; 330 nuargs += 1; 331 } // if 332 uargs[nuargs] = NULL; // terminate argument list 333 334 #ifdef __DEBUG_H__ 335 cerr << "cfa-cpp nuargs: " << o_name << " " << CFA_flag << " " << nuargs << endl; 336 for ( i = 0; uargs[i] != NULL; i += 1 ) { 337 cerr << uargs[i] << " "; 338 } // for 339 cerr << endl; 340 #endif // __DEBUG_H__ 341 342 execvp( uargs[0], (char * const *)uargs ); // should not return 343 perror( "CFA Translator error: cpp level, execvp" ); 344 exit( EXIT_FAILURE ); 345 } // if 346 347 wait( &code ); // wait for child to finish 348 349 #ifdef __DEBUG_H__ 350 cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl; 351 #endif // __DEBUG_H__ 352 353 // Must unlink here because file must exist across execvp. 354 rmtmpfile(); // remove tmpname 355 356 if ( WIFSIGNALED(code) ) { // child failed ? 357 cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl; 358 exit( EXIT_FAILURE ); 359 } // if 360 361 exit( WEXITSTATUS(code) ); 362 } // Stage1 363 364 365 void Stage2( const int argc, const char * const * argv ) { 366 int i; 367 368 string arg; 369 370 const char *cpp_in = NULL; 371 372 const char *args[argc + 100]; // leave space for 100 additional cfa command line values 373 int nargs = 1; // number of arguments in args list; 0 => command name 374 375 // process all the arguments 376 377 checkEnv( args, nargs ); // arguments passed via environment variables 378 379 for ( i = 1; i < argc; i += 1 ) { 380 #ifdef __DEBUG_H__ 381 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl; 382 #endif // __DEBUG_H__ 383 arg = argv[i]; 384 #ifdef __DEBUG_H__ 385 cerr << "arg:\"" << arg << "\"" << endl; 386 #endif // __DEBUG_H__ 387 if ( prefix( arg, "-" ) ) { 388 // strip inappropriate flags 389 390 if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" || 391 // Currently CFA does not suppose precompiled .h files. 392 prefix( arg, "--output-pch" ) ) { 393 394 // strip inappropriate flags with an argument 395 396 } else if ( arg == "-auxbase" || arg == "-auxbase-strip" || arg == "-dumpbase" ) { 397 i += 1; 398 #ifdef __DEBUG_H__ 399 cerr << "arg:\"" << argv[i] << "\"" << endl; 400 #endif // __DEBUG_H__ 401 402 // all other flags 403 404 } else { 405 args[nargs] = argv[i]; // pass the flag along 406 nargs += 1; 407 if ( arg == "-o" ) { 408 i += 1; 409 args[nargs] = argv[i]; // pass the argument along 410 nargs += 1; 411 #ifdef __DEBUG_H__ 412 cerr << "arg:\"" << argv[i] << "\"" << endl; 413 #endif // __DEBUG_H__ 414 } // if 415 } // if 416 } else { // obtain input and possibly output files 417 if ( cpp_in == NULL ) { 418 cpp_in = argv[i]; 419 #ifdef __DEBUG_H__ 420 cerr << "cpp_in:\"" << cpp_in << "\"" << endl; 421 #endif // __DEBUG_H__ 422 } else { 456 exit( EXIT_FAILURE ); // tell gcc not to go any further 457 } // Stage2 458 459 460 int main( const int argc, const char * const argv[], const char * const env[] ) { 461 #ifdef __DEBUG_H__ 462 for ( int i = 0; env[i] != NULL; i += 1 ) { 463 cerr << env[i] << endl; 464 } // for 465 #endif // __DEBUG_H__ 466 467 string arg = argv[1]; 468 469 // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed. 470 471 if ( arg == "-E" ) { 472 #ifdef __DEBUG_H__ 473 cerr << "Stage1" << endl; 474 #endif // __DEBUG_H__ 475 Stage1( argc, argv ); 476 } else if ( arg == "-fpreprocessed" ) { 477 #ifdef __DEBUG_H__ 478 cerr << "Stage2" << endl; 479 #endif // __DEBUG_H__ 480 Stage2( argc, argv ); 481 } else { 423 482 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl; 424 483 exit( EXIT_FAILURE ); 425 } // if 426 } // if 427 } // for 428 429 #ifdef __DEBUG_H__ 430 cerr << "args:"; 431 for ( i = 1; i < nargs; i += 1 ) { 432 cerr << " " << args[i]; 433 } // for 434 cerr << endl; 435 if ( cpp_in != NULL ) cerr << " " << cpp_in; 436 #endif // __DEBUG_H__ 437 438 args[0] = compiler_name.c_str(); 439 args[nargs] = "-S"; // only compile and put assembler output in specified file 440 nargs += 1; 441 args[nargs] = cpp_in; 442 nargs += 1; 443 args[nargs] = NULL; // terminate argument list 444 445 #ifdef __DEBUG_H__ 446 cerr << "stage2 nargs: " << nargs << endl; 447 for ( i = 0; args[i] != NULL; i += 1 ) { 448 cerr << args[i] << " "; 449 } // for 450 cerr << endl; 451 #endif // __DEBUG_H__ 452 453 execvp( args[0], (char * const *)args ); // should not return 454 perror( "CFA Translator error: cpp level, execvp" ); 455 exit( EXIT_FAILURE ); // tell gcc not to go any further 456 } // Stage2 457 458 459 int main( const int argc, const char * const argv[], const char * const env[] ) { 460 #ifdef __DEBUG_H__ 461 for ( int i = 0; env[i] != NULL; i += 1 ) { 462 cerr << env[i] << endl; 463 } // for 464 #endif // __DEBUG_H__ 465 466 string arg = argv[1]; 467 468 // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed. 469 470 if ( arg == "-E" ) { 471 #ifdef __DEBUG_H__ 472 cerr << "Stage1" << endl; 473 #endif // __DEBUG_H__ 474 Stage1( argc, argv ); 475 } else if ( arg == "-fpreprocessed" ) { 476 #ifdef __DEBUG_H__ 477 cerr << "Stage2" << endl; 478 #endif // __DEBUG_H__ 479 Stage2( argc, argv ); 480 } else { 481 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl; 482 exit( EXIT_FAILURE ); 483 } // if 484 } // if 484 485 } // main 485 486 486 487 487 // Local Variables: // 488 // tab-width: 4 // 489 // mode: c++ // 488 490 // compile-command: "make install" // 489 491 // End: //
Note: See TracChangeset
for help on using the changeset viewer.