cmdnov.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:  Command line parsing for Novell Netware file formats.
*
****************************************************************************/


#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include "linkstd.h"
#include "alloc.h"
#include "command.h"
#include "msg.h"
#include "exenov.h"
#include "loadnov.h"
#include "wlnkmsg.h"
#include "cmdnov.h"
#include "nwpfx.h"

static bool             GetNovImport( void );
static bool             GetNovExport( void );
extern bool             ProcNLM( void );

static bool             ProcModuleTypeN( int n );

static bool IsNetWarePrefix( const char * pToken, int nLen )
{
    if( NULL == pToken )
        return( FALSE );
    if( (pToken[0] == '(') && (pToken[nLen-1] == ')') )
        return( TRUE );
    return( FALSE );
}

/*
//  should move these somewhere more suitable
*/
#define IS_NUMBER(ptr)     ((*ptr >= '0') && (*ptr <= '9'))
#define IS_WHITESPACE(ptr) (*(ptr) == ' ' || *(ptr) =='\t' || *(ptr) == '\r')

static bool NetWareSplitSymbol( char * tokenThis, int tokenLen, char ** name, int *namelen, char **prefix, int *prefixlen )
{
    char    *findAt = tokenThis;
    int     nLen = tokenLen;

    if( (NULL == tokenThis) || (0 == tokenLen) || (NULL == name) || (NULL == namelen) || (NULL == prefix) || (NULL == prefixlen) )
        return( FALSE );

    *name = *prefix = NULL;
    *namelen = *prefixlen = 0;

    while( nLen ) {
        if( '@' == *findAt )
            break;
        if( '\0' == *findAt ) {
            nLen = 0;   /* force zero */
            break;
        }
        findAt++;
        nLen--;
    }

    if( 0 == nLen ) {
        *name = tokenThis;
        *namelen = tokenLen;
        return( TRUE );
    }

    /*
    //  findAt now points at an @ symbol. this maybe a stdcall designator or a prefixed symbol.
    //  if the following character is a number then it must be stdcall as it is illegal to start
    //  a function name with a numeric character (I believe)
    */

    if( IS_NUMBER(&findAt[1]) ) {
        *name = tokenThis;
        *namelen = tokenLen;
        return( TRUE );
    }

    *prefix = tokenThis;
    *prefixlen = (int)(findAt - tokenThis);

    *name = &findAt[1];
    *namelen = nLen-1;

    return( TRUE );
}

/*
//  Trouble! In files, import and export specifiers may or may not have a trailing comma
//  so we look ahead to Token.next and see if there is a comma next (after whitespace)
//  and if there is then we don't set this flag else we do
//  this also affects us using
//      IMPORT x, (PREFIX), y, (PREFIX), x
*/
static unsigned int DoWeNeedToSkipASeparator( bool CheckDirectives )
{
    char *parse;

    if( (NULL == (parse = Token.next)) || ('\0' == *parse) )
        return( 0 );

    while( ('\0' != *parse) && (IS_WHITESPACE(parse)) )
        parse++;

    if( '\0' == *parse )
        return( 0 );

    if( ',' == *parse )
        return( 0 );

    /*
    //  skip cr-lf
    */
    if( ('\n' == *parse) || ('\r' == *parse) )
        parse++;
    if( ('\n' == *parse) || ('\r' == *parse) )
        parse++;

    /*
    //  always skip to the next token if the next available token is not a comma
    //  this will allow individual tokens without commas which isn't a big deal
    */
    if( ('\0' != *parse) && (',' != *parse) ) {
        /*
        //  If the next token is __not__ a comma then we need to check that it is not a directive
        //  before allowing the skip!
        */
        if( CheckDirectives ) {
            int     len = 0;
            char    *t = parse;

            while( !IS_WHITESPACE(t) ) {
                t++;
                len++;
            }

            if( MatchOne( Directives, SEP_NO, parse, len ) ) {
                return( 0 );
            }
        }
        return( 1 );
    }

    return( 0 );
}

extern bool ProcNovImport( void )
/*******************************/
{
    SetCurrentPrefix( NULL, 0 );
    return( ProcArgListEx( GetNovImport, TOK_INCLUDE_DOT, CmdFile ) );
}

extern bool ProcNovExport( void )
/*******************************/
{
    SetCurrentPrefix( NULL, 0 );
    return( ProcArgListEx( GetNovExport, TOK_INCLUDE_DOT, CmdFile ) );
}

#ifndef NDEBUG
extern int printf( const char *fmt, ... );
#endif

