parse.c

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

C
871
字号
 * Parse the /EXPORT option, which is of the form
 *      /EXPORT:entryname[=internalname][,@ordinal[,NONAME]][,DATA]
 */
static int parse_export( OPT_STRING **optStr )
/********************************************/
{
    char *              strStart;
    char *              str;
    char *              p;
    char *              entryName = NULL;
    char *              internalName = NULL;
    char *              ordinal = NULL;
    size_t              len;
    int                 retcode = 1;

    /*** Extract the export string ***/
    if( !CmdScanRecogChar( ':' ) ) {
        FatalError( "/EXPORT requires an argument" );
        return( 0 );
    }
    str = CmdScanString();
    strStart = str;
    if( str == NULL ) {
        FatalError( "/EXPORT requires an argument" );
        return( 0 );
    }

    /*** Extract the entryName ***/
    p = str;
    while( *p != '\0'  &&  *p != '='  &&  *p != ',' )  p++;
    if( p == str ) {
        retcode = 0;
    } else {
        len = p - str + 1;
        if( str[0] != '\'' || str[len-2] != '\'' ) {
            len += 2;
            entryName = AllocMem( len );
            entryName[0] = '\'';
            memcpy( &(entryName[1]), str, len-3 );
            entryName[len-2] = '\'';
        } else {
            entryName = AllocMem( len );
            memcpy( entryName, str, len-1 );
        }
        entryName[len-1] = '\0';
        str = p;
    }

    /*** Extract the internalName ***/
    if( *str == '='  &&  retcode != 0 ) {
        str++;
        p = str;
        while( *p != '\0'  &&  *p != ',' )  p++;
        if( p == str ) {
            retcode = 0;
        } else {
            len = p - str + 1;
            if( str[0] != '\'' || str[len-2] != '\'' ) {
                len += 2;
                internalName = AllocMem( len );
                internalName[0] = '\'';
                memcpy( &(internalName[1]), str, len-3 );
                internalName[len-2] = '\'';
            } else {
                internalName = AllocMem( len );
                memcpy( internalName, str, len-1 );
            }
            internalName[len-1] = '\0';
            str = p;
        }
    }

    /*** Extract the ordinal ***/
    if( *str == ','  &&  retcode != 0 ) {
        if( *(++str) != '@' ) {
            retcode = 0;
        } else {
            str++;
            p = str;
            while( *p != '\0'  &&  isdigit( *p ) )  p++;
            if( p == str ) {
                retcode = 0;
            } else {
                len = p - str + 1;
                ordinal = AllocMem( len );
                memcpy( ordinal, str, len-1 );
                ordinal[len-1] = '\0';
            }
        }
    }

    /*** Abort on error ***/
    if( retcode == 0 ) {
        if( entryName != NULL )  FreeMem( entryName );
        if( internalName != NULL )  FreeMem( internalName );
        if( ordinal != NULL )  FreeMem( ordinal );
        FreeMem( strStart );
        return( 0 );
    }

    /*** Merge together Watcom-style:  entryName[.ordinal][=internalName] ***/
    FreeMem( strStart );
    len = strlen( entryName );
    if( ordinal != NULL ) {
        len++;                          /* for '.' */
        len += strlen( ordinal );
    }
    if( internalName != NULL ) {
        len++;                          /* for '=' */
        len += strlen( internalName );
    }
    str = AllocMem( len );
    *str = '\0';
    strcat( str, entryName );
    if( ordinal != NULL ) {
        strcat( str, "." );
        strcat( str, ordinal );
    }
    if( internalName != NULL ) {
        strcat( str, "=" );
        strcat( str, internalName );
    }
    add_string( optStr, str, 0 );
    FreeMem( entryName );
    if( internalName != NULL )  FreeMem( internalName );
    if( ordinal != NULL )  FreeMem( ordinal );

    return( 1 );
}


/*
 * Parse the /HEAP option.
 */
static int parse_heap( OPT_STRING **p )
/*************************************/
{
    return( do_string_parse( p, "HEAP", 1, 0 ) );
}


/*
 * Parse the /IMPLIB option.
 */
static int parse_implib( OPT_STRING **p )
/***************************************/
{
    return( do_string_parse( p, "IMPLIB", 1, 0 ) );
}


/*
 * Parse the /INCLUDE option.
 */
static int parse_include( OPT_STRING **p )
/****************************************/
{
    return( do_string_parse( p, "INCLUDE", 0, '\'' ) );
}


/*
 * Parse the /INCREMENTAL option.
 */
static int parse_incremental( OPT_STRING **p )
/********************************************/
{
    char *              str;

    if( !CmdScanRecogChar( ':' ) ) {
        FatalError( "/INCREMENTAL requires an argument" );
        return( 0 );
    }
    str = CmdScanString();
    if( str == NULL ) {
        FatalError( "/INCREMENTAL requires an argument" );
        return( 0 );
    }
    if( !stricmp( str, "yes" )  ||  !stricmp( str, "no" ) ) {
        add_string( p, str, 0 );
        return( 1 );
    } else {
        FatalError( "Invalid argument '%s' to /INCREMENTAL", str );
        return( 0 );
    }
}


