translat.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 888 行 · 第 1/2 页
C
888 行
/****************************************************************************
*
* 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 LINK to Watcom options.
*
****************************************************************************/
#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 "link.h"
#include "message.h"
#include "memory.h"
#include "pathconv.h"
#include "translat.h"
#include "system.h"
#define UNSUPPORTED_STR_SIZE 512
#if defined(__TARGET_386__)
#define SYS_NT_CHARMODE "nt"
#define SYS_NT_WINDOWED "nt_win"
#define SYS_NT_DLL "nt_dll"
#define LIBDIR_SUFFIX "\\lib386"
#define NT_LIBDIR_SUFFIX "\\lib386\\nt"
#elif defined(__TARGET_AXP__)
#define SYS_NT_CHARMODE "ntaxp"
#define SYS_NT_WINDOWED "ntaxp_win"
#define SYS_NT_DLL "ntaxp_dll"
#define LIBDIR_SUFFIX "\\libaxp"
#define NT_LIBDIR_SUFFIX "\\libaxp\\nt"
#elif defined(__TARGET_PPC__)
#define SYS_NT_CHARMODE "ntppc"
#define SYS_NT_WINDOWED "ntppc_win"
#define SYS_NT_DLL "ntppc_dll"
#define LIBDIR_SUFFIX "\\libppc"
#define NT_LIBDIR_SUFFIX "\\libppc\\nt"
#else
#error Unrecognized CPU type
#endif
/*
* Various flags to keep in mind while translating options.
*/
static struct XlatStatus {
int dll : 1; /* we're building a DLL */
int exp : 1; /* there is an .exp file */
} status;
/*
* Initialize a struct XlatStatus.
*/
static void init_status( struct XlatStatus *status )
/**************************************************/
{
memset( status, 0, sizeof(struct XlatStatus) );
}
/*
* 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( const 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->exetype ) append_unsupported( opts, "EXETYPE" );
if( cmdOpts->fixed ) append_unsupported( opts, "FIXED" );
if( cmdOpts->machine ) append_unsupported( opts, "MACHINE" );
if( cmdOpts->noentry ) append_unsupported( opts, "NOENTRY" );
if( cmdOpts->order ) append_unsupported( opts, "ORDER" );
if( cmdOpts->pdb ) append_unsupported( opts, "PDB" );
if( cmdOpts->profile ) append_unsupported( opts, "PROFILE" );
if( cmdOpts->section ) append_unsupported( opts, "SECTION" );
if( cmdOpts->verbose ) append_unsupported( opts, "VERBOSE" );
if( cmdOpts->vxd ) append_unsupported( opts, "VXD" );
if( cmdOpts->warn ) append_unsupported( opts, "WARN" );
/*** If an unsupported option was used, give a warning ***/
if( opts[0] != '\0' ) {
UnsupportedOptsMessage( opts );
}
}
/*
* 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;
char * newstr;
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->description;
while( strList != NULL ) {
add_string( &cmdOpts->comment_value, strList->str );
strList = strList->next;
}
strList = info->exports;
while( strList != NULL ) {
add_string( &cmdOpts->export_value, strList->str );
cmdOpts->export = 1;
strList = strList->next;
}
if( !cmdOpts->dll ) {
if( info->makeDll ) {
cmdOpts->dll = 1;
}
}
if( !cmdOpts->base ) {
if( info->baseAddr != NULL ) {
add_string( &cmdOpts->base_value, info->baseAddr );
cmdOpts->base = 1;
}
}
if( !cmdOpts->heap ) {
if( info->heapsize != NULL ) {
add_string( &cmdOpts->heap_value, info->heapsize );
cmdOpts->heap = 1;
}
}
if( !cmdOpts->internaldllname ) {
if( info->internalDllName != NULL ) {
add_string( &cmdOpts->internaldllname_value, info->internalDllName );
cmdOpts->internaldllname = 1;
}
}
if( !cmdOpts->out ) {
if( info->name != NULL ) {
newstr = PathConvert( info->name, '\'' );
add_string( &cmdOpts->out_value, newstr );
cmdOpts->out = 1;
}
}
if( !cmdOpts->stack ) {
if( info->stacksize != NULL ) {
add_string( &cmdOpts->stack_value, info->stacksize );
cmdOpts->stack = 1;
}
}
if( !cmdOpts->stub ) {
if( info->stub != NULL ) {
add_string( &cmdOpts->stub_value, info->stub );
cmdOpts->stub = 1;
}
}
if( !cmdOpts->version ) {
if( info->version != NULL ) {
add_string( &cmdOpts->version_value, info->version );
cmdOpts->version = 1;
}
}
FreeDefInfo(info);
} else {
FatalError( "Error parsing %s -- aborting",
cmdOpts->def_value->data );
}
}
}
/*
* Called by InitFuzzy when an error occurs.
*/
static int fuzzy_init_callback( const char *filename )
/****************************************************/
{
Warning( "Cannot extract external symbols from '%s' -- fuzzy linking may not work",
filename );
return( 1 );
}
/*
* Given a symbol, fuzzy match it and create an export directive.
* Returns a pointer to a newly allocated buffer, which the caller is
* responsible for freeing. This function was formerly ExportFuzzy().
*/
static char *fuzzy_export( char *export )
/***************************************/
{
char * internalname = NULL;
char * ordinal = NULL;
char * therest = NULL;
char * entryname = NULL;
char * exportcopy;
char * p = NULL;
int len = 4; /* for the '.', '=', ' ', and required +1 */
exportcopy = DupStrMem( export );
p = strchr( exportcopy+1, '\'' );
if( exportcopy[0] != '\'' || p == NULL ) Zoinks(); // the entryname must be in quotes
p++;
if( *p != '\0' ) { /* there is something after the entryname */
entryname = p; // char after the entryname
p = strchr( p, '=' );
if( p != NULL ) { /* internalname found */
*p = '\0';
internalname = p + 1;
p = strchr( internalname, ' ' );
if( p != NULL ) { /* there is something after the internalname */
*p = '\0';
therest = p + 1;
}
}
p = strchr( entryname, '.' );
if( p != NULL ) { /* ordinal found */
*p = '\0';
ordinal = p + 1;
if( internalname == NULL ) {
p = strchr( ordinal, ' ' );
if( p != NULL ) { /* there is something after the ordinal */
*p = '\0';
therest = p + 1;
}
}
len += strlen( ordinal );
}
if( internalname == NULL && ordinal == NULL ) {
p = strchr( entryname, ' ' );
if( p != NULL ) { /* there is something after the entryname */
*p = '\0';
therest = p + 1;
}
}
*entryname = '\0'; /* separate the entry name from the rest of the export directive */
}
entryname = exportcopy;
len += strlen( entryname );
if( internalname == NULL ) {
internalname = MatchFuzzy( entryname );
} else {
internalname = MatchFuzzy( internalname );
}
if( therest != NULL ) {
strupr( therest );
len += strlen( therest );
}
/*** Create and return the proper export directive ***/
if( internalname != NULL ) {
len += strlen( internalname );
p = AllocMem( len );
*p = '\0';
strcat( p, entryname );
if( ordinal ) {
strcat( p, "." );
strcat( p, ordinal );
}
strcat( p, "=" );
strcat( p, internalname );
if( therest != NULL ) {
strcat( p, " " );
strcat( p, therest );
}
} else { // no changes to export directive are required
p = export;
}
FreeMem( exportcopy );
return( p );
}
/*
* Initialize fuzzy linking.
*/
static void init_fuzzy( OPT_STRING *objs, OPT_STRING *libs,
OPT_STRING *defaultlibs )
/*********************************************************/
{
char * envvar;
unsigned count;
char * newstr;
char * start;
char * end;
OPT_STRING * optStr;
char ** objsvector;
char ** libsvector;
char ** libpathsvector;
size_t len;
/*** Get the object file names into an array ***/
count = 0;
optStr = objs;
while( optStr != NULL ) {
count++;
optStr = optStr->next;
}
objsvector = AllocMem( (count+1) * sizeof(char*) );
count = 0;
optStr = objs;
while( optStr != NULL ) {
objsvector[count] = optStr->data;
count++;
optStr = optStr->next;
}
objsvector[count] = NULL;
/*** Get the library file names into an array ***/
count = 0;
optStr = libs;
while( optStr != NULL ) {
count++;
optStr = optStr->next;
}
optStr = defaultlibs;
while( optStr != NULL ) {
count++;
optStr = optStr->next;
}
libsvector = AllocMem( (count+1) * sizeof(char*) );
count = 0;
optStr = libs;
while( optStr != NULL ) {
libsvector[count] = optStr->data;
count++;
optStr = optStr->next;
}
optStr = defaultlibs;
while( optStr != NULL ) {
libsvector[count] = optStr->data;
count++;
optStr = optStr->next;
}
libsvector[count] = NULL;
/*** Get the library paths from LIB into the 'libpathsvector' array ***/
count = 0;
libpathsvector = AllocMem( (count+1) * sizeof(char*) );
envvar = getenv( "LIB" );
if( envvar != NULL ) {
newstr = DupStrMem( envvar );
start = newstr;
while( start != NULL && *start != '\0' ) {
end = strchr( start, ';' );
if( end != NULL ) {
while( *end == ';' ) {
*end = '\0';
end++;
}
}
count++;
libpathsvector = ReallocMem( libpathsvector, (count+1) * sizeof(char*) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?