utils.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 349 行
C
349 行
/****************************************************************************
*
* 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: UTILS : utility routines for the MS linker file translator
*
****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <setjmp.h>
#include "ms2wlink.h"
static char * DefExt[] = {
".obj",
".exe",
".map",
".lib",
".def",
".lnk",
".obj" // for overlay object files.
};
extern char * PromptText[] = {
"object modules ",
"run file ",
"list file ",
"libraries ",
"definitions file "
};
static bool WritePrompt;
extern void * MemAlloc( unsigned );
extern void MemFree( void * );
extern void Error( char * );
extern unsigned QWrite( f_handle, void *, unsigned, char * );
extern bool QIsConIn( f_handle );
extern void QSetBinary( f_handle );
extern char * Msg2Splice( char *, char * );
extern char * Msg3Splice( char *, char *, char * );
extern format_type FmtType;
extern cmdentry * Commands[];
extern bool MapOption;
extern void UtilsInit( void )
/***************************/
// check to see if STDIN is the console. if not, don't write prompt.
{
QSetBinary( STDIN_HANDLE );
WritePrompt = QIsConIn( STDIN_HANDLE );
}
void ImplyFormat( format_type typ )
/*********************************/
{
if( FmtType == FMT_DEFAULT ) FmtType = typ;
}
extern char *FileName( char *buff, int len, char etype, bool force )
/******************************************************************/
{
char *namptr;
char *ptr;
int cnt;
namptr = buff + len;
cnt = 0;
while( cnt != len ) {
cnt++;
--namptr;
if( *namptr == '\\' || *namptr == '/' ) break;
}
if( *namptr == '\\' || *namptr == '/' ) {
namptr++;
}
cnt = len - ( (int) namptr - (int) buff );
namptr = buff + len;
while( *namptr != '.' && --cnt != 0 ) {
namptr--;
}
if( *namptr != '.' || force ) {
if( cnt != 0 ) {
len = cnt;
}
ptr = MemAlloc( len + strlen( DefExt[ etype ] ) + 1 );
memcpy( ptr, buff, len );
strcpy( ptr + len, DefExt[ etype ] );
} else {
ptr = MemAlloc( len + 1 );
memcpy( ptr, buff, len );
ptr[ len ] = '\0';
}
return( ptr );
}
extern void AddCommand( char *msg, int prompt, bool verbatim )
/************************************************************/
{
cmdentry * cmd;
cmdentry * list;
cmd = MemAlloc( sizeof( cmdentry ) );
cmd->command = msg;
cmd->asis = verbatim;
cmd->next = NULL;
list = Commands[ prompt ];
if( list == NULL ) {
Commands[ prompt ] = cmd;
} else { // always add at the end of the list.
while( list->next != NULL ) {
list = list->next;
}
list->next = cmd;
}
}
extern void Warning( char *msg, int prompt )
/******************************************/
// print a warning to the linker command file in the form of a linker comment.
{
AddCommand( Msg2Splice( "# ", msg ), prompt, TRUE );
}
extern void AddOption( char *msg )
/********************************/
{
AddCommand( Msg2Splice( "option ", msg ), OPTION_SLOT, TRUE );
}
extern void AddNumOption( char *msg, unsigned value )
/****************************************************/
{
char buffer[ 7 ];
char * msg2;
utoa( value, buffer, 10 );
msg2 = Msg3Splice( msg, "=", buffer );
AddOption( msg2 );
MemFree( msg2 );
}
extern void AddStringOption( char *msg, char *string, int len )
/*************************************************************/
{
char * cmd;
int msglen;
char * tmp;
msglen = strlen( msg );
cmd = alloca( len + msglen + 2 );
memcpy( cmd, msg, msglen );
tmp = cmd + msglen;
*tmp++ = '=';
memcpy( tmp, string, len );
tmp += len;
*tmp = '\0';
AddOption( cmd );
}
extern void NotSupported( char *msg )
/***********************************/
{
char * msg2;
msg2 = Msg2Splice( msg, " option is not supported by WLINK" );
Warning( msg2, OPTION_SLOT );
MemFree( msg2 );
}
extern void NotNecessary( char *msg )
/***********************************/
{
char * msg2;
msg2 = Msg2Splice( msg, " option is not necessary when using WLINK" );
Warning( msg2, OPTION_SLOT );
MemFree( msg2 );
}
extern char * Msg2Splice( char *msg1, char *msg2 )
/************************************************/
// splice 2 messages together
{
int len1;
int len2;
char * both;
len1 = strlen( msg1 );
len2 = strlen( msg2 );
both = MemAlloc( len1 + len2 + 1 );
memcpy( both, msg1, len1 );
memcpy( both+len1, msg2, len2 );
*(both + len1 + len2) = '\0';
return( both );
}
extern char * Msg3Splice( char *msg1, char *msg2, char *msg3 )
/************************************************************/
{
int len1;
int len2;
int len3;
char * all;
len1 = strlen( msg1 );
len2 = strlen( msg2 );
len3 = strlen( msg3 );
all = MemAlloc( len1 + len2 + len3 + 1 );
memcpy( all, msg1, len1 );
memcpy( all+len1, msg2, len2 );
memcpy( all+len1+len2, msg3, len3 );
*(all+len1+len2+len3) = '\0';
return( all );
}
extern char * FindNotAsIs( int slot )
/***********************************/
// search through the given slot for a command which isn't marked "asis"
// since comments are "asis", this can be used to determine if a filename is
// specified, and what that filename is.
{
cmdentry * cmd;
for( cmd = Commands[ slot ]; cmd != NULL; cmd = cmd->next ) {
if( !cmd->asis ) {
return( cmd->command );
}
}
return( NULL );
}
static char * FindObjectName( void )
/**********************************/
{
char * msg;
msg = FindNotAsIs( OBJECT_SLOT );
if( msg == NULL ) {
msg = FindNotAsIs( OVERLAY_SLOT );
if( msg == NULL ) {
Error( "no object files specified" );
}
}
return( msg );
}
static void PromptStart( char * msg, int prompt )
/***********************************************/
{
char * text;
text = PromptText[ prompt ];
QWrite( STDERR_HANDLE, text, strlen( text ), "console" );
QWrite( STDERR_HANDLE, "[", 1, "console" );
if( msg != NULL ) {
QWrite( STDERR_HANDLE, msg, strlen( msg ), "console" );
}
}
extern void OutPutPrompt( int prompt )
/************************************/
{
char * msg;
if( !WritePrompt ) return;
msg = NULL;
switch( prompt ) {
case RUN_SLOT:
msg = FindObjectName();
msg = FileName( msg, strlen( msg ), E_LOAD, TRUE );
PromptStart( msg, prompt );
MemFree( msg );
break;
case MAP_SLOT:
if( MapOption ) {
msg = FindNotAsIs( RUN_SLOT );
if( msg == NULL ) {
msg = FindObjectName();
}
msg = FileName( msg, strlen( msg ), E_MAP, TRUE );
PromptStart( msg, prompt );
MemFree( msg );
break;
} // note the possible fall through.
case DEF_SLOT:
msg = "nul";
default: // note the fall through
PromptStart( msg, prompt );
QWrite( STDERR_HANDLE, DefExt[ prompt ], 4, "console" );
}
QWrite( STDERR_HANDLE, "]:", 2, "console" );
}
// spawn/suicide support.
static void *SpawnStack;
extern int Spawn( void (*fn)() )
/******************************/
{
void *save_env;
jmp_buf env;
int status;
save_env = SpawnStack;
SpawnStack = env;
status = setjmp( env );
if( status == 0 ) {
(*fn)();
}
SpawnStack = save_env; /* unwind */
return( status );
}
extern void Suicide( void )
/*************************/
{
if( SpawnStack != NULL ) {
longjmp( SpawnStack, 1 );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?