option.c

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

C
734
字号
/****************************************************************************
*
*                            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:  command and source line option processing
*
****************************************************************************/


#include "ftnstd.h"
#include "progsw.h"
#include "errcod.h"
#include "cpopt.h"
#include "optflags.h"
#include "global.h"
#include "intcnv.h"
#include "csetinfo.h"
#include "fmemmgr.h"
#include "ferror.h"
#include "comio.h"
#include "inout.h"

#include <stdlib.h>
#include <ctype.h>
#include <string.h>

extern  char            *SkipBlanks(char *);
extern  void            MacroDEFINE(char *,uint);
extern  void            MacroUNDEFINE(char *,uint);
extern  void            MacroIFDEF(char *,uint);
extern  void            MacroIFNDEF(char *,uint);
extern  void            MacroELIFDEF(char *,uint);
extern  void            MacroELIFNDEF(char *,uint);
extern  void            MacroELSE(void);
extern  void            MacroENDIF(void);
extern  void            ProcPragma(char *);
extern  void            __UseChineseCharSet(void);
extern  void            __UseJapaneseCharSet(void);
extern  void            __UseKoreanCharSet(void);

extern  character_set   CharSetInfo;

extern  uint            DataThreshold;

// Compiler directives

#define CD_INCLUDE      1
#define CD_EJECT        2
#define CD_PRAGMA       3
#define CD_IFDEF        4
#define CD_IFNDEF       5
#define CD_ENDIF        6
#define CD_ELSE         7
#define CD_ELIFDEF      8
#define CD_ELIFNDEF     9
#define CD_DEFINE       10
#define CD_UNDEFINE     11

static const char __FAR * const __FAR CompDrctvs[] = {
    "INCLUDE",
    "EJECT",
    "PRAGMA",
    "IFDEF",
    "IFNDEF",
    "ENDIF",
    "ELSE",
    "ELSEIFDEF",
    "ELSEIFNDEF",
    "DEFINE",
    "UNDEFINE",
    NULL
};

#define DISK_MASK       (OPT_TYPE|OPT_PRINT)

// Used for matching OZOpts bits
#define _BitsMatched( bits, ptrn )      !((bits & ptrn) ^ ptrn)

#define INCLUDE_SEP     ';'

static  char    *SkipOpt( char *buff ) {
//======================================

// Skip over an option.

    while( isalnum( *buff ) ) {
        buff++;
    }
    return( buff );
}


static  bool    GetValue( opt_entry *optn, char *ptr, char **val ) {
//==================================================================

// Get pointer to option value.

    *val = SkipBlanks( ptr );
    if( ( **val != '=' ) && ( **val != '#' ) ) {
        Warning( CO_NEED_EQUALS, optn->option );
        return( FALSE );
    } else {
        *val = SkipBlanks( *val + sizeof( char ) );
        return( TRUE);
    }
}


static  void    BitOption( opt_entry *optn, bool negated ) {
//==========================================================

// Process an option that has a bit value.

    ftnoption   opt_bit;

    opt_bit = optn->value;
    if( !negated ) {
        // TYPE turns off PRINT and vice-versa
        if( opt_bit & DISK_MASK ) {
            NewOptions &= ~DISK_MASK;
            NewOptions |= OPT_LIST;
        }
        if( opt_bit & OPT_LIST ) {
            SetLst( TRUE );
        }
        // SAVE turns off AUTOMATIC and vice-versa
        if( opt_bit & ( OPT_SAVE | OPT_AUTOMATIC ) ) {
            NewOptions &= ~( OPT_SAVE | OPT_AUTOMATIC );
        }
        NewOptions |= opt_bit;
    } else if( opt_bit & OPT_NO_NO ) {
        Warning( CO_BAD_NO, optn->option );
    } else {
        NewOptions &= ~opt_bit;
        if( opt_bit & OPT_LIST ) {
            SetLst( FALSE );
        }
    }
}


static  void    XLOption( opt_entry *optn, bool negated ) {
//=========================================================

// Extend source line beyond column 72.

    optn = optn;
    if( negated ) {
        LastColumn = LAST_COL;
    } else {
        LastColumn = SRCLEN;
    }
}


static  char    *SkipToken( char *buff ) {
//========================================

    for(;;) {
        if( *buff == NULLCHAR ) break;
        if( *buff == ' ' ) break;
        if( *buff == '\t' ) break;
        buff++;
    }
    return( buff );
}


static  void    DefOption( opt_entry *optn, char *ptr ) {
//=======================================================

// Define a macro.

    optn = optn;
    MacroDEFINE( ptr, SkipToken( ptr ) - ptr );
}


