keyword.c

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

C
1,426
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


/*
 *  KEYWORD : Routines for parsing Microsoft keywords.
 *
*/

#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include "ms2wlink.h"
#include "command.h"

extern void         AddCommand( char *, int, bool );
extern void         NotNecessary( char * );
extern void         NotSupported( char * );
extern void         AddNumOption( char *, unsigned );
extern void         AddStringOption( char *, char *, int );
extern void         Warning( char *, int );
extern void         AddOption( char * );
extern void         Suicide( void );
extern void *       MemAlloc( unsigned );
extern void         EatWhite( void );
extern bool         MakeToken( sep_type, bool );
extern void         DirectiveError( void );
extern bool         GetNumber( unsigned long * );
extern void         WriteHelp( void );
extern void         ImplyFormat( format_type );
extern void         StartNewFile( char * );
extern void         ParseDefFile( void );
extern char *       ToString( void );

extern bool         MapOption;
extern format_type  FmtType;
extern extra_type   FmtInfo;
extern bool         DebugInfo;

extern cmdfilelist *CmdFile;

static void             (*MultiLine)() = NULL;
static char *           OptionBuffer;
static int              BufferLeft;
static bool             SegWarning = FALSE;
static bool             GotModName = FALSE;
static bool             GotOvl;

typedef struct parse_entry {
    char                *keyword;
    void                (*rtn)(void);
    char                minlen;
} parse_entry;

static void ProcAlignment( void );
static void ProcBatch( void );
static void ProcCodeview( void );
static void ProcCParMaxAlloc( void );
static void ProcDosseg( void );
static void ProcDSAllocate( void );
static void ProcDynamic( void );
static void ProcExePack( void );
static void ProcFarCallTranslation( void );
static void ProcHelp( void );
static void ProcHigh( void );
static void ProcIncremental( void );
static void ProcInformation( void );
static void ProcLineNumbers( void );
static void ProcMap( void );
static void ProcNoDefaultLibrarySearch( void );
static void ProcNoExtendedDictSearch( void );
static void ProcNoFarCallTranslation( void );
static void ProcNoGroupAssociation( void );
static void ProcNoIgnoreCase( void );
static void ProcNoLogo( void );
static void ProcNoNullsDosseg( void );
static void ProcNoPackCode( void );
static void ProcNoPackFunctions( void );
static void ProcOldOverlay( void );
static void ProcOnError( void );
static void ProcOverlayInterrupt( void );
static void ProcPackCode( void );
static void ProcPackData( void );
static void ProcPackFunctions( void );
static void ProcPadCode( void );
static void ProcPadData( void );
static void ProcPause( void );
static void ProcPMType( void );
static void ProcQuickLibrary( void );
static void ProcR( void );
static void ProcSegments( void );
static void ProcStack( void );
static void ProcTiny( void );
static void ProcWarnFixup( void );

static  parse_entry     OptionsTable[] = {
    "alignment",        ProcAlignment,      1,
    "batch",            ProcBatch,          1,
    "codeview",         ProcCodeview,       2,
    "cparmaxalloc",     ProcCParMaxAlloc,   2,
    "dynamic",          ProcDynamic,        2,
    "dosseg",           ProcDosseg,         2,
    "dsallocate",       ProcDSAllocate,     2,
    "exepack",          ProcExePack,        1,
    "farcalltranslation", ProcFarCallTranslation, 1,
    "help",             ProcHelp,           2,
    "high",             ProcHigh,           2,
    "incremental",      ProcIncremental,    3,
    "information",      ProcInformation,    1,
    "linenumbers",      ProcLineNumbers,    2,
    "map",              ProcMap,            1,
    "nodefaultlibrarysearch", ProcNoDefaultLibrarySearch, 3,
    "noextendeddictsearch", ProcNoExtendedDictSearch, 3,
    "nofarcalltranslation", ProcNoFarCallTranslation, 3,
    "nogroupassociation", ProcNoGroupAssociation, 3,
    "noignorecase",     ProcNoIgnoreCase,   3,
    "nologo",           ProcNoLogo,         3,
    "nonullsdosseg",    ProcNoNullsDosseg,  3,
    "nopackcode",       ProcNoPackCode,     7,
    "nopackfunctions",  ProcNoPackFunctions,7,
    "oldoverlay",       ProcOldOverlay,     4,
    "onerror",          ProcOnError,        3,
    "overlayinterrupt", ProcOverlayInterrupt,1,
    "packcode",         ProcPackCode,       5,
    "packdata",         ProcPackData,       5,
    "padcode",          ProcPadCode,        4,
    "paddata",          ProcPadData,        4,
    "pause",            ProcPause,          3,
    "pmtype",           ProcPMType,         2,
    "quicklibrary",     ProcQuickLibrary,   1,
    "r",                ProcR,              1,
    "segments",         ProcSegments,       2,
    "stack",            ProcStack,          2,
    "tiny",             ProcTiny,           1,
    "warnfixup",        ProcWarnFixup,      1,
    NULL
};

