| [b87a5ed] | 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 | //
 | 
|---|
| [51b73452] | 7 | // cc1.cc -- 
 | 
|---|
| [b87a5ed] | 8 | //
 | 
|---|
 | 9 | // Author           : Peter A. Buhr
 | 
|---|
| [51b73452] | 10 | // Created On       : Fri Aug 26 14:23:51 2005
 | 
|---|
 | 11 | // Last Modified By : Peter A. Buhr
 | 
|---|
| [d3b7937] | 12 | // Last Modified On : Mon Jan 25 16:05:15 2016
 | 
|---|
 | 13 | // Update Count     : 56
 | 
|---|
| [51b73452] | 14 | //
 | 
|---|
 | 15 | 
 | 
|---|
 | 16 | #include <iostream>
 | 
|---|
 | 17 | using std::cerr;
 | 
|---|
 | 18 | using std::endl;
 | 
|---|
 | 19 | #include <string>
 | 
|---|
 | 20 | using std::string;
 | 
|---|
| [b87a5ed] | 21 | #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
 | 
|---|
| [51b73452] | 25 | 
 | 
|---|
| [b87a5ed] | 26 | #include "config.h"                                                                             // configure info
 | 
|---|
| [51b73452] | 27 | 
 | 
|---|
 | 28 | 
 | 
|---|
 | 29 | //#define __DEBUG_H__
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 | 
 | 
|---|
| [b87a5ed] | 32 | string compiler_name( GCC_PATH );                                               // path/name of C compiler
 | 
|---|
| [51b73452] | 33 | 
 | 
|---|
 | 34 | string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" );
 | 
|---|
| [d9a0e76] | 35 | string D__CFA_FLAGPREFIX__( "-D__CFA_FLAG__=" );
 | 
|---|
| [51b73452] | 36 | 
 | 
|---|
| [bdd516a] | 37 | char tmpname[] = P_tmpdir "/CFAXXXXXX";
 | 
|---|
 | 38 | int tmpfilefd = -1;
 | 
|---|
 | 39 | 
 | 
|---|
| [51b73452] | 40 | 
 | 
|---|
 | 41 | bool prefix( string arg, string pre ) {
 | 
|---|
| [b87a5ed] | 42 |         return arg.substr( 0, pre.size() ) == pre;
 | 
|---|
| [51b73452] | 43 | } // prefix
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 | 
 | 
|---|
 | 46 | void checkEnv( const char *args[], int &nargs ) {
 | 
|---|
| [b87a5ed] | 47 |         char *value;
 | 
|---|
| [51b73452] | 48 | 
 | 
|---|
| [b87a5ed] | 49 |         value = getenv( "__COMPILER__" );
 | 
|---|
 | 50 |         if ( value != NULL ) {
 | 
|---|
 | 51 |                 compiler_name = value;
 | 
|---|
| [51b73452] | 52 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 53 |                 cerr << "env arg:\"" << compiler_name << "\"" << endl;
 | 
|---|
| [51b73452] | 54 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 55 |         } // if
 | 
|---|
| [51b73452] | 56 | 
 | 
|---|
| [b87a5ed] | 57 |         value = getenv( "__GCC_MACHINE__" );
 | 
|---|
 | 58 |         if ( value != NULL ) {
 | 
|---|
 | 59 |                 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
 | 
|---|
| [51b73452] | 60 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 61 |                 cerr << "env arg:\"" << args[nargs] << "\"" << endl;
 | 
|---|
| [51b73452] | 62 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 63 |                 nargs += 1;
 | 
|---|
 | 64 |         } // if
 | 
|---|
| [51b73452] | 65 | 
 | 
|---|
| [b87a5ed] | 66 |         value = getenv( "__GCC_VERSION__" );
 | 
|---|
 | 67 |         if ( value != NULL ) {
 | 
|---|
 | 68 |                 args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
 | 
|---|
| [51b73452] | 69 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 70 |                 cerr << "env arg:\"" << args[nargs] << "\"" << endl;
 | 
|---|
| [51b73452] | 71 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 72 |                 nargs += 1;
 | 
|---|
 | 73 |         } // if
 | 
|---|
| [51b73452] | 74 | } // checkEnv
 | 
