| [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
 | 
|---|
| [f8b6d921] | 12 | // Last Modified On : Wed Jan 18 08:14:21 2017
 | 
|---|
 | 13 | // Update Count     : 81
 | 
|---|
| [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 | 
 | 
|---|
| [e24f13a] | 32 | string compiler_name( CFA_BACKEND_CC );                                 // 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
 | 
|---|
| [7b937575] | 110 |         const char *cargs[20];                                                          // leave space for 20 additional cfa-cpp command line values
 | 
|---|
 | 111 |         int ncargs = 1;                                                                         // 0 => command name
 | 
|---|
| [51b73452] | 112 | 
 | 
|---|
| [b87a5ed] | 113 |         signal( SIGINT,  sigTermHandler );
 | 
|---|
 | 114 |         signal( SIGTERM, sigTermHandler );
 | 
|---|
| [bdd516a] | 115 | 
 | 
|---|
| [7b937575] | 116 | #ifdef __DEBUG_H__
 | 
|---|
 | 117 |         cerr << "Stage1" << endl;
 | 
|---|
 | 118 | #endif // __DEBUG_H__
 | 
|---|
 | 119 | 
 | 
|---|
| [b87a5ed] | 120 |         // process all the arguments
 | 
|---|
| [51b73452] | 121 | 
 | 
|---|
| [b87a5ed] | 122 |         checkEnv( args, nargs );                                                        // arguments passed via environment variables
 | 
|---|
| [51b73452] | 123 | 
 | 
|---|
| [b87a5ed] | 124 |         for ( i = 1; i < argc; i += 1 ) {
 | 
|---|
| [51b73452] | 125 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 126 |                 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 127 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 128 |                 arg = argv[i];
 | 
|---|
| [51b73452] | 129 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 130 |                 cerr << "arg:\"" << arg << "\"" << endl;
 | 
|---|
| [51b73452] | 131 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 132 |                 if ( prefix( arg, "-" ) ) {
 | 
|---|
 | 133 |                         // strip g++ flags that are inappropriate or cause duplicates in subsequent passes
 | 
|---|
 | 134 | 
 | 
|---|
 | 135 |                         if ( arg == "-quiet" ) {
 | 
|---|
 | 136 |                         } else if ( arg == "-imultilib" || arg == "-imultiarch" ) {
 | 
|---|
 | 137 |                                 i += 1;                                                                 // and the argument
 | 
|---|
 | 138 |                         } else if ( prefix( arg, "-A" ) ) {
 | 
|---|
 | 139 |                         } else if ( prefix( arg, "-D__GNU" ) ) {
 | 
|---|
 | 140 |                                 //********
 | 
|---|
 | 141 |                                 // GCC 5.6.0 SEPARATED THE -D FROM THE ARGUMENT!
 | 
|---|
 | 142 |                                 //********
 | 
|---|
 | 143 |                         } else if ( arg == "-D" && prefix( argv[i + 1], "__GNU" ) ) {
 | 
|---|
 | 144 |                                 i += 1;                                                                 // and the argument
 | 
|---|
 | 145 | 
 | 
|---|
 | 146 |                                 // strip flags controlling cpp step
 | 
|---|
 | 147 | 
 | 
|---|
 | 148 |                         } else if ( arg == "-D__CPP__" ) {
 | 
|---|
 | 149 |                                 cpp_flag = true;
 | 
|---|
 | 150 |                         } else if ( arg == "-D" && string( argv[i + 1] ) == "__CPP__" ) {
 | 
|---|
 | 151 |                                 i += 1;                                                                 // and the argument
 | 
|---|
 | 152 |                                 cpp_flag = true;
 | 
|---|
| [4c82a3c] | 153 |                         } else if ( arg == "-D__CFA_PREPROCESS__" ) {
 | 
|---|
| [b87a5ed] | 154 |                                 CFA_flag = true;
 | 
|---|
| [4c82a3c] | 155 |                         } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA_PREPROCESS__" ) {
 | 
|---|
| [b87a5ed] | 156 |                                 i += 1;                                                                 // and the argument
 | 
|---|
 | 157 |                                 CFA_flag = true;
 | 
|---|
 | 158 |                         } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {
 | 
|---|
| [7b937575] | 159 |                                 cargs[ncargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
 | 
|---|
 | 160 |                                 ncargs += 1;
 | 
|---|
| [b87a5ed] | 161 |                         } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {
 | 
|---|
| [7b937575] | 162 |                                 cargs[ncargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
 | 
|---|
 | 163 |                                 ncargs += 1;
 | 
|---|
| [b87a5ed] | 164 |                                 i += 1;                                                                 // and the argument
 | 
|---|
 | 165 |                         } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
 | 
|---|
 | 166 |                                 bprefix = arg.substr( D__GCC_BPREFIX__.size() );
 | 
|---|
 | 167 |                         } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) {
 | 
|---|
 | 168 |                                 bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 );
 | 
|---|
 | 169 |                                 i += 1;                                                                 // and the argument
 | 
|---|
 | 170 | 
 | 
|---|
| [f8b6d921] | 171 |                         // all other flags
 | 
|---|
| [b87a5ed] | 172 | 
 | 
|---|
 | 173 |                         } else if ( arg == "-o" ) {
 | 
|---|
 | 174 |                                 i += 1;
 | 
|---|
 | 175 |                                 o_name = argv[i];
 | 
|---|
 | 176 |                         } else {
 | 
|---|
 | 177 |                                 args[nargs] = argv[i];                                  // pass the flag along
 | 
|---|
 | 178 |                                 nargs += 1;
 | 
|---|
 | 179 |                                 // CPP flags with an argument
 | 
|---|
| [f8b6d921] | 180 |                                 if ( arg == "-D" || arg == "-U" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" ||
 | 
|---|
| [b87a5ed] | 181 |                                          arg == "-include" || arg == "-imacros" || arg == "-idirafter" || arg == "-iprefix" ||
 | 
|---|
 | 182 |                                          arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) {
 | 
|---|
 | 183 |                                         i += 1;
 | 
|---|
 | 184 |                                         args[nargs] = argv[i];                          // pass the argument along
 | 
|---|
 | 185 |                                         nargs += 1;
 | 
|---|
| [51b73452] | 186 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 187 |                                         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 188 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 189 |                                 } else if ( arg == "-MD" || arg == "-MMD" ) {
 | 
|---|
 | 190 |                                         args[nargs] = "-MF";                            // insert before file
 | 
|---|
 | 191 |                                         nargs += 1;
 | 
|---|
 | 192 |                                         i += 1;
 | 
|---|
 | 193 |                                         args[nargs] = argv[i];                          // pass the argument along
 | 
|---|
 | 194 |                                         nargs += 1;
 | 
|---|
| [51b73452] | 195 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 196 |                                         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 197 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 198 |                                 } // if
 | 
|---|
 | 199 |                         } // if
 | 
|---|
 | 200 |                 } else {                                                                                // obtain input and possibly output files
 | 
|---|
 | 201 |                         if ( cpp_in == NULL ) {
 | 
|---|
 | 202 |                                 cpp_in = argv[i];
 | 
|---|
 | 203 | #ifdef __DEBUG_H__
 | 
|---|
 | 204 |                                 cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
 | 
|---|
 | 205 | #endif // __DEBUG_H__
 | 
|---|
 | 206 |                         } else if ( cpp_out == NULL ) {
 | 
|---|
 | 207 |                                 cpp_out = argv[i];
 | 
|---|
| [51b73452] | 208 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 209 |                                 cerr << "cpp_out:\"" << cpp_out << "\""<< endl;
 | 
|---|
| [51b73452] | 210 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 211 |                         } else {
 | 
|---|
 | 212 |                                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 213 |                                 exit( EXIT_FAILURE );
 | 
|---|
 | 214 |                         } // if
 | 
|---|
 | 215 |                 } // if
 | 
|---|
 | 216 |         } // for
 | 
