parsems.c

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

C
604
字号
/****************************************************************************
*
*                            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:  PARSEMS : Routines for parsing Microsoft command files.
*
****************************************************************************/

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

cmdfilelist *    CmdFile;

static int              OverlayLevel = 0;

extern cmdentry *   Commands[];
extern char *       PromptText[];
extern bool         HaveDefFile;

extern void         Error( char * );
extern void         OutPutPrompt( int );
extern f_handle     QOpenR( char * );
extern unsigned     QRead( f_handle, void *, unsigned, char * );
extern void         QClose( f_handle, char * );
extern unsigned long QFileSize( f_handle );
extern bool         QReadStr( f_handle, char *, unsigned, char * );
extern void         AddCommand( char *, int, bool );
extern void         Warning( char *, int );
extern char *       FileName( char *, int, char, bool );
extern char *       Msg3Splice( char *, char *, char * );
extern void *       MemAlloc( unsigned );
extern void *       TryAlloc( unsigned );
extern void         MemFree( void * );
extern bool         ProcessOptions( void );
extern void         ProcessDefCommand( void );
extern void *       FindNotAsIs( int );

extern bool         MakeToken( sep_type, bool );
extern bool         GetNumber( unsigned long * );
extern char *       ToString( void );

extern void EatWhite( void )
/**************************/
{
    while(*CmdFile->current == ' ' || *CmdFile->current == '\t'
                                          || *CmdFile->current == '\r') {
        CmdFile->current++;
    }
}

extern bool InitParsing( void )
/*****************************/
// initialize the parsing stuff, and see if there is anything on the command
// line.
{
    CmdFile = MemAlloc( sizeof( cmdfilelist ) );
    CmdFile->next = NULL;
    CmdFile->buffer = MemAlloc( MAX_LINE );   // maximum size of a command line.
    CmdFile->how = COMMANDLINE;
    CmdFile->oldhow = COMMANDLINE;
    CmdFile->where = MIDST;
    CmdFile->name = NULL;
    CmdFile->file = NIL_HANDLE;
    getcmd( CmdFile->buffer );
    CmdFile->current = CmdFile->buffer;
    EatWhite();
    if( *CmdFile->current == '?' ) {
        return( FALSE );
    }
    return( TRUE );
}

extern void FreeParserMem( void )
/*******************************/
{
    cmdfilelist *   nextone;


    while( CmdFile != NULL ) {
        if( CmdFile->file != NIL_HANDLE ) {
            QClose( CmdFile->file, CmdFile->name );
        }
        MemFree( CmdFile->buffer );
        MemFree( CmdFile->name );
        nextone = CmdFile->next;
        MemFree( CmdFile );
        CmdFile = nextone;
    }
}

static void NextPrompt( int *prompt )
/***********************************/
{
    (*prompt)++;
    if( *prompt >= 5 ) {
        CmdFile->where = ENDOFCMD;
    } else if( OverlayLevel > 0 ) {
        Warning( "ending overlay parenthesis not found", OVERLAY_SLOT );
        OverlayLevel = 0;
    }
}

static void GetNewLine( prompt )
/******************************/
{
    if( CmdFile->how == NONBUFFERED ) {
        if( QReadStr( CmdFile->file, CmdFile->buffer, MAX_LINE,CmdFile->name )){
            CmdFile->where = ENDOFFILE;
        } else {
            CmdFile->where = MIDST;
        }
        CmdFile->current = CmdFile->buffer;
    } else if( CmdFile->how == BUFFERED ) {               // interactive.
        CmdFile->where = MIDST;
        while( *CmdFile->current != '\n' ) {       //go until next line found;
            if( *CmdFile->current == '\0' ) {
                CmdFile->where = ENDOFFILE;
                break;
            }
            CmdFile->current++;
        }
    } else {
        CmdFile->how = INTERACTIVE;
        CmdFile->oldhow = INTERACTIVE;
        OutPutPrompt( prompt );
        if( QReadStr( STDIN_HANDLE, CmdFile->buffer, MAX_LINE, "console" ) ) {
            CmdFile->where = ENDOFCMD;
        } else {
            CmdFile->where = MIDST;
        }
        CmdFile->current = CmdFile->buffer;
    }
}