|---|
 | 75 | 
 | 
|---|
 | 76 | 
 | 
|---|
| [bdd516a] | 77 | void rmtmpfile() {
 | 
|---|
| [b87a5ed] | 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
 | 
|---|
| [bdd516a] | 83 | } // rmtmpfile
 | 
|---|
 | 84 | 
 | 
|---|
 | 85 | 
 | 
|---|
 | 86 | void sigTermHandler( int signal ) {
 | 
|---|
| [b87a5ed] | 87 |         if ( tmpfilefd != -1 ) {                                                        // RACE, file created ?
 | 
|---|
 | 88 |                 rmtmpfile();                                                                    // remove
 | 
|---|
 | 89 |                 exit( EXIT_FAILURE );                                                   // terminate 
 | 
|---|
 | 90 |         } // if
 | 
|---|
| [bdd516a] | 91 | } // sigTermHandler
 | 
|---|
 | 92 | 
 | 
|---|
 | 93 | 
 | 
|---|
| [51b73452] | 94 | void Stage1( const int argc, const char * const argv[] ) {
 | 
|---|
| [b87a5ed] | 95 |         int code;
 | 
|---|
 | 96 |         int i;
 | 
|---|
| [51b73452] | 97 | 
 | 
|---|
| [b87a5ed] | 98 |         string arg;
 | 
|---|
 | 99 |         string bprefix;
 | 
|---|
| [51b73452] | 100 | 
 | 
|---|
| [b87a5ed] | 101 |         const char *cpp_in = NULL;
 | 
|---|
 | 102 |         const char *cpp_out = NULL;
 | 
|---|
| [51b73452] | 103 | 
 | 
|---|
| [b87a5ed] | 104 |         bool CFA_flag = false;
 | 
|---|
 | 105 |         bool cpp_flag = false;
 | 
|---|
 | 106 |         const char *o_name = NULL;
 | 
|---|
| [51b73452] | 107 | 
 | 
|---|
| [b87a5ed] | 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
 | 
|---|
| [51b73452] | 112 | 
 | 
|---|
| [b87a5ed] | 113 |         signal( SIGINT,  sigTermHandler );
 | 
|---|
 | 114 |         signal( SIGTERM, sigTermHandler );
 | 
|---|
| [bdd516a] | 115 | 
 | 
|---|
| [b87a5ed] | 116 |         // process all the arguments
 | 
|---|
| [51b73452] | 117 | 
 | 
|---|
| [b87a5ed] | 118 |         checkEnv( args, nargs );                                                        // arguments passed via environment variables
 | 
|---|
| [51b73452] | 119 | 
 | 
|---|
| [b87a5ed] | 120 |         for ( i = 1; i < argc; i += 1 ) {
 | 
|---|
| [51b73452] | 121 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 122 |                 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 123 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 124 |                 arg = argv[i];
 | 
|---|
| [51b73452] | 125 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 126 |                 cerr << "arg:\"" << arg << "\"" << endl;
 | 
|---|
| [51b73452] | 127 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 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;
 | 
|---|
| [51b73452] | 182 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 183 |                                         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 184 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 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;
 | 
|---|
| [51b73452] | 191 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 192 |                                         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 193 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 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];
 | 
|---|
| [51b73452] | 204 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 205 |                                 cerr << "cpp_out:\"" << cpp_out << "\""<< endl;
 | 
|---|
| [51b73452] | 206 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 207 |                         } else {
 | 
|---|
 | 208 |                                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 209 |                                 exit( EXIT_FAILURE );
 | 
|---|
 | 210 |                         } // if
 | 