|---|
 | 217 | 
 | 
|---|
| [51b73452] | 218 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 219 |         cerr << "args:";
 | 
|---|
 | 220 |         for ( i = 1; i < nargs; i += 1 ) {
 | 
|---|
 | 221 |                 cerr << " " << args[i];
 | 
|---|
 | 222 |         } // for
 | 
|---|
 | 223 |         if ( cpp_in != NULL ) cerr << " " << cpp_in;
 | 
|---|
 | 224 |         if ( cpp_out != NULL ) cerr << " " << cpp_out;
 | 
|---|
 | 225 |         cerr << endl;
 | 
|---|
| [51b73452] | 226 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 227 | 
 | 
|---|
 | 228 |         if ( cpp_in == NULL ) {
 | 
|---|
| [51b73452] | 229 |                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 230 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 231 |         } // if
 | 
|---|
| [b87a5ed] | 232 | 
 | 
|---|
 | 233 |         if ( cpp_flag ) {
 | 
|---|
 | 234 |                 // The -E flag is specified on the cfa command so only run the preprocessor and output is written to standard
 | 
|---|
 | 235 |                 // output or -o. The call to cfa has a -E so it does not have to be added to the argument list.
 | 
|---|
 | 236 | 
 | 
|---|
 | 237 |                 args[0] = compiler_name.c_str();
 | 
|---|
 | 238 |                 args[nargs] = cpp_in;
 | 
|---|
 | 239 |                 nargs += 1;
 | 
|---|
 | 240 |                 if ( o_name != NULL ) {                                                 // location for output
 | 
|---|
 | 241 |                         args[nargs] = "-o";
 | 
|---|
 | 242 |                         nargs += 1;
 | 
|---|
 | 243 |                         args[nargs] = o_name;
 | 
|---|
 | 244 |                         nargs += 1;
 | 
|---|
 | 245 |                 } // if
 | 
|---|
 | 246 |                 args[nargs] = NULL;                                                             // terminate argument list
 | 
|---|
| [51b73452] | 247 | 
 | 
|---|
 | 248 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 249 |                 cerr << "nargs: " << nargs << endl;
 | 
|---|
 | 250 |                 for ( i = 0; args[i] != NULL; i += 1 ) {
 | 
|---|
 | 251 |                         cerr << args[i] << " ";
 | 
|---|
 | 252 |                 } // for
 | 
|---|
 | 253 |                 cerr << endl;
 | 
|---|
| [51b73452] | 254 | #endif // __DEBUG_H__
 | 
|---|
 | 255 | 
 | 
|---|
| [b87a5ed] | 256 |                 execvp( args[0], (char *const *)args );                 // should not return
 | 
|---|
 | 257 |                 perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 258 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 259 |         } // if
 | 
