optencod.c

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

C
1,981
字号
        if( p[len-1] == '\n' ) {
            p[len-1] = '\0';
        }
    }
    return( strdup( p ) );
}

// :argequal. <char>
static void doARGEQUAL( char *p )
{
    p = skipSpace( p );
    if( *p == '\0' ) {
        fail( ":argequal. must have <char> specified\n" );
    } else {
        alternateEqual = *p;
        optFlag.alternate_equal = 1;
    }
}

// :cmt comment text
static void doCMT( char *p )
{
    p = p;
}

// :internal.
static void doINTERNAL( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_internal = 1;
    }
}

// :option. <option> <synonym> ...
static void doOPTION( char *p )
{
    OPTION *synonym;

    targetTitle = NULL;
    synonym = NULL;
    while( *p ) {
        p = skipSpace( p );
        if( *p == '\0' ) break;
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        synonym = pushNewOption( tokbuff, synonym );
    }
    getsUsage = TAG_OPTION;
}

// :target. <targ> <targ> ...
static void doTARGET( char *p )
{
    unsigned mask;
    OPTION *o;

    while( *p ) {
        p = skipSpace( p );
        if( *p == '\0' ) break;
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        mask = findTarget( tokbuff );
        if( targetTitle != NULL ) {
            targetTitle->target |= mask;
        } else {
            for( o = optionList; o != NULL; o = o->synonym ) {
                o->target |= mask;
            }
        }
    }
}

// :ntarget. <targ> <targ> ...
static void doNTARGET( char *p )
{
    unsigned mask;
    OPTION *o;

    while( *p ) {
        p = skipSpace( p );
        if( *p == '\0' ) break;
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        mask = findTarget( tokbuff );
        if( targetTitle != NULL ) {
            targetTitle->ntarget |= mask;
        } else {
            for( o = optionList; o != NULL; o = o->synonym ) {
                o->ntarget |= mask;
            }
        }
    }
}

// :number. [<fn>] [<default>]
static void doNUMBER( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_number = 1;
        o->is_simple = 0;
    }
    p = skipSpace( p );
    if( *p != '\0' ) {
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        for( o = optionList; o != NULL; o = o->synonym ) {
            o->check = strdup( tokbuff );
        }
        p = skipSpace( p );
        if( *p != '\0' ) {
            p = copyNonSpaceUntil( p, tokbuff, '\0' );
            for( o = optionList; o != NULL; o = o->synonym ) {
                o->number_default = atoi( tokbuff );
                o->default_specified = 1;
            }
        }
    }
}

// :multiple.
static void doMULTIPLE( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_multiple = 1;
    }
}

// :nochain.
static void doNOCHAIN( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->nochain = 1;
    }
}

// :id. [<fn>]
static void doID( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_id = 1;
        o->is_simple = 0;
    }
    p = skipSpace( p );
    if( *p != '\0' ) {
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        for( o = optionList; o != NULL; o = o->synonym ) {
            o->check = strdup( tokbuff );
        }
    }
}

// :char. [<fn>]
static void doCHAR( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_char = 1;
        o->is_simple = 0;
    }
    p = skipSpace( p );
    if( *p != '\0' ) {
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        for( o = optionList; o != NULL; o = o->synonym ) {
            o->check = strdup( tokbuff );
        }
    }
}

// :immediate. <fn>
static void doIMMEDIATE( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_immediate = 1;
        o->is_simple = 0;
    }
    p = skipSpace( p );
    if( *p != '\0' ) {
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        for( o = optionList; o != NULL; o = o->synonym ) {
            o->immediate = strdup( tokbuff );
        }
    } else {
        fail( ":immediate. must have <fn> specified\n" );
    }
}

// :code. <source-code>
static void doCODE( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_code = 1;
        o->is_simple = 0;
    }
    p = skipSpace( p );
    if( *p != '\0' ) {
        for( o = optionList; o != NULL; o = o->synonym ) {
            o->code = strdup( p );
        }
    } else {
        fail( ":immediate. must have <fn> specified\n" );
    }
}

// :file.
static void doFILE( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_file = 1;
        o->is_simple = 0;
    }
}

// :dir.
static void doDIR( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_dir = 1;
        o->is_simple = 0;
    }
}

// :optional.
static void doOPTIONAL( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_optional = 1;
    }
}
// :negate.
static void doNEGATE( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_negate = 1;
        if( o->enumerate ){
            fail( "must be non-enumeration switch for negate tag\n" );
        }
    }
}


// :noequal.
static void doNOEQUAL( char *p )
{
    p = p;
    optFlag.no_equal = 1;
}

// :page. <text>
static void doPAGE( char *p )
{
    pageUsage[LANG_English] = pickUpRest( p );
    getsUsage = TAG_PAGE;
}

// :path.
static void doPATH( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_path = 1;
        o->is_simple = 0;
    }
}