|---|
 | 211 |                 } // if
 | 
|---|
 | 212 |         } // for
 | 
|---|
 | 213 | 
 | 
|---|
| [51b73452] | 214 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 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;
 | 
|---|
| [51b73452] | 222 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 223 | 
 | 
|---|
 | 224 |         if ( cpp_in == NULL ) {
 | 
|---|
| [51b73452] | 225 |                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 226 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 227 |         } // if
 | 
|---|
| [b87a5ed] | 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
 | 
|---|
| [51b73452] | 243 | 
 | 
|---|
 | 244 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 245 |                 cerr << "nargs: " << nargs << endl;
 | 
|---|
 | 246 |                 for ( i = 0; args[i] != NULL; i += 1 ) {
 | 
|---|
 | 247 |                         cerr << args[i] << " ";
 | 
|---|
 | 248 |                 } // for
 | 
|---|
 | 249 |                 cerr << endl;
 | 
|---|
| [51b73452] | 250 | #endif // __DEBUG_H__
 | 
|---|
 | 251 | 
 | 
|---|
| [b87a5ed] | 252 |                 execvp( args[0], (char *const *)args );                 // should not return
 | 
|---|
 | 253 |                 perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 254 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 255 |         } // if
 | 
|---|
| [51b73452] | 256 | 
 | 
|---|
| [b87a5ed] | 257 |         // Create a temporary file to store output of the C preprocessor.
 | 
|---|
| [51b73452] | 258 | 
 | 
|---|
| [b87a5ed] | 259 |         tmpfilefd = mkstemp( tmpname );
 | 
|---|
 | 260 |         if ( tmpfilefd == -1 ) {
 | 
|---|
 | 261 |                 perror( "CFA Translator error: cpp level, mkstemp" );
 | 
|---|
 | 262 |                 exit( EXIT_FAILURE );
 | 
|---|
| [51b73452] | 263 |         } // if
 | 
|---|
 | 264 | 
 | 
|---|
 | 265 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 266 |         cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl;
 | 
|---|
| [51b73452] | 267 | #endif // __DEBUG_H__
 | 
|---|
 | 268 | 
 | 
|---|
| [b87a5ed] | 269 |         // Run the C preprocessor and save the output in tmpfile.
 | 
|---|
| [51b73452] | 270 | 
 | 
|---|
| [b87a5ed] | 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
 | 
|---|
| [51b73452] | 279 | 
 | 
|---|
| [b87a5ed] | 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
 | 
|---|
| [51b73452] | 284 | 
 | 
|---|
 | 285 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 286 |                 cerr << "cpp nargs: " << nargs << endl;
 | 
|---|
 | 287 |                 for ( i = 0; args[i] != NULL; i += 1 ) {
 | 
|---|
 | 288 |                         cerr << args[i] << " ";
 | 
|---|
 | 289 |                 } // for
 | 
|---|
 | 290 |                 cerr << endl;
 | 
|---|
| [51b73452] | 291 | #endif // __DEBUG_H__
 | 
|---|
 | 292 | 
 | 
|---|
| [b87a5ed] | 293 |                 execvp( args[0], (char *const *)args );                 // should not return
 | 
|---|
 | 294 |                 perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 295 |                 exit( EXIT_FAILURE );
 | 
|---|
| [51b73452] | 296 |         } // if
 | 
|---|
 | 297 | 
 | 
|---|
| [b87a5ed] | 298 |         wait( &code );                                                                          // wait for child to finish
 | 
|---|
| [51b73452] | 299 | 
 | 
|---|
 | 300 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 301 |         cerr << "return code from cpp:" << WEXITSTATUS(code) << endl;
 | 
|---|
| [51b73452] | 302 | #endif // __DEBUG_H__
 | 
|---|
 | 303 | 
 | 
|---|
| [b87a5ed] | 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
 | 
