cmdline.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,052 行 · 第 1/2 页
C
1,052 行
/****************************************************************************
*
* 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: Command Line Parser
*
****************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "linkstd.h"
#include "exeos2.h"
#include "msg.h"
#include "alloc.h"
#include "command.h"
#include "wlnkmsg.h"
#include "cmdall.h"
#include "cmdos2.h"
#include "cmdqnx.h"
#include "cmdnov.h"
#include "cmdelf.h"
#include "cmdphar.h"
#include "cmddos.h"
#include "cmdline.h"
#include "overlays.h"
#include "fileio.h"
#include "symtrace.h"
#include "reloc.h"
// #include "strtab.h"
// #include "carve.h"
// #include "permdata.h"
#include "dbgall.h"
#ifdef _INT_DEBUG
unsigned int Debug;
#endif
extern void GetExtraCommands( void );
static void Crash( bool );
static void Help( void );
static void DoCmdParse( void );
static void DisplayOptions( void );
static bool ProcDosHelp( void );
static bool ProcOS2Help( void );
static bool ProcPharHelp( void );
static bool ProcNovellHelp( void );
static bool ProcQNXHelp( void );
static bool ProcELFHelp( void );
static bool ProcWindowsHelp( void );
static bool ProcWinVxdHelp( void );
static bool ProcNTHelp( void );
static void WriteHelp( unsigned first_ln, unsigned last_ln, bool prompt );
static parse_entry FormatHelp[] = {
"Dos", ProcDosHelp, MK_ALL, 0,
#ifdef _OS2
"OS2", ProcOS2Help, MK_ALL, 0,
"WINdows", ProcWindowsHelp, MK_ALL, 0,
"VXD", ProcWinVxdHelp, MK_ALL, 0,
"NT", ProcNTHelp, MK_ALL, 0,
#endif
#ifdef _PHARLAP
"PHARlap", ProcPharHelp, MK_ALL, 0,
#endif
#ifdef _NOVELL
"NOVell", ProcNovellHelp, MK_ALL, 0,
#endif
#ifdef _QNXLOAD
"QNX", ProcQNXHelp, MK_ALL, 0,
#endif
#ifdef _ELF
"ELF", ProcELFHelp, MK_ALL, 0,
#endif
NULL
};
byte Extension;
file_list ** CurrFList;
tok Token;
commandflag CmdFlags;
char * Name;
sysblock * SysBlocks;
sysblock * LinkCommands;
static sysblock * PrevCommand;
#define INIT_FILE_NAME "wlink.lnk"
extern void InitCmdFile( void )
/******************************/
{
PrevCommand = NULL;
}
extern void SetSegMask(void)
/***************************/
{
FmtData.SegShift = 16 - FmtData.Hshift;
FmtData.SegMask = (1 << FmtData.SegShift) - 1;
}
static void ResetCmdFile( void )
/******************************/
/* do all the initialization necessary for parsing a command file */
{
SysBlocks = NULL;
Extension = E_LOAD;
Name = NULL;
CmdFlags = CF_UNNAMED;
Path = NULL;
memset( &FmtData, 0, sizeof(FmtData) );
FmtData.base = NO_BASE_SPEC;
FmtData.objalign = NO_BASE_SPEC;
FmtData.type = MK_ALL;
FmtData.def_seg_flags = SEG_LEVEL_3;
FmtData.output_raw = FALSE;
FmtData.output_hex = FALSE;
FmtData.Hshift = 12; // May want different value for some 32 bit segmented modes
FmtData.FillChar = 0; // Default fillchar for segment alignment
SetSegMask();
CurrSect = Root;
CurrFList = &Root->files;
DBIFlag = 0; /* default is only global information */
}
extern void DoCmdFile( char *fname )
/**********************************/
/* start parsing the command */
{
exe_format possible;
f_handle file;
size_t namelen;
unsigned extension;
ResetCmdFile();
if( fname == NULL || *fname == '\0' ) {
_ChkAlloc( fname, (10*1024) ); // arbitrarily large buffer that won't
GetCmdLine( fname ); // be overflowed
NewCommandSource( NULL, fname, COMMANDLINE );
} else {
NewCommandSource( NULL, fname, ENVIRONMENT );
}
if( IsStdOutConsole() ) {
CmdFlags |= CF_TO_STDOUT;
}
while( *fname == ' ' ) {
fname++;
}
if( QSysHelp( &Token.next ) ) {
Help();
}
if( *fname == '?' ) {
Token.next = fname + 1; // skip question mark.
Help();
#if defined( __UNIX__ )
} else if( *fname == '-' ) {
#else
} else if( *fname == '-' || *fname == '/' ) {
#endif
if( *(fname + 1) == '?' ) {
Token.next = fname + 2; // skip /?
Help();
}
}
if( *fname == '\0' ) { // go into interactive mode.
Token.how = INTERACTIVE;
Token.where = ENDOFLINE;
LnkMsg( INF+MSG_PRESS_CTRL_Z, NULL );
}
#if _DEVELOPMENT == _ON
file = SearchPath( "nwlink.lnk" );
if( file == NIL_HANDLE ) {
file = SearchPath( INIT_FILE_NAME );
}
#else
file = SearchPath( INIT_FILE_NAME );
#endif
if( file != NIL_HANDLE ) {
_ChkAlloc( fname, sizeof(INIT_FILE_NAME));
memcpy( fname, INIT_FILE_NAME, sizeof(INIT_FILE_NAME) );
SetCommandFile( file, fname );
}
if( Spawn( DoCmdParse ) ) {
Ignite();
Suicide();
}
GetExtraCommands();
if( !(LinkState & FMT_DECIDED) ) {
/* restrict set to automatically decided ones */
#if defined( __QNX__ )
#define LAST_CHANCE ( MK_OS2_LX | MK_OS2_LE | MK_OS2_NE | MK_QNX )
#elif defined( __LINUX__ )
#define LAST_CHANCE ( MK_OS2_LX | MK_OS2_LE | MK_OS2_NE | MK_ELF )
#elif defined( __NT__ )
#define LAST_CHANCE ( MK_OS2_LX | MK_OS2_NE | MK_WINDOWS | MK_PE | MK_DOS_EXE | MK_WIN_VXD )
#else
#define LAST_CHANCE ( MK_OS2_LX | MK_OS2_LE | MK_OS2_NE | MK_DOS_EXE | MK_PHAR_SIMPLE )
#endif
HintFormat( LAST_CHANCE );
} else {
/* restrict to a unique type */
for( possible = 1; possible != 0; possible *= 2 ) {
if( FmtData.type & possible ) {
FmtData.type = possible;
break;
}
}
}
if( FmtData.type & (MK_NOVELL | MK_DOS) && LinkFlags & INC_LINK_FLAG ) {
LnkMsg( FTL+MSG_FORMAT_BAD_OPTION, "s", "incremental" );
}
#ifdef _NOVELL
if( FmtData.type & MK_NOVELL ) {
CmdNovFini();
} else
#endif
if( FmtData.type & MK_OVERLAYS ) {
CmdOvlFini();
AddObjLib( "wovl.lib", 0 ); // add a reference to wovl.lib
}
if( Name == NULL || !(CmdFlags & CF_HAVE_FILES) ) {
Ignite();
LnkMsg( FTL+MSG_NO_FILES_FOUND, NULL );
}
namelen = strlen( Name );
if( MapFlags & MAP_FLAG ) {
if( MapFName == NULL ) {
MapFName = FileName( Name, (int) namelen, E_MAP, TRUE );
}
} else {
MapFlags = 0; // if main isn't set, don't set anything.
}
if( SymFileName == NULL && (CmdFlags & CF_SEPARATE_SYM ||
(LinkFlags & OLD_DBI_FLAG && FmtData.type & MK_COM)) ) {
SymFileName = FileName( Name, (int) namelen, E_SYM, TRUE );
}
if( FmtData.make_implib && FmtData.implibname == NULL ) {
if( FmtData.make_impfile ) {
extension = E_LBC;
} else {
extension = E_LIBRARY;
}
FmtData.implibname = FileName( Name, (int) namelen, (byte) extension, TRUE );
}
CheckTraces();
BurnUtils();
PruneSystemList();
NumberSections();
DBIInit();
}
extern char * GetNextLink( void )
/*******************************/
{
char * cmd;
cmd = NULL;
_LnkFree( PrevCommand );
if( LinkCommands != NULL ) {
PrevCommand = LinkCommands;
LinkCommands = LinkCommands->next;
cmd = PrevCommand->commands;
}
return cmd;
}
#define PREFIX_SIZE 8
struct extra_cmd_info {
unsigned type;
char prefix[PREFIX_SIZE+1];
bool retry;
};
static struct extra_cmd_info ExtraCmds[] = {
EXTRA_NAME_DIR, "name ", FALSE,
EXTRA_OBJ_FILE, "file ", TRUE,
EXTRA_LIB_FILE, "lib ", TRUE,
EXTRA_RES_FILE, "opt res=", FALSE,
0, "\0", FALSE
};
extern void GetExtraCommands( void )
/**********************************/
{
struct extra_cmd_info const *cmd;
char buff[ _MAX_PATH + PREFIX_SIZE ];
cmd = ExtraCmds;
while( cmd->prefix[0] != '\0' ) {
for(;;) {
memcpy( buff, cmd->prefix, PREFIX_SIZE );
if( !GetAddtlCommand( cmd->type, buff + PREFIX_SIZE ) ) break;
NewCommandSource( NULL, buff, COMMANDLINE );
if( Spawn( DoCmdParse ) ) break;
if( !cmd->retry ) break;
}
cmd++;
}
}
extern void Syntax( void )
/************************/
{
if( Token.this == NULL ) {
LnkMsg( LOC+LINE+FTL+MSG_DIRECTIVE_ERR_BEGINNING, NULL );
} else {
Token.this[Token.len] = '\0';
LnkMsg( LOC+LINE+FTL+MSG_DIRECTIVE_ERR, "s", Token.this );
}
}
static void Crash( bool check_file )
/**********************************/
{
char buff[81];
unsigned len;
f_handle fp;
if( check_file ) {
fp = SearchPath( "wlink.hlp" );
if( fp != NIL_HANDLE ) {
WLPrtBanner();
for( ;; ) {
len = QRead( fp, buff, 80, "wlink.hlp" );
if( len == 0 ) break;
buff[len] = '\0';
WriteStdOut( buff );
}
QClose( fp, "wlink.hlp" );
Ignite();
Suicide();
}
}
DisplayOptions();
Ignite();
Suicide();
}
static void Help( void )
/**********************/
// display help, optionally allowing the user to specifiy the format he/she
// wants the help for.
{
EatWhite();
if( *Token.next == '?' ) {
Crash( FALSE );
} else if( *Token.next == '\0' || !ProcOne( FormatHelp, SEP_NO, FALSE ) ) {
Crash( TRUE );
} else {
Ignite();
Suicide();
}
}
static void DoCmdParse( void )
/****************************/
{
while( GetToken( SEP_END, TOK_INCLUDE_DOT ) == FALSE ) {
if( ProcOne( Directives, SEP_NO, TRUE ) == FALSE ) {
Syntax();
}
RestoreParser();
}
}
static void WriteGenHelp( void )
/******************************/
{
WLPrtBanner();
WriteHelp( MSG_GENERAL_HELP_0, MSG_GENERAL_HELP_51, FALSE );
}
static void DisplayOptions( void )
/********************************/
{
bool isout;
isout = FALSE;
if( CmdFlags & CF_TO_STDOUT ) {
isout = TRUE;
}
WriteGenHelp();
#if defined( _QNXLOAD ) && defined( __QNX__ )
WriteHelp( MSG_QNX_HELP_0, MSG_QNX_HELP_15, isout );
#endif
#ifdef _EXE
WriteHelp( MSG_DOS_HELP_0, MSG_DOS_HELP_15, isout );
#endif
#ifdef _OS2
WriteHelp( MSG_OS2_HELP_0, MSG_OS2_HELP_31, isout );
WriteHelp( MSG_WINDOWS_HELP_0, MSG_WINDOWS_HELP_31, isout );
WriteHelp( MSG_WIN_VXD_HELP_0, MSG_WIN_VXD_HELP_31, isout );
WriteHelp( MSG_NT_HELP_0, MSG_NT_HELP_31, isout );
#endif
#ifdef _PHARLAP
WriteHelp( MSG_PHAR_HELP_0, MSG_PHAR_HELP_15, isout );
#endif
#ifdef _NOVELL
WriteHelp( MSG_NOVELL_HELP_0, MSG_NOVELL_HELP_31, isout );
#endif
#if defined( _QNXLOAD ) && !defined( __QNX__ )
WriteHelp( MSG_QNX_HELP_0, MSG_QNX_HELP_15, isout );
#endif
#ifdef _ELF
WriteHelp( MSG_ELF_HELP_0, MSG_ELF_HELP_15, isout );
#endif
}
#ifdef _EXE
static bool ProcDosHelp( void )
/*****************************/
{
WriteGenHelp();
WriteHelp( MSG_DOS_HELP_0, MSG_DOS_HELP_15, CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
#endif
#ifdef _OS2
static bool ProcOS2Help( void )
/*****************************/
{
WriteGenHelp();
WriteHelp( MSG_OS2_HELP_0, MSG_OS2_HELP_31, CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
static bool ProcWindowsHelp( void )
/*********************************/
{
WriteGenHelp();
WriteHelp( MSG_WINDOWS_HELP_0, MSG_WINDOWS_HELP_31,
CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
static bool ProcWinVxdHelp( void )
/*********************************/
{
WriteGenHelp();
WriteHelp( MSG_WIN_VXD_HELP_0, MSG_WIN_VXD_HELP_31,
CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
static bool ProcNTHelp( void )
/****************************/
{
WriteGenHelp();
WriteHelp( MSG_NT_HELP_0, MSG_NT_HELP_31, CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
#endif
#ifdef _PHARLAP
static bool ProcPharHelp( void )
/******************************/
{
WriteGenHelp();
WriteHelp( MSG_PHAR_HELP_0, MSG_PHAR_HELP_15, CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
#endif
#ifdef _NOVELL
static bool ProcNovellHelp( void )
/********************************/
{
WriteGenHelp();
WriteHelp( MSG_NOVELL_HELP_0, MSG_NOVELL_HELP_31,
CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
#endif
#ifdef _QNXLOAD
static bool ProcQNXHelp( void )
/*******************************/
{
WriteGenHelp();
WriteHelp( MSG_QNX_HELP_0, MSG_QNX_HELP_15, CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
#endif
#ifdef _ELF
static bool ProcELFHelp( void )
/*******************************/
{
WriteGenHelp();
WriteHelp( MSG_ELF_HELP_0, MSG_ELF_HELP_15, CmdFlags & CF_TO_STDOUT );
return( TRUE );
}
#endif
static void PressKey( void );
static void WriteMsg( char msg_buffer[] );
static void WriteHelp( unsigned first_ln, unsigned last_ln, bool prompt )
/***********************************************************************/
{
char msg_buffer[RESOURCE_MAX_SIZE];
int previous_null = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?