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 + -
显示快捷键?