static void ProcAppLoader( void );
static void ProcCode( void );
static void ProcData( void );
static void ProcDescription( void );
static void ProcExeType( void );
static void ProcExports( void );
static void ProcFunctions( void );
static void ProcHeapsize( void );
static void ProcImports( void );
static void ProcInclude( void );
static void ProcLibrary( void );
static void ProcName( void );
static void ProcOld( void );
static void ProcProtMode( void );
static void ProcRealMode( void );
static void ProcDefSegments( void );
static void ProcStackSize( void );
static void ProcStub( void );
static void ProcVirtual( void );

static  parse_entry     DefStatements[] = {
    "apploader",        ProcAppLoader,      9,
    "code",             ProcCode,           4,
    "data",             ProcData,           4,
    "description",      ProcDescription,    11,
    "exetype",          ProcExeType,        7,
    "exports",          ProcExports,        7,
    "functions",        ProcFunctions,      9,
    "heapsize",         ProcHeapsize,       8,
    "imports",          ProcImports,        7,
    "include",          ProcInclude,        7,
    "library",          ProcLibrary,        7,
    "name",             ProcName,           4,
    "old",              ProcOld,            3,
    "protmode",         ProcProtMode,       8,
    "realmode",         ProcRealMode,       8,
    "segments",         ProcDefSegments,    8,
    "stacksize",        ProcStackSize,      9,
    "stub",             ProcStub,           4,
    "virtual",          ProcVirtual,        7,
    NULL
};

static void ProcPreload( void );
static void ProcLoadOnCall( void );
static void ProcExecuteOnly( void );
static void ProcExecuteRead( void );
static void ProcIopl( void );
static void ProcNoIopl( void );
static void ProcConforming( void );
static void ProcNonConforming( void );
static void ProcMoveable( void );
static void ProcFixed( void );
static void ProcDiscardable( void );
static void ProcNonDiscardable( void );

static  parse_entry     CodeAttributes[] = {
    "preload",          ProcPreload,        7,
    "loadoncall",       ProcLoadOnCall,     10,
    "executeonly",      ProcExecuteOnly,    11,
    "executeread",      ProcExecuteRead,    11,
    "iopl",             ProcIopl,           4,
    "noiopl",           ProcNoIopl,         6,
    "conforming",       ProcConforming,     10,
    "nonconforming",    ProcNonConforming,  13,
    "moveable",         ProcMoveable,       8,
    "movable",          ProcMoveable,       7,
    "fixed",            ProcFixed,          5,
    "discardable",      ProcDiscardable,    11,
    "nondiscardable",   ProcNonDiscardable, 14,
    NULL
};

static void ProcReadOnly( void );
static void ProcReadWrite( void );
static void ProcShared( void );
static void ProcNonShared( void );

static  parse_entry     SegAttributes[] = {
    "preload",          ProcPreload,        7,
    "loadoncall",       ProcLoadOnCall,     10,
    "executeonly",      ProcExecuteOnly,    11,
    "executeread",      ProcExecuteRead,    11,
    "iopl",             ProcIopl,           4,
    "noiopl",           ProcNoIopl,         6,
    "conforming",       ProcConforming,     10,
    "nonconforming",    ProcNonConforming,  13,
    "readonly",         ProcReadOnly,       8,
    "readwrite",        ProcReadWrite,      9,
    "shared",           ProcShared,         6,
    "nonshared",        ProcNonShared,      9,
    "moveable",         ProcMoveable,       7,
    "fixed",            ProcFixed,          5,
    "discardable",      ProcDiscardable,    11,
    "nondiscardable",   ProcNonDiscardable, 14,
    NULL
};

static void ProcNone( void );
static void ProcSingle( void );
static void ProcMultiple( void );

static  parse_entry     DataAttributes[] = {
    "none",             ProcNone,           4,
    "single",           ProcSingle,         6,
    "multiple",         ProcMultiple,       8,
    "shared",           ProcShared,         6,
    "nonshared",        ProcNonShared,      9,
    "readonly",         ProcReadOnly,       8,
    "readwrite",        ProcReadWrite,      9,
    "iopl",             ProcIopl,           4,
    "noiopl",           ProcNoIopl,         6,
    "preload",          ProcPreload,        7,
    "loadoncall",       ProcLoadOnCall,     10,
    "moveable",         ProcMoveable,       7,
    "fixed",            ProcFixed,          5,
    "discardable",      ProcDiscardable,    11,
    "nondiscardable",   ProcNonDiscardable, 14,
    NULL
};

static void ProcClass( void );
static void ProcOvl( void );

static  parse_entry     SegOptions[] = {
    "class",            ProcClass,      5,
    "ovl",              ProcOvl,        3,
    NULL
};
static void NullRoutine( void );
static void SetWindows( void );
static void SetWindowsVxD( void );
static void SetWindowsVxDDyn( void );
static void SetOS2( void );