|---|
| [51b73452] | 260 | 
 | 
|---|
| [b87a5ed] | 261 |         // Create a temporary file to store output of the C preprocessor.
 | 
|---|
| [51b73452] | 262 | 
 | 
|---|
| [b87a5ed] | 263 |         tmpfilefd = mkstemp( tmpname );
 | 
|---|
 | 264 |         if ( tmpfilefd == -1 ) {
 | 
|---|
 | 265 |                 perror( "CFA Translator error: cpp level, mkstemp" );
 | 
|---|
 | 266 |                 exit( EXIT_FAILURE );
 | 
|---|
| [51b73452] | 267 |         } // if
 | 
|---|
 | 268 | 
 | 
|---|
 | 269 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 270 |         cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl;
 | 
|---|
| [51b73452] | 271 | #endif // __DEBUG_H__
 | 
|---|
 | 272 | 
 | 
|---|
| [b87a5ed] | 273 |         // Run the C preprocessor and save the output in tmpfile.
 | 
|---|
| [51b73452] | 274 | 
 | 
|---|
| [b87a5ed] | 275 |         if ( fork() == 0 ) {                                                             // child process ?
 | 
|---|
 | 276 |                 // -o xxx.ii cannot be used to write the output file from cpp because no output file is created if cpp detects
 | 
|---|
 | 277 |                 // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error,
 | 
|---|
 | 278 |                 // when cpp writes to stdout. Hence, stdout is redirected into the temporary file.
 | 
|---|
 | 279 |                 if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname
 | 
|---|
 | 280 |                         perror( "CFA Translator error: cpp level, freopen" );
 | 
|---|
 | 281 |                         exit( EXIT_FAILURE );
 | 
|---|
 | 282 |                 } // if
 | 
