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