static  void    PathOption( opt_entry *optn, char *ptr ) {
//========================================================

// Process "INCPATH=" option.

    char        *tmp;
    int         len;

    optn = optn;
    if( !IncludePath ) {
        IncludePath = FMemAlloc( strlen( ptr ) + 1 );
        *IncludePath = '\0';
    } else {
        len = strlen( IncludePath );
        tmp = FMemAlloc( strlen( ptr ) + len + 2 );
        strcpy( tmp, IncludePath );
        FMemFree( IncludePath );
        IncludePath = tmp;
        // We must glue the strings together correctly.
        if( ( tmp[ len - 1 ] != INCLUDE_SEP ) && ( *ptr != INCLUDE_SEP ) ) {
            tmp[ len ] = INCLUDE_SEP;
            tmp[ len + 1 ] = '\0';
        } else if( (tmp[len - 1] == INCLUDE_SEP) && (*ptr == INCLUDE_SEP) ) {
            tmp[ len - 1 ] = '\0';
        }
    }
    strcat( IncludePath, ptr );
}


void            FiniProcCmd(void) {
//=================================

    if( IncludePath ) {
        FMemFree( IncludePath );
    }
}


static  unsigned_32     OptV( opt_entry *optn, char *ptr ) {
//==========================================================

// Process an option that requires a value.

    unsigned_32 number;

    if( !isdigit( *ptr ) ) {
        Warning( CO_WANT_NUMBER, optn->option );
    }
    number = 0;
    for(;;) {
        number = 10 * number + ( *ptr - '0' );
        ptr++;
        if( isdigit( *ptr ) == 0 ) break;
    }
    return( number );
}



#define _Excl( excl_bits )  if( opt_bit & ( excl_bits ) ) {       \
                                CGOpts &= ~( excl_bits );         \
                            }


static  void    CGOption( opt_entry *optn, bool negated ) {
//=========================================================

// Process a code generator option.

    unsigned_32 opt_bit;

    opt_bit = optn->value;
    if( !negated ) {
#if _CPU == 8086
        _Excl( CGOPT_M_MEDIUM | CGOPT_M_LARGE | CGOPT_M_HUGE );
#elif _CPU == 386
        _Excl( CGOPT_M_FLAT | CGOPT_M_SMALL | CGOPT_M_COMPACT |
               CGOPT_M_MEDIUM | CGOPT_M_LARGE );
        _Excl( CGOPT_BD | CGOPT_BM );
        _Excl( CGOPT_STACK_CHK | CGOPT_STACK_GROW );
#elif _CPU == _AXP || _CPU == _PPC
        _Excl( CGOPT_BD | CGOPT_BM );
#else
  #error Unknown platform
#endif
        _Excl( CGOPT_DB_LINE | CGOPT_DB_LOCALS );
        _Excl( CGOPT_DI_CV | CGOPT_DI_DWARF | CGOPT_DI_WATCOM );
        CGOpts |= opt_bit;
    } else if( !(opt_bit & CGOPT_NO_NO) ) {
        CGOpts &= ~opt_bit;
    } else {
        Warning( CO_BAD_NO, optn->option );
    }
}


#define _OZExcl( excl_bits )  if( opt_bit & ( excl_bits ) ) {       \
                                   OZOpts &= ~( excl_bits );        \
                              }

static  void    OZOption( opt_entry *optn, bool negated ) {
//=========================================================

// Process a optimization option.

    unsigned_32 opt_bit;

    opt_bit = optn->value;
    if( !negated ) {
        _OZExcl( OZOPT_O_SPACE | OZOPT_O_TIME );
        OZOpts |= opt_bit;
    } else if( !(opt_bit & OZOPT_NO_NO) ) {
        OZOpts &= ~opt_bit;
    } else {
        Warning( CO_BAD_NO, optn->option );
    }
}


#define _CPUExcl( excl_bits )  if( opt_bit & ( excl_bits ) ) {       \
                                   CPUOpts &= ~( excl_bits );        \
                               }

#if _CPU == 8086 || _CPU == 386
static  void    CPUOption( opt_entry *optn, bool negated ) {
//==========================================================

// Process a code generator option.

    unsigned_32 opt_bit;

    opt_bit = optn->value;
    if( !negated ) {
#if _CPU == 8086
        _CPUExcl( CPUOPT_8086 | CPUOPT_80186 | CPUOPT_80286 |
                  CPUOPT_80386 | CPUOPT_80486 | CPUOPT_80586 );
#else
        _CPUExcl( CPUOPT_80386 | CPUOPT_80486 | CPUOPT_80586 );
#endif
        _CPUExcl( CPUOPT_FPC | CPUOPT_FPI | CPUOPT_FPI87 )
        _CPUExcl( CPUOPT_FPC | CPUOPT_FP287 | CPUOPT_FP387 | CPUOPT_FP5 );
        CPUOpts |= opt_bit;
    } else if( !(opt_bit & CPUOPT_NO_NO) ) {
        CPUOpts &= ~opt_bit;
    } else {
        Warning( CO_BAD_NO, optn->option );
    }
}
#endif


static  void    DTOption( opt_entry *optn, char *ptr ) {
//======================================================

// Process "DT=" option.

    DataThreshold = OptV( optn, ptr );
}


static  void    FOOption( opt_entry *optn, char *ptr ) {
//======================================================

// Process "FO=" option.

    optn = optn;

⌨️ 快捷键说明

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