|---|
| [51b73452] | 283 | 
 | 
|---|
| [b87a5ed] | 284 |                 args[0] = compiler_name.c_str();
 | 
|---|
 | 285 |                 args[nargs] = cpp_in;                                                   // input to cpp
 | 
|---|
 | 286 |                 nargs += 1;
 | 
|---|
 | 287 |                 args[nargs] = NULL;                                                             // terminate argument list
 | 
|---|
| [51b73452] | 288 | 
 | 
|---|
 | 289 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 290 |                 cerr << "cpp nargs: " << nargs << endl;
 | 
|---|
 | 291 |                 for ( i = 0; args[i] != NULL; i += 1 ) {
 | 
|---|
 | 292 |                         cerr << args[i] << " ";
 | 
|---|
 | 293 |                 } // for
 | 
|---|
 | 294 |                 cerr << endl;
 | 
|---|
| [51b73452] | 295 | #endif // __DEBUG_H__
 | 
|---|
 | 296 | 
 | 
|---|
| [b87a5ed] | 297 |                 execvp( args[0], (char *const *)args );                 // should not return
 | 
|---|
 | 298 |                 perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 299 |                 exit( EXIT_FAILURE );
 | 
|---|
| [51b73452] | 300 |         } // if
 | 
|---|
 | 301 | 
 | 
|---|
| [b87a5ed] | 302 |         wait( &code );                                                                          // wait for child to finish
 | 
|---|
| [51b73452] | 303 | 
 | 
|---|
 | 304 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 305 |         cerr << "return code from cpp:" << WEXITSTATUS(code) << endl;
 | 
|---|
| [51b73452] | 306 | #endif // __DEBUG_H__
 | 
|---|
 | 307 | 
 | 
|---|
| [b87a5ed] | 308 |         if ( WIFSIGNALED(code) != 0 ) {                                         // child failed ?
 | 
|---|
 | 309 |                 rmtmpfile();                                                                    // remove tmpname
 | 
|---|
 | 310 |                 cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl;
 | 
|---|
 | 311 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 312 |         } // if
 | 
|---|
| [51b73452] | 313 | 
 | 
|---|
| [b87a5ed] | 314 |         if ( WEXITSTATUS(code) != 0 ) {                                         // child error ?
 | 
|---|
 | 315 |                 rmtmpfile();                                                                    // remove tmpname
 | 
|---|
 | 316 |                 exit( WEXITSTATUS( code ) );                                    // do not continue
 | 
|---|
 | 317 |         } // if
 | 
|---|
| [51b73452] | 318 | 
 | 
|---|
| [b87a5ed] | 319 |         // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard
 | 
|---|
 | 320 |         // output.  Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file.
 | 
|---|
| [51b73452] | 321 | 
 | 