|---|
| [51b73452] | 309 | 
 | 
|---|
| [b87a5ed] | 310 |         if ( WEXITSTATUS(code) != 0 ) {                                         // child error ?
 | 
|---|
 | 311 |                 rmtmpfile();                                                                    // remove tmpname
 | 
|---|
 | 312 |                 exit( WEXITSTATUS( code ) );                                    // do not continue
 | 
|---|
 | 313 |         } // if
 | 
|---|
| [51b73452] | 314 | 
 | 
|---|
| [b87a5ed] | 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.
 | 
|---|
| [51b73452] | 317 | 
 | 
|---|
| [b87a5ed] | 318 |         if ( fork() == 0 ) {                                                            // child runs CFA
 | 
|---|
 | 319 |                 uargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
 | 
|---|
 | 320 | 
 | 
|---|
 | 321 |                 uargs[nuargs] = tmpname;
 | 
|---|
 | 322 |                 nuargs += 1;
 | 
|---|
 | 323 |                 if ( o_name != NULL ) {
 | 
|---|
 | 324 |                         uargs[nuargs] = o_name;
 | 
|---|
 | 325 |                         nuargs += 1;
 | 
|---|
 | 326 |                 } else if ( ! CFA_flag ) {                                              // run cfa-cpp ?
 | 
|---|
 | 327 |                         uargs[nuargs] = cpp_out;
 | 
|---|
 | 328 |                         nuargs += 1;
 | 
|---|
 | 329 |                 } // if
 | 
|---|
 | 330 |                 uargs[nuargs] = NULL;                                                   // terminate argument list
 | 
|---|
| [51b73452] | 331 | 
 | 
|---|
 | 332 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 333 |                 cerr << "cfa-cpp nuargs: " << o_name << " " << CFA_flag << " " << nuargs << endl;
 | 
|---|
 | 334 |                 for ( i = 0; uargs[i] != NULL; i += 1 ) {
 | 
|---|
 | 335 |                         cerr << uargs[i] << " ";
 | 
|---|
 | 336 |                 } // for
 | 
|---|
 | 337 |                 cerr << endl;
 | 
|---|
| [51b73452] | 338 | #endif // __DEBUG_H__
 | 
|---|
 | 339 | 
 | 
|---|
| [b87a5ed] | 340 |                 execvp( uargs[0], (char * const *)uargs );              // should not return
 | 
|---|
 | 341 |                 perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 342 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 343 |         } // if
 | 
|---|
| [51b73452] | 344 | 
 | 
|---|
| [b87a5ed] | 345 |         wait( &code );                                                                          // wait for child to finish
 | 
|---|
| [51b73452] | 346 | 
 | 
|---|
 | 347 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 348 |         cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl;
 | 
|---|
| [51b73452] | 349 | #endif // __DEBUG_H__
 | 
|---|
 | 350 | 
 | 
|---|
| [b87a5ed] | 351 |         // Must unlink here because file must exist across execvp.
 | 
|---|
 | 352 |         rmtmpfile();                                                                            // remove tmpname
 | 
|---|
| [51b73452] | 353 | 
 | 
|---|
| [b87a5ed] | 354 |         if ( WIFSIGNALED(code) ) {                                                      // child failed ?
 | 
|---|
 | 355 |                 cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl;
 | 
|---|
 | 356 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 357 |         } // if
 | 
|---|
| [51b73452] | 358 | 
 | 
|---|
| [b87a5ed] | 359 |         exit( WEXITSTATUS(code) );
 | 
|---|
| [51b73452] | 360 | } // Stage1
 | 
|---|
 | 361 | 
 | 
|---|
 | 362 | 
 | 