static void RestoreCmdLine( void )
/********************************/
// Restore a saved command line.
{
    void *  temp;

    QClose( CmdFile->file, CmdFile->name );
    MemFree( CmdFile->name );
    MemFree( CmdFile->buffer );
    temp = CmdFile->next;
    MemFree( CmdFile );
    CmdFile = temp;
}

extern void ParseDefFile( void )
/******************************/
// parse a .def file
{
    char        hmm;

    while( CmdFile->where != ENDOFFILE ) {
        switch( CmdFile->where ) {
        case MIDST:
            EatWhite();
            hmm = *CmdFile->current;
            switch( hmm ) {
            case '\0':
                if( CmdFile->how == BUFFERED ) {
                    CmdFile->where = ENDOFFILE;
                    break;
                }                // NOTE the fall through.
            case '\n':
                if( CmdFile->how == BUFFERED ) {
                    CmdFile->current++;
                } else {
                    CmdFile->where = ENDOFLINE;
                }
                break;
            case ';':
                CmdFile->where = ENDOFLINE;    // a comment.
                break;
            default:          // must be a command
                ProcessDefCommand();
                break;
            }
            break;
        case ENDOFLINE:
            GetNewLine( DEF_SLOT );
            break;
        }
    }
    RestoreCmdLine();
}

extern void StartNewFile( char *fname )
/*************************************/
{
    cmdfilelist *   newfile;
    unsigned long   size;

    newfile = MemAlloc( sizeof( cmdfilelist ) );
    newfile->name = fname;
    newfile->file = NIL_HANDLE;
    newfile->next = CmdFile;
    CmdFile = newfile;
    CmdFile->buffer = NULL;
    newfile->file = QOpenR( newfile->name );
    size = QFileSize( newfile->file );
    if( size < 65510 ) {       // if can alloc a chunk big enough
        CmdFile->buffer = TryAlloc( size + 1 );
        if( CmdFile->buffer != NULL ) {
            size = QRead( newfile->file, CmdFile->buffer, size, newfile->name );
            *(CmdFile->buffer + size) = '\0';
            CmdFile->where = MIDST;
            CmdFile->how = BUFFERED;
            CmdFile->current = CmdFile->buffer;
        }
    }
    if( CmdFile->buffer == NULL ) {  // if couldn't buffer for some reason.
        CmdFile->where = ENDOFLINE;
        CmdFile->how = NONBUFFERED;
        CmdFile->buffer = MemAlloc( MAX_LINE + 1 );// have to have at least this
        CmdFile->current = CmdFile->buffer;        // much RAM or death ensues.
    }
}

static void ProcessDefFile( void )
/********************************/
{
    cmdentry *  cmd;

    if( Commands[ DEF_SLOT ] == NULL ) {
        return;
    }
    HaveDefFile = 1;
    cmd = Commands[ DEF_SLOT ];
    StartNewFile( FileName( cmd->command, strlen( cmd->command ), E_DEF,FALSE));
    ParseDefFile();
}

static void ProcessFileName( int prompt )
/***************************************/
// process a file name and put it into the proper slot.
{
    char *  name;
    char *  msg;

    if( OverlayLevel > 0 ) {
        prompt = OVERLAY_SLOT;
    }
    if( !MakeToken( SEP_NO, TRUE ) ) {
        Error( "file name not recognized" );
    } else {
        if( (prompt == MAP_SLOT || prompt == RUN_SLOT || prompt == DEF_SLOT)
                                          && FindNotAsIs( prompt ) != NULL ) {
            msg = Msg3Splice( "only one ",PromptText[ prompt ], "allowed" );
            Warning( msg, prompt );
            MemFree( msg );
        } else {
            name = FileName( CmdFile->token, CmdFile->len, prompt, FALSE );
            AddCommand( name, prompt, FALSE );
        }
    }
}

extern void DirectiveError( void )
/********************************/
{
    char *  msg;
    int     offset;

    offset = 22 + CmdFile->len;
    msg = alloca( offset + 2 );
    memcpy( msg, "directive error near '", 22 );
    memcpy( msg+22, CmdFile->token, CmdFile->len );
    *( msg + offset) = '\'';
    *( msg + offset + 1) = '\0';
    Error( msg );
}

extern void ParseMicrosoft( void )
/********************************/

⌨️ 快捷键说明

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