|---|
| [b87a5ed] | 322 |         if ( fork() == 0 ) {                                                            // child runs CFA
 | 
|---|
| [7b937575] | 323 |                 cargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
 | 
|---|
| [b87a5ed] | 324 | 
 | 
|---|
| [4acc87f] | 325 |                 // Source file-name used to generate routine names containing global initializations for TU.
 | 
|---|
| [7b937575] | 326 |                 cargs[ncargs] = ( *new string( "-F" ) ).c_str();
 | 
|---|
 | 327 |                 ncargs += 1;
 | 
|---|
| [4acc87f] | 328 |                 cargs[ncargs] = ( *new string( string( cpp_in ) ) ).c_str();
 | 
|---|
| [7b937575] | 329 |                 ncargs += 1;
 | 
|---|
 | 330 | 
 | 
|---|
 | 331 |                 cargs[ncargs] = tmpname;
 | 
|---|
 | 332 |                 ncargs += 1;
 | 
|---|
| [b87a5ed] | 333 |                 if ( o_name != NULL ) {
 | 
|---|
| [7b937575] | 334 |                         cargs[ncargs] = o_name;
 | 
|---|
 | 335 |                         ncargs += 1;
 | 
|---|
| [b87a5ed] | 336 |                 } else if ( ! CFA_flag ) {                                              // run cfa-cpp ?
 | 
|---|
| [7b937575] | 337 |                         cargs[ncargs] = cpp_out;
 | 
|---|
 | 338 |                         ncargs += 1;
 | 
|---|
| [b87a5ed] | 339 |                 } // if
 | 
|---|
| [7b937575] | 340 |                 cargs[ncargs] = NULL;                                                   // terminate argument list
 | 
|---|
| [51b73452] | 341 | 
 | 
|---|
 | 342 | #ifdef __DEBUG_H__
 | 
|---|
| [7b937575] | 343 |                 cerr << "cfa-cpp ncargs: " << o_name << " " << CFA_flag << " " << ncargs << endl;
 | 
|---|
 | 344 |                 for ( i = 0; cargs[i] != NULL; i += 1 ) {
 | 
|---|
 | 345 |                         cerr << cargs[i] << " ";
 | 
|---|
| [b87a5ed] | 346 |                 } // for
 | 
|---|
 | 347 |                 cerr << endl;
 | 
|---|
| [51b73452] | 348 | #endif // __DEBUG_H__
 | 
|---|
 | 349 | 
 | 
|---|
| [7b937575] | 350 |                 execvp( cargs[0], (char * const *)cargs );              // should not return
 | 
|---|
| [b87a5ed] | 351 |                 perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 352 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 353 |         } // if
 | 
|---|
| [51b73452] | 354 | 
 | 
|---|
| [b87a5ed] | 355 |         wait( &code );                                                                          // wait for child to finish
 | 
|---|
| [51b73452] | 356 | 
 | 
|---|
 | 357 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 358 |         cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl;
 | 
|---|
| [51b73452] | 359 | #endif // __DEBUG_H__
 | 
|---|
 | 360 | 
 | 
|---|
| [b87a5ed] | 361 |         // Must unlink here because file must exist across execvp.
 | 
|---|
 | 362 |         rmtmpfile();                                                                            // remove tmpname
 | 
|---|
| [51b73452] | 363 | 
 | 
|---|
| [b87a5ed] | 364 |         if ( WIFSIGNALED(code) ) {                                                      // child failed ?
 | 
|---|
 | 365 |                 cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl;
 | 
|---|
 | 366 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 367 |         } // if
 | 
|---|
| [51b73452] | 368 | 
 | 
|---|
| [b87a5ed] | 369 |         exit( WEXITSTATUS(code) );
 | 
|---|
| [51b73452] | 370 | } // Stage1
 | 
|---|
 | 371 | 
 | 
|---|
 | 372 | 
 | 
