translat.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 888 行 · 第 1/2 页
C
888 行
libpathsvector[count-1] = DupStrMem( start );
start = end;
}
FreeMem( newstr );
}
/*** Get the default library paths into the 'libpathsvector' array ***/
envvar = getenv( "WATCOM" );
if( envvar != NULL ) {
count += 2;
libpathsvector = ReallocMem( libpathsvector, (count+1) * sizeof(char*) );
len = strlen( envvar ) + strlen( NT_LIBDIR_SUFFIX ) + 1;
libpathsvector[count-2] = AllocMem( len );
sprintf( libpathsvector[count-2], "%s%s", envvar, NT_LIBDIR_SUFFIX );
len = strlen( envvar ) + strlen( LIBDIR_SUFFIX ) + 1;
libpathsvector[count-1] = AllocMem( len );
sprintf( libpathsvector[count-1], "%s%s", envvar, LIBDIR_SUFFIX );
}
libpathsvector[count] = NULL;
/*** Ok, now do something with these arrays ***/
InitFuzzy( (const char**)objsvector, (const char**)libsvector,
(const char**)libpathsvector, fuzzy_init_callback );
FreeMem( objsvector );
FreeMem( libsvector );
for( count=0; libpathsvector[count]!=NULL; count++ ) {
FreeMem( libpathsvector[count] );
}
FreeMem( libpathsvector );
}
/*
* Determine the name of the executable, and place it in the given buffer.
*/
static void get_executable_name( const OPT_STORAGE *cmdOpts, char *firstObj,
char *executable )
/**************************************************************************/
{
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
if( cmdOpts->out ) {
strcpy( executable, cmdOpts->out_value->data );
} else {
_splitpath( firstObj, drive, dir, fname, NULL );
if( !cmdOpts->dll ) {
_makepath( executable, drive, dir, fname, ".exe" );
} else {
_makepath( executable, drive, dir, fname, ".dll" );
}
}
}
/*
* Destroy an OPT_STRING.
*/
static void del_string( OPT_STRING **p )
/**************************************/
{
OPT_STRING * s;
while( *p != NULL ) {
s = *p;
*p = s->next;
FreeMem( s );
}
}
/*
* Parse linker options.
*/
static void linker_opts( struct XlatStatus *status,
const OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/*********************************************************************/
{
OPT_STRING * optStr;
OPT_STRING * objs = NULL;
OPT_STRING * libs = NULL;
char * p;
char * newstr;
char * filename;
int fileType;
int numFiles;
char * firstObj = NULL;
char executable[_MAX_PATH];
char * tmp;
char * envvar;
/*** Process all object file names ***/
for( numFiles=0; ; numFiles++ ) {
filename = GetNextFile( &fileType, TYPE_OBJ_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
if( cmdOpts->export || cmdOpts->entry ) {
add_string( &objs, filename );
}
newstr = PathConvert( filename, '\'' );
if( firstObj == NULL ) firstObj = newstr;
if( numFiles == 0 ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "FILE {" );
}
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, " %s", newstr );
}
if( numFiles != 0 ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "}" );
} else {
Warning( "No object files specified" );
FatalError( "Nothing to do!" );
}
/*** Process all library file names ***/
for( ;; ) {
filename = GetNextFile( &fileType, TYPE_LIB_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
if( cmdOpts->export || cmdOpts->entry ) {
add_string( &libs, filename );
}
newstr = PathConvert( filename, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "LIBRARY %s", newstr );
}
/*** Process all '.exp' file names ***/
for( ;; ) {
filename = GetNextFile( &fileType, TYPE_EXP_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
status->exp=1;
newstr = PathConvert( filename, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "@ %s", newstr );
}
/*** Process all '.rbj' and '.rs' file names ***/
for( ;; ) {
filename = GetNextFile( &fileType, TYPE_RBJ_FILE, TYPE_RS_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
newstr = PathConvert( filename, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION RESOURCE %s", newstr );
}
/*** Process the LIB environment variable ***/
envvar = getenv( "LIB" );
if( envvar != NULL ) {
newstr = PathConvert( envvar, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "LIBPATH %s", newstr );
}
if( cmdOpts->incremental ) {
if( !stricmp( cmdOpts->incremental_value->data, "yes" ) ) {
if( cmdOpts->release ) {
Warning( "Ignoring /INCREMENTAL due to /RELEASE" );
} else {
if( !cmdOpts->_10x ) {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION incremental" );
}
}
}
}
if( cmdOpts->align ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION alignment=%u",
cmdOpts->align_value );
}
if( cmdOpts->base ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION offset=%s",
cmdOpts->base_value->data );
}
optStr = cmdOpts->comment_value;
while( optStr != NULL ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION description %s",
optStr->data );
optStr = optStr->next;
}
if( cmdOpts->debug ) {
if( cmdOpts->_10x ) {
AppendCmdLine( cmdLine, LINK_SYSTEM_SECTION, "DEBUG dwarf" );
} else {
AppendCmdLine( cmdLine, LINK_SYSTEM_SECTION, "DEBUG dwarf all" );
}
}
optStr = cmdOpts->defaultlib_value;
while( optStr != NULL ) {
newstr = PathConvert( optStr->data, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "LIBRARY %s", newstr );
optStr = optStr->next;
}
/*** Initialize fuzzy linking if necessary ***/
if( cmdOpts->export || cmdOpts->entry ) {
if( !cmdOpts->nofuzzy ) {
init_fuzzy( objs, libs, cmdOpts->defaultlib_value );
}
}
/*** Handle the /entry option ***/
if( cmdOpts->entry ) {
if( cmdOpts->nofuzzy ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
"REFERENCE %s OPTION start=%s",
cmdOpts->entry_value->data,
cmdOpts->entry_value->data );
} else {
p = MatchFuzzy( cmdOpts->entry_value->data );
if( p != NULL ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
"REFERENCE %s OPTION start=%s", p, p );
FreeMem( p );
} else {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
"REFERENCE %s OPTION start=%s",
cmdOpts->entry_value->data,
cmdOpts->entry_value->data );
}
}
}
/*** Handle export directives ***/
if( cmdOpts->export ) {
if( cmdOpts->nofuzzy ) {
optStr = cmdOpts->export_value;
while( optStr != NULL ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "EXPORT %s",
optStr->data );
optStr = optStr->next;
}
} else {
optStr = cmdOpts->export_value;
while( optStr != NULL ) {
p = fuzzy_export( optStr->data );
if( p != NULL ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION,
"EXPORT %s", p );
FreeMem( p );
}
optStr = optStr->next;
}
}
}
if( objs != NULL ) del_string( &objs );
if( libs != NULL ) del_string( &libs );
/*** Deinitialize fuzzy linking if necessary ***/
if( cmdOpts->export || cmdOpts->entry ) {
if( !cmdOpts->nofuzzy ) {
FiniFuzzy();
}
}
if( cmdOpts->forcemultiple ) {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION redefsok" );
}
if( cmdOpts->forceundefined ) {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION undefsok" );
}
if( cmdOpts->heap ) {
p = strchr( cmdOpts->heap_value->data, ',' );
if( p == NULL ) { /* /HEAP:reserve */
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION heapsize=%s",
cmdOpts->heap_value->data );
} else { /* /HEAP:reserve,commit */
*p = '\0';
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION heapsize=%s",
cmdOpts->heap_value->data );
p++;
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "COMMIT heap=%s", p );
}
}
if( cmdOpts->implib ) {
newstr = PathConvert( cmdOpts->implib_value->data, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION implib=%s",
newstr );
}
optStr = cmdOpts->include_value;
while( optStr != NULL ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "REFERENCE %s",
optStr->data );
optStr = optStr->next;
}
if( cmdOpts->internaldllname ) {
newstr = DupQuoteStrMem( cmdOpts->internaldllname_value->data, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION modname=%s",
newstr );
}
if( cmdOpts->map ) {
if( cmdOpts->map_value != NULL ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION map=%s",
cmdOpts->map_value->data );
} else {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION map" );
}
}
if( cmdOpts->nowopts && cmdOpts->nodefaultlib ) {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION nodefaultlibs" );
}
if( cmdOpts->opt_level == OPT_opt_level_optref ) {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION eliminate" );
}
if( cmdOpts->out ) {
newstr = PathConvert( cmdOpts->out_value->data, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "NAME %s", newstr );
}
if( cmdOpts->release ) {
AppendCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION checksum" );
}
if( cmdOpts->stack ) {
p = strchr( cmdOpts->stack_value->data, ',' );
if( p == NULL ) { /* /STACK:reserve */
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stack=%s",
cmdOpts->stack_value->data );
} else { /* /STACK:reserve,commit */
*p = '\0';
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stack=%s",
cmdOpts->stack_value->data );
p++;
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "COMMIT stack=%s", p );
}
} else {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stack=1M" );
}
if( cmdOpts->stub ) {
if( (*cmdOpts->stub_value->data == '\'') ) {
tmp = cmdOpts->stub_value->data + 1; /* skip leading ' */
tmp[ strlen(tmp)-1 ] = '\0'; /* smite trailing ' */
} else {
tmp = cmdOpts->stub_value->data;
}
newstr = PathConvert( tmp, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION stub=%s",
newstr );
}
if( cmdOpts->version ) {
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION version=%s",
cmdOpts->version_value->data );
}
/*** Process all resource file names ***/
get_executable_name( cmdOpts, firstObj, executable );
for( ;; ) {
filename = GetNextFile( &fileType, TYPE_RES_FILE, TYPE_INVALID_FILE );
if( filename == NULL ) break;
newstr = PathConvert( filename, '\'' );
AppendFmtCmdLine( cmdLine, LINK_OPTS_SECTION, "OPTION resource=%s", newstr );
}
}
/*
* Activate default options.
*/
static void default_opts( struct XlatStatus *status,
const OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
{
if (!cmdOpts->nowopts)
{
AppendCmdLine(cmdLine, LINK_OPTS_SECTION, "OPTION quiet");
} /* if */
} /* default_opts() */
/*
* Activate options which have been parsed but not yet turned on.
*/
static void merge_opts( struct XlatStatus *status, const OPT_STORAGE *cmdOpts,
CmdLine *cmdLine )
/****************************************************************************/
{
OPT_STRING *curr;
char *p;
char *system = SYS_NT_CHARMODE;
if( cmdOpts->subsystem ) {
p = strchr( cmdOpts->subsystem_value->data, ',' );
if( p != NULL ) *p = '=';
p = cmdOpts->subsystem_value->data;
if( !strnicmp( p, "WINDOWS", 7 ) || !strnicmp( p, "NATIVE", 6 ) ) {
AppendCmdLine(cmdLine, LINK_SYSTEM_SECTION, "RUNTIME windows=4.0");
system = SYS_NT_WINDOWED;
} else {
AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "RUNTIME %s", p);
}
}
if( cmdOpts->dll ) {
AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "SYSTEM %s initinstance terminstance", SYS_NT_DLL );
if( !cmdOpts->implib && !status->exp ) {
AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "OPTION implib" );
}
} else {
AppendFmtCmdLine( cmdLine, LINK_SYSTEM_SECTION, "SYSTEM %s", system );
}
/*** Add any options meant for the Watcom tools ***/
if (cmdOpts->passwopts)
{
for (curr = cmdOpts->passwopts_value; curr; curr = curr->next)
{
AppendCmdLine(cmdLine, LINK_OPTS_SECTION, curr->data);
}
}
}
/*
* Translate scanned MS options to Watcom options.
*/
void OptionsTranslate( OPT_STORAGE *cmdOpts, CmdLine *cmdLine )
/*************************************************************/
{
/*** Parse the /nologo switch now so we can print the banner ***/
init_status( &status );
if( cmdOpts->nologo ) {
QuietModeMessage();
} else {
BannerMessage();
}
/*** Parse everything ***/
unsupported_opts( cmdOpts );
default_opts( &status, cmdOpts, cmdLine );
def_file_opts( cmdOpts );
linker_opts( &status, cmdOpts, cmdLine );
merge_opts( &status, cmdOpts, cmdLine );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?