static bool GetNovImport( void )
/******************************/
{
    symbol  *sym;
    char    *name = NULL;
    char    *prefix = NULL;
    int     namelen = 0;
    int     prefixlen = 0;

    /*
    //  we need to trap import/export prefixes here. Unfortunately the prefix context
    //  is not followed by a valid seperator so the GetToken() call in ProcArgList
    //  at the end of the do...while loop terminates the loop after we return from
    //  this call (and WildCard from where we were called of course
    */
    if( IsNetWarePrefix( Token.this, Token.len ) ) {
        bool result;
        if( FALSE == (result = SetCurrentPrefix( Token.this, Token.len )) )
            return( FALSE );

        Token.skipToNext = DoWeNeedToSkipASeparator( FALSE );

#ifndef NDEBUG
        printf( "Set new prefix. Skip = %d\n", Token.skipToNext );
#endif

        return( result );
    }

    if( !NetWareSplitSymbol( Token.this, Token.len, &name, &namelen, &prefix, &prefixlen ) ) {
        return( FALSE );
    }

    sym = SymXOpNWPfx( ST_DEFINE_SYM, name, namelen, prefix, prefixlen );
    if( sym == NULL || sym->p.import != NULL ) {
        return( TRUE );
    }

#ifndef NDEBUG
    printf( "imported %s from %s\n", sym->name, sym->prefix ? sym->prefix : "(NONE)" );
#endif

    SET_SYM_TYPE( sym, SYM_IMPORTED );
    sym->info |= SYM_DCE_REF;   // make sure we don't try to get rid of these.
    SetNovImportSymbol( sym );

    Token.skipToNext = DoWeNeedToSkipASeparator( TRUE );

    return( TRUE );
}

extern void SetNovImportSymbol( symbol * sym )
/********************************************/
{
    sym->p.import = DUMMY_IMPORT_PTR;
}

static bool GetNovExport( void )
/******************************/
{
    symbol  *sym;
    char    *name = NULL;
    char    *prefix = NULL;
    int     namelen = 0;
    int     prefixlen = 0;

    /*
    //  we need to trap import/export prefixes here. Unfortunately the prefix context
    //  is not followed by a valid seperator so the GetToken() call in ProcArgList
    //  at the end of the do...while loop terminates the loop after we return from
    //  this call (and WildCard from where we were called of course
    */
    if( IsNetWarePrefix( Token.this, Token.len ) ) {
        bool result;

        if( FALSE == (result = SetCurrentPrefix( Token.this, Token.len )) )
            return( FALSE );

        Token.skipToNext = DoWeNeedToSkipASeparator( FALSE );
        return( result );
    }

    if( !NetWareSplitSymbol( Token.this, Token.len, &name, &namelen, &prefix, &prefixlen ) ) {
        return( FALSE );
    }

    sym = SymXOpNWPfx( ST_CREATE | ST_REFERENCE, name, namelen, prefix, prefixlen );

    sym->info |= SYM_DCE_REF | SYM_EXPORTED;
/*    AddNameTable( Token.this, Token.len, TRUE, &FmtData.u.nov.exp.export ); */
    AddNameTable( name, namelen, TRUE, &FmtData.u.nov.exp.export );

    Token.skipToNext = DoWeNeedToSkipASeparator( TRUE );

    return( TRUE );
}

extern bool ProcScreenName( void )
/********************************/
{
    if( !GetToken( SEP_NO, TOK_INCLUDE_DOT ) ) {
        return( FALSE );
    }
    if( Token.len > MAX_SCREEN_NAME_LENGTH ) {
        LnkMsg( LOC+LINE+WRN+MSG_VALUE_TOO_LARGE, "s", "screenname" );
    } else {
        if( FmtData.u.nov.screenname != NULL ) {
            _LnkFree( FmtData.u.nov.screenname );  // assume second is correct.
        }
        FmtData.u.nov.screenname = tostring();
    }
    return( TRUE );
}

extern bool ProcCheck( void )
/***************************/
{
    if( !GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
        return( FALSE );
    }
    FmtData.u.nov.checkfn = tostring();
    return( TRUE );
}

extern bool ProcMultiLoad( void )
/*******************************/
{
    FmtData.u.nov.exeflags |= NOV_MULTIPLE;
    return( TRUE );
}

extern bool ProcAutoUnload( void )
/*******************************/
{
    FmtData.u.nov.exeflags |= NOV_AUTOUNLOAD;
    return( TRUE );
}


extern bool ProcReentrant( void )
/*******************************/
{
    FmtData.u.nov.exeflags |= NOV_REENTRANT;
    return( TRUE );
}

extern bool ProcSynch( void )
/***************************/
{
    FmtData.u.nov.exeflags |= NOV_SYNCHRONIZE;
    return( TRUE );
}

extern bool ProcPseudoPreemption( void )
/**************************************/
{
    FmtData.u.nov.exeflags |= NOV_PSEUDOPREEMPTION;
    return( TRUE );
}

extern bool ProcNLMFlags( void )
/******************************/
{

⌨️ 快捷键说明

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