|---|
 | 363 | void Stage2( const int argc, const char * const * argv ) {
 | 
|---|
| [b87a5ed] | 364 |         int i;
 | 
|---|
| [51b73452] | 365 | 
 | 
|---|
| [b87a5ed] | 366 |         string arg;
 | 
|---|
| [51b73452] | 367 | 
 | 
|---|
| [b87a5ed] | 368 |         const char *cpp_in = NULL;
 | 
|---|
| [51b73452] | 369 | 
 | 
|---|
| [b87a5ed] | 370 |         const char *args[argc + 100];                                           // leave space for 100 additional cfa command line values
 | 
|---|
 | 371 |         int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
 | 
|---|
| [51b73452] | 372 | 
 | 
|---|
| [b87a5ed] | 373 |         // process all the arguments
 | 
|---|
| [51b73452] | 374 | 
 | 
|---|
| [b87a5ed] | 375 |         checkEnv( args, nargs );                                                        // arguments passed via environment variables
 | 
|---|
| [51b73452] | 376 | 
 | 
|---|
| [b87a5ed] | 377 |         for ( i = 1; i < argc; i += 1 ) {
 | 
|---|
| [51b73452] | 378 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 379 |                 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 380 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 381 |                 arg = argv[i];
 | 
|---|
| [51b73452] | 382 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 383 |                 cerr << "arg:\"" << arg << "\"" << endl;
 | 
|---|
| [51b73452] | 384 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 385 |                 if ( prefix( arg, "-" ) ) {
 | 
|---|
 | 386 |                         // strip inappropriate flags
 | 
|---|
| [51b73452] | 387 | 
 | 
|---|
| [b87a5ed] | 388 |                         if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" ||
 | 
|---|
 | 389 |                                  // Currently CFA does not suppose precompiled .h files.
 | 
|---|
 | 390 |                                  prefix( arg, "--output-pch" ) ) {
 | 
|---|
| [51b73452] | 391 | 
 | 
|---|
| [b87a5ed] | 392 |                                 // strip inappropriate flags with an argument
 | 
|---|
| [51b73452] | 393 | 
 | 
|---|
| [b87a5ed] | 394 |                         } else if ( arg == "-auxbase" || arg == "-auxbase-strip" || arg == "-dumpbase" ) {
 | 
|---|
 | 395 |                                 i += 1;
 | 
|---|
| [51b73452] | 396 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 397 |                                 cerr << "arg:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 398 | #endif // __DEBUG_H__
 | 
|---|
 | 399 | 
 | 
|---|
| [b87a5ed] | 400 |                                 // all other flags
 | 
|---|
| [51b73452] | 401 | 
 | 
|---|
| [b87a5ed] | 402 |                         } else {
 | 
|---|
 | 403 |                                 args[nargs] = argv[i];                                  // pass the flag along
 | 
|---|
 | 404 |                                 nargs += 1;
 | 
|---|
 | 405 |                                 if ( arg == "-o" ) {
 | 
|---|
 | 406 |                                         i += 1;
 | 
|---|
 | 407 |                                         args[nargs] = argv[i];                          // pass the argument along
 | 
|---|
 | 408 |                                         nargs += 1;
 | 
|---|
| [51b73452] | 409 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 410 |                                         cerr << "arg:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 411 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 412 |                                 } // if
 | 
|---|
 | 413 |                         } // if
 | 
|---|
 | 414 |                 } else {                                                                                // obtain input and possibly output files
 | 
|---|
 | 415 |                         if ( cpp_in == NULL ) {
 | 
|---|
 | 416 |                                 cpp_in = argv[i];
 | 
|---|
| [51b73452] | 417 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 418 |                                 cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
 | 
|---|
| [51b73452] | 419 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 420 |                         } else {
 | 
|---|
 | 421 |                                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 422 |                                 exit( EXIT_FAILURE );
 | 
|---|
 | 423 |                         } // if
 | 
|---|
 | 424 |                 } // if
 | 
|---|
 | 425 |         } // for
 | 
|---|
| [51b73452] | 426 | 
 | 
|---|
 | 427 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 428 |         cerr << "args:";
 | 
|---|
 | 429 |         for ( i = 1; i < nargs; i += 1 ) {
 | 
|---|
 | 430 |                 cerr << " " << args[i];
 | 
|---|
 | 431 |         } // for
 | 
|---|
 | 432 |         cerr << endl;
 | 
|---|
 | 433 |         if ( cpp_in != NULL ) cerr << " " << cpp_in;
 | 
|---|
| [51b73452] | 434 | #endif // __DEBUG_H__
 | 
|---|
 | 435 | 
 | 
|---|
| [b87a5ed] | 436 |         args[0] = compiler_name.c_str();
 | 
|---|
 | 437 |         args[nargs] = "-S";                                                                     // only compile and put assembler output in specified file
 | 
|---|
 | 438 |         nargs += 1;
 | 
|---|
 | 439 |         args[nargs] = cpp_in;
 | 
|---|
 | 440 |         nargs += 1;
 | 
|---|
 | 441 |         args[nargs] = NULL;                                                                     // terminate argument list
 | 
|---|
| [51b73452] | 442 | 
 | 
|---|
 | 443 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 444 |         cerr << "stage2 nargs: " << nargs << endl;
 | 
|---|
 | 445 |         for ( i = 0; args[i] != NULL; i += 1 ) {
 | 
|---|
 | 446 |                 cerr << args[i] << " ";
 | 
|---|
 | 447 |         } // for
 | 
|---|
 | 448 |         cerr << endl;
 | 
|---|
| [51b73452] | 449 | #endif // __DEBUG_H__
 | 
|---|
 | 450 | 
 | 
|---|
| [b87a5ed] | 451 |         execvp( args[0], (char * const *)args );                        // should not return
 | 
|---|
 | 452 |         perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 453 |         exit( EXIT_FAILURE );                                                           // tell gcc not to go any further
 | 
|---|
| [51b73452] | 454 | } // Stage2
 | 
