Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

driver.cc

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.
00003 
00004   Permission to use, copy, distribute and modify this software and   
00005   its documentation for any purpose is hereby granted without fee,        
00006   provided that the above copyright notice appear in all copies and that 
00007   both that copyright notice and this permission notice appear in 
00008   supporting documentation.
00009 
00010   Shigeru Chiba makes no representations about the suitability of this 
00011   software for any purpose.  It is provided "as is" without express or
00012   implied warranty.
00013 */
00014 
00015 /*
00016   Copyright (c) 1995, 1996 Xerox Corporation.
00017   All Rights Reserved.
00018 
00019   Use and copying of this software and preparation of derivative works
00020   based upon this software are permitted. Any copy of this software or
00021   of any derivative work must include the above copyright notice of
00022   Xerox Corporation, this paragraph and the one after it.  Any
00023   distribution of this software or derivative works must comply with all
00024   applicable United States export control laws.
00025 
00026   This software is made available AS IS, and XEROX CORPORATION DISCLAIMS
00027   ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
00028   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029   PURPOSE, AND NOTWITHSTANDING ANY OTHER PROVISION CONTAINED HEREIN, ANY
00030   LIABILITY FOR DAMAGES RESULTING FROM THE SOFTWARE OR ITS USE IS
00031   EXPRESSLY DISCLAIMED, WHETHER ARISING IN CONTRACT, TORT (INCLUDING
00032   NEGLIGENCE) OR STRICT LIABILITY, EVEN IF XEROX CORPORATION IS ADVISED
00033   OF THE POSSIBILITY OF SUCH DAMAGES.
00034 */
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <iostream.h>
00039 #include <string.h>
00040 #include "token.h"
00041 #include "buffer.h"
00042 #include "parse.h"
00043 #include "walker.h"
00044 #include "classwalk.h"
00045 #include "ptree-core.h"
00046 #include "mop.h"
00047 
00048 #if defined(_MSC_VER)
00049 #include <stdlib.h>
00050 #else
00051 #include <unistd.h>
00052 #endif
00053 
00054 static char thisVersion[] = "2.5.12";
00055 
00056 static char copyingNote[]
00057         = "Copyright (c) 1997-2001 Shigeru Chiba.  All Rights Reserved.\n"
00058           "Copyright (c) 1995, 1996 Xerox Corporation. All Rights Reserved.";
00059 
00060 const char opencxxErrorMessage[] = " Error(s).  OpenC++ stops.\n";
00061 
00062 extern const char* compilerName;
00063 
00064 bool showProgram;
00065 bool doCompile;
00066 bool makeExecutable;
00067 bool doPreprocess;
00068 bool doTranslate;
00069 bool verboseMode;
00070 bool regularCpp;
00071 bool makeSharedLibrary;
00072 char* sharedLibraryName;
00073 bool preprocessTwice;
00074 
00075 const int NARGS = 64;
00076 const char* cppArgv[NARGS];
00077 const char* ccArgv[NARGS];
00078 static const char* cc2Argv[NARGS];      // arguments following a source file
00079 int cppArgc = 0;
00080 int ccArgc = 0;
00081 static int cc2Argc = 0;
00082 static int numOfObjectFiles = 0;
00083 
00084 // defined in driver2.cc
00085 extern bool ParseTargetSpecificOptions(char* arg, char*& source_file);
00086 extern void RunLinker();
00087 extern char* RunPreprocessor(const char* src);
00088 extern char* OpenCxxOutputFileName(const char* src);
00089 extern void RunCompiler(const char* src, const char* occserc);
00090 
00091 // defined in metaclass.cc
00092 extern void LoadMetaclass(char*);
00093 
00094 void Compile(int argc, char** argv);
00095 void ParseCmdOptions(int from, int argc, char** argv, char*& source_file);
00096 void AddCppOption(const char* arg);
00097 void AddCcOption(const char* arg);
00098 void CloseCcOptions();
00099 bool IsCxxSource(char* fname);
00100 void ShowCommandLine(const char* cmd, const char** args);
00101 
00102 static void ReadStdin();
00103 static void ReadFile(const char* src);
00104 static char* RunOpencxx(const char* src);
00105 static int ParseOpencxx(Program* parse);
00106 static char* ParseOptions(int argc, char** argv);
00107 static void ShowVersion();
00108 static void ShowHelp(char**);
00109 static void AddCc2Option(const char* arg);
00110 static void RecordCmdOption(char* option);
00111 static void ParseCcOptions(char* arg, char*& source_file);
00112 
00113 
00114 void Compile(int argc, char** argv)
00115 {
00116     char* src = ParseOptions(argc, argv);
00117     if(src != nil)
00118         ReadFile(src);
00119     else
00120         if(numOfObjectFiles == 0)
00121             ReadStdin();
00122         else
00123             RunLinker();
00124 }
00125 
00126 static void ReadStdin()
00127 {
00128     cerr << "OpenC++: No source file.  Read from console.\n";
00129 
00130     ProgramFromStdin prog;
00131     int nerrors = ParseOpencxx(&prog);
00132 
00133     if(!showProgram)
00134         if(nerrors == 0)
00135             prog.Write(cout, "stdout");
00136         else{
00137             cerr << nerrors << opencxxErrorMessage;
00138             exit(1);
00139         }
00140 }
00141 
00142 static void ReadFile(const char* src)
00143 {
00144     char *occfile;
00145 
00146     if(doPreprocess){
00147         char* cppfile = RunPreprocessor(src);
00148         occfile = RunOpencxx(cppfile);
00149         unlink(cppfile);
00150         delete cppfile;
00151     }
00152     else
00153         occfile = RunOpencxx(src);
00154 
00155     if(doCompile){
00156         RunCompiler(src, occfile);
00157         // unlink(occfile);
00158     }
00159 
00160     delete occfile;
00161 }
00162 
00163 static char* RunOpencxx(const char* src)
00164 {
00165     char* dest = OpenCxxOutputFileName(src);
00166 
00167     ifstream src_stream(src);
00168     if(!src_stream){
00169         perror(src);
00170         exit(1);
00171     }
00172 
00173     ProgramFile src_prog(src_stream);
00174     if(verboseMode){
00175         if(doTranslate)
00176             cerr << "[Translate... " << src
00177                  << " into: " << dest << "]\n";
00178         else
00179             cerr << "[Parse... " << src << "]\n";
00180     }
00181 
00182     int nerrors = ParseOpencxx(&src_prog);
00183 
00184     if(nerrors != 0){
00185         cerr << nerrors << opencxxErrorMessage;
00186         exit(1);
00187     }
00188 
00189     if(doTranslate){
00190         ofstream dest_stream(dest, (ios::out | ios::trunc));
00191         if(!dest_stream){
00192             perror(dest);
00193             exit(1);
00194         }
00195 
00196         src_prog.Write(dest_stream, dest);
00197     }
00198 
00199     src_stream.close();
00200     return dest;
00201 }
00202 
00203 static int ParseOpencxx(Program* prog)
00204 {
00205     Lex lex(prog);
00206     Parser parse(&lex);
00207     ClassWalker w(&parse);
00208     Ptree* def;
00209 
00210     while(parse.rProgram(def)){
00211         if(showProgram)
00212             def->Display2(cout);
00213 
00214         if(doTranslate){
00215             Ptree* def2 = w.Translate(def);
00216             Ptree* before = w.GetInsertedPtree();
00217             Ptree* after = w.GetAppendedPtree();
00218 
00219             prog->Insert(def, before, after);
00220             if(def != def2)
00221                 prog->MinimumSubst(def2, def);
00222         }
00223     }
00224 
00225     return parse.NumOfErrors();
00226 }
00227 
00228 static char* ParseOptions(int argc, char** argv)
00229 {
00230     char* source_file = nil;
00231     showProgram = FALSE;
00232     doCompile = TRUE;
00233     verboseMode = FALSE;
00234     makeExecutable = TRUE;
00235     doPreprocess = TRUE;
00236     doTranslate = TRUE;
00237     regularCpp = FALSE;
00238     makeSharedLibrary = FALSE;
00239     sharedLibraryName = nil;
00240     preprocessTwice = FALSE;
00241 
00242     AddCppOption(compilerName);
00243     AddCcOption(compilerName);
00244 
00245     ParseCmdOptions(1, argc, argv, source_file);
00246 
00247     return source_file;
00248 }
00249 
00250 void ParseCmdOptions(int from, int argc, char** argv, char*& source_file)
00251 {
00252     int i;
00253     for(i = from; i < argc; ++i)
00254         if(strcmp("--", argv[i]) == 0)
00255             break;
00256         else if(strcmp("-E", argv[i]) == 0)
00257             doCompile = FALSE;
00258         else if(strcmp("-g", argv[i]) == 0)
00259             AddCcOption(argv[i]);
00260         else if (strcmp("-n", argv[i]) == 0)
00261             doPreprocess = FALSE;
00262         else if(*argv[i] == '-' && argv[i][1] == 'm'){
00263             makeSharedLibrary = TRUE;
00264             sharedLibraryName = &argv[i][2];
00265         }
00266         else if (strcmp("-P", argv[i]) == 0)
00267             preprocessTwice = TRUE;
00268         else if (strcmp("-p", argv[i]) == 0)
00269             doTranslate = FALSE;
00270         else if (strcmp("-C", argv[i]) == 0) {
00271             AddCppOption("-C");
00272             preprocessTwice = TRUE;
00273         }
00274         else if(strcmp("-c", argv[i]) == 0)
00275             makeExecutable = FALSE;
00276         else if(strcmp("-l", argv[i]) == 0){
00277             cout << "[Loaded metaclasses...]\n";
00278             opcxx_ListOfMetaclass::PrintAllMetaclasses();
00279             exit(0);
00280         }
00281         else if(*argv[i] == '-' && argv[i][1] == 'S')
00282             LoadMetaclass(&argv[i][2]);
00283         else if(strcmp("-s", argv[i]) == 0)
00284             showProgram = TRUE;
00285         else if(strcmp("-v", argv[i]) == 0)
00286             verboseMode = TRUE;
00287         else if(strcmp("-V", argv[i]) == 0){
00288             ShowVersion();
00289             exit(1);
00290         }
00291         else if (strcmp("--regular-c++", argv[i]) == 0)
00292             regularCpp = TRUE;
00293         else if(*argv[i] == '-'
00294                 && (argv[i][1] == 'D' || argv[i][1] == 'I'))
00295             AddCppOption(argv[i]);
00296         else if(*argv[i] == '-' && argv[i][1] == 'd' && argv[i][2] != '\0')
00297             AddCppOption(&argv[i][2]);
00298         else if(*argv[i] == '-' && argv[i][1] == 'M')
00299             RecordCmdOption(&argv[i][2]);
00300         else if(*argv[i] == '-'){
00301             ShowVersion();
00302             ShowHelp(argv);
00303             exit(1);
00304         }
00305         else if(!ParseTargetSpecificOptions(argv[i], source_file))
00306             ParseCcOptions(argv[i], source_file);
00307 
00308     while(++i < argc)
00309         if(!ParseTargetSpecificOptions(argv[i], source_file))
00310             ParseCcOptions(argv[i], source_file);
00311 
00312     if(!doTranslate)
00313         doCompile = FALSE;
00314 }
00315 
00316 static void ShowVersion()
00317 {
00318     cerr << "OpenC++ version " << thisVersion << "\n" << copyingNote << "\n";
00319 }
00320 
00321 static void ShowHelp(char** argv)
00322 {
00323     cerr << "Usage: "
00324          << argv[0]
00325          << " [-l][-s][-V][-v][-E][-m[<file name>]][-c][-n][-p][--regular-c++]\n"
00326          << "\t\t[-I<directory>][-D<macro>[=<def>]][-M<option>[=<value>]]\n"
00327          << "\t\t[-g][-d<option>][-S<metaclass>]\n"
00328          << "\t\t[-- <compiler options>] <source file>\n"
00329          << "\n"
00330          << "    -g             Produce debugging information\n"
00331          << "    -M             Specify an <option> with <value> passed to metaobjects\n"
00332          << "    -l             List metaclasses\n"
00333          << "    -S             Load a metaclass\n"
00334          << "    -s             Show program tree on stdout\n"
00335          << "    -V             Show version\n"
00336          << "    -v             Verbose mode\n"
00337          << "\n"
00338          << " Building stages options\n"
00339          << "    -n             Don't preprocess\n"
00340          << "    -p             Don't translate (stop after parsing)\n"
00341          << "    -E             Don't compile (stop after translation)\n"
00342          << "    -c             Don't make executable (stop after compilation)\n"
00343 #if !defined(IRIX_CC) && !defined (_MSC_VER)
00344          << "    -P             Preprocess again after translation\n"
00345 #endif
00346          << "    -m             Compile a metaclass (make a shared library)\n"
00347          << "\n"
00348          << " Preprocessor options\n"
00349          << "    -I<directory>  Add <directory> to the #include path\n"
00350          << "    -D<name>=<def> Define a macro <name> as <def>\n"
00351          << "    -d<option>     Specify a preprocessor option\n"
00352 #if !defined(IRIX_CC) && !defined (_MSC_VER)
00353          << "    -C             Don't discard comments\n"
00354 #endif
00355          << "\n"
00356          << " Other options\n"
00357          << "    --regular-c++  Inhibit the extended syntax\n";
00358 }
00359 
00360 void AddCppOption(const char* arg)
00361 {
00362     if(cppArgc < NARGS)
00363         cppArgv[cppArgc++] = arg;
00364     else{
00365         cerr << "OpenC++: too many arguments\n";
00366         exit(1);
00367     }
00368 }
00369 
00370 void AddCcOption(const char* arg)
00371 {
00372     if(ccArgc < NARGS)
00373         ccArgv[ccArgc++] = arg;
00374     else{
00375         cerr << "OpenC++: too many arguments\n";
00376         exit(1);
00377     }
00378 }
00379 
00380 void CloseCcOptions()
00381 {
00382     for(int i = 0; i < cc2Argc; ++i)
00383         AddCcOption(cc2Argv[i]);
00384 
00385     AddCcOption((char*)0);
00386 }
00387 
00388 static void AddCc2Option(const char* arg)
00389 {
00390     if(cc2Argc < NARGS)
00391         cc2Argv[cc2Argc++] = arg;
00392     else{
00393         cerr << "OpenC++: too many arguments\n";
00394         exit(1);
00395     }
00396 }
00397 
00398 static void RecordCmdOption(char* option)
00399 {
00400     if(option == nil || *option == '\0')
00401         return;
00402 
00403     char* value = strchr(option, '=');
00404     if(value != nil)
00405         *value++ = '\0';
00406 
00407     if(!Class::RecordCmdLineOption(option, value)){
00408         cerr << "OpenC++: Too many -M options.\n";
00409         exit(1);
00410     }
00411 }
00412 
00413 static void ParseCcOptions(char* arg, char*& source_file)
00414 {
00415     static char* errmsg
00416         = "OpenC++: only a single source file is accepted at a time.\n";
00417 
00418     if(arg != nil && arg[0] != '-'){
00419         if(IsCxxSource(arg))
00420             if(source_file == nil){
00421                 source_file = arg;
00422                 return;
00423             }
00424             else{
00425                 cerr << errmsg;
00426                 exit(1);
00427             }
00428     }
00429 
00430     ++numOfObjectFiles;
00431     if(source_file == nil)      // source file is already given
00432         AddCcOption(arg);
00433     else
00434         AddCc2Option(arg);
00435 
00436     return;
00437 }
00438 
00439 /*
00440   File Naming convention
00441 
00442   .c, .C, .cc, .cpp, .cxx : C++ source files
00443   .mc : metaclass files
00444   .occ, .ii, .i (IRIX_CC): temporary files used by OpenC++
00445 */
00446 bool IsCxxSource(char* fname)
00447 {
00448     char* ext = strrchr(fname, '.');
00449     if(ext == nil)
00450         return FALSE;
00451 
00452     if(strcmp(ext,    ".cc") == 0
00453        || strcmp(ext, ".C") == 0
00454        || strcmp(ext, ".c") == 0
00455        || strcmp(ext, ".mc") == 0
00456        || strcmp(ext, ".cxx") == 0
00457        || strcmp(ext, ".cpp") == 0
00458        || strcmp(ext, ".ii") == 0
00459        || strcmp(ext, ".i") == 0
00460        || strcmp(ext, ".occ") == 0)
00461         return TRUE;
00462 
00463     return FALSE;
00464 }
00465 
00466 void ShowCommandLine(const char*, const char** args)
00467 {
00468     while(*args != nil)
00469         cerr << ' ' << *args++;
00470 }

Generated on Mon Feb 10 17:32:46 2003 for VFiasco Semantics Compiler by doxygen1.2.15