cmdline.c

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

C
709
字号
/****************************************************************************
*
*                            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:  Librarian command line parsing.
*
****************************************************************************/


#include <wlib.h>

#define AR_MODE_ENV "WLIB$AR"

#define eatwhite( c ) while( *(c) && isspace( *(c) ) ) ++(c);
#define notwhite( c ) ( (c) != '\0' && !isspace( c ) )

options_def     Options;
lib_cmd         *CmdList;

void GetString( char **pc, char *buff, int singlequote, int ignoreSpaceInQuotes )
{
    char *c = *pc;
    char  quote;

    eatwhite(c);

    if ((*c == '\"') || (singlequote && (*c == '\''))) {
        quote = *c;
        c++;
        while ((*c != '\0') && (*c != quote)) {
            *buff++ = *c++;
        }
        if (*c == quote) {
            c++;
        }
    } else {
        int inquote = FALSE;

        while( inquote || notwhite( *c ) ) {
            if (ignoreSpaceInQuotes) {
                if (*c == 0x00) {
                    break;
                } else if ((*c == '\"') || (*c == '\'')) {
                    inquote = !inquote;
                }
            }
            *buff++ = *c++;
        }
    }
    *buff = '\0';
    *pc = c;
}

char *GetEqual( char **pc, char *buff, char *ext )
{
    char *c = *pc;
    char *ret;

    eatwhite( c );
    if( *c == '=' ) {
        ++c;
        eatwhite( c );
    } else {
        c = *pc;
    }
    if( *c == ' ' || *c == '\0' ) return( NULL );
    GetString( &c, buff, FALSE, FALSE );
    if( ext != NULL ) {
        DefaultExtension( buff, ext );
    }
    ret = DupStr( buff );
    *pc = c;
    return( ret );
}

static void SetPageSize( unsigned short new_size )
{
    unsigned int i;
    Options.page_size = MIN_PAGE_SIZE;
    for( i = 4; i < 16; i++ ){
        if( new_size & 1<<i ){
            Options.page_size = 1<<i;
        }
    }
    if( Options.page_size < new_size ){
        Options.page_size <<= 1;
    }
}

static void DuplicateOption( char *c )
{
    FatalError( ERR_DUPLICATE_OPTION, c );
}