|---|
 | 373 | void Stage2( const int argc, const char * const * argv ) {
 | 
|---|
| [b87a5ed] | 374 |         int i;
 | 
|---|
| [51b73452] | 375 | 
 | 
|---|
| [b87a5ed] | 376 |         string arg;
 | 
|---|
| [51b73452] | 377 | 
 | 
|---|
| [b87a5ed] | 378 |         const char *cpp_in = NULL;
 | 
|---|
| [51b73452] | 379 | 
 | 
|---|
| [b87a5ed] | 380 |         const char *args[argc + 100];                                           // leave space for 100 additional cfa command line values
 | 
|---|
 | 381 |         int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
 | 
|---|
| [51b73452] | 382 | 
 | 
|---|
| [7b937575] | 383 | #ifdef __DEBUG_H__
 | 
|---|
 | 384 |         cerr << "Stage2" << endl;
 | 
|---|
 | 385 | #endif // __DEBUG_H__
 | 
|---|
 | 386 | 
 | 
|---|
| [b87a5ed] | 387 |         // process all the arguments
 | 
|---|
| [51b73452] | 388 | 
 | 
|---|
| [b87a5ed] | 389 |         checkEnv( args, nargs );                                                        // arguments passed via environment variables
 | 
|---|
| [51b73452] | 390 | 
 | 
|---|
| [b87a5ed] | 391 |         for ( i = 1; i < argc; i += 1 ) {
 | 
|---|
| [51b73452] | 392 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 393 |                 cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 394 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 395 |                 arg = argv[i];
 | 
|---|
| [51b73452] | 396 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 397 |                 cerr << "arg:\"" << arg << "\"" << endl;
 | 
|---|
| [51b73452] | 398 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 399 |                 if ( prefix( arg, "-" ) ) {
 | 
|---|
 | 400 |                         // strip inappropriate flags
 | 
|---|
| [51b73452] | 401 | 
 | 
|---|
| [b87a5ed] | 402 |                         if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" ||
 | 
|---|
 | 403 |                                  // Currently CFA does not suppose precompiled .h files.
 | 
|---|
 | 404 |                                  prefix( arg, "--output-pch" ) ) {
 | 
|---|
| [51b73452] | 405 | 
 | 
|---|
| [b87a5ed] | 406 |                                 // strip inappropriate flags with an argument
 | 
|---|
| [51b73452] | 407 | 
 | 
|---|
| [b87a5ed] | 408 |                         } else if ( arg == "-auxbase" || arg == "-auxbase-strip" || arg == "-dumpbase" ) {
 | 
|---|
 | 409 |                                 i += 1;
 | 
|---|
| [51b73452] | 410 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 411 |                                 cerr << "arg:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 412 | #endif // __DEBUG_H__
 | 
|---|
 | 413 | 
 | 
|---|
| [b87a5ed] | 414 |                                 // all other flags
 | 
|---|
| [51b73452] | 415 | 
 | 
|---|
| [b87a5ed] | 416 |                         } else {
 | 
|---|
 | 417 |                                 args[nargs] = argv[i];                                  // pass the flag along
 | 
|---|
 | 418 |                                 nargs += 1;
 | 
|---|
 | 419 |                                 if ( arg == "-o" ) {
 | 
|---|
 | 420 |                                         i += 1;
 | 
|---|
 | 421 |                                         args[nargs] = argv[i];                          // pass the argument along
 | 
|---|
 | 422 |                                         nargs += 1;
 | 
|---|
| [51b73452] | 423 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 424 |                                         cerr << "arg:\"" << argv[i] << "\"" << endl;
 | 
|---|
| [51b73452] | 425 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 426 |                                 } // if
 | 
|---|
 | 427 |                         } // if
 | 
|---|
 | 428 |                 } else {                                                                                // obtain input and possibly output files
 | 
|---|
 | 429 |                         if ( cpp_in == NULL ) {
 | 
|---|
 | 430 |                                 cpp_in = argv[i];
 | 
|---|
| [51b73452] | 431 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 432 |                                 cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
 | 
|---|
| [51b73452] | 433 | #endif // __DEBUG_H__
 | 
|---|
| [b87a5ed] | 434 |                         } else {
 | 
|---|
 | 435 |                                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 436 |                                 exit( EXIT_FAILURE );
 | 
|---|
 | 437 |                         } // if
 | 
|---|
 | 438 |                 } // if
 | 
|---|
 | 439 |         } // for
 | 
|---|
| [51b73452] | 440 | 
 | 
