cmdall.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,562 行 · 第 1/3 页
C
1,562 行
/****************************************************************************
*
* 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: Commands common to all executable formats
*
****************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include "walloca.h"
#include "linkstd.h"
#include "msg.h"
#include "alloc.h"
#include "command.h"
#include "wlnkmsg.h"
#include "strtab.h"
#include "dbgall.h"
#include "cmddos.h"
#include "cmdline.h"
#include "symtrace.h"
#include "objio.h"
#include "loadfile.h"
#include "carve.h"
#include "permdata.h"
#include "cmdall.h"
static void * LastFile;
static file_list ** LastLibFile;
void ResetCmdAll( void )
/**********************/
{
LastFile = NULL;
LastLibFile = NULL;
LibPath = NULL;
}
extern bool ProcDosSeg( void )
/****************************/
/* process DOSSEG option */
{
LinkState |= DOSSEG_FLAG;
DEBUG(( DBG_OLD, "dosseg" ));
return( TRUE );
}
extern bool ProcName( void )
/**************************/
{
if( !GetToken( SEP_NO, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) ) return( FALSE );
CmdFlags &= ~CF_UNNAMED;
if( Name != NULL ) {
_LnkFree( Name );
}
Name = tostring(); // just keep the name around for now.
return( TRUE );
}
extern bool ProcFormat( void )
/****************************/
{
if( LinkState & FMT_SPECIFIED ) {
LnkMsg( LOC+LINE+FTL + MSG_MULTIPLE_MODES_FOUND, NULL );
}
LinkState |= FMT_SPECIFIED;
return( ProcOne( Models, SEP_NO, TRUE ) );
}
static bool AddOption( void )
/***************************/
{
Token.thumb = REJECT;
if( ProcOne( MainOptions, SEP_NO, FALSE ) == FALSE ) return( FALSE );
return TRUE;
}
extern bool ProcOptions( void )
/*****************************/
{
return ProcArgList( AddOption, TOK_INCLUDE_DOT );
}
extern bool ProcDebug( void )
/***************************/
{
bool gotmod;
if( CmdFlags & CF_FILES_BEFORE_DBI ) {
LnkMsg( LOC+LINE+WRN+MSG_DEBUG_AFTER_FILES, NULL );
}
gotmod = ProcOne( DbgMods, SEP_NO, FALSE );
DBIFlag &= ~DBI_MASK;
if( ProcOne( PosDbgMods, SEP_NO, FALSE ) ) {
while( ProcOne( PosDbgMods, SEP_COMMA, FALSE ) != FALSE ); /*null loop*/
} else {
DBIFlag |= DBI_ALL; //DBI_MASK;
if( !gotmod ) {
return FALSE;
}
}
return TRUE;
}
extern bool ProcDwarfDBI( void )
/******************************/
{
if( LinkFlags & (ANY_DBI_FLAG & ~DWARF_DBI_FLAG) ) {
LnkMsg( LOC+LINE+WRN+MSG_MULT_DBI_FORMATS, NULL );
return TRUE;
}
LinkFlags |= DWARF_DBI_FLAG;
return( TRUE );
}
extern bool ProcWatcomDBI( void )
/*******************************/
{
if( LinkFlags & (ANY_DBI_FLAG & ~OLD_DBI_FLAG) ) {
LnkMsg( LOC+LINE+WRN+MSG_MULT_DBI_FORMATS, NULL );
return TRUE;
}
LinkFlags |= OLD_DBI_FLAG;
return( TRUE );
}
extern bool ProcCodeviewDBI( void )
/*********************************/
{
if( LinkFlags & (ANY_DBI_FLAG & ~CV_DBI_FLAG) ) {
LnkMsg( LOC+LINE+WRN+MSG_MULT_DBI_FORMATS, NULL );
return TRUE;
}
LinkFlags |= CV_DBI_FLAG;
return TRUE;
}
extern bool ProcLine( void )
/**************************/
{
if( !(LinkFlags & ANY_DBI_FLAG) ) {
LinkFlags |= DWARF_DBI_FLAG;
}
DBIFlag |= DBI_LINE;
return( TRUE );
}
#if 0
extern bool ProcDBIStatic( void )
/*******************************/
{
if( !(LinkFlags & ANY_DBI_FLAG) ) {
LinkFlags |= DWARF_DBI_FLAG;
}
DBIFlag |= DBI_STATICS;
return( TRUE );
}
#endif
extern bool ProcType( void )
/**************************/
{
if( !(LinkFlags & ANY_DBI_FLAG) ) {
LinkFlags |= DWARF_DBI_FLAG;
}
DBIFlag |= DBI_TYPE;
return( TRUE );
}
extern bool ProcLocal( void )
/***************************/
{
if( !(LinkFlags & ANY_DBI_FLAG) ) {
LinkFlags |= DWARF_DBI_FLAG;
}
DBIFlag |= DBI_LOCAL;
return( TRUE );
}
extern bool ProcAll( void )
/*************************/
{
if( !(LinkFlags & ANY_DBI_FLAG) ) {
LinkFlags |= DWARF_DBI_FLAG;
}
DBIFlag |= DBI_ALL;
return( TRUE );
}
static bool AddAlias( void )
/**************************/
/* add an individual alias */
{
char * name;
int namelen;
namelen = Token.len;
name = alloca( namelen );
memcpy( name, Token.this, namelen );
if( !GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
return( FALSE );
}
MakeSymAlias( name, namelen, tostring(), Token.len );
return( TRUE );
}
extern bool ProcAlias( void )
/***************************/
{
return( ProcArgList( &AddAlias, TOK_INCLUDE_DOT ) );
}
static bool AddReference( void )
/******************************/
{
symbol * sym;
sym = SymXOp( ST_REFERENCE | ST_CREATE, Token.this, Token.len );
sym->info |= SYM_DCE_REF; /* make sure it stays around */
return( TRUE );
}
extern bool ProcReference( void )
/*******************************/
{
return( ProcArgList( &AddReference, TOK_INCLUDE_DOT ) );
}
extern bool ProcOSName( void )
/****************************/
{
if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
if( FmtData.osname != NULL ) {
_LnkFree( FmtData.osname );
}
FmtData.osname = tostring();
return( TRUE );
}
return( FALSE );
}
extern bool ProcEliminate( void )
/*******************************/
/* turn on dead code elimination */
{
LinkFlags |= STRIP_CODE;
return( TRUE );
}
extern bool ProcMaxErrors( void )
/*******************************/
/* set a maximum number of errors for the linker to generate */
{
if( !GetLong( &MaxErrors ) ) return( FALSE );
LinkFlags |= MAX_ERRORS_FLAG;
return( TRUE );
}
extern bool ProcSymFile( void )
/*****************************/
{
if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) != FALSE ) {
if( SymFileName != NULL ) {
_LnkFree( SymFileName );
}
SymFileName = FileName( Token.this, Token.len, E_SYM, FALSE );
}
return( TRUE );
}
static file_list * AllocNewFile( member_list *member )
/****************************************************/
{
file_list * new_entry;
_PermAlloc( new_entry, sizeof(file_list) );
new_entry->next_file = NULL;
new_entry->status = DBIFlag;
new_entry->strtab = NULL;
new_entry->u.member = member;
if( member != NULL ) {
new_entry->status |= STAT_HAS_MEMBER;
}
return( new_entry );
}
static void * AddObjFile( char *name, char *member, file_list **filelist )
/************************************************************************/
{
file_list * new_entry;
member_list * new_member;
new_member = NULL;
if( member != NULL ) {
_ChkAlloc( new_member, offsetof(member_list,name) + strlen( member ) + 1 );
new_member->flags = DBIFlag;
strcpy( new_member->name, member );
new_member->next = NULL;
_LnkFree( member );
new_entry = CurrSect->files;
while( new_entry != NULL ) {
if( FNAMECMPSTR( new_entry->file->name, name ) == 0 ) {
CmdFlags |= CF_MEMBER_ADDED;
if( new_entry->u.member != NULL ) {
LinkList( &new_entry->u.member, new_member );
return( new_member );
} else {
_LnkFree( new_member ); // user did a stupid thing.
return( new_entry->u.member );
}
}
new_entry = new_entry->next_file;
}
}
new_entry = AllocNewFile( new_member );
if( new_member != NULL ) {
new_entry->file = AllocUniqueFileEntry( name, LibPath );
new_entry->file->flags |= INSTAT_LIBRARY;
} else {
new_entry->file = AllocFileEntry( name, Path );
}
*filelist = new_entry;
return( new_entry );
}
extern file_list *AddObjLib( char *name, unsigned char priority )
/***************************************************************/
{
file_list **next_owner;
file_list **proc_owner;
file_list * proc_curr;
file_list * newproc;
bool added;
DEBUG(( DBG_OLD, "Adding Object library name %s", name ));
proc_owner = &ObjLibFiles;
for(;;) {
proc_curr = *proc_owner;
if( proc_curr == NULL ) break;
if( proc_curr->priority < priority ) break;
/* if library already exists with a higher priority */
if( FNAMECMPSTR( proc_curr->file->name, name ) == 0 ) return(proc_curr);
proc_owner = &proc_curr->next_file;
}
added = TRUE;
next_owner = proc_owner; /* replace library if it exists */
for(;;) { /* with a lower priority */
if( proc_curr == NULL ) break;
if( FNAMECMPSTR( proc_curr->file->name, name ) == 0 ) {
*next_owner = proc_curr->next_file; /* move entry up */
proc_curr->next_file = *proc_owner;
*proc_owner = proc_curr;
proc_curr->priority = priority;
newproc = proc_curr;
added = FALSE;
break;
}
next_owner = &proc_curr->next_file;
proc_curr = *next_owner;
}
if( added ) { /* if we need to add one */
newproc = AllocNewFile( NULL );
newproc->file = AllocUniqueFileEntry( name, LibPath );
newproc->file->flags |= INSTAT_LIBRARY | INSTAT_OPEN_WARNING;
newproc->priority = priority;
newproc->next_file = *proc_owner;
*proc_owner = newproc;
LinkState |= LIBRARIES_ADDED;
}
return( newproc );
}
static bool AddLibFile( void )
/****************************/
{
char * ptr;
char * membname;
file_list * entry;
CmdFlags &= ~CF_MEMBER_ADDED;
ptr = GetFileName( &membname, FALSE );
if( membname != NULL ) {
LnkMsg( LOC+LINE+WRN+MSG_NO_MEMB_IN_LIBFILE, NULL );
_LnkFree( membname );
_LnkFree( ptr );
return TRUE;
}
entry = AllocNewFile( NULL );
entry->file = AllocFileEntry( ptr, LibPath );
entry->next_file = *LastLibFile;
*LastLibFile = entry;
LastLibFile = &entry->next_file;
if( *LastLibFile == NULL ) { // no file directives found yet
CurrFList = LastLibFile;
}
entry->file->flags |= INSTAT_USE_LIBPATH;
_LnkFree( ptr );
return( TRUE );
}
extern bool ProcLibFile( void )
/*****************************/
/* process FILE command */
{
if( (LinkFlags & (DWARF_DBI_FLAG |OLD_DBI_FLAG | NOVELL_DBI_FLAG) ) == 0 ) {
CmdFlags |= CF_FILES_BEFORE_DBI;
}
if( LastLibFile == NULL ) {
LastLibFile = &Root->files;
}
return( ProcArgList( &AddLibFile, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) );
}
static bool AddModFile( void )
/*****************************/
{
char * ptr;
char * membname;
ptr = GetFileName( &membname, FALSE );
AddHTableElem(Root->modFilesHashed, ptr);
LinkFlags |= GOT_CHGD_FILES;
return( TRUE );
}
static bool AddFile( void )
/*************************/
{
char * ptr;
char * membname;
file_list ** temp;
CmdFlags &= ~CF_MEMBER_ADDED;
if( CmdFlags & CF_AUTOSECTION ) {
if( CmdFlags & CF_SECTION_THERE ) { // is section there already?
CmdFlags &= ~CF_SECTION_THERE;
} else {
MakeNewSection();
}
}
ptr = GetFileName( &membname, TRUE );
temp = CurrFList;
if( *CurrFList != NULL ) {
CurrFList = &(*CurrFList)->next_file;
}
LastFile = AddObjFile( ptr, membname, CurrFList );
if( CmdFlags & CF_MEMBER_ADDED ) {
CurrFList = temp; // go back to previous entry.
} else if( membname != NULL ) { // 1st member added
LastFile = ((file_list *)LastFile)->u.member;
CmdFlags |= CF_MEMBER_ADDED;
}
_LnkFree( ptr );
return( TRUE );
}
extern bool ProcFiles( void )
/***************************/
/* process FILE command */
{
if( (LinkFlags & (DWARF_DBI_FLAG|OLD_DBI_FLAG | NOVELL_DBI_FLAG) ) == 0 ) {
CmdFlags |= CF_FILES_BEFORE_DBI;
}
return( ProcArgList( &AddFile, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) );
}
extern bool ProcModFiles( void )
/***************************/
{
return( ProcArgList( &AddModFile, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) );
}
#define MAX_PRIORITY 255
static bool AddLib( void )
/************************/
{
char * ptr;
file_list * result;
ptr = FileName( Token.this, Token.len, E_LIBRARY, FALSE );
result = AddObjLib( ptr, MAX_PRIORITY );
result->status |= STAT_USER_SPECD;
if( CmdFlags & CF_SET_SECTION ) {
result->status |= STAT_LIB_FIXED;
if( OvlLevel == 0 ) {
result->ovlref = 0;
} else {
result->ovlref = OvlNum - 1;
}
}
if( CmdFlags & CF_DOING_OPTLIB ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?