Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/C++/occ/driver2.cc
    1| /*
    2|   Copyright (C) 1997-2000 Shigeru Chiba, University of Tsukuba.
    3| 
    4|   Permission to use, copy, distribute and modify this software and   
    5|   its documentation for any purpose is hereby granted without fee,        
    6|   provided that the above copyright notice appear in all copies and that 
    7|   both that copyright notice and this permission notice appear in 
    8|   supporting documentation.
    9| 
   10|   Shigeru Chiba makes no representations about the suitability of this 
   11|   software for any purpose.  It is provided "as is" without express or
   12|   implied warranty.
   13| */
   14| /*
   15|   Copyright (c) 1995, 1996 Xerox Corporation.
   16|   All Rights Reserved.
   17| 
   18|   Use and copying of this software and preparation of derivative works
   19|   based upon this software are permitted. Any copy of this software or
   20|   of any derivative work must include the above copyright notice of
   21|   Xerox Corporation, this paragraph and the one after it.  Any
   22|   distribution of this software or derivative works must comply with all
   23|   applicable United States export control laws.
   24| 
   25|   This software is made available AS IS, and XEROX CORPORATION DISCLAIMS
   26|   ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
   27|   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   28|   PURPOSE, AND NOTWITHSTANDING ANY OTHER PROVISION CONTAINED HEREIN, ANY
   29|   LIABILITY FOR DAMAGES RESULTING FROM THE SOFTWARE OR ITS USE IS
   30|   EXPRESSLY DISCLAIMED, WHETHER ARISING IN CONTRACT, TORT (INCLUDING
   31|   NEGLIGENCE) OR STRICT LIABILITY, EVEN IF XEROX CORPORATION IS ADVISED
   32|   OF THE POSSIBILITY OF SUCH DAMAGES.
   33| */
   34| 
   35| #if defined(IRIX_CC)
   36| // for open()
   37| #include <sys/types.h>
   38| #include <sys/stat.h>
   39| #include <fcntl.h>
   40| #endif
   41| 
   42| #include <stdio.h>
   43| #include <stdlib.h>
   44| #include <unistd.h>
   45| #include <string.h>
   46| #include <fstream.h>
   47| #include "types.h"
   48| 
   49| // g++ recognizes a .ii file as preprocessed C++ source code.
   50| // CC recognizes a .i file as preprocessed C++ source code.
   51| 
   52| #if defined(IRIX_CC)
   53| #define OUTPUT_EXT      
   54| #else
   55| #define OUTPUT_EXT      
   56| #endif
   57| 
   58| #define CPP_EXT        
   59| #define SLIB_EXT        
   60| #define OBJ_EXT        
   61| 
   62| extern "C" {
   63| #if !defined(IRIX_CC) && !defined(__GLIBC__) && !defined(__STRICT_ANSI__)
   64|     int execvp(...);
   65| #endif
   66|     int wait(int*);
   67| }
   68| 
   69| #if defined(IRIX_CC)
   70| const char* compilerName = "CC";
   71| #else
   72| const charcompilerName = "g++";
   73| #endif
   74| const charlinkerName = "ld";
   75| const charopencxxErrorMessage = " Error(s).  OpenC++ stops.\n";
   76| 
   77| // defined in driver.cc
   78| 
   79| extern bool showProgram;
   80| extern bool doCompile;
   81| extern bool makeExecutable;
   82| extern bool doPreprocess;
   83| extern bool doTranslate;
   84| extern bool verboseMode;
   85| extern bool regularCpp;
   86| extern bool makeSharedLibrary;
   87| extern charsharedLibraryName;
   88| extern bool preprocessTwice;
   89| 
   90| extern const charcppArgv[];
   91| extern const charccArgv[];
   92| 
   93| extern void ParseCmdOptions(int from, int argc, char** argv, char*& source);
   94| extern void AddCppOption(const char* arg);
   95| extern void AddCcOption(const char* arg);
   96| extern void CloseCcOptions();
   97| extern void ShowCommandLine(const char* cmd, const char** args);
   98| 
   99| bool ParseTargetSpecificOptions(char* arg, char*& source_file);
  100| void RunLinker();
  101| charRunPreprocessor(const char* src);
  102| charOpenCxxOutputFileName(const char* src);
  103| void RunCompiler(const char* src, const char* occsrc);
  104| void RunSoCompiler(const char* src_file);
  105| voidLoadSoLib(char* file_name);
  106| voidLookupSymbol(void* handle, char* symbol);
  107| 
  108| #if !SHARED_OPTION
  109| static void RunSoLinker(const char* org_src, char* target);
  110| #endif
  111| static charMakeTempFilename(const char* src, const char* suffix);
  112| 
  113| 
  114| bool ParseTargetSpecificOptions(char*, char*&)
  115| {
  116|     return FALSE;
  117| }
  118| 
  119| void RunLinker()
  120| {
  121|     if(!doCompile || !makeExecutable){
  122|         cerr << "OpenC++: no source file.\n";
  123|         return;
  124|     }
  125| 
  126|     const charlinker = compilerName;
  127|     charslib = nil;
  128|     if(makeSharedLibrary){
  129| #if SHARED_OPTION
  130| #if defined(IRIX_CC)
  131|         AddCcOption("-n32");
  132| #else
  133|         AddCcOption("-fPIC");
  134| #endif
  135|         AddCcOption("-shared");
  136| #else /* SHARED_OPTION */
  137|         AddCcOption("-Bshareable");
  138|         linker = linkerName;
  139| #endif
  140|         if(sharedLibraryName != nil && *sharedLibraryName != '\0'){
  141|             slib = MakeTempFilename(sharedLibraryName, SLIB_EXT);
  142|             AddCcOption("-o");
  143|             AddCcOption(slib);
  144|         }
  145|     }
  146| 
  147|     ccArgv[0] = linker;
  148|     CloseCcOptions();
  149| 
  150|     if(verboseMode){
  151|         cerr << "[Link... ";
  152|         ShowCommandLine(linkerccArgv);
  153|         cerr << "]\n";
  154|     }
  155| 
  156|     if(fork() == 0){
  157|         execvp(linker, (char**)ccArgv);
  158|         perror("cannot invoke a compiler");
  159|     }
  160|     else{
  161|         int status;
  162| 
  163|         wait(&status);
  164|         if(status != 0)
  165|             exit(1);
  166|     }
  167| 
  168|     delete [] slib;
  169| }
  170| 
  171| charRunPreprocessor(const char* src)
  172| {
  173|     chardest = MakeTempFilename(src, CPP_EXT);
  174|     if(!regularCpp)
  175|         AddCppOption("-D__opencxx");
  176| 
  177|     AddCppOption("-E");
  178| #if defined(IRIX_CC)
  179|     AddCppOption("-n32");
  180| #else
  181|     AddCppOption("-o");
  182|     AddCppOption(dest);
  183|     AddCppOption("-x");
  184|     AddCppOption("c++");
  185| #endif
  186|     AddCppOption(src);
  187|     AddCppOption((char*)0);
  188| 
  189|     if(verboseMode){
  190|         cerr << "[Preprocess... ";
  191|         ShowCommandLine(compilerNamecppArgv);
  192| #if defined(IRIX_CC)
  193|         cerr << " > " << dest;
  194| #endif
  195|         cerr << "]\n";
  196|     }
  197| 
  198|     if(fork() == 0){
  199| #if defined(IRIX_CC)
  200|         int fd = open(dest, O_WRONLY | O_CREAT, 0666);
  201|         if (fd < 0) {
  202|             perror(dest);
  203|             exit(1);
  204|         }
  205|         dup2(fd, 1);
  206| #endif
  207|         execvp(compilerName, (char**)cppArgv);
  208|         perror("cannot invoke a compiler");
  209|     }
  210|     else{
  211|         int status;
  212| 
  213|         wait(&status);
  214|         if(status != 0)
  215|             exit(1);
  216|     }
  217| 
  218|     return dest;
  219| }
  220| 
  221| charOpenCxxOutputFileName(const char* src)
  222| {
  223|     return MakeTempFilename(src, OUTPUT_EXT);
  224| }
  225| 
  226| /*
  227|    To create a shared library foo.so from foo.cc,
  228| 
  229|    SunOS, Solaris, Linux (v2.0, gcc 2.7.2.2):
  230|                g++ -fPIC -shared -o foo.so foo.cc
  231| 
  232|    Irix with naitive CC:
  233|                CC -shared -n32 -o foo.so foo.cc
  234| 
  235|    FreeBSD:     g++ -fPIC -c f
  236|                ld -Bshareable -o foo.so foo.o
  237| 
  238| */
  239| void RunCompiler(const char* org_src, const char* occ_src)
  240| {
  241|     charslib = nil;
  242|     if(makeSharedLibrary){
  243|         const charname = org_src;
  244|         if(sharedLibraryName != nil && *sharedLibraryName != '\0')
  245|             name = sharedLibraryName;
  246| 
  247|         slib = MakeTempFilename(name, SLIB_EXT);
  248| #if SHARED_OPTION
  249| #if defined(IRIX_CC)
  250|         AddCcOption("-n32");
  251| #else
  252|         AddCcOption("-fPIC");
  253| #endif
  254|         AddCcOption("-shared");
  255|         if(makeExecutable){
  256|             AddCcOption("-o");
  257|             AddCcOption(slib);
  258|         }
  259|         else
  260|             AddCcOption("-c");
  261| #else /* SHARED_OPTION */
  262|         AddCcOption("-fPIC");
  263|         AddCcOption("-c");
  264| #endif
  265|     }
  266|     else
  267|         if(!makeExecutable)
  268|             AddCcOption("-c");
  269| 
  270| #if !defined(IRIX_CC)
  271|     if(preprocessTwice){
  272|         AddCcOption("-x");
  273|         AddCcOption("c++");
  274|     }
  275| #endif
  276| 
  277|     AddCcOption(occ_src);
  278|     CloseCcOptions();
  279| 
  280|     if(verboseMode){
  281|         cerr << "[Compile... ";
  282|         ShowCommandLine(compilerNameccArgv);
  283|         cerr << "]\n";
  284|     }
  285| 
  286|     if(fork() == 0){
  287|         execvp(compilerName, (char**)ccArgv);
  288|         perror("cannot invoke a compiler");
  289|     }
  290|     else{
  291|         int status;
  292| 
  293|         wait(&status);
  294|         if(status != 0)
  295|             exit(1);
  296|     }
  297| 
  298| #if !SHARED_OPTION
  299|     if(makeSharedLibrary && makeExecutable)
  300|         RunSoLinker(org_src, slib);
  301| #endif
  302| 
  303|     delete [] slib;
  304| }
  305| 
  306| void RunSoCompiler(const char* src_file)
  307| {
  308|     const charcc_argv[8];
  309|     int i = 0;
  310| 
  311|     charslib = MakeTempFilename(src_file, SLIB_EXT);
  312|     cc_argv[i++] = compilerName;
  313| #if SHARED_OPTION
  314| #if defined(IRIX_CC)
  315|     cc_argv[i++] = "-n32";
  316| #else
  317|     cc_argv[i++] = "-fPIC";
  318| #endif
  319|     cc_argv[i++] = "-shared";
  320|     cc_argv[i++] = "-o";
  321|     cc_argv[i++] = slib;
  322| #else
  323|     cc_argv[i++] = "-fPIC";
  324|     cc_argv[i++] = "-c";
  325| #endif
  326|     cc_argv[i++] = src_file;
  327|     cc_argv[i++] = (char*)0;
  328| 
  329|     if(verboseMode){
  330|         cerr << "[Compile... ";
  331|         ShowCommandLine(compilerNamecc_argv);
  332|         cerr << "]\n";
  333|     }
  334| 
  335|     if(fork() == 0){
  336|         execvp(compilerName, (char**)cc_argv);
  337|         perror("cannot invoke a compiler");
  338|     }
  339|     else{
  340|         int status;
  341| 
  342|         wait(&status);
  343|         if(status != 0)
  344|             exit(1);
  345|     }
  346| 
  347| #if !SHARED_OPTION
  348|     RunSoLinker(src_file, slib);
  349| #endif
  350| 
  351|     delete [] slib;
  352| }
  353| 
  354| voidLoadSoLib(char* file_name)
  355| {
  356|     voidhandle = nil;
  357| #if USE_DLOADER
  358|     handle = dlopen(file_name, RTLD_GLOBAL | RTLD_LAZY);
  359|     handle = dlopen(file_name, RTLD_GLOBAL | RTLD_LAZY);
  360|     if(handle == NULL){
  361|         cerr << "dlopen(" << file_name << ") failed: " << dlerror() << '\n';
  362|         exit(1);
  363|     }
  364| #endif /* USE_DLOADER */
  365| 
  366|     return handle;
  367| }
  368| 
  369| voidLookupSymbol(void* handle, char* symbol)
  370| {
  371|     voidfunc = nil;
  372| #if USE_DLOADER
  373|     func = dlsym(handlesymbol);
  374|     if(func == NULL){
  375|         cerr << "dlsym() failed (non metaclass?): " << dlerror() << '\n';
  376|         exit(1);
  377|     }
  378| #endif
  379|     return func;
  380| }
  381| 
  382| // RunSoLinker() is used only if SHARED_OPTION is false (FreeBSD).
  383| #if !SHARED_OPTION
  384| 
  385| static void RunSoLinker(const char* org_src, char* target)
  386| {
  387|     const char* ld_argv[6];
  388|     ld_argv[0] = linkerName;
  389|     ld_argv[1] = "-Bshareable";
  390|     ld_argv[2] = "-o";
  391|     ld_argv[3] = target;
  392|     ld_argv[4] = MakeTempFilename(org_src, OBJ_EXT);
  393|     ld_argv[5] = (char*)0;
  394| 
  395|     if(verboseMode){
  396|         cerr << "[Link... ";
  397|         ShowCommandLine(linkerName, ld_argv);
  398|         cerr << "]\n";
  399|     }
  400| 
  401|     if(fork() == 0){
  402|         execvp(linkerName, (char**)ld_argv);
  403|         perror("cannot invoke a linker");
  404|     }
  405|     else{
  406|         int status;
  407| 
  408|         wait(&status);
  409|         if(status != 0)
  410|             exit(1);
  411|     }
  412| 
  413|     unlink(ld_argv[4]);
  414|     delete [] ld_argv[4];
  415| }
  416| #endif /* SHARED_OPTION */
  417| 
  418| /*
  419|    For example, if src is "../foo.cc", MakeTempFilename() makes
  420|    "foo.<suffix>".
  421| */
  422| static charMakeTempFilename(const char* src, const char* suffix)
  423| {
  424|     const charstart;
  425|     const charend;
  426| 
  427|     start = strrchr(src'/');
  428|     if(start == nil)
  429|         start = src;
  430|     else
  431|         ++start;
  432| 
  433|     end = strrchr(start'.');
  434|     if(end == nil)
  435|         end = src + strlen(src);
  436| 
  437|     charresult = new char[end - start + strlen(suffix) + 1];
  438|     strncpy(resultstartend - start);
  439|     result[end - start] = '\0';
  440|     strcat(resultsuffix);
  441|     return result;
  442| }