static bool ParseOption( char **pc, char *buff )
{
    bool        rc;
    long        page_size;
    char        *c = *pc;
    char        *start = c;
    char        *page;
    char        *endptr;

    rc = TRUE;
    switch( *c++ ) {
    case '-':
    case '/':
        eatwhite( c );
        switch( tolower( *c++ ) ) {
        case '?': //                       (don't create .bak file)
            Banner();
            Usage();
            break;
        case 'b': //                       (don't create .bak file)
            Options.no_backup = 1;
            break;
        case 'c': //                       (case sensitive)
            Options.respect_case = 1;
            break;
        case 'd': // = <object_output_directory>
            if( Options.output_directory ) {
                DuplicateOption( start );
            }
            Options.output_directory = GetEqual( &c, buff, NULL );
            if( access( Options.output_directory, F_OK ) != 0 ) {
                FatalError( ERR_DIR_NOT_EXIST, Options.output_directory );
            }
            break;
        case 'i':
            switch( tolower(*c++) ) {
                case 'n':
                    switch( tolower(*c++) ) {
                        case 'n':
                            Options.nr_ordinal = FALSE;
                            break;
                        case 'o':
                            Options.nr_ordinal = TRUE;
                            break;
                        default:
                            return( FALSE );
                    }
                    break;
                case 'r':
                    switch( tolower(*c++) ) {
                        case 'n':
                            Options.r_ordinal = FALSE;
                            break;
                        case 'o':
                            Options.r_ordinal = TRUE;
                            break;
                        default:
                            return( FALSE );
                    }
                    break;
                case 'a':
                    if( Options.processor ) {
                        DuplicateOption( start );
                    }
                    Options.processor = WL_PROC_AXP;
                    break;
                case 'p':
                    if( Options.processor ) {
                        DuplicateOption( start );
                    }
                    Options.processor = WL_PROC_PPC;
                    break;
                case 'i':
                    if( Options.processor ) {
                        DuplicateOption( start );
                    }
                    Options.processor = WL_PROC_X86;
                    break;
                case 'e':
                    if( Options.filetype ) {
                        DuplicateOption( start );
                    }
                    Options.filetype = WL_TYPE_ELF;
                    break;
                case 'c':
                    if( Options.filetype ) {
                        DuplicateOption( start );
                    }
                    Options.filetype = WL_TYPE_COFF;
                    break;
                case 'o':
                    if( Options.filetype ) {
                        DuplicateOption( start );
                    }
                    Options.filetype = WL_TYPE_OMF;
                    break;
                default:
                    return ( FALSE );
            }
            break;
        case 'h':
            Banner();
            Usage();
            break;
        case 'l': // [ = <list_file_name> ]
            if( Options.list_contents ) {
                DuplicateOption( start );
            }
            Options.list_contents = 1;
            Options.list_file = GetEqual( &c, buff, EXT_LST );
            break;
        case 'm': //                       (display C++ mangled names)
            Options.mangled = 1;
            break;
        case 'o': // = <out_library_name>
            if( Options.output_name ) {
                DuplicateOption( start );
            }
            Options.output_name = GetEqual( &c, buff, EXT_LIB );
            break;
        case 'q': //                       (don't print header)
            Options.quiet = 1;
            break;
        case 'v': //                       (don't print header)
            Options.quiet = 0;
            break;
        case 'x': //                       (explode all objects in library)
            Options.explode = 1;
            Options.explode_ext = GetEqual( &c, buff, NULL );
            if( Options.explode_ext == NULL )
                Options.explode_ext = EXT_OBJ;
            break;
        case 'z':
            if( (*c == 'l') && (*(c + 1) == 'd') ) {
                c += 2;
                if( Options.strip_dependency ) {
                    DuplicateOption( start );
                }
                Options.strip_dependency = 1; //(strip dependency info)
                break;
            } else if( Options.strip_expdef ) {
                DuplicateOption( start );
            }
            Options.strip_expdef = 1;       // JBS 99/07/09
            Options.export_list_file = GetEqual( &c, buff, NULL );
            break;
        case 't':
            if (*c == 'l') {
                ++c;
                Options.list_contents = 1;
                Options.terse_listing = 1; // (internal terse listing option)
            } else {
                Options.trim_path = 1; //(trim THEADR pathnames)
            }
            break;
        case 'f':
            switch( tolower(*c++) ) {
                case 'm':
                    if( Options.libtype ) {
                        DuplicateOption( start );
                    }
                    Options.libtype = WL_TYPE_MLIB;
                    Options.elf_found = 1;
                    break;
                case 'a':
                    if( Options.libtype ) {
                        DuplicateOption( start );
                    }
                    Options.libtype = WL_TYPE_AR;
                    Options.coff_found = 1;
                    break;
                case 'o':
                    if( Options.libtype ) {
                        DuplicateOption( start );
                    }
                    Options.libtype = WL_TYPE_OMF;
                    Options.omf_found = 1;
                    break;
                default:
                    return ( FALSE );
            }
            break;
    // following only used by OMF libary format
        case 'p':
            if( Options.page_size ) {
                DuplicateOption( start );
            }
            page = GetEqual( &c, buff, NULL );
            errno = 0;
            page_size = strtoul( page, &endptr, 0 );
            if( *endptr != '\0' ){
                FatalError( ERR_BAD_CMDLINE, start );
            } else if ( errno == ERANGE || page_size > MAX_PAGE_SIZE ) {
                FatalError( ERR_PAGE_RANGE );
            }
            MemFree( page );
            SetPageSize( page_size );
            break;
        case 'n': //                       (always create a new library)
            Options.new_library = 1;
            break;
        case 's':
            Options.strip_line = 1;
            break;
        default:
            return( FALSE );
        }
        break;
    default:
        return( FALSE );
    }
    *pc = c;
    return( TRUE );
}

void AddCommand( operation ops, char *name )
{
    lib_cmd         *new;

    new = MemAllocGlobal( sizeof( lib_cmd ) + strlen( name ) );
    strcpy( new->name, name );
    new->fname = NULL;
    if( ops == OP_EXTRACT ) {
        char    *p;

        p = strchr( new->name, '=' );
        if( p != NULL ) {
            *p = '\0';
            new->fname = p + 1;
        }
    }
    new->next = CmdList;
    new->ops = ops;
    CmdList = new;
}

static void FreeCommands( void )
{
    lib_cmd     *cmd, *next;

⌨️ 快捷键说明

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