source: driver/cfa.cc @ d4778a6

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since d4778a6 was 8c17ab0, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

add quoted identifiers, add compilation include directory, reformatted some files

  • Property mode set to 100644
File size: 11.2 KB
Line 
1//                              -*- Mode: C++ -*-
2//
3// CForall Version 1.0, Copyright (C) Peter A. Buhr 2002
4//
5// cfa.cc --
6//
7// Author           : Peter A. Buhr
8// Created On       : Tue Aug 20 13:44:49 2002
9// Last Modified By : Peter A. Buhr
10// Last Modified On : Tue Nov 11 09:19:15 2014
11// Update Count     : 106
12//
13
14#include <iostream>
15#include <cstdio>                                       // perror
16#include <cstdlib>                                      // putenv, exit
17#include <unistd.h>                                     // execvp
18#include <string>                                       // STL version
19
20#include "config.h"                                     // configure info
21
22using std::cerr;
23using std::endl;
24using std::string;
25
26
27//#define __DEBUG_H__
28
29
30bool prefix( string arg, string pre ) {
31    return arg.substr( 0, pre.size() ) == pre;
32} // prefix
33
34
35void shuffle( const char *args[], int S, int E, int N ) {
36    // S & E index 1 passed the end so adjust with -1
37#ifdef __DEBUG_H__
38    cerr << "shuffle:" << S << " " << E << " " << N << endl;
39#endif // __DEBUG_H__
40    for ( int j = E-1 + N; j > S-1 + N; j -=1 ) {
41#ifdef __DEBUG_H__
42        cerr << "\t" << j << " " << j-N << endl;
43#endif // __DEBUG_H__
44        args[j] = args[j-N];
45    } // for
46} // shuffle
47
48
49int main( int argc, char *argv[] ) {
50    string Version( VERSION );                          // current version number from CONFIG
51    string Major( "0" ), Minor( "0" ), Patch( "0" );    // default version numbers
52    int posn1 = Version.find( "." );                    // find the divider between major and minor version numbers
53    if ( posn1 == -1 ) {                                // not there ?
54        Major = Version;
55    } else {
56        Major = Version.substr( 0, posn1 );
57        int posn2 = Version.find( ".", posn1 + 1 );     // find the divider between minor and patch numbers
58        if ( posn2 == -1 ) {                            // not there ?
59            Minor = Version.substr( posn1 );
60        } else {
61            Minor = Version.substr( posn1 + 1, posn2 - posn1 - 1 );
62            Patch = Version.substr( posn2 + 1 );
63        } // if
64    } // if
65
66    string installincdir( CFA_INCDIR );                 // fixed location of cc1 and cfa-cpp commands
67    string installlibdir( CFA_LIBDIR );                 // fixed location of include files
68
69    string heading;                                     // banner printed at start of cfa compilation
70    string arg;                                         // current command-line argument during command-line parsing
71    string Bprefix;                                     // path where gcc looks for compiler command steps
72    string langstd;                                     // language standard
73
74    string compiler_path( GCC_PATH );                   // path/name of C compiler
75    string compiler_name;                               // name of C compiler
76
77    bool nonoptarg = false;                             // indicates non-option argument specified
78    bool link = true;                                   // linking as well as compiling
79    bool verbose = false;                               // -v flag
80    bool quiet = false;                                 // -quiet flag
81    bool debug = true;                                  // -debug flag
82    bool help = false;                                  // -help flag
83    bool CFA_flag = false;                              // -CFA flag
84    bool cpp_flag = false;                              // -E or -M flag, preprocessor only
85    bool debugging = false;                             // -g flag
86
87    const char *args[argc + 100];                       // cfa command line values, plus some space for additional flags
88    int sargs = 1;                                      // starting location for arguments in args list
89    int nargs = sargs;                                  // number of arguments in args list; 0 => command name
90
91    const char *libs[argc + 20];                        // non-user libraries must come separately, plus some added libraries and flags
92    int nlibs = 0;
93
94#ifdef __DEBUG_H__
95    cerr << "CFA:" << endl;
96#endif // __DEBUG_H__
97
98    // process command-line arguments
99
100    for ( int i = 1; i < argc; i += 1 ) {
101#ifdef __DEBUG_H__
102        cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
103#endif // __DEBUG_H__
104        arg = argv[i];                                  // convert to string value
105#ifdef __DEBUG_H__
106        cerr << "arg:\"" << arg << "\"" << endl;
107#endif // __DEBUG_H__
108        if ( prefix( arg, "-" ) ) {
109            // pass through arguments
110
111            if ( arg == "-Xlinker" || arg == "-o" ) {
112                args[nargs] = argv[i];                  // pass the argument along
113                nargs += 1;
114                i += 1;
115                if ( i == argc ) continue;              // next argument available ?
116                args[nargs] = argv[i];                  // pass the argument along
117                nargs += 1;
118            } else if ( arg == "-XCFA" ) {              // CFA pass through
119                i += 1;
120                args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + argv[i] ) ).c_str();
121                nargs += 1;
122
123            // CFA specific arguments
124
125            } else if ( arg == "-CFA" ) {
126                CFA_flag = true;                        // strip the -CFA flag
127                link = false;
128                args[nargs] = "-E";                     // replace the argument with -E
129                nargs += 1;
130            } else if ( arg == "-debug" ) {
131                debug = true;                           // strip the debug flag
132            } else if ( arg == "-nodebug" ) {
133                debug = false;                          // strip the nodebug flag
134            } else if ( arg == "-quiet" ) {
135                quiet = true;                           // strip the quiet flag
136            } else if ( arg == "-noquiet" ) {
137                quiet = false;                          // strip the noquiet flag
138            } else if ( arg == "-help" ) {
139                help = true;                            // strip the help flag
140            } else if ( arg == "-nohelp" ) {
141                help = false;                           // strip the nohelp flag
142            } else if ( arg == "-compiler" ) {
143                // use the user specified compiler
144                i += 1;
145                if ( i == argc ) continue;              // next argument available ?
146                compiler_path = argv[i];
147                if ( putenv( (char *)( *new string( string( "__U_COMPILER__=" ) + argv[i]) ).c_str() ) != 0 ) {
148                    cerr << argv[0] << " error, cannot set environment variable." << endl;
149                    exit( EXIT_FAILURE );
150                } // if
151
152            // C++ specific arguments
153
154            } else if ( arg == "-v" ) {
155                verbose = true;                         // verbosity required
156                args[nargs] = argv[i];                  // pass the argument along
157                nargs += 1;
158            } else if ( arg == "-g" ) {
159                debugging = true;                       // symbolic debugging required
160                args[nargs] = argv[i];                  // pass the argument along
161                nargs += 1;
162            } else if ( prefix( arg, "-B" ) ) {
163                Bprefix = arg.substr(2);                // strip the -B flag
164                args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
165                nargs += 1;
166            } else if ( prefix( arg, "-b" ) ) {
167                if ( arg.length() == 2 ) {              // separate argument ?
168                    i += 1;
169                    if ( i == argc ) continue;          // next argument available ?
170                    arg += argv[i];                     // concatenate argument
171                } // if
172                // later versions of gcc require the -b option to appear at the start of the command line
173                shuffle( args, sargs, nargs, 1 );       // make room at front of argument list
174                args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
175                if ( putenv( (char *)( *new string( string( "__GCC_MACHINE__=" ) + arg ) ).c_str() ) != 0 ) {
176                    cerr << argv[0] << " error, cannot set environment variable." << endl;
177                    exit( EXIT_FAILURE );
178                } // if
179                sargs += 1;
180                nargs += 1;
181            } else if ( prefix( arg, "-V" ) ) {
182                if ( arg.length() == 2 ) {              // separate argument ?
183                    i += 1;
184                    if ( i == argc ) continue;          // next argument available ?
185                    arg += argv[i];                     // concatenate argument
186                } // if
187                // later versions of gcc require the -V option to appear at the start of the command line
188                shuffle( args, sargs, nargs, 1 );       // make room at front of argument list
189                args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
190                if ( putenv( (char *)( *new string( string( "__GCC_VERSION__=" ) + arg ) ).c_str() ) != 0 ) {
191                    cerr << argv[0] << " error, cannot set environment variable." << endl;
192                    exit( EXIT_FAILURE );
193                } // if
194                sargs += 1;
195                nargs += 1;
196            } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) {
197                args[nargs] = argv[i];                  // pass the argument along
198                nargs += 1;
199                if ( arg == "-E" || arg == "-M" || arg == "-MM" ) {
200                    cpp_flag = true;                    // cpp only
201                } // if
202                link = false;                           // no linkage required
203            } else if ( arg[1] == 'l' ) {
204                // if the user specifies a library, load it after user code
205                libs[nlibs] = argv[i];
206                nlibs += 1;
207            } else {
208                // concatenate any other arguments
209                args[nargs] = argv[i];
210                nargs += 1;
211            } // if
212        } else {
213            // concatenate other arguments
214            args[nargs] = argv[i];
215            nargs += 1;
216            nonoptarg = true;
217        } // if
218    } // for
219
220#ifdef __DEBUG_H__
221    cerr << "args:";
222    for ( int i = 1; i < nargs; i += 1 ) {
223        cerr << " " << args[i];
224    } // for
225    cerr << endl;
226#endif // __DEBUG_H__
227
228    if ( cpp_flag && CFA_flag ) {
229        cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
230        exit( EXIT_FAILURE );
231    } // if
232
233    string d;
234    if ( debug ) {
235        d = "-d";
236    } // if
237
238    args[nargs] = "-I" CFA_INCDIR;
239    nargs += 1;
240
241    if ( link ) {
242        // include the cfa library in case it's needed
243        args[nargs] = "-L" CFA_LIBDIR;
244        nargs += 1;
245        args[nargs] = "-lcfa";
246        nargs += 1;
247    } // if
248
249    // add the correct set of flags based on the type of compile this is
250
251    args[nargs] = ( *new string( string("-D__CFA_MAJOR__=") + Major ) ).c_str();
252    nargs += 1;
253    args[nargs] = ( *new string( string("-D__CFA_MINOR__=") + Minor ) ).c_str();
254    nargs += 1;
255
256    if ( cpp_flag ) {
257        args[nargs] = "-D__CPP__";
258        nargs += 1;
259    } // if
260
261    if ( CFA_flag ) {
262        args[nargs] = "-D__CFA__";
263        nargs += 1;
264    } // if
265
266    if ( debug ) {
267        heading += " (debug)";
268        args[nargs] = "-D__CFA_DEBUG__";
269        nargs += 1;
270    } else {
271        heading += " (no debug)";
272    } // if
273
274    if ( Bprefix.length() == 0 ) {
275        Bprefix = installlibdir;
276        args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
277        nargs += 1;
278    } // if
279
280    // execute the compilation command
281
282    args[0] = compiler_path.c_str();                    // set compiler command for exec
283    // find actual name of the compiler independent of the path to it
284    int p = compiler_path.find_last_of( '/' );          // scan r -> l for first '/'
285    if ( p == -1 ) {
286        compiler_name = compiler_path;
287    } else {
288        compiler_name = *new string( compiler_path.substr( p + 1 ) );
289    } // if
290
291    if ( prefix( compiler_name, "gcc" ) ) {             // allow suffix on gcc name
292        args[nargs] = "-no-integrated-cpp";
293        nargs += 1;
294        args[nargs] = "-Wno-deprecated"; 
295        nargs += 1;
296        args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
297        nargs += 1;
298    } else {
299        cerr << argv[0] << " error, compiler " << compiler_name << " not supported." << endl;
300        exit( EXIT_FAILURE );
301    } // if
302
303    for ( int i = 0; i < nlibs; i += 1 ) {              // copy non-user libraries after all user libraries
304        args[nargs] = libs[i];
305        nargs += 1;
306    } // for
307
308    args[nargs] = NULL;                                 // terminate with NULL
309
310#ifdef __DEBUG_H__
311    cerr << "nargs: " << nargs << endl;
312    cerr << "args:" << endl;
313    for ( int i = 0; args[i] != NULL; i += 1 ) {
314        cerr << " \"" << args[i] << "\"" << endl;
315    } // for
316#endif // __DEBUG_H__
317
318    if ( ! quiet ) {
319        cerr << "CFA " << "Version " << Version << heading << endl;
320
321        if ( help ) {
322            cerr <<
323                "-debug\t\t\t: use cfa runtime with debug checking" << endl <<
324                "-help\t\t\t: print this help message" << endl <<
325                "-quiet\t\t\t: print no messages from the cfa command" << endl <<
326                "-CFA\t\t\t: run the cpp preprocessor and the cfa-cpp translator" << endl <<
327                "-XCFA -cfa-cpp-flag\t: pass next flag as-is to the cfa-cpp translator" << endl <<
328                "...\t\t\t: any other " << compiler_name << " flags" << endl;
329        } // if
330    } // if
331
332    if ( verbose ) {
333        if ( argc == 2 ) exit( EXIT_SUCCESS );          // if only the -v flag is specified, do not invoke gcc
334
335        for ( int i = 0; args[i] != NULL; i += 1 ) {
336            cerr << args[i] << " ";
337        } // for
338        cerr << endl;
339    } // if
340
341    if ( ! nonoptarg ) {
342        cerr << argv[0] << " error, no input files" << endl;
343        exit( EXIT_FAILURE );
344    } // if
345
346    // execute the command and return the result
347
348    execvp( args[0], (char *const *)args );             // should not return
349    perror( "CFA Translator error: cfa level, execvp" );
350    exit( EXIT_FAILURE );
351} // main
352
353// Local Variables: //
354// compile-command: "make install" //
355// End: //
Note: See TracBrowser for help on using the repository browser.