translat.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 779 行 · 第 1/2 页
C
779 行
/****************************************************************************
*
* 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: Translate Microsoft LIB to Watcom options.
*
****************************************************************************/
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cmdline.h"
#include "deffile.h"
#include "error.h"
#include "file.h"
#include "fuzzy.h"
#include "lib.h"
#include "message.h"
#include "memory.h"
#include "pathconv.h"
#include "translat.h"
#include "system.h"
#define UNSUPPORTED_STR_SIZE 512
static char * stristr( const char *str, const char *substr );
static FILE * exp = NULL; /* '.exp' file containing export entries for the linker */
static OPT_STRING * comment = NULL;
static OPT_STRING * base = NULL;
static OPT_STRING * heap = NULL;
static OPT_STRING * stack = NULL;
static OPT_STRING * internaldllname = NULL;
static OPT_STRING * stub = NULL;
static OPT_STRING * version = NULL;
/*
* Add one more unsupported option to optStr.
*/
static void append_unsupported( char *optStr, char *opt )
/*******************************************************/
{
if( optStr[0] != '\0' ) {
strcat( optStr, " /" );
} else {
strcat( optStr, "/" );
}
strcat( optStr, opt );
}
/*
* Parse unsupported options.
*/
static void unsupported_opts( OPT_STORAGE *cmdOpts )
/**************************************************/
{
char opts[UNSUPPORTED_STR_SIZE];
/*** Build a string listing all unsupported options that were used ***/
opts[0] = '\0';
if( cmdOpts->debugtype ) append_unsupported( opts, "DEBUGTYPE" );
if( cmdOpts->import ) append_unsupported( opts, "IMPORT" );
if( cmdOpts->include ) append_unsupported( opts, "INCLUDE" );
if( cmdOpts->mac ) append_unsupported( opts, "MAC" );
if( cmdOpts->nodefaultlib) append_unsupported( opts, "NODEFAULTLIB");
if( cmdOpts->subsystem ) append_unsupported( opts, "SUBSYSTEM" );
if( cmdOpts->verbose ) append_unsupported( opts, "VERBOSE" );
/*** If an unsupported option was used, give a warning ***/
if( opts[0] != '\0' ) {
UnsupportedOptsMessage( opts );
}
if (cmdOpts->machine) {
if ( (stricmp("IX86",cmdOpts->machine_value->data)!=0) &&
(stricmp("I386",cmdOpts->machine_value->data)!=0) &&
(stricmp("APX",cmdOpts->machine_value->data)!=0) &&
(stricmp("ALPHA",cmdOpts->machine_value->data)!=0) ) {
Warning("%s target platform is not supported",cmdOpts->machine_value->data);
}
}
}
/*
* Add another string to an OPT_STRING.
*/
static void add_string( OPT_STRING **p, char *str )
/*************************************************/
{
OPT_STRING * buf;
OPT_STRING * curElem;
/*** Make a new list item ***/
buf = AllocMem( sizeof(OPT_STRING) + strlen(str) );
strcpy( buf->data, 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 if necessary.
*/
static void def_file_opts( OPT_STORAGE *cmdOpts )
/***********************************************/
{
DefInfo * info;
StringList * strList;
if( cmdOpts->def ) {
#ifdef __TARGET_AXP__
info = ParseDefFile( cmdOpts->def_value->data,
!cmdOpts->nofuzzy );
#else
info = ParseDefFile( cmdOpts->def_value->data );
#endif
if( info != NULL ) {
strList = info->exports;
while( strList != NULL ) {
cmdOpts->export=1;
add_string( &cmdOpts->export_value, strList->str );
strList = strList->next;
}
strList = info->description;
while( strList != NULL ) {
add_string( &comment, strList->str );
strList = strList->next;
}
if( info->name != NULL ) {
add_string( &cmdOpts->name_value, info->name );
cmdOpts->name = 1;
}
if( info->baseAddr != NULL ) {
add_string( &base, info->baseAddr );
}
if( info->heapsize != NULL ) {
add_string( &heap, info->heapsize );
}
if( info->stacksize != NULL ) {
add_string( &stack, info->stacksize );
}
if( info->internalDllName != NULL ) {
add_string( &internaldllname, info->internalDllName );
}
if( info->stub != NULL ) {
add_string( &stub, info->stub );
}
if( info->version != NULL ) {
add_string( &version, info->version );
}
FreeDefInfo(info);
} else {
FatalError( "Error parsing %s -- aborting",
cmdOpts->def_value->data );
}
}
}
/*
* Get first library or object file from the list. WLIB will use its name as its main library.
*/
static void get_library(OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/**************************************************************/
{
char * filename;
char * filecopy;
int fileType;
char * newfilename;
char * tempfilename;
int quotes_found=0;
filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
if( filename != NULL ) {
if (fileType==TYPE_OBJ_FILE){
if ((cmdOpts->list) || (cmdOpts->extract)) {
for (;;) {
if( stristr( filename, ".obj" ) == NULL ) {
AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", filename );
FreeMem(filename);
break;
} else {
FreeMem(filename);
filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
}
if (filename==NULL) FatalError("no library or object files specified!");
}
} else {
/*** Strip quotes from filename and the extension ***/
filecopy=DupStrMem(filename);
newfilename = ReallocMem( filename, strlen(filename)+4 );
if( *newfilename == '"' ) {
tempfilename = newfilename + 1; /* skip leading " */
quotes_found=1;
} else {
tempfilename = newfilename;
}
if (strchr(tempfilename,'.')==NULL) Zoinks();
*strchr(tempfilename,'.') = '\0';
/*** Append '.lib' at the end of filename and add quotes if needed ***/
if (quotes_found) {
tempfilename = DupQuoteStrMem(strcat(tempfilename,".lib"),'"');
} else {
tempfilename = DupStrMem(strcat(tempfilename,".lib"));
}
FreeMem( newfilename );
AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", tempfilename );
FreeMem( tempfilename );
AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "-+%s", filecopy );
}
} else {
AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "%s", filename );
FreeMem(filename);
}
} else {
FatalError("no library or object files specified!");
}
}
/*
* Get the rest of library files and object files from the list.
*/
static void get_files(CmdLine *cmdLine )
/**************************************/
{
char * filename;
int fileType;
for( ;; ) {
filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
AppendFmtCmdLine( cmdLine, LIB_OPTS_SECTION, "-+%s", filename );
FreeMem( filename );
}
/*** Ignore all '.rbj', '.rs', and '.res' files ***/
for( ;; ) {
filename = GetNextFile( &fileType, TYPE_RES_FILE, TYPE_RBJ_FILE,
TYPE_RS_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
Warning( "Ignoring resource file '%s'", filename );
FreeMem( filename );
}
}
/*
* Appends '.' to a filename without extension ie. 'my_file' becomes 'my_file.'
*/
static char *VerifyDot( char *filename )
/************************************/
{
char * newfilename;
char * tempfilename;
char * filecopy;
int quotes_found=0;
filecopy = DupStrMem(filename);
if (strchr(filename,'.')==NULL) {
/*** Strip quotes from filename ***/
newfilename = ReallocMem( filecopy, strlen(filecopy)+2 );
if( *newfilename == '"' ) {
tempfilename = newfilename + 1; /* skip leading " */
tempfilename[ strlen(tempfilename)-1 ] = '\0'; /* smite trailing " */
quotes_found=1;
} else {
tempfilename = newfilename;
}
/*** Append '.' at the end of filename and add quotes if needed ***/
if (quotes_found) {
filecopy = DupQuoteStrMem(strcat(tempfilename,"."),'"');
} else {
filecopy = DupStrMem(strcat(tempfilename,"."));
}
FreeMem( newfilename );
}
return filecopy;
}
/*
* Called by InitFuzzy when an error occurs.
*/
static int fuzzy_init_callback( const char *filename )
/****************************************************/
{
Warning( "Cannot extract external symbols from '%s' -- fuzzy name matching may not work",
filename );
return( 1 );
}
/*
* Initialize fuzzy linking.
*/
static void init_fuzzy( void )
/****************************/
{
unsigned count;
char * filename;
char * newstr;
char ext[_MAX_EXT];
char ** objsvector;
/*** Get the object file names into an array ***/
count = 0;
objsvector = AllocMem( (count+1) * sizeof(char*) );
for( ;; ) {
filename = GetNextFile( NULL, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
newstr = PathConvert( filename, '\'' );
/*** Skip .res files ***/
_splitpath( newstr, NULL, NULL, NULL, ext );
if( !stricmp( ext, ".res" ) ) {
FreeMem( newstr );
continue;
}
objsvector[count] = newstr;
count++;
objsvector = ReallocMem( objsvector, (count+1) * sizeof(char*) );
}
objsvector[count] = NULL;
/*** Ok, now tell the fuzzy module to initialize itself ***/
InitFuzzy( (const char**)objsvector, NULL, NULL, fuzzy_init_callback );
FreeMem( objsvector );
}
/*
* Destroy an OPT_STRING.
*/
static void del_string( OPT_STRING **p )
/**************************************/
{
OPT_STRING * s;
while( *p != NULL ) {
s = *p;
*p = s->next;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?