owcc.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,135 行 · 第 1/3 页

C
1,135
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  POSIX style compiler driver.
*
****************************************************************************/


/* FIXME
 *  if linking is done, remove objects afterwards?
 *  unrecognized options should warn, possibly error
 *  should owcc output a warning message if -b names unknown target?
 *  -S should remove .o files
 */

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "getopt.h"
#include <process.h>
#include <malloc.h>
#include <conio.h>

#include "clcommon.h"
#include "banner.h"
#undef  _BANEXTRA
#define _BANEXTRA _BANEXSHORT

#if defined(__UNIX__)
#define strfcmp strcmp
#else
#define strfcmp stricmp
#endif

#define DIS         "wdis"
#define CC          "wcc386"          /* Open Watcom C compiler          */
#define CCXX        "wpp386"          /* Open Watcom C++ compiler        */
#define WCLENV      "OWCC"
#define _NAME_      "C/C++32 "

#ifdef __UNIX__
#define PATH_SEP_STR "/"
#else
#define PATH_SEP_STR "/\\"
#endif
#define OUTPUTFILE  "a.out"
#define LINK        "wlink"             /* Open Watcom linker              */
#define TEMPFILE    "@__wcl__.lnk"      /* temporary linker directive file */

char *OptEnvVar = WCLENV;           /* Data interface for GetOpt()        */

static  char    *Word;              /* one parameter                      */
static  char    *SystemName;        /* system to link for                 */
static  char    Files[MAX_CMD];     /* list of filenames from Cmd         */
static  char    CC_Opts[MAX_CMD];   /* list of compiler options from Cmd  */
static  char    target_CC[20] = CC;    /* name of the wcc variant to use     */
static  char    target_CCXX[20] = CCXX; /* name of the wpp variant to use     */
static  char    CC_Path[_MAX_PATH]; /* path name for wcc.exe              */
static  char    PathBuffer[_MAX_PATH];/* buffer for path name of tool     */
static  char    *Link_Name;         /* Temp_Link copy if /fd specified    */
static  char    *Temp_Link;         /* temporary linker directive file    */
                                    /* Temp_Link concurrent usages clash  */
static  struct directives *Directive_List; /* linked list of directives   */
static  char    *StackSize;         /* size of stack                      */
static  char    DebugFlag;          /* debug info wanted                  */
static  char    CPU_Class;          /* [0..6]86, 'm'ips or 'a'xp          */
static  char    Conventions[2];     /* 'r' for -3r or 's' for -3s         */
static  char    *O_Name;            /* name of -o option                  */

static  char    preprocess_only;    /* flag: -E option used?              */
static  char    cpp_want_lines;     /* flag: want #lines output?          */
static  char    cpp_keep_comments;  /* flag: keep comments in output?     */
static  char    cpp_encrypt_names;  /* flag: encrypt C++ names?           */
static  char    *cpp_linewrap;      /* line length for cpp output         */



/*
 *  Static function prototypes
 */

static void MakeName( char *, char * );

#undef pick
#define pick(code,english)      english

extern const char *WclMsgs[] = {
#include "wclmsg.h"
};

static const char *EnglishHelp[] = {
#include "owcchelp.gh"
    NULL
};

typedef struct {
    char    *LongName;  /* if ending in ':', copy rest to OW option */
    char    *WatcomName;
} option_mapping;

/* Map of options which don't need special treatment */
option_mapping mappings[] = {
    { "fpmath=287", "fp2" },
    { "fpmath=387", "fp3" },
    { "fptune=586", "fp5" },
    { "fptune=686", "fp6" },
    { "fno-short-enum", "ei" },
    { "fshort-enum", "em" },
    { "fsigned-char", "j" },
    { "fpack-struct=:", "zp" },
    { "ffar-data-threshold=:", "zt" },
    { "frtti", "xr" },
    { "fmessage-full-path", "ef" },
    { "femit-names", "en" },
    { "fbrowser", "db" },
    { "fhook-epilogue", "ee" },
    { "fhook-prologue=:", "ep" },
    { "fhook-prologue", "ep" },
    { "fwrite-def", "v" },
    { "fwrite-def-without-typedefs", "zg" },
    { "fno-stack-check", "s" },
    { "fgrow-stack", "sg" },
    { "fstack-probe", "st" },
    { "fno-writable-strings", "zc" },
    { "fnostdlib", "zl" },
    { "ffunction-sections", "zm" },
    { "fno-strict-aliasing", "oa" },
    { "fguess-branch-probability", "ob" },
    { "fno-optimize-sibling-calls", "oc" },
    { "finline-functions", "oe" },
    { "finline-limit=:", "oe=" },
    { "fno-omit-frame-pointer", "of" },
    { "fno-omit-leaf-frame-pointer", "of+" },
    { "frerun-optimizer", "oh" },
    { "finline-intrinsics-max", "oi+" },
    { "finline-intrinsics", "oi" },
    { "finline-fp-rounding", "zri" },
    { "fomit-fp-rounting", "zro" },
    { "fschedule-prologue", "ok" },
    { "floop-optimize", "ol" },
    { "funroll-loops", "ol+" },
    { "finline-math", "om" },
    { "funsafe-math-optimizations", "on" },
    { "ffloat-store", "op" },
    { "fschedule-insns", "or" },
    { "fkeep-duplicates", "ou" },
    { "fno-eh", "xd" },
    { "feh-direct", "xst" },
    { "feh-table", "xss" },
    { "feh", "xs" },
    { "ftabstob=:", "t=" },
    /* { "mcmodel=:", "m" }, --- handled explicitly */
    { "mabi=cdecl", "ecc" },
    { "mabi=stdcall", "ecd" },
    { "mabi=fastcall", "ecf" },
    { "mabi=pascal", "ecp" },
    { "mabi=fortran", "ecr" },
    { "mabi=syscall", "ecs" },
    { "mabi=watcall", "ecw" },
    { "mwindows", "bg" },
    { "mconsole", "bc" },
    { "mthreads", "bm" },
    { "mrtdll", "br" },
    { "mdefault-windowing", "bw" },
    { "msoft-float", "fpc" },
    { "w", "w0" },
    { "Wlevel:", "w" },
    { "Wall", "w4" },
    { "Wextra", "wx" },
    { "Werror", "we" },
    { "Wn:", "wce=" },
    { "Wno-n:", "wcd=" },
    { "Woverlay", "wo" },
    { "Wpadded", "zpw" },
    { "Wc,-:", "" },
    { "Wstop-after-errors=:", "e" },
    { "ansi", "za" },
    { "std=c99", "za99" },
    { "std=c89", "za" },
    { "std=ow", "ze" },
    { "O0", "od" },
    { "O1", "oil" },
    { "O2", "onatx" },
    { "O3", "onatxl+" },
    { "Os", "os" },
    { "Ot", "ot" },
    { "O", "oil" },
    { "H", "fti" },
    { "fignore-line-directives", "pil" },
    { "fvoid-ptr-arithmetic", "zev" },
    { "shared", "bd" },
};