/*
 * Parse the undocumented /INTERNALDLLNAME_ option.
 */
static int parse_internaldllname_( OPT_STRING **p )
/*************************************************/
{
    return( do_string_parse( p, "INTERNALDLLNAME_", 1, 0 ) );
}


/*
 * Parse the /MACHINE option.
 */
static int parse_machine( OPT_STRING **p )
/****************************************/
{
    return( do_string_parse( p, "MACHINE", 0, 0 ) );
}


/*
 * Parse the /MAP option.
 */
static int parse_map( OPT_STRING **p )
/************************************/
{
    char *              str;

    if( !CmdScanRecogChar( ':' ) )  return( 1 );
    str = CmdScanString();
    if( str != NULL ) {
        add_string( p, str, 0 );
    }
    return( 1 );
}


/*
 * Parse the /ORDER option.
 */
static int parse_order( OPT_STRING **p )
/**************************************/
{
    return( do_string_parse( p, "ORDER", 0, 0 ) );
}


/*
 * Parse the /OUT option.
 */
static int parse_out( OPT_STRING **p )
/************************************/
{
    return( do_string_parse( p, "OUT", 1, 0 ) );
}


/*
 * Parse the /passwopts option.
 */
static int parse_passwopts( OPT_STRING **p )
{
    char *str;
    char *src;
    char *dst;

    if (!CmdScanRecogChar(':'))
    {
        FatalError("/passwopts:{argument} requires an argument");
        return 0;
    }

    str = CmdScanString();
    if (str == NULL)
    {
        FatalError("/passwopts requires an argument");
        return 0;
    }

    /*
     * If quoted, stip out the quote characters.
     */
    if (*str == '\"')
    {
        for (dst = str, src = str + 1; *src && (*src != '\"'); )
        {
            *dst++ = *src++;
        }

        if (*src != '\"')
        {
            FatalError("/passwopts argument is missing closing quote");
            return 0;
        }

        *dst = 0x00;
    }

    add_string(p, str, 0);
    return 1;
} /* parse_passwopts() */


/*
 * Parse the /PDB option.
 */
static int parse_pdb( OPT_STRING **p )
/************************************/
{
    return( do_string_parse( p, "PDB", 0, 0 ) );
}


/*
 * Parse the /SECTION option.
 */
static int parse_section( OPT_STRING **p )
/****************************************/
{
    return( do_string_parse( p, "SECTION", 1, 0 ) );
}


/*
 * Parse the /STACK option.
 */
static int parse_stack( OPT_STRING **p )
/**************************************/
{
    return( do_string_parse( p, "STACK", 1, 0 ) );
}


/*
 * Parse the /STUB option.
 */
static int parse_stub( OPT_STRING **p )
/*************************************/
{
    return( do_string_parse( p, "STUB", 1, 0 ) );
}


/*
 * Parse the /SUBSYSTEM option.
 */
static int parse_subsystem( OPT_STRING **p )
/******************************************/
{
    return( do_string_parse( p, "SUBSYSTEM", 1, 0 ) );
}


/*
 * Parse the /VERSION option.
 */
static int parse_version( OPT_STRING **p )
/****************************************/
{
    return( do_string_parse( p, "VERSION", 1, 0 ) );
}


/*
 * Set /OPT:NOREF when /DEBUG is used.
 */
static void handle_debug( OPT_STORAGE *cmdOpts, int x )
/*****************************************************/
{
    x = x;
    cmdOpts->opt_level = OPT_opt_level_optnoref;

    if( cmdOpts->debug_value != NULL ) {
        // suppress this diagnostic,
        // it appears that MS ignores this option also.
        //Warning( "Ignoring unsupported argument '%s' to /DEBUG", cmdOpts->debug_value->data );
        OPT_CLEAN_STRING( &cmdOpts->debug_value );
    }
}


/*
 * Suppress warning messages.
 */
static void handle_nowwarn( OPT_STORAGE *cmdOpts, int x )
/*******************************************************/
{
    x = x;
    cmdOpts = cmdOpts;
    DisableWarnings( 1 );
}


/*
 * Return the next character (forced to lowercase since LINK's options are
 * not case-sensitive) and advance to the next one.
 */
static int OPT_GET_LOWER( void )
/******************************/
{
    return( tolower( GetCharContext() ) );
}


/*
 * If the next character is ch (in either uppercase or lowercase form), it
 * is consumed and a non-zero value is returned; otherwise, it is not
 * consumed and zero is returned.
 */
static int OPT_RECOG_LOWER( int ch )
/**********************************/
{
    return( CmdScanRecogChar( ch ) );
}


/*
 * Back up one character.
 */
static void OPT_UNGET( void )
/***************************/
{
    UngetCharContext();
}


/*
 * Scan a number.  No leading whitespace is permitted.
 */
static int OPT_GET_NUMBER( unsigned *p )
/**************************************/
{
    unsigned            value;

    if( !CmdScanRecogChar( ':' ) )  return( 0 );
    if( CmdScanNumber( &value ) ) {
        *p = value;
        return( 1 );
    } else {
        return( 0 );
    }
}


/* Include after all static functions were declared */
#include "optparsc.gh"

⌨️ 快捷键说明

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