deffile.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,067 行 · 第 1/3 页
C
1,067 行
/****************************************************************************
*
* 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!
*
****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "cmdscan.h"
#include "context.h"
#include "deffile.h"
#include "error.h"
#include "memory.h"
#include "message.h"
#define TRUE 1
#define FALSE 0
#define SET_ERROR error = TRUE
#define CLEAR_GOT_FLAGS exportsGotEntryName = FALSE; \
exportsGotInternalName = FALSE; \
exportsGotOrdinal = FALSE; \
exportsGotPrivate = FALSE; \
exportsGotResident = FALSE; \
heapGotReserve = FALSE; \
heapGotCommit = FALSE; \
stackGotReserve = FALSE; \
stackGotCommit = FALSE; \
stubGotFile = FALSE; \
versionGotMajor = FALSE; \
versionGotMinor = FALSE;
static int next_token( int state, int *newCmd, int *newLine, int fileCharsOk, int atCharsOk );
static char * get_word( void );
static void strip_quotes( char *str );
static int eat_comments( int *newLine );
static char * string_convert( const char *str );
enum {
STATE_CLEAR, /* general states */
STATE_EOF,
STATE_BASE, /* keyword states */
STATE_DESCRIPTION,
STATE_EXETYPE,
STATE_EXPORT,
STATE_EXPORTS,
STATE_HEAPSIZE,
STATE_LIBRARY,
STATE_NAME,
STATE_SECTIONS,
STATE_SEGMENTS,
STATE_STACKSIZE,
STATE_STUB,
STATE_VERSION,
STATE_PRIVATE,
STATE_PROTMODE, /* unsupported states */
STATE_CODE,
STATE_DATA,
STATE_NONAME,
STATE_RESIDENTNAME,
STATE_AT, /* separator states, they must be together !!! */
STATE_COMMA,
STATE_EQUAL,
STATE_PERIOD,
STATE_STRING /* option value states */
};
static int breakStates[] = { /* break a command on these */
STATE_CLEAR,
STATE_EOF,
STATE_DESCRIPTION,
STATE_EXETYPE,
STATE_EXPORT,
STATE_EXPORTS,
STATE_HEAPSIZE,
STATE_LIBRARY,
STATE_NAME,
STATE_SECTIONS,
STATE_SEGMENTS,
STATE_STACKSIZE,
STATE_STUB,
STATE_PROTMODE,
STATE_CODE,
STATE_DATA,
STATE_NONAME,
-1
};
static char * curToken = NULL;
#ifdef __TARGET_AXP__
/*
* Strip leading _ and @nn from stdcall names when alpha
*/
void FuzzyMassageAXPStdcall( char *name ) {
char *first;
char *last;
first = name;
last = name + strlen( name ) - 1;
if( *first == '\'' ) {
first++;
name++;
}
if( *last == '\'' ) last--;
if( *first == '_' && isdigit( *last ) ) {
first++;
last--;
while( isdigit( *last ) ) {
last--;
}
if( *last == '\@' ) {
*last++ = '\'';
*last = '\0';
while( *first ) {
*name++ = *first++;
}
*name = '\0';
}
}
}
#endif
/*
* Add another string to a StringList.
*/
static void add_string( StringList **p, char *str )
/*************************************************/
{
StringList * buf;
StringList * curElem;
/*** Make a new list item ***/
buf = AllocMem( sizeof(StringList) );
buf->str = DupStrMem( str );
buf->next = NULL;
/*** Put it at the end of the list ***/
if( *p == NULL ) {
*p = buf;
} else {
curElem = *p;
while( curElem->next != NULL ) curElem = curElem->next;
curElem->next = buf;
}
}
/*
* Parse a .def file. Returns NULL on error, or a DefInfo* on success.
*/
#ifdef __TARGET_AXP__
DefInfo *ParseDefFile( const char *filename, int dofuzzylink )
#else
DefInfo *ParseDefFile( const char *filename )
#endif
/****************************************************************/
{
char * newfilename = DupStrMem( filename );
DefInfo * info;
int alive = TRUE;
int error = FALSE;
int state = STATE_CLEAR;
int mergeNow;
int mergeNow2;
int mergeType;
int foundNewLine;
char * exportsEntryName;
int exportsGotEntryName;
char * exportsInternalName;
int exportsGotInternalName;
char * exportsOrdinal;
int exportsGotOrdinal;
int exportsGotPrivate;
int exportsGotResident;
char * stackReserve;
int stackGotReserve;
char * stackCommit;
int stackGotCommit;
int stubGotFile;
char * heapReserve;
int heapGotReserve;
char * heapCommit;
int heapGotCommit;
char * versionMajor;
int versionGotMajor;
char * versionMinor;
int versionGotMinor;
int len;
char * str;
/*** Initialize ***/
strip_quotes( newfilename );
if( OpenFileContext( newfilename ) ) {
FreeMem( newfilename );
return( NULL );
}
info = AllocMem( sizeof( DefInfo ) );
memset( info, 0, sizeof( DefInfo ) );
/*** Process the commands, one by one ***/
while( alive ) {
if( error ) {
Warning( "Error near '%s' in %s -- aborting .def processing",
curToken, newfilename );
FreeMem( info );
FreeMem( newfilename );
return( NULL );
}
switch( state ) {
case STATE_CLEAR:
CLEAR_GOT_FLAGS; /* initialize locals */
mergeType = STATE_CLEAR;
mergeNow = FALSE;
state = next_token(STATE_CLEAR, NULL, NULL, FALSE, !exportsGotEntryName ); /* get next command */
break;
case STATE_DESCRIPTION: /* DESCRIPTION "text" */
state = next_token(STATE_DESCRIPTION, NULL, NULL, FALSE, FALSE );
switch( state ) {
case STATE_STRING:
str = string_convert( curToken );
if( *str == '"' ) { // change " to '
*str ='\'';
str[strlen(str)-1] = '\'';
}
add_string( &info->description, str );
state = STATE_CLEAR;
break;
default:
SET_ERROR;
break;
}
break;
case STATE_EXPORTS:
/* EXPORTS entryname[=internalname] [@ordinal[ NONAME ] [DATA] [ PRIVATE ] [RESIDENTNAME] */
state = next_token(STATE_EXPORTS, &mergeNow, &foundNewLine, FALSE, !exportsGotEntryName );
if( mergeNow ) {
if( !exportsGotEntryName ) {
mergeNow = 0;
break;
}
while( !foundNewLine ) {
if (next_token( STATE_EXPORTS, NULL, &foundNewLine, FALSE, FALSE )==STATE_EOF) break;
}
state = STATE_EXPORTS;
break;
}
switch( state ) {
case STATE_STRING:
if( exportsGotEntryName ) {
SET_ERROR;
} else {
exportsEntryName = DupQuoteStrMem( curToken, '\'' );
#ifdef __TARGET_AXP__
FuzzyMassageAXPStdcall( exportsEntryName );
#endif
exportsGotEntryName = 1;
mergeType = STATE_EXPORTS;
if( foundNewLine ) {
mergeNow = 1;
}
}
state = STATE_EXPORTS;
break;
case STATE_AT:
if( !exportsGotEntryName ) {
SET_ERROR;
} else {
state = next_token(STATE_EXPORTS, &mergeNow, &foundNewLine, FALSE, !exportsGotEntryName );
if( mergeNow ) break;
switch( state ) {
case STATE_STRING:
exportsOrdinal = DupStrMem( curToken );
exportsGotOrdinal = 1;
state = STATE_EXPORTS;
if( foundNewLine ) {
mergeNow = 1;
}
break;
case STATE_EOF:
break;
default:
SET_ERROR;
break;
}
}
break;
case STATE_EQUAL:
if( !exportsGotEntryName || exportsGotOrdinal ) {
SET_ERROR;
} else {
state = next_token(STATE_EXPORTS, &mergeNow, &foundNewLine, FALSE, !exportsGotInternalName );
if( mergeNow ) break;
switch( state ) {
case STATE_STRING:
exportsInternalName = DupQuoteStrMem( curToken, '\'' );
#ifdef __TARGET_AXP__
FuzzyMassageAXPStdcall( exportsInternalName );
#endif
exportsGotInternalName = 1;
state = STATE_EXPORTS;
if( foundNewLine ) {
mergeNow = 1;
}
break;
case STATE_EOF:
break;
default:
SET_ERROR;
break;
}
}
break;
case STATE_PRIVATE:
if( !exportsGotEntryName ) {
SET_ERROR;
} else {
exportsGotPrivate = 1;
mergeNow = 1;
}
state = STATE_EXPORTS;
break;
case STATE_RESIDENTNAME:
if( !exportsGotEntryName ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?