Changeset b87a5ed for driver/cc1.cc


Ignore:
Timestamp:
May 16, 2015, 3:36:19 PM (10 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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
Message:

licencing: first groups of files

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//
    57// cc1.cc --
    6 // 
    7 // Author           : Richard C. Bilson
     8//
     9// Author           : Peter A. Buhr
    810// Created On       : Fri Aug 26 14:23:51 2005
    911// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Thu May 14 13:24:45 2015
    11 // Update Count     : 43
     12// Last Modified On : Sat May 16 07:42:14 2015
     13// Update Count     : 49
    1214//
    13 
    1415
    1516#include <iostream>
     
    1819#include <string>
    1920using std::string;
    20 #include <cstdio>                                       // stderr, stdout, perror, fprintf
    21 #include <cstdlib>                                      // getenv, exit, mkstemp
    22 #include <unistd.h>                                     // execvp, fork, unlink
    23 #include <sys/wait.h>                                   // wait
    24 
    25 #include "config.h"                                     // configure info
     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
     25
     26#include "config.h"                                                                             // configure info
    2627
    2728
     
    2930
    3031
    31 string compiler_name( GCC_PATH );                       // path/name of C compiler
     32string compiler_name( GCC_PATH );                                               // path/name of C compiler
    3233
    3334string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" );
     
    3940
    4041bool prefix( string arg, string pre ) {
    41     return arg.substr( 0, pre.size() ) == pre;
     42        return arg.substr( 0, pre.size() ) == pre;
    4243} // prefix
    4344
    4445
    4546void 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
     77void 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
     86void sigTermHandler( int signal ) {
     87        if ( tmpfilefd != -1 ) {                                                        // RACE, file created ?
     88                rmtmpfile();                                                                    // remove
     89                exit( EXIT_FAILURE );                                                   // terminate
     90        } // if
     91} // sigTermHandler
     92
     93
     94void 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
     366void 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
    62441        nargs += 1;
    63     } // if
    64 
    65     value = getenv( "__GCC_VERSION__" );
    66     if ( value != NULL ) {
    67         args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
    68 #ifdef __DEBUG_H__
    69         cerr << "env arg:\"" << args[nargs] << "\"" << endl;
    70 #endif // __DEBUG_H__
    71         nargs += 1;
    72     } // if
    73 } // checkEnv
    74 
    75 
    76 void rmtmpfile() {
    77     if ( unlink( tmpname ) == -1 ) {                    // remove tmpname
    78         perror ( "CFA Translator error: cpp failed" );
    79         exit( EXIT_FAILURE );
    80     } // if
    81     tmpfilefd = -1;                                     // mark closed
    82 } // rmtmpfile
    83 
    84 
    85 void sigTermHandler( int signal ) {
    86     if ( tmpfilefd != -1 ) {                            // RACE, file created ?
    87         rmtmpfile();                                    // remove
    88         exit( EXIT_FAILURE );                           // terminate
    89     } // if
    90 } // sigTermHandler
    91 
    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 values
    108     int nargs = 1;                                      // number of arguments in args list; 0 => command name
    109     const char *uargs[20];                              // leave space for 20 additional cfa-cpp command line values
    110     int nuargs = 1;                                     // 0 => command name
    111 
    112     signal( SIGINT,  sigTermHandler );
    113     signal( SIGTERM, sigTermHandler );
    114 
    115     // process all the arguments
    116 
    117     checkEnv( args, nargs );                            // arguments passed via environment variables
    118 
    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 passes
    129 
    130             if ( arg == "-quiet" ) {
    131             } else if ( arg == "-imultilib" || arg == "-imultiarch" ) {
    132                 i += 1;                                 // and the argument
    133             } 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 argument
    140 
    141             // strip flags controlling cpp step
    142 
    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 argument
    147                 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 argument
    152                 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 argument
    160             } 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 argument
    165 
    166             // all other flags
    167 
    168             } else if ( arg == "-o" ) {
    169                 i += 1;
    170                 o_name = argv[i];
    171             } else {
    172                 args[nargs] = argv[i];                  // pass the flag along
    173                 nargs += 1;
    174                 // CPP flags with an argument
    175                 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 along
    180                     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 file
    186                     nargs += 1;
    187                     i += 1;
    188                     args[nargs] = argv[i];              // pass the argument along
    189                     nargs += 1;
    190 #ifdef __DEBUG_H__
    191                     cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    192 #endif // __DEBUG_H__
    193                 } // if
    194             } // if
    195         } else {                                        // obtain input and possibly output files
    196             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             } // if
    210         } // if
    211     } // for
    212 
    213 #ifdef __DEBUG_H__
    214     cerr << "args:";
    215     for ( i = 1; i < nargs; i += 1 ) {
    216         cerr << " " << args[i];
    217     } // for
    218     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     } // if
    227 
    228     if ( cpp_flag ) {
    229         // The -E flag is specified on the cfa command so only run the preprocessor and output is written to standard
    230         // 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();
    233442        args[nargs] = cpp_in;
    234443        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;
    245448        for ( i = 0; args[i] != NULL; i += 1 ) {
    246             cerr << args[i] << " ";
     449                cerr << args[i] << " ";
    247450        } // for
    248451        cerr << endl;
    249452#endif // __DEBUG_H__
    250453
    251         execvp( args[0], (char *const *)args );         // should not return
     454        execvp( args[0], (char * const *)args );                        // should not return
    252455        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
     460int 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 {
    423482                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    424483                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
    484485} // main
    485486
    486 
    487487// Local Variables: //
     488// tab-width: 4 //
     489// mode: c++ //
    488490// compile-command: "make install" //
    489491// End: //
Note: See TracChangeset for help on using the changeset viewer.