translat.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 838 行 · 第 1/2 页
C
838 行
/****************************************************************************
*
* 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: Translate MS options to Watcom options.
*
****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "cl.h"
#include "cmdline.h"
#include "error.h"
#include "macro.h"
#include "message.h"
#include "pathconv.h"
#include "translat.h"
#include "system.h"
#define UNSUPPORTED_STR_SIZE 512
#define FORCE_C_COMPILE 1
#define FORCE_CPP_COMPILE 2
/*
* Various flags to keep in mind while translating options.
*/
static struct XlatStatus {
int forcedLanguage; /* can force C or C++ compile */
int debugLevel; /* value for -d<num> switch */
int warnLevel; /* value for -w<num> switch */
int charTypeUnsigned : 1; /* char = signed char by default */
int parmsInRegs : 1; /* use register calling convention */
int justCompile : 1; /* don't link */
int preprocessToFile : 1; /* preprocess file.c to file.i */
int disable_c : 1; /* compile */
int disable_FA : 1; /* generate listing file */
int disable_Fa : 1; /* set listing file name */
int disable_Fm : 1; /* generate map file */
int disable_Fo : 1; /* set object file name */
int opt_oa : 1; /* use -oa option */
int opt_od : 1; /* use -od option */
int opt_oi : 1; /* use -oi option */
int opt_ol : 1; /* use -ol option */
int opt_ol_plus : 1; /* use -ol+ option */
int opt_om : 1; /* use -om option */
int opt_on : 1; /* use -on option */
int opt_op : 1; /* use -op option */
int opt_os : 1; /* use -os option */
int opt_ot : 1; /* use -ot option */
int opt_ox : 1; /* use -ox option */
#ifdef __TARGET_386__
int opt_of : 1; /* use -of option */
int opt_or : 1; /* use -or option */
#endif
} status;
/*
* Add one more unsupported option to optStr.
*/
static void append_unsupported( char *optStr, char *opt )
/*******************************************************/
{
if( optStr[0] != '\0' ) {
strcat( optStr, " /" );
} else {
strcat( optStr, "/" );
}
strcat( optStr, opt );
}
/*
* Parse unsupported options.
*/
static void unsupported_opts( OPT_STORAGE *cmdOpts )
/**************************************************/
{
char opts[UNSUPPORTED_STR_SIZE];
/*** Build a string listing all unsupported options that were used ***/
opts[0] = '\0';
if( cmdOpts->Fa ) append_unsupported( opts, "Fa" );
if( cmdOpts->FA ) append_unsupported( opts, "FA" );
if( cmdOpts->FAc ) append_unsupported( opts, "FAc" );
if( cmdOpts->FAcs ) append_unsupported( opts, "FAcs" );
if( cmdOpts->FAs ) append_unsupported( opts, "FAs" );
if( cmdOpts->Fd ) append_unsupported( opts, "Fd" );
if( cmdOpts->Fr ) append_unsupported( opts, "Fr" );
switch( cmdOpts->calling_convention ) {
case OPT_calling_convention_Gd:
append_unsupported( opts, "Gd" );
break;
case OPT_calling_convention_Gr:
append_unsupported( opts, "Gr" );
break;
case OPT_calling_convention_Gz:
append_unsupported( opts, "Gz" );
break;
}
if( cmdOpts->H ) append_unsupported( opts, "H" );
if( cmdOpts->Ow ) append_unsupported( opts, "Ow" );
if( cmdOpts->u ) append_unsupported( opts, "u" );
if( cmdOpts->V ) append_unsupported( opts, "V" );
if( cmdOpts->vd0 ) append_unsupported( opts, "vd0" );
if( cmdOpts->vd1 ) append_unsupported( opts, "vd1" );
if( cmdOpts->vmb ) append_unsupported( opts, "vmb" );
if( cmdOpts->vmg ) append_unsupported( opts, "vmg" );
if( cmdOpts->vmm ) append_unsupported( opts, "vmm" );
if( cmdOpts->vms ) append_unsupported( opts, "vms" );
if( cmdOpts->vmv ) append_unsupported( opts, "vmv" );
if( cmdOpts->X ) append_unsupported( opts, "X" );
if( cmdOpts->debug_info == OPT_debug_info_Zi ) {
append_unsupported( opts, "Zi" );
}
if( cmdOpts->Zn ) append_unsupported( opts, "Zn" );
/*** If an unsupported option was used, give a warning ***/
if( opts[0] != '\0' ) {
UnsupportedOptsMessage( opts );
}
}
/*
* Initialize a struct XlatStatus.
*/
static void init_status( struct XlatStatus *status )
/**************************************************/
{
memset( status, 0, sizeof(struct XlatStatus) );
status->warnLevel = 1; /* default is /W1 */
status->parmsInRegs = 1; /* it's faster this way */
status->opt_od = 1; /* default is no optimization */
#ifdef __TARGET_386__
status->opt_of = 1; /* default is to make stack frames */
status->opt_or = 1; /* default is pipeline optimizing */
#endif
}
/*
* Translate options related to C++ and not to C.
*/
static void c_plus_plus_opts( struct XlatStatus *status, OPT_STORAGE *cmdOpts,
CmdLine *compCmdLine )
/**************************************************************************/
{
AppendCmdLine( compCmdLine, CL_C_CPP_OPTS_SECTION, "-xs" );
if( cmdOpts->_10x ) {
AppendCmdLine( compCmdLine, CL_C_CPP_OPTS_SECTION, "-zo" );
}
}
/*
* Translate options related to the preprocessor.
*/
static void preprocessor_opts( struct XlatStatus *status,
OPT_STORAGE *cmdOpts, CmdLine *compCmdLine )
/*************************************************************************/
{
int preserveComments = 0;
int includeLines = 1; /* use #line directives */
int preprocess = 0;
OPT_STRING * optStr;
char * newpath;
optStr = cmdOpts->I_value;
while( optStr != NULL ) {
newpath = PathConvert( optStr->data, '"' );
AppendFmtCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-i=%s", newpath );
optStr = optStr->next;
}
optStr = cmdOpts->FI_value;
while( optStr != NULL ) {
newpath = PathConvert( optStr->data, '"' );
AppendFmtCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-fi=%s", newpath );
optStr = optStr->next;
}
if( cmdOpts->C ) {
if( !cmdOpts->E && !cmdOpts->P && !cmdOpts->EP ) {
Warning( "/C requires /E, /P, or /EP -- option ignored" );
} else {
preserveComments = 1;
}
}
if( cmdOpts->E ) {
status->disable_c = 1;
status->disable_FA = 1;
status->disable_Fa = 1;
status->disable_Fm = 1;
status->disable_Fo = 1;
preprocess = 1;
}
if( cmdOpts->P ) {
status->disable_c = 1;
status->disable_FA = 1;
status->disable_Fa = 1;
status->disable_Fm = 1;
status->disable_Fo = 1;
preprocess = 1;
status->preprocessToFile = 1;
}
if( cmdOpts->EP ) {
status->disable_c = 1;
status->disable_FA = 1;
status->disable_Fa = 1;
status->disable_Fm = 1;
status->disable_Fo = 1;
preprocess = 1;
includeLines = 0;
}
if( preprocess ) {
AppendFmtCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-p%s%s",
includeLines ? "l" : "",
preserveComments ? "c" : "" );
}
}
/*
* Translate options related to precompiled headers.
*/
static void precomp_header_opts( struct XlatStatus *status,
OPT_STORAGE *cmdOpts, CmdLine *compCmdLine )
/***************************************************************************/
{
char * newpath;
if( cmdOpts->Fp ) {
newpath = PathConvert( cmdOpts->Fp_value->data, '"' );
AppendFmtCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-fhq=%s", newpath );
} else {
switch( cmdOpts->precomp_headers ) {
case OPT_precomp_headers_Yc:
/* fall through */
case OPT_precomp_headers_Yu:
/* fall through */
case OPT_precomp_headers_YX:
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-fhq" );
break;
case OPT_precomp_headers_default:
break;
default:
Zoinks();
}
}
if( cmdOpts->Yd ) {
/* done by default */
}
}
/*
* Parse various options which defy categorization.
*/
static void misc_opts( struct XlatStatus *status, OPT_STORAGE *cmdOpts,
CmdLine *compCmdLine )
/*********************************************************************/
{
if( cmdOpts->J ) {
status->charTypeUnsigned = 1;
}
if( cmdOpts->Tc ) {
status->forcedLanguage = FORCE_C_COMPILE;
}
if( cmdOpts->Tp ) {
status->forcedLanguage = FORCE_CPP_COMPILE;
}
switch( cmdOpts->warn_level ) {
case OPT_warn_level_w:
status->warnLevel = 0;
break;
case OPT_warn_level_W:
status->warnLevel = cmdOpts->W_value;
break;
case OPT_warn_level_default:
/* use default value */
break;
default:
Zoinks();
}
switch( cmdOpts->iso ) {
case OPT_iso_Za:
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-za" );
if( cmdOpts->iso_timestamp > cmdOpts->Op_timestamp ) {
status->opt_op = 1;
}
break;
case OPT_iso_Ze:
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-ze" );
break;
case OPT_iso_default:
/* use default value */
break;
default:
Zoinks();
}
if( cmdOpts->Zs ) {
status->disable_c = 1;
status->disable_FA = 1;
status->disable_Fa = 1;
status->disable_Fm = 1;
status->disable_Fo = 1;
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-zs" );
}
if( !status->disable_c ) {
if( cmdOpts->FR ) {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-db" );
}
#ifdef __TARGET_386__
switch( cmdOpts->arch_i86 ) { /* what is the CPU */
case OPT_arch_i86_G3:
if( status->parmsInRegs ) {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-3r" );
} else {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-3s" );
}
break;
case OPT_arch_i86_G4:
case OPT_arch_i86_GB:
default:
if( status->parmsInRegs ) {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-4r" );
} else {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-4s" );
}
break;
case OPT_arch_i86_G5:
if( status->parmsInRegs ) {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-5r" );
} else {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-5s" );
}
break;
}
#endif
switch( cmdOpts->stack_probes ) {
case OPT_stack_probes_Ge:
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-st" );
break;
case OPT_stack_probes_Gs:
#ifndef __TARGET_AXP__
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-sg" );
#else
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-s" );
#endif
break;
case OPT_stack_probes_default:
break;
default:
Zoinks();
}
if( cmdOpts->WX ) {
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-we" );
}
if( cmdOpts->Zg ) {
status->disable_c = 1;
status->disable_FA = 1;
status->disable_Fa = 1;
status->disable_Fm = 1;
status->disable_Fo = 1;
Warning( "Prototypes will be output to .def file(s), not standard output" );
AppendCmdLine( compCmdLine, CL_C_OPTS_SECTION, "-v" );
}
}
}
/*
* Translate options related to object files.
*/
static void object_opts( struct XlatStatus *status, OPT_STORAGE *cmdOpts,
CmdLine *compCmdLine )
/***********************************************************************/
{
char * newpath;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?