// :chain. <char> <usage>
//
// mark options that start with <char> as chainable
// i.e., -oa -ox == -oax
static void doCHAIN( char *p )
{
    char c;

    p = skipSpace( p );
    if( *p == '\0' ) {
        fail( "missing <char> in :chain. tag\n" );
    }
    c = *p;
    chainOption[ c ] |= CHAIN_YES;
    ++p;
    p = skipSpace( p );
    chainUsage[ c ][ LANG_English ] = pickUpRest( p );
    lastChain = c;
    getsUsage = TAG_CHAIN;
}

// :enumerate. <name>
static void doENUMERATE( char *p )
{
    NAME *n;
    OPTION *o;

    p = skipSpace( p );
    if( *p == '\0' ) {
        fail( "missing <name> in :enumerate. tag\n" );
    }
    p = copyNonSpaceUntil( p, tokbuff, '\0' );
    n = findName( &enumList, tokbuff );
    if( n == NULL ) {
        n = addName( &enumList, tokbuff );
    }
    addEnumerator( tokbuff, "default" );
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->enumerate = n;
        if( o->is_timestamp ) {
            o->enumerate->is_timestamp = 1;
        }
    }
}

// :special. <fn>
static void doSPECIAL( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_special = 1;
        o->is_simple = 0;
    }
    p = skipSpace( p );
    if( *p == '\0' ) {
        fail( "missing <fn> in :special. tag\n" );
    }
    p = copyNonSpaceUntil( p, tokbuff, '\0' );
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->special = strdup( tokbuff );
    }
    p = skipSpace( p );
    if( *p != '\0' ) {
        p = copyNonSpaceUntil( p, tokbuff, '\0' );
        for( o = optionList; o != NULL; o = o->synonym ) {
            o->special_arg_usage = strdup( tokbuff );
        }
    }
}

// :prefix.
static void doPREFIX( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_prefix = 1;
        o->is_simple = 0;
    }
}

// :usage. <usage-text>
static void doUSAGE( char *p )
{
    OPTION *o;

    for( o = optionList; o != NULL; o = o->synonym ) {
        o->lang_usage[ LANG_English ] = pickUpRest( p );
    }
}

// :jusage. <kanji-usage-text>
static void doJUSAGE( char *p )
{
    char *usage;
    OPTION *o;

    switch( getsUsage ) {
    case TAG_PAGE:
        pageUsage[LANG_Japanese] = pickUpRest( p );
        break;
    case TAG_CHAIN:
        chainUsage[lastChain][LANG_Japanese] = pickUpRest( p );
        break;
    case TAG_OPTION:
        for( o = optionList; o != NULL; o = o->synonym ) {
            usage = pickUpRest( p );
            if( *usage == '\0' ) {
                usage = strdup( o->lang_usage[LANG_English] );
            }
            o->lang_usage[LANG_Japanese] = usage;
        }
        break;
    default:
        fail( ":jusage. must follow :chain., :option., or :page.\n" );
    }
}

// :title. <text>
static void doTITLE( char *p )
{
    TITLE **i;
    TITLE *t;

    i = &titleList;
    for( t = *i; t != NULL; t = *i ) {
        i = &(t->next);
    }
    t = calloc( sizeof( *t ), 1 );
    t->next = *i;
    *i = t;
    t->target = 0;
    t->ntarget = 0;
    t->lang_title[ LANG_English ] = strdup( p );
    targetTitle = t;
}

// :jtitle. <text>
static void doJTITLE( char *p )
{
    TITLE *t;

    t = targetTitle;
    if( t == NULL ) {
        fail( ":jtitle. must follow a :title.\n" );
    }
    t->lang_title[ LANG_Japanese ] = strdup( p );
}

// :timestamp.
static void doTIMESTAMP( char *p )
{
    OPTION *o;

    p = p;
    for( o = optionList; o != NULL; o = o->synonym ) {
        o->is_timestamp = 1;
        o->is_simple = 0;
        if( o->enumerate != NULL ) {
            o->enumerate->is_timestamp = 1;
        }
    }
}

static void checkForGMLEscape( char *p )
{
    int is_escape;
    char c1, c2;

    c1 = *p++;
    if( c1 == '\0' || ! isalpha( c1 ) ) {
        return;
    }
    c2 = *p++;
    if( c2 == '\0' || ! isalpha( c2 ) ) {
        return;
    }
    is_escape = 0;
    if( *p == '\0' || ! isalpha( *p ) ) {
        is_escape = 1;
    }
    if( is_escape ) {
        fail( "possible GML escape sequence: &%c%c\n", c1, c2 );
    }
}

static void checkForGMLEscapeSequences( void )
{
    char c;
    char *p;

    p = ibuff;
    for(;;) {
        c = *p++;
        if( c == '\0' ) break;
        if( c == '&' ) {
            checkForGMLEscape( p );
        }
    }
}

static void readInputFile( void )

⌨️ 快捷键说明

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