|---|
 | 455 | 
 | 
|---|
 | 456 | 
 | 
|---|
 | 457 | int main( const int argc, const char * const argv[], const char * const env[] ) {
 | 
|---|
 | 458 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 459 |         for ( int i = 0; env[i] != NULL; i += 1 ) {
 | 
|---|
 | 460 |                 cerr << env[i] << endl;
 | 
|---|
 | 461 |         } // for
 | 
|---|
| [51b73452] | 462 | #endif // __DEBUG_H__
 | 
|---|
 | 463 | 
 | 
|---|
| [b87a5ed] | 464 |         string arg = argv[1];
 | 
|---|
| [51b73452] | 465 | 
 | 
|---|
| [b87a5ed] | 466 |         // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed.
 | 
|---|
| [51b73452] | 467 | 
 | 
|---|
| [b87a5ed] | 468 |         if ( arg == "-E" ) {
 | 
|---|
| [51b73452] | 469 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 470 |                 cerr << "Stage1" << endl;
 | 
|---|
| [51b73452] | 471 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 472 |                 Stage1( argc, argv );
 | 
|---|
 | 473 |         } else if ( arg == "-fpreprocessed" ) {
 | 
|---|
| [51b73452] | 474 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 475 |                 cerr << "Stage2" << endl;
 | 
|---|
| [51b73452] | 476 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 477 |                 Stage2( argc, argv );
 | 
|---|
 | 478 |         } else {
 | 
|---|
 | 479 |                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 480 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 481 |         } // if
 | 
|---|
| [51b73452] | 482 | } // main
 | 
|---|
 | 483 | 
 | 
|---|
 | 484 | // Local Variables: //
 | 
|---|
| [b87a5ed] | 485 | // tab-width: 4 //
 | 
|---|
 | 486 | // mode: c++ //
 | 
|---|
| [51b73452] | 487 | // compile-command: "make install" //
 | 
|---|
 | 488 | // End: //
 | 
|---|