|---|
 | 441 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 442 |         cerr << "args:";
 | 
|---|
 | 443 |         for ( i = 1; i < nargs; i += 1 ) {
 | 
|---|
 | 444 |                 cerr << " " << args[i];
 | 
|---|
 | 445 |         } // for
 | 
|---|
 | 446 |         cerr << endl;
 | 
|---|
 | 447 |         if ( cpp_in != NULL ) cerr << " " << cpp_in;
 | 
|---|
| [51b73452] | 448 | #endif // __DEBUG_H__
 | 
|---|
 | 449 | 
 | 
|---|
| [b87a5ed] | 450 |         args[0] = compiler_name.c_str();
 | 
|---|
 | 451 |         args[nargs] = "-S";                                                                     // only compile and put assembler output in specified file
 | 
|---|
 | 452 |         nargs += 1;
 | 
|---|
 | 453 |         args[nargs] = cpp_in;
 | 
|---|
 | 454 |         nargs += 1;
 | 
|---|
 | 455 |         args[nargs] = NULL;                                                                     // terminate argument list
 | 
|---|
| [51b73452] | 456 | 
 | 
|---|
 | 457 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 458 |         cerr << "stage2 nargs: " << nargs << endl;
 | 
|---|
 | 459 |         for ( i = 0; args[i] != NULL; i += 1 ) {
 | 
|---|
 | 460 |                 cerr << args[i] << " ";
 | 
|---|
 | 461 |         } // for
 | 
|---|
 | 462 |         cerr << endl;
 | 
|---|
| [51b73452] | 463 | #endif // __DEBUG_H__
 | 
|---|
 | 464 | 
 | 
|---|
| [b87a5ed] | 465 |         execvp( args[0], (char * const *)args );                        // should not return
 | 
|---|
 | 466 |         perror( "CFA Translator error: cpp level, execvp" );
 | 
|---|
 | 467 |         exit( EXIT_FAILURE );                                                           // tell gcc not to go any further
 | 
|---|
| [51b73452] | 468 | } // Stage2
 | 
|---|
 | 469 | 
 | 
|---|
 | 470 | 
 | 
|---|
 | 471 | int main( const int argc, const char * const argv[], const char * const env[] ) {
 | 
|---|
 | 472 | #ifdef __DEBUG_H__
 | 
|---|
| [b87a5ed] | 473 |         for ( int i = 0; env[i] != NULL; i += 1 ) {
 | 
|---|
 | 474 |                 cerr << env[i] << endl;
 | 
|---|
 | 475 |         } // for
 | 
|---|
| [51b73452] | 476 | #endif // __DEBUG_H__
 | 
|---|
 | 477 | 
 | 
|---|
| [b87a5ed] | 478 |         string arg = argv[1];
 | 
|---|
| [51b73452] | 479 | 
 | 
|---|
| [b87a5ed] | 480 |         // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed.
 | 
|---|
| [51b73452] | 481 | 
 | 
|---|
| [b87a5ed] | 482 |         if ( arg == "-E" ) {
 | 
|---|
 | 483 |                 Stage1( argc, argv );
 | 
|---|
 | 484 |         } else if ( arg == "-fpreprocessed" ) {
 | 
|---|
 | 485 |                 Stage2( argc, argv );
 | 
|---|
 | 486 |         } else {
 | 
|---|
 | 487 |                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 | 
|---|
 | 488 |                 exit( EXIT_FAILURE );
 | 
|---|
 | 489 |         } // if
 | 
|---|
| [51b73452] | 490 | } // main
 | 
|---|
 | 491 | 
 | 
|---|
 | 492 | // Local Variables: //
 | 
|---|
| [b87a5ed] | 493 | // tab-width: 4 //
 | 
|---|
 | 494 | // mode: c++ //
 | 
|---|
| [51b73452] | 495 | // compile-command: "make install" //
 | 
|---|
 | 496 | // End: //
 | 
|---|