static  parse_entry     ExeTypeKeywords[] = {
    "os2",              SetOS2,             3,
    "windows",          SetWindows,         7,
    "dos4",             NullRoutine,        4,
    "dev386",           SetWindowsVxD,      6,
    "dynamic",          SetWindowsVxDDyn,   7,
    "unknown",          NullRoutine,        7,
    NULL
};

static void ProcWindowApi( void );
static void ProcWindowCompat( void );
static void ProcNotWindowCompat( void );
static void ProcNewFiles( void );

static  parse_entry     ApplicationTypes[] = {
    "windowapi",        ProcWindowApi,      9,
    "windowcompat",     ProcWindowCompat,   12,
    "notwindowcompat",  ProcNotWindowCompat,15,
    "newfiles",         ProcNewFiles,       8,
    NULL
};

static void ProcNoVIO( void );

static  parse_entry     PMTypes[] = {
    "pm",               ProcWindowApi,      2,
    "vio",              ProcWindowCompat,   3,
    "novio",            ProcNoVIO,          5,
    NULL
};

static void ProcPrivateLib( void );

static  parse_entry     LibraryTypes[] = {
    "privatelib",       ProcPrivateLib,     10,
    NULL
};

static void ProcDevice( void );

static  parse_entry     DeviceKeyword[] = {
    "device",           ProcDevice,         6,
    NULL
};

static bool ProcessKeyList( parse_entry *entry )
/**********************************************/
{
    char                *key;
    char                *ptr;
    int                 len;
    int                 plen;

    while( entry->keyword != NULL ) {
        key = entry->keyword;
        ptr = CmdFile->token;
        len = 0;
        plen = CmdFile->len;
        for(;;) {
            if( plen == 0 && len >= entry->minlen ) {
                MultiLine = NULL;               // for processdefcommand.
                (*entry->rtn)();
                return( TRUE );
            }
            if( *key == '\0' || tolower( *ptr ) != *key ) break;
            ptr++;
            key++;
            len++;
            plen--;
        }
        /* here if this is no match */
        entry++;
    }
    /* here if no match in table */
    return( FALSE );
}

static bool ProcessKeyword( parse_entry *entry )
/**********************************************/
// returns TRUE if keyword found.
{
    bool    ret;

    if( !MakeToken( SEP_NO, FALSE ) ) {
        return( FALSE );
    }
    ret = ProcessKeyList( entry );
    if( !ret ) {
        CmdFile->current = CmdFile->token;     // reparse the token later.
    }
    return( ret );
}

// the microsoft definitions file.

extern void ProcessDefCommand( void )
/***********************************/
{
    if( !ProcessKeyword( DefStatements ) ) {
        if( MultiLine != NULL ) {
            (*MultiLine)();
        } else {
            DirectiveError();
        }
    }
}

static void SetWindows( void )
/****************************/
{
    unsigned long       bogus;

    FmtType = FMT_WINDOWS;
    if( !MakeToken( SEP_NO, FALSE ) ) return;
    if( !GetNumber( &bogus ) ) {
        CmdFile->current = CmdFile->token;      // reparse the token later
    }
}

static void SetWindowsVxD( void )
/****************************/
{
    FmtType = FMT_WINVXD;
    FmtInfo = NO_EXTRA;
}

static void SetWindowsVxDDyn( void )
/****************************/
{
    FmtType = FMT_WINVXDDYN;
    FmtInfo = NO_EXTRA;
}

static void SetOS2( void )
/************************/
{
    FmtType = FMT_OS2;
}

static void ProcAppLoader( void )
/*******************************/
{
    NotSupported( "apploader" );
    if( !MakeToken( SEP_QUOTE, TRUE ) ) {
        MakeToken( SEP_NO, TRUE );
    }
}

#define CODE_BUFFER_LEN 105

static void ProcCode( void )
/**************************/
{
    char    buffer[ CODE_BUFFER_LEN ];
    char *  result;
    int     len;

    memcpy( buffer, "segment type code", 17 );
    OptionBuffer = buffer + 17;
    BufferLeft = CODE_BUFFER_LEN - 18;
    if( !ProcessKeyword( CodeAttributes ) ) {
        Warning( "argument for code statement not valid", OPTION_SLOT );
    } else {    // get the rest of the attributes.
        while( ProcessKeyword( CodeAttributes ) ) {}     // NULL statement.
        if( BufferLeft != CODE_BUFFER_LEN - 18 ) {      // attribute spec'd.
            len = CODE_BUFFER_LEN - BufferLeft - 1;
            result = MemAlloc( CODE_BUFFER_LEN - BufferLeft + 1);
            memcpy( result, buffer, len );
            *(result + len) = '\0';
            AddCommand( result, OPTION_SLOT, FALSE );
        }
    }
}

⌨️ 快捷键说明

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