/* Others to be checked:
    { "-tp=<name>                      (C) set #pragma on <name>",

OW options that might be useful to add:
    -ft / -fx  non-8.3 include search options

*/

void print_banner( void )
{
    static int  done;

    if( done ) return;
    puts( banner1w( _NAME_ "Compiler Driver Program", _WCL_VERSION_ ) );
    puts( banner2( "1988" ) );
    puts( banner3 );
    puts( banner3a );
    done = 1;
}

static char *xlate_fname( char *name )
{
#ifndef __UNIX__
    /* On non-POSIX hosts, pathnames must be translated to format
     * expected by other tools.
     */
    char    *run = name;

    while( *run ) {
    if( *run == '/' )
        *run = '\\';
    run++;
    }
#endif
    return( name );
}

/* The following 'f' functions are designed to handle filenames */
static char *strfcat( char *target, const char *source )
{
    return( xlate_fname( strcat( target, source ) ) );
}

static char *strfdup( const char *source )
{
    return( xlate_fname( strdup( source ) ) );
}

void addccopt( int option, char *opt )
{
    char    op[4];

    op[0] = ' ';
    op[1] = '-';
    op[2] = option;
    op[3] = '\0';
    strcat( CC_Opts, op );
    if( opt )
        strcat( CC_Opts, opt );
}

static int FileExtension( char *p, char *ext )
{
    char        *dot;

    dot = NULL;
    while( *p != '\0' ) {
        if( *p == '.' )  dot = p;
        ++p;
    }
    if( dot != NULL ) {
        if( strfcmp( dot, ext ) == 0 ) {
            return( 1 );                /* indicate file extension matches */
        }
    }
    return( 0 );                        /* indicate no match */
}

static  void AddDirective( char *directive )
/******************************************/
{
    struct directives   *p;
    struct directives   *p2;

    p = MemAlloc( sizeof( struct directives ) );
    p->next = NULL;
    p->directive = MemAlloc( strlen( directive ) + 1 );
    strcpy( p->directive, directive );
    if( Directive_List == NULL ) {
        Directive_List = p;
    } else {
        p2 = Directive_List;
        while( p2->next != NULL ) {
            p2 = p2->next;
        }
        p2->next = p;
    }
}

static  int  ConsultSpecsFile( const char *target )
/*************************************************/
{
    FILE    *specs;
    char    line[MAX_CMD];
    char    start_line[MAX_CMD] = "system begin ";
    int     in_target = FALSE;
    char    *p, *blank;

    FindPath( "specs.owc", PathBuffer );
    specs = fopen( PathBuffer, "r" );
    if( !specs ) {
        fprintf( stderr, "Could not open specs file '%s' for reading!\n",
                 PathBuffer );
        exit( EXIT_FAILURE );
    }

    /* search for a block whose first line is "system begin <target>" ... */
    strcat( start_line, target );
    while( fgets( line, MAX_CMD, specs ) ) {
        p = strchr( line, '\n' );
        if( p ) {
            *p = '\0';
        }
        if( !stricmp( line, start_line ) ) {
            in_target = TRUE;
        } else if( !stricmp( line, "end" ) ) {
            in_target = FALSE;
        } else if( in_target ) {
            for( p = line; isspace( (unsigned char)*p ); p++ )
                ; /* do nothing else */
            if( strncmp ( p, "wcc", 3 ) ) {
                /* wrong format --> don't use this line */
                continue;
            }
            blank = strchr( p, ' ' );
            if( !blank ) {
                blank = strchr( p, '\t' );
            }
            if( blank ) {
                *blank = '\0';
            }
            strcpy( target_CC, p );

            /* this is a little nasty: transform 'wcc386' into 'wpp386', in-place */
            p[1] = p[2] = 'p';
            strcpy( target_CCXX, p );
            if( blank ) {
                /* if there are further options, copy them */
                *blank = ' ';
                strcat( CC_Opts, blank );
            }
            fclose( specs );
            return( 1 );
        }
    }
    fclose( specs );
    return( 0 );
}

static  int  Parse( int argc, char **argv )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?