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 + -
显示快捷键?