2835 lines
89 KiB
C++
2835 lines
89 KiB
C++
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
Copyright (c) 1989-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
cmdana.cxx
|
||
|
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file handles all command (switch) processing for the MIDL compiler.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
|
||
|
Author:
|
||
|
|
||
|
vibhasc
|
||
|
|
||
|
Nov-12-1991 VibhasC Modified to conform to coding style gudelines
|
||
|
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
The command analysis is handled by a command analyser object. The MIDL
|
||
|
compiler registers its arguments with the command analyser and calls the
|
||
|
ProcessArgs functions. The ProcessArgs performs syntactic analysis of the
|
||
|
switch specification by checking for (1) proper switch syntax, (2) duplicate
|
||
|
definition of the switch, and (3) illegal switch specification. After all
|
||
|
the switches are analysed, the SetPostDefault function is called to set the
|
||
|
default compiler switch values etc.
|
||
|
|
||
|
Currently switches fall into these categories:
|
||
|
|
||
|
(1) one-time switches : these can be specified only once, and the
|
||
|
redefinition results in a warning and the second defintion
|
||
|
overrides the first. Examples are -cc_cmd / -cc_opt etc.
|
||
|
|
||
|
(2) multiple definition switches: such switches can be specified
|
||
|
multiple times. These include /I, /D, /U etc.
|
||
|
|
||
|
(3) filename switches : this is switch class specialises in filename
|
||
|
argument handling.
|
||
|
|
||
|
(4) ordinary switches : all other switches fall into this category.
|
||
|
Normally a redef of such a switch is also a warning. These are
|
||
|
different from the one-time switch category just for convenience.
|
||
|
These switches normally set some internal flag etc and do not need
|
||
|
the user specified argument to be stored in string form like
|
||
|
the -cc_cmd etc.
|
||
|
|
||
|
A general word about the command analyser. Switch syntax comes in various
|
||
|
flavours. Some switches take arguments, some do not. Switches which have
|
||
|
arguments may have spaces necesary between the arguments and switch name,
|
||
|
others may not. The most interesting case, however is when the switch
|
||
|
may have as its argument a switch-like specification, which should not be
|
||
|
confused with another MIDL switch. We keep a data-base of switches in the
|
||
|
switch descriptor, which keeps info about the switch name, switch
|
||
|
enumeration and the switch syntax descriptor. The core switch syntax
|
||
|
analyser is BumpThisArg which uses this descriptor.
|
||
|
|
||
|
Also, some switches like -W? and -Wx must really be separate switches
|
||
|
because -W? and -Wx can co-exist at the same time. If we treat the switch
|
||
|
recognition as the same, then the code must detect a separate definition,
|
||
|
and set the command analyser flags.This approach results in unnecessary code
|
||
|
all over the place. An alternative is to recognise the Wx as a separate
|
||
|
switch in the SearchForSwitch routine and return a different switch to
|
||
|
the command analyser. This is a much cleaner approach. Only, the parsing
|
||
|
becomes tricky. Since -W? and -Wx look VERY similar, and SearchForSwitch
|
||
|
stops at the first match, we need to define -Wx BEFORE -W in the switch
|
||
|
descriptor table. This happens also with the client client_env and -server
|
||
|
and -server_env switches. In any case it we remember to properly keep
|
||
|
tables such that the longer string is kept first, this problem gets isolated
|
||
|
to a very small, manageable part of the command analyser. I therefore
|
||
|
chose this approach.
|
||
|
|
||
|
Note: MIDL_INTERNAL is specified by a C preprocessor command line -D option.
|
||
|
This corresponds to debugging builds for internal purposes only.
|
||
|
----------------------------------------------------------------------------*/
|
||
|
|
||
|
#pragma warning ( disable : 4514 4710 )
|
||
|
|
||
|
/****************************************************************************
|
||
|
* include files
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include "cmdline.h"
|
||
|
#include "stream.hxx"
|
||
|
#include "midlvers.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <io.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
/****************************************************************************
|
||
|
* local definitions
|
||
|
***************************************************************************/
|
||
|
|
||
|
/**
|
||
|
** definitions for the type of switch arguments.
|
||
|
** switches may or may not expect arguments, there may be spaces
|
||
|
** between the switch and its argument(s). One special case is when the
|
||
|
** argument can be switch like, .ie have the - or / as the argument starter,
|
||
|
** so we need to treat such switches specially.
|
||
|
**/
|
||
|
|
||
|
#define ARG_NONE (0x01) /* no arg for this switch */
|
||
|
#define ARG_YES (0x02) /* arg expected for this switch */
|
||
|
#define ARG_SPACE (0x04) /* (a) space(s) may be present */
|
||
|
#define ARG_NO_SPACE (0x08) /* no space is allowed */
|
||
|
#define ARG_SWITCH_LIKE (0x10) /* the arg may be switch-like */
|
||
|
#define ARG_OPTIONAL (ARG_YES + ARG_NONE + ARG_SPACE)
|
||
|
|
||
|
|
||
|
#define ARG_SPACED (ARG_YES + ARG_SPACE)
|
||
|
#define ARG_SPACE_NONE (ARG_YES + ARG_NO_SPACE)
|
||
|
#define ARG_SPACE_OPTIONAL (ARG_YES + ARG_NO_SPACE + ARG_SPACE)
|
||
|
#define ARG_CC_ETC (ARG_SPACE_OPTIONAL + ARG_SWITCH_LIKE)
|
||
|
|
||
|
/***
|
||
|
*** Preferably keep this table sorted by name.
|
||
|
*** Also, partially matching names like -client / -client_env, -W/-Wx must
|
||
|
*** be kept so that the longer sub-string appears first. The only
|
||
|
*** reason to keep this sorted, is so that we can visually ensure this.
|
||
|
***/
|
||
|
|
||
|
const struct sw_desc
|
||
|
{
|
||
|
const char * pSwitchName; // switch string
|
||
|
unsigned short flag; // switch descriptor
|
||
|
enum _swenum SwitchValue; // switch enum value
|
||
|
} switch_desc[] = {
|
||
|
{ "", ARG_NONE , SWITCH_NOTHING }
|
||
|
, { "?", ARG_NONE , SWITCH_HELP }
|
||
|
, { "D", ARG_SPACE_OPTIONAL , SWITCH_D }
|
||
|
, { "I", ARG_SPACE_OPTIONAL , SWITCH_I }
|
||
|
, { "O", ARG_SPACE_OPTIONAL , SWITCH_O }
|
||
|
, { "U", ARG_SPACE_OPTIONAL , SWITCH_U }
|
||
|
, { "WX", ARG_NONE , SWITCH_WX }
|
||
|
, { "W", ARG_SPACE_NONE , SWITCH_W }
|
||
|
, { "Zp", ARG_SPACE_NONE , SWITCH_ZP }
|
||
|
, { "Zs", ARG_NONE , SWITCH_ZS }
|
||
|
, { "append64", ARG_NONE , SWITCH_APPEND64 }
|
||
|
, { "acf", ARG_SPACE_OPTIONAL , SWITCH_ACF }
|
||
|
, { "c_ext", ARG_NONE , SWITCH_C_EXT }
|
||
|
, { "char", ARG_SPACED , SWITCH_CHAR }
|
||
|
, { "client", ARG_SPACED , SWITCH_CLIENT }
|
||
|
, { "confirm", ARG_NONE , SWITCH_CONFIRM }
|
||
|
, { "nologo", ARG_NONE , SWITCH_NOLOGO }
|
||
|
, { "cpp_cmd", ARG_CC_ETC , SWITCH_CPP_CMD }
|
||
|
, { "cpp_opt", ARG_CC_ETC , SWITCH_CPP_OPT }
|
||
|
, { "msc_ver", ARG_SPACED , SWITCH_MSC_VER }
|
||
|
, { "cstub", ARG_CC_ETC , SWITCH_CSTUB }
|
||
|
, { "nocstub", ARG_NONE , SWITCH_NO_CLIENT }
|
||
|
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
, { "dump", ARG_NONE , SWITCH_DUMP }
|
||
|
#endif // MIDL_INTERNAL
|
||
|
|
||
|
, { "debugexc", ARG_NONE , SWITCH_DEBUGEXC }
|
||
|
, { "debugline", ARG_NONE , SWITCH_DEBUGLINE }
|
||
|
, { "debug64_opt", ARG_SPACED , SWITCH_DEBUG64_OPT }
|
||
|
, { "debug64", ARG_SPACED , SWITCH_DEBUG64 }
|
||
|
, { "dlldata", ARG_CC_ETC , SWITCH_DLLDATA }
|
||
|
, { "env", ARG_SPACED , SWITCH_ENV }
|
||
|
, { "error", ARG_SPACED , SWITCH_ERROR }
|
||
|
, { "robust", ARG_NONE , SWITCH_ROBUST }
|
||
|
, { "header", ARG_CC_ETC , SWITCH_HEADER }
|
||
|
, { "help", ARG_NONE , SWITCH_HELP }
|
||
|
, { "iid", ARG_CC_ETC , SWITCH_IID }
|
||
|
, { "internal", ARG_NONE , SWITCH_INTERNAL }
|
||
|
, { "lcid", ARG_SPACED , SWITCH_LOCALE_ID }
|
||
|
, { "mktyplib203", ARG_NONE , SWITCH_MKTYPLIB }
|
||
|
, { "newtlb", ARG_NONE , SWITCH_NEW_TLB }
|
||
|
, { "no_cpp", ARG_NONE , SWITCH_NO_CPP }
|
||
|
, { "no_def_idir", ARG_NONE , SWITCH_NO_DEF_IDIR }
|
||
|
, { "no_warn", ARG_NONE , SWITCH_NO_WARN }
|
||
|
, { "use_epv", ARG_NONE , SWITCH_USE_EPV }
|
||
|
, { "no_default_epv",ARG_NONE , SWITCH_NO_DEFAULT_EPV }
|
||
|
, { "no_robust", ARG_NONE , SWITCH_NO_ROBUST }
|
||
|
, { "no_stamp", ARG_NONE , SWITCH_NO_STAMP }
|
||
|
, { "oldnames", ARG_NONE , SWITCH_OLDNAMES }
|
||
|
, { "oldtlb", ARG_NONE , SWITCH_OLD_TLB }
|
||
|
, { "osf", ARG_NONE , SWITCH_OSF }
|
||
|
, { "out", ARG_SPACE_OPTIONAL , SWITCH_OUT }
|
||
|
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
, { "override", ARG_NONE , SWITCH_OVERRIDE }
|
||
|
#endif // MIDL_INTERNAL
|
||
|
|
||
|
, { "pack", ARG_SPACED , SWITCH_PACK }
|
||
|
, { "prefix", ARG_SPACED , SWITCH_PREFIX }
|
||
|
// , { "suffix", ARG_SPACED , SWITCH_SUFFIX }
|
||
|
, { "proxy", ARG_CC_ETC , SWITCH_PROXY }
|
||
|
, { "noproxy", ARG_NONE , SWITCH_NO_PROXY }
|
||
|
, { "proxydef", ARG_CC_ETC , SWITCH_PROXY_DEF }
|
||
|
, { "noproxydef", ARG_NONE , SWITCH_NO_PROXY_DEF }
|
||
|
, { "dlldef", ARG_CC_ETC , SWITCH_DLL_SERVER_DEF }
|
||
|
, { "nodlldef", ARG_NONE , SWITCH_NO_DLL_SERVER_DEF }
|
||
|
, { "dllmain", ARG_CC_ETC , SWITCH_DLL_SERVER_CLASS_GEN }
|
||
|
, { "nodllmain", ARG_NONE , SWITCH_NO_DLL_SERVER_CLASS_GEN }
|
||
|
, { "reg", ARG_CC_ETC , SWITCH_SERVER_REG }
|
||
|
, { "noreg", ARG_NONE , SWITCH_NO_SERVER_REG }
|
||
|
, { "exesuppt", ARG_CC_ETC , SWITCH_EXE_SERVER }
|
||
|
, { "noexesuppt", ARG_NONE , SWITCH_NO_EXE_SERVER }
|
||
|
, { "exemain", ARG_CC_ETC , SWITCH_EXE_SERVER_MAIN }
|
||
|
, { "noexemain", ARG_NONE , SWITCH_NO_EXE_SERVER_MAIN }
|
||
|
, { "testclient", ARG_CC_ETC , SWITCH_TESTCLIENT }
|
||
|
, { "notestclient", ARG_NONE , SWITCH_NO_TESTCLIENT }
|
||
|
, { "methods", ARG_CC_ETC , SWITCH_CLASS_METHODS }
|
||
|
, { "nomethods", ARG_NONE , SWITCH_NO_CLASS_METHODS }
|
||
|
, { "iunknown", ARG_CC_ETC , SWITCH_CLASS_IUNKNOWN }
|
||
|
, { "noiunknown", ARG_NONE , SWITCH_NO_CLASS_IUNKNOWN }
|
||
|
, { "class_hdr", ARG_CC_ETC , SWITCH_CLASS_HEADER }
|
||
|
, { "noclass_hdr", ARG_NONE , SWITCH_NO_CLASS_HEADER }
|
||
|
|
||
|
, { "savePP", ARG_NONE , SWITCH_SAVEPP }
|
||
|
|
||
|
, { "server", ARG_SPACED , SWITCH_SERVER }
|
||
|
, { "sstub", ARG_CC_ETC , SWITCH_SSTUB }
|
||
|
, { "nosstub", ARG_NONE , SWITCH_NO_SERVER }
|
||
|
, { "syntax_check", ARG_NONE , SWITCH_SYNTAX_CHECK }
|
||
|
, { "target", ARG_SPACED , SWITCH_TARGET_SYSTEM }
|
||
|
, { "warn", ARG_SPACED , SWITCH_W }
|
||
|
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
, { "x", ARG_NONE , SWITCH_X }
|
||
|
#endif // MIDL_INTERNAL
|
||
|
|
||
|
, { "ms_ext", ARG_NONE , SWITCH_MS_EXT }
|
||
|
, { "ms_conf_struct",ARG_NONE , SWITCH_MS_CONF_STRUCT }
|
||
|
, { "ms_union", ARG_NONE , SWITCH_MS_UNION }
|
||
|
, { "no_format_opt", ARG_NONE , SWITCH_NO_FMT_OPT }
|
||
|
, { "app_config", ARG_NONE , SWITCH_APP_CONFIG }
|
||
|
, { "rpcss", ARG_NONE , SWITCH_RPCSS }
|
||
|
, { "hookole", ARG_NONE , SWITCH_HOOKOLE }
|
||
|
, { "netmonstub", ARG_CC_ETC , SWITCH_NETMON_STUB_OUTPUT_FILE}
|
||
|
, { "netmonobjstub", ARG_CC_ETC , SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE}
|
||
|
, { "netmon", ARG_NONE , SWITCH_NETMON }
|
||
|
, { "version_stamp", ARG_NONE , SWITCH_VERSION_STAMP }
|
||
|
// MKTYPLIB switches
|
||
|
, { "tlb", ARG_SPACED , SWITCH_TLIB }
|
||
|
, { "o", ARG_SPACED , SWITCH_REDIRECT_OUTPUT }
|
||
|
, { "h", ARG_CC_ETC , SWITCH_HEADER }
|
||
|
, { "align", ARG_SPACE_OPTIONAL , SWITCH_ZP }
|
||
|
, { "nocpp", ARG_NONE , SWITCH_NO_CPP }
|
||
|
, { "wire_compat" ,ARG_SPACED , SWITCH_WIRE_COMPAT }
|
||
|
, { "wi", ARG_SPACE_NONE , SWITCH_ODL_ENV } // win16, win32, win64
|
||
|
, { "do", ARG_SPACE_NONE , SWITCH_ODL_ENV } // dos
|
||
|
, { "ma", ARG_SPACE_NONE , SWITCH_ODL_ENV } // mac
|
||
|
, { "po", ARG_SPACE_NONE , SWITCH_ODL_ENV } // powermac
|
||
|
|
||
|
, { "no_buffer_reuse", ARG_NONE , SWITCH_NOREUSE_BUFFER }
|
||
|
, { "use_vt_int_ptr",ARG_NONE , SWITCH_USE_VT_INT_PTR }
|
||
|
, { "notlb" ,ARG_NONE , SWITCH_NO_TLIB }
|
||
|
, { "protocol" ,ARG_SPACED , SWITCH_TRANSFER_SYNTAX }
|
||
|
, { "ms_ext64" ,ARG_NONE , SWITCH_MS_EXT64 }
|
||
|
, { "debuginfo" ,ARG_NONE , SWITCH_DEBUGINFO }
|
||
|
};
|
||
|
|
||
|
const CHOICE CharChoice[] =
|
||
|
{
|
||
|
{ "signed" , CHAR_SIGNED }
|
||
|
,{ "unsigned" , CHAR_UNSIGNED }
|
||
|
,{ "ascii7" , CHAR_ANSI7 }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE ErrorChoice[] =
|
||
|
{
|
||
|
{ "all" , ERROR_ALL }
|
||
|
,{ "allocation" , ERROR_ALLOCATION }
|
||
|
,{ "bounds_check" , ERROR_BOUNDS_CHECK }
|
||
|
,{ "enum" , ERROR_ENUM }
|
||
|
,{ "ref" , ERROR_REF }
|
||
|
,{ "stub_data" , ERROR_STUB_DATA }
|
||
|
,{ "none" , ERROR_NONE }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE EnvChoice[] =
|
||
|
{
|
||
|
{ "dos" , ENV_OBSOLETE }
|
||
|
,{ "win16" , ENV_OBSOLETE }
|
||
|
,{ "win32" , ENV_WIN32 }
|
||
|
,{ "win64" , ENV_WIN64 }
|
||
|
,{ "mac" , ENV_OBSOLETE }
|
||
|
,{ "powermac" , ENV_OBSOLETE }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE SyntaxChoice[] =
|
||
|
{
|
||
|
{ "dce" , SYNTAX_DCE }
|
||
|
,{ "ndr64" , SYNTAX_NDR64 }
|
||
|
,{ "all" , SYNTAX_BOTH }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE TargetChoice[] =
|
||
|
{
|
||
|
{ "NT40" , NT40 }
|
||
|
,{ "NT50" , NT50 }
|
||
|
,{ "NT51" , NT51 }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE ClientChoice[] =
|
||
|
{
|
||
|
{ "stub" , CLNT_STUB }
|
||
|
,{ "none" , CLNT_NONE }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE ServerChoice[] =
|
||
|
{
|
||
|
{ "stub" , SRVR_STUB }
|
||
|
,{ "none" , SRVR_NONE }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
const CHOICE WireCompatChoice[] =
|
||
|
{
|
||
|
{ "enum16unionalign", WIRE_COMPAT_ENUM16UNIONALIGN }
|
||
|
,{ 0 , 0 }
|
||
|
};
|
||
|
|
||
|
|
||
|
#define IS_NUMERIC_1( pThisArg ) ((strlen( pThisArg) == 1 ) && \
|
||
|
(isdigit( *pThisArg )) )
|
||
|
|
||
|
// this is now the same for ALL platforms
|
||
|
#define C_COMPILER_NAME() ("cl.exe")
|
||
|
#define C_PREPROCESSOR_NAME() ("cl.exe")
|
||
|
#define ADDITIONAL_CPP_OPT() (" -E -nologo")
|
||
|
|
||
|
#define MIDL_HELP_FILE_NAME ("midl.hlp")
|
||
|
|
||
|
/****************************************************************************
|
||
|
* local data
|
||
|
***************************************************************************/
|
||
|
|
||
|
/****************************************************************************
|
||
|
* externs
|
||
|
***************************************************************************/
|
||
|
|
||
|
|
||
|
extern void ReportUnimplementedSwitch( short );
|
||
|
extern char * SwitchStringForValue( unsigned short );
|
||
|
extern _swenum SearchForSwitch( char ** );
|
||
|
extern STATUS_T SelectChoice( const CHOICE *, char *, short *);
|
||
|
extern bool PPCmdEngine( int argc, char *argv[], IDICT * );
|
||
|
|
||
|
extern void PrintArg( enum _swenum, char *, char * );
|
||
|
|
||
|
void CmdProcess( pair_switch*, CommandLine*, char* );
|
||
|
/****************************************************************************/
|
||
|
|
||
|
void
|
||
|
CommandLine::RegisterArgs(
|
||
|
char * pArgs[],
|
||
|
short cArguments
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine registers with the command analyser the argument vector
|
||
|
and argument count for user supplied arguments.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pArgs - Array of pointers to arguments ( switches etc ).
|
||
|
cArguments - count of arguments.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
The process of registering the arguments consists of keeping a local
|
||
|
copy of the argument vector pointer and count.
|
||
|
|
||
|
The argument vector is passed such that the argv[1] is the first
|
||
|
argument available to the command processor. Therefore , count is
|
||
|
one less too.
|
||
|
|
||
|
Why do we need registering the arguments ? In the process of parsing
|
||
|
we might want to skip an argument back or forward. So we keep a local
|
||
|
copy of the pointer to the arguments.
|
||
|
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
iArgV = 0;
|
||
|
pArgDict= new IDICT( 10, 5 );
|
||
|
fShowLogo = PPCmdEngine( cArguments, pArgs, pArgDict );
|
||
|
cArgs = pArgDict->GetCurrentSize();
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
CommandLine::GetNextArg()
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Get the next argument in the argument vector.
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
returns a pointer to the next argument.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
if no more arguments
|
||
|
return a null.
|
||
|
else
|
||
|
return the next argument pointer.
|
||
|
decrement the count, increment the pointer to point to the next arg.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
if(cArgs == 0 )
|
||
|
return (char *)NULL;
|
||
|
cArgs--;
|
||
|
return (char *)pArgDict->GetElement( (IDICTKEY)iArgV++);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CommandLine::UndoGetNextArg()
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Undo the effect of the last GetNextArg call.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
if this is not the first argument already
|
||
|
Push back the argument pointer.
|
||
|
Increment count.
|
||
|
else
|
||
|
Do nothing.
|
||
|
|
||
|
This prepares the argument vector to accept more GetNextArgCalls.
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
if(iArgV == 0)
|
||
|
return;
|
||
|
cArgs++;
|
||
|
iArgV--;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::ProcessArgs()
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Process command line arguments.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
STATUS_OK - if all is well
|
||
|
Error Status otherwise.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
char * pThisArg,
|
||
|
* pThisArgSave;
|
||
|
STATUS_T Status, ReturnStatus = STATUS_OK;
|
||
|
enum _swenum iSwitch;
|
||
|
short fSwitchDetected;
|
||
|
unsigned short SwitchValue;
|
||
|
|
||
|
|
||
|
// loop till all arguments have been processed.
|
||
|
|
||
|
while ( ( pThisArg = GetNextArg() ) != 0 )
|
||
|
{
|
||
|
|
||
|
fSwitchDetected = 0;
|
||
|
iSwitch = SWITCH_NOTHING;
|
||
|
|
||
|
// save this pointer, it is useful for error reporting.
|
||
|
|
||
|
pThisArgSave = pThisArg;
|
||
|
|
||
|
// if we saw a - or a / we have detected a switch. Get the index of
|
||
|
// the switch in the switch descriptor table. If the returned index
|
||
|
// was zero, either the switch was not a valid one, or we saw an input
|
||
|
// which is taken as an input filename specification. If the input
|
||
|
// filename has already been specified, this is an error.
|
||
|
|
||
|
if( *pThisArg == '-' || *pThisArg == '/' )
|
||
|
{
|
||
|
pThisArg++;
|
||
|
fSwitchDetected = 1;
|
||
|
iSwitch = SearchForSwitch( &pThisArg );
|
||
|
}
|
||
|
|
||
|
if( iSwitch == SWITCH_NOTHING )
|
||
|
{
|
||
|
|
||
|
if( fSwitchDetected || IsSwitchDefined( BASE_FILENAME ) )
|
||
|
{
|
||
|
char * p = new char[ strlen(pThisArg)+2+1 ];
|
||
|
|
||
|
sprintf(p, "\"%s\"", pThisArg );
|
||
|
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
fSwitchDetected ? UNKNOWN_SWITCH : UNKNOWN_ARGUMENT,
|
||
|
p);
|
||
|
|
||
|
delete p;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// the only way we can get here is if he did not specify a
|
||
|
// switch like input AND the input filename has not been
|
||
|
// defined yet. Hence this must be the input filename.
|
||
|
|
||
|
pInputFNSwitch = new filename_switch( pThisArg);
|
||
|
|
||
|
SwitchDefined( BASE_FILENAME );
|
||
|
|
||
|
}
|
||
|
|
||
|
continue;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// bump the input pointer to point to the argument. Depending on
|
||
|
// what type of argument this switch takes ( spaced, non-spaced,
|
||
|
// switch-like etc ) bump the argument pointer to the actual argument.
|
||
|
|
||
|
SwitchValue = unsigned short ( switch_desc[ iSwitch ].SwitchValue );
|
||
|
|
||
|
Status = BumpThisArg( &pThisArg, switch_desc[ iSwitch ].flag );
|
||
|
|
||
|
if( Status != STATUS_OK )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
Status,
|
||
|
pThisArgSave );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
MIDL_ASSERT(NULL != pThisArg);
|
||
|
|
||
|
// Process the switch. The input pointer is pointing to the
|
||
|
// argument to the switch, after the '-' or '/'.
|
||
|
|
||
|
switch( SwitchValue )
|
||
|
{
|
||
|
case SWITCH_CSTUB:
|
||
|
case SWITCH_HEADER:
|
||
|
case SWITCH_ACF:
|
||
|
case SWITCH_SSTUB:
|
||
|
case SWITCH_OUT:
|
||
|
case SWITCH_IID:
|
||
|
case SWITCH_PROXY:
|
||
|
case SWITCH_TESTCLIENT:
|
||
|
case SWITCH_CLASS_METHODS:
|
||
|
case SWITCH_CLASS_HEADER:
|
||
|
case SWITCH_CLASS_IUNKNOWN:
|
||
|
case SWITCH_PROXY_DEF:
|
||
|
case SWITCH_DLL_SERVER_DEF:
|
||
|
case SWITCH_DLL_SERVER_CLASS_GEN:
|
||
|
case SWITCH_SERVER_REG:
|
||
|
case SWITCH_EXE_SERVER:
|
||
|
case SWITCH_EXE_SERVER_MAIN:
|
||
|
case SWITCH_DLLDATA:
|
||
|
case SWITCH_TLIB:
|
||
|
case SWITCH_REDIRECT_OUTPUT:
|
||
|
case SWITCH_NETMON_STUB_OUTPUT_FILE:
|
||
|
case SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE:
|
||
|
Status = ProcessFilenameSwitch( SwitchValue, pThisArg );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_LOCALE_ID:
|
||
|
case SWITCH_PACK:
|
||
|
case SWITCH_ZP:
|
||
|
case SWITCH_NO_WARN:
|
||
|
case SWITCH_USE_EPV:
|
||
|
case SWITCH_NO_DEFAULT_EPV:
|
||
|
case SWITCH_DEBUGEXC:
|
||
|
case SWITCH_DEBUGLINE:
|
||
|
case SWITCH_SYNTAX_CHECK:
|
||
|
case SWITCH_ZS:
|
||
|
case SWITCH_NO_CPP:
|
||
|
case SWITCH_CLIENT:
|
||
|
case SWITCH_SERVER:
|
||
|
case SWITCH_ENV:
|
||
|
case SWITCH_TARGET_SYSTEM:
|
||
|
case SWITCH_RPCSS:
|
||
|
case SWITCH_NETMON:
|
||
|
case SWITCH_VERSION_STAMP:
|
||
|
case SWITCH_DUMP:
|
||
|
case SWITCH_OVERRIDE:
|
||
|
case SWITCH_SAVEPP:
|
||
|
case SWITCH_NO_DEF_IDIR:
|
||
|
case SWITCH_VERSION:
|
||
|
case SWITCH_CONFIRM:
|
||
|
case SWITCH_NOLOGO:
|
||
|
case SWITCH_CHAR:
|
||
|
case SWITCH_HELP:
|
||
|
case SWITCH_W:
|
||
|
case SWITCH_WX:
|
||
|
case SWITCH_X:
|
||
|
case SWITCH_O:
|
||
|
case SWITCH_APPEND64:
|
||
|
case SWITCH_APP_CONFIG:
|
||
|
case SWITCH_MS_EXT:
|
||
|
case SWITCH_MS_CONF_STRUCT:
|
||
|
case SWITCH_MS_UNION:
|
||
|
case SWITCH_OLDNAMES:
|
||
|
case SWITCH_NO_FMT_OPT:
|
||
|
case SWITCH_GUARD_DEFS:
|
||
|
case SWITCH_INTERNAL:
|
||
|
case SWITCH_NO_STAMP:
|
||
|
case SWITCH_ROBUST:
|
||
|
case SWITCH_NO_ROBUST:
|
||
|
case SWITCH_C_EXT:
|
||
|
case SWITCH_OSF:
|
||
|
case SWITCH_MKTYPLIB:
|
||
|
case SWITCH_OLD_TLB:
|
||
|
case SWITCH_NEW_TLB:
|
||
|
case SWITCH_NOREUSE_BUFFER:
|
||
|
case SWITCH_USE_VT_INT_PTR:
|
||
|
case SWITCH_NO_TLIB:
|
||
|
case SWITCH_TRANSFER_SYNTAX:
|
||
|
case SWITCH_MS_EXT64:
|
||
|
case SWITCH_DEBUGINFO:
|
||
|
Status = ProcessOrdinarySwitch( SwitchValue, pThisArg );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_ODL_ENV:
|
||
|
Status = ProcessOrdinarySwitch( SwitchValue, pThisArg );
|
||
|
SwitchValue = SWITCH_ENV;
|
||
|
break;
|
||
|
|
||
|
case SWITCH_ERROR:
|
||
|
case SWITCH_WIRE_COMPAT:
|
||
|
Status = ProcessSimpleMultipleSwitch( SwitchValue, pThisArg );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_D:
|
||
|
case SWITCH_I:
|
||
|
case SWITCH_U:
|
||
|
|
||
|
// specifically for -D/-I/-U we want the two characters
|
||
|
// -I / -D / -U inside too, so that we can pass it as such to
|
||
|
// the c preprocessor.
|
||
|
|
||
|
Status = ProcessMultipleSwitch( SwitchValue, pThisArgSave, pThisArg );
|
||
|
break;
|
||
|
|
||
|
|
||
|
case SWITCH_MSC_VER:
|
||
|
case SWITCH_CPP_CMD:
|
||
|
case SWITCH_CPP_OPT:
|
||
|
case SWITCH_DEBUG64_OPT:
|
||
|
case SWITCH_DEBUG64:
|
||
|
Status = ProcessOnetimeSwitch( SwitchValue, pThisArg );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_PREFIX:
|
||
|
|
||
|
CmdProcess( pSwitchPrefix, this, pThisArg );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_HOOKOLE:
|
||
|
RpcError( NULL, 0, SWITCH_NOT_SUPPORTED_ANYMORE, "hookole" );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
ReportUnimplementedSwitch( SwitchValue );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// set up the defintion vector, to indicate that the switch has been
|
||
|
// defined.
|
||
|
|
||
|
if( Status == ILLEGAL_ARGUMENT )
|
||
|
ReturnStatus = ILLEGAL_ARGUMENT;
|
||
|
|
||
|
SwitchDefined( SwitchValue );
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!IsSwitchDefined(SWITCH_OSF))
|
||
|
{
|
||
|
SwitchDefined(SWITCH_C_EXT);
|
||
|
SwitchDefined(SWITCH_MS_EXT);
|
||
|
}
|
||
|
|
||
|
// if the user has asked for output to be redirected, redirect stdout
|
||
|
if (IsSwitchDefined(SWITCH_REDIRECT_OUTPUT))
|
||
|
{
|
||
|
FILE * pFH;
|
||
|
char * newfile = pRedirectOutputSwitch->GetFileName();
|
||
|
|
||
|
if ( HasAppend64() || Is2ndCodegenRun() )
|
||
|
{
|
||
|
pFH = freopen(newfile, "r+", stdout);
|
||
|
|
||
|
if ( pFH )
|
||
|
{
|
||
|
if ( 0 != fseek( pFH, 0, SEEK_END ) )
|
||
|
RpcError( NULL, 0, ERROR_OPENING_FILE, newfile );
|
||
|
}
|
||
|
else
|
||
|
pFH = freopen(newfile, "a+", stdout);
|
||
|
}
|
||
|
else
|
||
|
pFH = freopen(newfile, "w", stdout);
|
||
|
|
||
|
if ( NULL == pFH )
|
||
|
RpcError( NULL, 0, ERROR_OPENING_FILE, newfile );
|
||
|
}
|
||
|
|
||
|
// if he has not specified the input filename, report
|
||
|
// error, but only if the confirm switch is not specified. If it is,
|
||
|
// processing will not occur anyway.
|
||
|
|
||
|
if(!IsSwitchDefined(BASE_FILENAME) )
|
||
|
{
|
||
|
if( IsSwitchDefined( SWITCH_CONFIRM ) )
|
||
|
{
|
||
|
pInputFNSwitch = new filename_switch( "sample.idl");
|
||
|
SwitchDefined( BASE_FILENAME );
|
||
|
}
|
||
|
else if( IsSwitchDefined( SWITCH_HELP ))
|
||
|
return STATUS_OK;
|
||
|
else
|
||
|
{
|
||
|
RpcError((char *)NULL,0,NO_INPUT_FILE, (char *)NULL);
|
||
|
return NO_INPUT_FILE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// set post switch processing defaults
|
||
|
|
||
|
ReturnStatus = SetPostDefaults();
|
||
|
|
||
|
return ReturnStatus;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::BumpThisArg(
|
||
|
char ** ppArg,
|
||
|
unsigned short flag
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Bump the argument pointer to the start of the argument that this switch
|
||
|
expects.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ppArg - pointer to the argument pointer.
|
||
|
flag - descriptor of the type of argument expected by the switch.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ILLEGAL_ARGUMENT - if the switch did not expect this argument
|
||
|
BAD_SWITCH_SYNTAX - if the switch + arg. syntax is improper.
|
||
|
MISSING_ARGUMENT - a mandatory arg. is missing.
|
||
|
STATUS_OK - evrything is hunky dory.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
In the routine below, fHasImmediateArg is a flag which is true if the
|
||
|
switch argument follws the switch name without any spaces in between.
|
||
|
Optional space is indicated in the switch descriptor as ARG_SPACE +
|
||
|
ARG_NO_SPACE, so it gets reflected in fSpaceOptional as fMustNotHaveSpace
|
||
|
&& fMustHaveSpace.
|
||
|
|
||
|
Other flags have self-explanatory names.
|
||
|
|
||
|
This routine forms the core syntax checker for the switches.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
char * pArg = *ppArg;
|
||
|
BOOL fMustHaveArg = (BOOL) !(flag & ARG_NONE);
|
||
|
BOOL fOptionalArg = (flag & ARG_NONE) && (flag & ARG_YES);
|
||
|
BOOL fMustHaveSpace = (BOOL) ((flag & ARG_SPACE) != 0 );
|
||
|
BOOL fMustNotHaveSpace = (BOOL) ((flag & ARG_NO_SPACE) != 0 );
|
||
|
BOOL fSpaceOptional = (BOOL) (fMustNotHaveSpace &&
|
||
|
fMustHaveSpace );
|
||
|
BOOL fSwitchLike = (BOOL) ((flag & ARG_SWITCH_LIKE) != 0 );
|
||
|
BOOL fHasImmediateArg = (*pArg != 0);
|
||
|
BOOL fMustGetNextArg = FALSE;
|
||
|
|
||
|
|
||
|
// first deal with the case of the switch having an optional argument.
|
||
|
// If the switch has an optional argument, then check the next argument
|
||
|
// to see if it is switch like. If it is, then this switch was specified
|
||
|
// without an argument. If it is not, then the next argument is taken to
|
||
|
// be the argument for the switch.
|
||
|
|
||
|
if( fOptionalArg )
|
||
|
{
|
||
|
|
||
|
pArg = GetNextArg();
|
||
|
if(!fSwitchLike && pArg && ((*pArg == '-') || (*pArg == '/') ) )
|
||
|
{
|
||
|
UndoGetNextArg();
|
||
|
pArg = (char *)0;
|
||
|
}
|
||
|
*ppArg = pArg;
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
// if the switch must not have an immediate argument and has one,
|
||
|
// it is an error.
|
||
|
|
||
|
if( !fMustHaveArg && fHasImmediateArg )
|
||
|
|
||
|
return ILLEGAL_ARGUMENT;
|
||
|
|
||
|
else if ( fMustHaveArg )
|
||
|
{
|
||
|
|
||
|
// if it needs an argument, and has an immediate argument, it is bad
|
||
|
// if the switch must have space.
|
||
|
|
||
|
if( fHasImmediateArg )
|
||
|
{
|
||
|
|
||
|
if( fMustHaveSpace && !fSpaceOptional )
|
||
|
return BAD_SWITCH_SYNTAX;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// This is the case when the switch must have an argument and
|
||
|
// does not seem to have an immediate argument. This is fine only
|
||
|
// if space was either optional or expected. In either case, we must
|
||
|
// assume that the next argument is the argument for this switch.
|
||
|
|
||
|
// If switch must not have any space then this is a case of
|
||
|
// bad switch syntax.
|
||
|
|
||
|
|
||
|
if( fSpaceOptional || fMustHaveSpace )
|
||
|
fMustGetNextArg = TRUE;
|
||
|
else
|
||
|
return BAD_SWITCH_SYNTAX;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( fMustGetNextArg )
|
||
|
{
|
||
|
|
||
|
// we arrive here if the switch expects an argument and
|
||
|
// space between the switch and the argument is optional.
|
||
|
|
||
|
// Note that the flag fHasImmediateArg now specifies whether
|
||
|
// the argument is present at all.
|
||
|
|
||
|
pArg = GetNextArg();
|
||
|
|
||
|
fHasImmediateArg = (BOOL) ( pArg && (*pArg != 0) );
|
||
|
|
||
|
if( fHasImmediateArg )
|
||
|
{
|
||
|
|
||
|
// we got the next argument.
|
||
|
// If we get something that looks like a switch, and this switch
|
||
|
// does not expect switch_like arguments, then this is illegal
|
||
|
// argument for the switch.
|
||
|
|
||
|
if(!fSwitchLike && ((*pArg == '-') || (*pArg == '/') ) )
|
||
|
{
|
||
|
UndoGetNextArg();
|
||
|
return ILLEGAL_ARGUMENT;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
// well, we expect an argument, and didnt get one. He just
|
||
|
// shot himself is all I can say.
|
||
|
|
||
|
return MISSING_ARG;
|
||
|
}
|
||
|
|
||
|
// we have found the right argument.
|
||
|
|
||
|
*ppArg = pArg;
|
||
|
|
||
|
// finally ! out of this mess.
|
||
|
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::ProcessOnetimeSwitch(
|
||
|
short SwitchNo,
|
||
|
char * pThisArg
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Process a onetime switch.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SwitchNo - switch number being processed.
|
||
|
pThisArg - pointer to the argument for this switch.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
Check for duplicate definition of this switch. If there is a duplicate
|
||
|
definition, override the previous one after warning him.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
onetime_switch ** ppSSwitch;
|
||
|
|
||
|
switch( SwitchNo )
|
||
|
{
|
||
|
case SWITCH_CPP_CMD: ppSSwitch = &pCppCmdSwitch; break;
|
||
|
case SWITCH_CPP_OPT: ppSSwitch = &pCppOptSwitch; break;
|
||
|
case SWITCH_MSC_VER:
|
||
|
ppSSwitch = &pMSCVerSwitch;
|
||
|
MSCVersion = (unsigned short) atoi( pThisArg );
|
||
|
break;
|
||
|
case SWITCH_DEBUG64: ppSSwitch = &pDebug64Switch; break;
|
||
|
case SWITCH_DEBUG64_OPT:ppSSwitch = &pDebug64OptSwitch; break;
|
||
|
default: return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
if( IsSwitchDefined(SwitchNo) )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
SWITCH_REDEFINED,
|
||
|
SwitchStringForValue( SwitchNo ) );
|
||
|
|
||
|
delete *ppSSwitch;
|
||
|
}
|
||
|
|
||
|
(*ppSSwitch) = new onetime_switch( pThisArg );
|
||
|
return STATUS_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::ProcessMultipleSwitch(
|
||
|
short SwitchNo,
|
||
|
char * pThisArg,
|
||
|
char * pActualArg
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Process a multiple occurrence switch.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SwitchNo - switch number being processed.
|
||
|
pThisArg - pointer to the argument for this switch.
|
||
|
pActualArg - pointer to the actual argument to -I/-D etc
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
Multiple specifications can occur. Dont check for duplicate definitions.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
|
||
|
char * pTemp = pThisArg;
|
||
|
multiple_switch ** ppMSwitch;
|
||
|
|
||
|
switch( SwitchNo )
|
||
|
{
|
||
|
case SWITCH_D: ppMSwitch = &pDSwitch; break;
|
||
|
case SWITCH_I: ppMSwitch = &pISwitch; break;
|
||
|
case SWITCH_U: ppMSwitch = &pUSwitch; break;
|
||
|
default: return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
// now set the switches. Space is optional
|
||
|
// If no space exists between the -I/-D value of pActualArg will point to
|
||
|
// the byte next to the end of -I/-D etc. If there is at least one space,
|
||
|
// the pActualArg will point further away. This fact can be used to decide
|
||
|
// how the argument needs to be presented to the c preprocessor.
|
||
|
// If we need the space, then create a new buffer with the space between the
|
||
|
// -I/-D etc.
|
||
|
|
||
|
// I assume the assumptions above will hold true even for segmented
|
||
|
// architectures.
|
||
|
|
||
|
size_t ActualArgOffset = pActualArg - pThisArg;
|
||
|
|
||
|
if( ( pActualArg - (pThisArg+2) ) != 0 )
|
||
|
{
|
||
|
|
||
|
// we need a space
|
||
|
ActualArgOffset = strlen( pThisArg ) + 1; // 1 for space
|
||
|
pTemp = new char [ ActualArgOffset +
|
||
|
strlen( pActualArg ) +
|
||
|
1 // 1 for terminator.
|
||
|
];
|
||
|
sprintf( pTemp, "%s %s", pThisArg, pActualArg );
|
||
|
}
|
||
|
|
||
|
if(!(*ppMSwitch) )
|
||
|
*ppMSwitch = new multiple_switch( pTemp, ActualArgOffset );
|
||
|
else
|
||
|
(*ppMSwitch)->Add( pTemp, ActualArgOffset );
|
||
|
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::ProcessFilenameSwitch(
|
||
|
short SwitchNo,
|
||
|
char * pThisArg
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Process a filename switch.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SwitchNo - switch number being processed.
|
||
|
pThisArg - pointer to the argument for this switch.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
STATUS_OK if all is well, error otherwise.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
This is like a single occurrence switch too. Warn if duplicate definition
|
||
|
and override the previous specification.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
|
||
|
filename_switch ** ppFNSwitch;
|
||
|
BOOL fCheck = TRUE;
|
||
|
char agBaseName[ _MAX_FNAME ];
|
||
|
|
||
|
switch( SwitchNo )
|
||
|
{
|
||
|
case SWITCH_CSTUB: ppFNSwitch = &pCStubSwitch; break;
|
||
|
case SWITCH_HEADER: ppFNSwitch = &pHeaderSwitch; break;
|
||
|
case SWITCH_ACF: ppFNSwitch = &pAcfSwitch; break;
|
||
|
case SWITCH_SSTUB: ppFNSwitch = &pSStubSwitch; break;
|
||
|
case SWITCH_OUT: ppFNSwitch = &pOutputPathSwitch; fCheck=FALSE; break;
|
||
|
case SWITCH_IID: ppFNSwitch = &pIIDSwitch; break;
|
||
|
case SWITCH_PROXY: ppFNSwitch = &pProxySwitch; break;
|
||
|
case SWITCH_DLLDATA: ppFNSwitch = &pDllDataSwitch; break;
|
||
|
case SWITCH_TLIB: ppFNSwitch = &pTlibSwitch; break;
|
||
|
case SWITCH_REDIRECT_OUTPUT: ppFNSwitch = &pRedirectOutputSwitch; break;
|
||
|
case SWITCH_NETMON_STUB_OUTPUT_FILE: ppFNSwitch = &pNetmonStubSwitch; break;
|
||
|
case SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE: ppFNSwitch = &pNetmonStubObjSwitch; break;
|
||
|
default: return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
if( IsSwitchDefined(SwitchNo) )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
SWITCH_REDEFINED,
|
||
|
SwitchStringForValue( SwitchNo ) );
|
||
|
|
||
|
delete *ppFNSwitch;
|
||
|
}
|
||
|
|
||
|
(*ppFNSwitch) = new filename_switch( pThisArg );
|
||
|
|
||
|
// check for validity of the switch. All switches other than the
|
||
|
// out switch must have a base name specified.
|
||
|
|
||
|
if( fCheck )
|
||
|
{
|
||
|
(*ppFNSwitch)->GetFileNameComponents( (char *)NULL,
|
||
|
(char *)NULL,
|
||
|
agBaseName,
|
||
|
(char *)NULL );
|
||
|
|
||
|
if( agBaseName[ 0 ] == '\0' )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
ILLEGAL_ARGUMENT,
|
||
|
SwitchStringForValue( SwitchNo ) );
|
||
|
}
|
||
|
}
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::ProcessOrdinarySwitch(
|
||
|
short SWValue,
|
||
|
char * pThisArg
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
process ordinary switch catrgory.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SWValue - switch value
|
||
|
pThisArg - the users argument to this switch.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
check and warn for redefinition of the switch. Switch Warn is a special
|
||
|
case, the warn can be redefined. The last specified warning level is
|
||
|
valid.
|
||
|
|
||
|
Generally we let the user who redefines a switch off the hook. When the
|
||
|
arguments to a switch are wrong, we report an error and return an illegal
|
||
|
argument status.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
short Temp;
|
||
|
STATUS_T Status = STATUS_OK;
|
||
|
|
||
|
if( IsSwitchDefined( SWValue ) && (SWValue != SWITCH_O) )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
SWITCH_REDEFINED,
|
||
|
SwitchStringForValue( SWValue ) );
|
||
|
}
|
||
|
|
||
|
switch( SWValue )
|
||
|
{
|
||
|
case SWITCH_PACK:
|
||
|
SwitchDefined( SWITCH_ZP );
|
||
|
// fall through
|
||
|
case SWITCH_ZP:
|
||
|
{
|
||
|
int TempZeePee = atoi( pThisArg );
|
||
|
if (!TempZeePee || !IsValidZeePee( TempZeePee ) )
|
||
|
goto illarg;
|
||
|
ZeePee = (unsigned short)TempZeePee;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SWITCH_LOCALE_ID:
|
||
|
|
||
|
SwitchDefined( SWITCH_LOCALE_ID );
|
||
|
LocaleId = atoi( pThisArg );
|
||
|
/*
|
||
|
if ( ! CurrentCharSet.SetDbcsLeadByteTable( LocaleId ) )
|
||
|
{
|
||
|
char temp[20];
|
||
|
|
||
|
sprintf( temp, "%d", LocaleId );
|
||
|
RpcError( NULL, 0, INVALID_LOCALE_ID, temp );
|
||
|
}
|
||
|
*/
|
||
|
break;
|
||
|
|
||
|
case SWITCH_W:
|
||
|
|
||
|
// warning level of 0 specifies no warnings.
|
||
|
|
||
|
Temp = short( *pThisArg - '0' );
|
||
|
|
||
|
if( ( !IS_NUMERIC_1( pThisArg ) ) ||
|
||
|
( Temp > WARN_LEVEL_MAX ) )
|
||
|
goto illarg;
|
||
|
|
||
|
WLevel = Temp;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case SWITCH_O:
|
||
|
{
|
||
|
if ( ! *pThisArg )
|
||
|
goto illarg;
|
||
|
|
||
|
if ( OptimFlags &
|
||
|
(OPTIMIZE_SIZE | OPTIMIZE_ANY_INTERPRETER) )
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
SWITCH_REDEFINED,
|
||
|
SwitchStringForValue( SWValue ) );
|
||
|
|
||
|
if ( strcmp( pThisArg, "s" ) == 0 )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_SIZE );
|
||
|
OptimLevel = OPT_LEVEL_OS;
|
||
|
}
|
||
|
else if ( strcmp( pThisArg, "i" ) == 0 )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_INTERPRETER );
|
||
|
OptimLevel = OPT_LEVEL_OI;
|
||
|
}
|
||
|
else if ( strcmp( pThisArg, "ic" ) == 0 )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OIC;
|
||
|
RpcError( 0, 0, OIC_SUPPORT_PHASED_OUT, "Oi1");
|
||
|
}
|
||
|
else if ( strcmp( pThisArg, "i1" ) == 0 )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OIC;
|
||
|
RpcError( NULL, 0, CMD_OI1_PHASED_OUT, "Oi1");
|
||
|
}
|
||
|
else if ( strcmp( pThisArg, "icf" ) == 0 ||
|
||
|
strcmp( pThisArg, "if" ) == 0 )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OICF;
|
||
|
}
|
||
|
else if ( strcmp( pThisArg, "i2" ) == 0 )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OICF;
|
||
|
RpcError( NULL, 0, CMD_OI2_OBSOLETE, "Oi2");
|
||
|
}
|
||
|
else
|
||
|
goto illarg;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SWITCH_ODL_ENV:
|
||
|
pThisArg -= 2; // back up past the first three characters of the switch "win"
|
||
|
SWValue = SWITCH_ENV; // to ensure that the right thing gets reported if an error occurs
|
||
|
// fall through to SWITCH_ENV
|
||
|
|
||
|
case SWITCH_ENV:
|
||
|
|
||
|
if( SelectChoice( EnvChoice,pThisArg, &Temp ) != STATUS_OK )
|
||
|
goto illarg;
|
||
|
|
||
|
Env = (unsigned char) Temp;
|
||
|
|
||
|
if (ENV_OBSOLETE == Env)
|
||
|
RpcError( NULL, 0, SWITCH_NOT_SUPPORTED_ANYMORE, pThisArg );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case SWITCH_TARGET_SYSTEM:
|
||
|
|
||
|
if( SelectChoice( TargetChoice, pThisArg, &Temp ) != STATUS_OK )
|
||
|
goto illarg;
|
||
|
TargetSystem = (TARGET_ENUM) Temp;
|
||
|
GetNdrVersionControl().SetTargetSystem(TargetSystem);
|
||
|
break;
|
||
|
|
||
|
case SWITCH_TRANSFER_SYNTAX:
|
||
|
if ( SelectChoice( SyntaxChoice, pThisArg, &Temp ) != STATUS_OK )
|
||
|
goto illarg;
|
||
|
TargetSyntax = (SYNTAX_ENUM) Temp;
|
||
|
break;
|
||
|
|
||
|
case SWITCH_NO_WARN:
|
||
|
|
||
|
WLevel = 0; // was WARN_LEVEL_MAX
|
||
|
break;
|
||
|
|
||
|
case SWITCH_INTERNAL:
|
||
|
RpcError( 0, 0, INTERNAL_SWITCH_USED, NULL );
|
||
|
|
||
|
case SWITCH_NO_STAMP:
|
||
|
case SWITCH_NETMON:
|
||
|
case SWITCH_VERSION_STAMP:
|
||
|
case SWITCH_DEBUGEXC:
|
||
|
case SWITCH_DEBUGLINE:
|
||
|
case SWITCH_SYNTAX_CHECK:
|
||
|
case SWITCH_ZS:
|
||
|
case SWITCH_NO_CPP:
|
||
|
case SWITCH_SAVEPP:
|
||
|
case SWITCH_DUMP:
|
||
|
case SWITCH_OVERRIDE:
|
||
|
case SWITCH_NO_DEF_IDIR:
|
||
|
case SWITCH_USE_EPV:
|
||
|
case SWITCH_NO_DEFAULT_EPV:
|
||
|
case SWITCH_VERSION:
|
||
|
case SWITCH_CONFIRM:
|
||
|
case SWITCH_NOLOGO:
|
||
|
case SWITCH_HELP:
|
||
|
case SWITCH_WX:
|
||
|
case SWITCH_X:
|
||
|
case SWITCH_APPEND64:
|
||
|
case SWITCH_APP_CONFIG:
|
||
|
case SWITCH_MS_EXT:
|
||
|
case SWITCH_MS_CONF_STRUCT:
|
||
|
case SWITCH_MS_UNION:
|
||
|
case SWITCH_OLDNAMES:
|
||
|
case SWITCH_NO_FMT_OPT:
|
||
|
case SWITCH_GUARD_DEFS:
|
||
|
case SWITCH_C_EXT:
|
||
|
case SWITCH_OSF:
|
||
|
case SWITCH_MKTYPLIB:
|
||
|
case SWITCH_OLD_TLB:
|
||
|
case SWITCH_NEW_TLB:
|
||
|
case SWITCH_NO_SERVER:
|
||
|
case SWITCH_NO_CLIENT:
|
||
|
case SWITCH_NO_HEADER:
|
||
|
case SWITCH_NO_IID:
|
||
|
case SWITCH_NO_DLLDATA:
|
||
|
case SWITCH_NO_PROXY:
|
||
|
case SWITCH_NO_CLASS_METHODS:
|
||
|
case SWITCH_NO_CLASS_IUNKNOWN:
|
||
|
case SWITCH_NO_CLASS_HEADER:
|
||
|
case SWITCH_NO_PROXY_DEF:
|
||
|
case SWITCH_NO_DLL_SERVER_DEF:
|
||
|
case SWITCH_NO_DLL_SERVER_CLASS_GEN:
|
||
|
case SWITCH_NO_SERVER_REG:
|
||
|
case SWITCH_NO_EXE_SERVER:
|
||
|
case SWITCH_NO_EXE_SERVER_MAIN:
|
||
|
case SWITCH_NO_TESTCLIENT:
|
||
|
case SWITCH_RPCSS:
|
||
|
case SWITCH_ROBUST:
|
||
|
case SWITCH_NO_ROBUST:
|
||
|
case SWITCH_NOREUSE_BUFFER:
|
||
|
case SWITCH_USE_VT_INT_PTR:
|
||
|
case SWITCH_NO_TLIB:
|
||
|
case SWITCH_MS_EXT64:
|
||
|
case SWITCH_DEBUGINFO:
|
||
|
SwitchDefined( SWValue );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_CPP_CMD:
|
||
|
case SWITCH_CPP_OPT:
|
||
|
case SWITCH_MSC_VER:
|
||
|
case SWITCH_DEBUG64:
|
||
|
case SWITCH_DEBUG64_OPT:
|
||
|
|
||
|
ProcessOnetimeSwitch( SWValue, pThisArg );
|
||
|
break;
|
||
|
|
||
|
case SWITCH_CLIENT:
|
||
|
|
||
|
if( SelectChoice( ClientChoice, pThisArg ,&Temp ) != STATUS_OK )
|
||
|
goto illarg;
|
||
|
fClient = (unsigned char) Temp;
|
||
|
break;
|
||
|
|
||
|
case SWITCH_SERVER:
|
||
|
|
||
|
if( SelectChoice( ServerChoice, pThisArg ,&Temp ) != STATUS_OK )
|
||
|
goto illarg;
|
||
|
fServer = (unsigned char) Temp;
|
||
|
break;
|
||
|
|
||
|
case SWITCH_CHAR:
|
||
|
|
||
|
if( SelectChoice( CharChoice, pThisArg ,&Temp ) != STATUS_OK )
|
||
|
goto illarg;
|
||
|
CharOption = (unsigned char) Temp;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
|
||
|
illarg:
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
Status = ILLEGAL_ARGUMENT,
|
||
|
SwitchStringForValue( SWValue ) );
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::ProcessSimpleMultipleSwitch(
|
||
|
short SWValue,
|
||
|
char * pThisArg
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
process simple switches which can be multiply defined.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SWValue - switch value
|
||
|
pThisArg - the users argument to this switch.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
check and warn for redefinition of the switch. Switch Warn is a special
|
||
|
case, the warn can be redefined. The last specified warning level is
|
||
|
valid.
|
||
|
|
||
|
Generally we let the user who redefines a switch off the hook. When the
|
||
|
arguments to a switch are wrong, we report an error and return an illegal
|
||
|
argument status.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
short Temp;
|
||
|
STATUS_T Status = STATUS_OK;
|
||
|
|
||
|
switch( SWValue )
|
||
|
{
|
||
|
case SWITCH_ERROR:
|
||
|
Temp = ERROR_NONE;
|
||
|
if( pThisArg && SelectChoice( ErrorChoice, pThisArg ,&Temp ) != STATUS_OK )
|
||
|
{
|
||
|
Status = ILLEGAL_ARGUMENT;
|
||
|
RpcError( (char *)0,
|
||
|
0,
|
||
|
Status,
|
||
|
SwitchStringForValue( SWValue )
|
||
|
);
|
||
|
}
|
||
|
if( Temp == ERROR_NONE)
|
||
|
ErrorOption = ERROR_NONE;
|
||
|
else
|
||
|
ErrorOption |= Temp;
|
||
|
break;
|
||
|
|
||
|
case SWITCH_WIRE_COMPAT:
|
||
|
if( !pThisArg || ( SelectChoice( WireCompatChoice, pThisArg ,&Temp ) != STATUS_OK ) )
|
||
|
{
|
||
|
Status = ILLEGAL_ARGUMENT;
|
||
|
RpcError( (char *)0,
|
||
|
0,
|
||
|
Status,
|
||
|
SwitchStringForValue( SWValue )
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
WireCompatOption |= Temp;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::SetPostDefaults()
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Set compiler switch defaults for switches not specified.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
char agDrive[ _MAX_DRIVE ];
|
||
|
char agPath[ _MAX_PATH ];
|
||
|
char agBaseName[ _MAX_FNAME ];
|
||
|
char agExt[ _MAX_EXT ];
|
||
|
char agBuffer[ _MAX_DRIVE + _MAX_PATH + _MAX_FNAME + _MAX_EXT + 1 ];
|
||
|
|
||
|
|
||
|
if( !IsSwitchDefined( SWITCH_OUT ) )
|
||
|
{
|
||
|
strcpy( agDrive, "");
|
||
|
strcpy( agPath, ".\\");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_splitpath( pOutputPathSwitch->GetFileName(),
|
||
|
agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
agExt );
|
||
|
strcat( agPath, agBaseName );
|
||
|
strcat( agPath, agExt );
|
||
|
delete pOutputPathSwitch;
|
||
|
}
|
||
|
|
||
|
agBaseName[0] = '\0';
|
||
|
agExt[0] = '\0';
|
||
|
|
||
|
_makepath( agBuffer, agDrive, agPath, agBaseName, agExt );
|
||
|
|
||
|
|
||
|
pOutputPathSwitch = new filename_switch( agBuffer );
|
||
|
|
||
|
_splitpath( agBuffer, agDrive, agPath, agBaseName, agExt );
|
||
|
|
||
|
// we have all the components but the base filename must be the
|
||
|
// filename of the input file. So we get this component of the base
|
||
|
// filename
|
||
|
|
||
|
pInputFNSwitch->GetFileNameComponents( (char *)NULL,
|
||
|
(char *)NULL,
|
||
|
agBaseName,
|
||
|
(char *)NULL );
|
||
|
|
||
|
// if the cstub switch is not set, set the default.
|
||
|
|
||
|
if(!IsSwitchDefined( SWITCH_CSTUB ) )
|
||
|
{
|
||
|
pCStubSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".c",
|
||
|
"_c" );
|
||
|
}
|
||
|
else
|
||
|
pCStubSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
|
||
|
// if the sstub switch is not set, set the default
|
||
|
|
||
|
if(!IsSwitchDefined( SWITCH_SSTUB ) )
|
||
|
{
|
||
|
pSStubSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".c",
|
||
|
"_s" );
|
||
|
}
|
||
|
else
|
||
|
pSStubSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
|
||
|
|
||
|
// if the IID switch is not set, set it
|
||
|
if(!IsSwitchDefined( SWITCH_IID ) )
|
||
|
{
|
||
|
pIIDSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".c",
|
||
|
"_i" );
|
||
|
}
|
||
|
else
|
||
|
pIIDSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
|
||
|
// if the Proxy switch is not set, set it
|
||
|
if(!IsSwitchDefined( SWITCH_PROXY ) )
|
||
|
{
|
||
|
pProxySwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".c",
|
||
|
"_p" );
|
||
|
}
|
||
|
else
|
||
|
pProxySwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
|
||
|
if (!IsSwitchDefined( SWITCH_TLIB ) )
|
||
|
{
|
||
|
pTlibSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".tlb",
|
||
|
"" );
|
||
|
}
|
||
|
else
|
||
|
pTlibSwitch->TransformFileNameForOut(agDrive, agPath);
|
||
|
|
||
|
// if the DllData switch is not set, set it
|
||
|
if(!IsSwitchDefined( SWITCH_DLLDATA ) )
|
||
|
{
|
||
|
pDllDataSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
"dlldata",
|
||
|
".c",
|
||
|
"" );
|
||
|
}
|
||
|
else
|
||
|
pDllDataSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
|
||
|
// if the acf switch is not set, set it
|
||
|
|
||
|
if(!IsSwitchDefined( SWITCH_ACF ) )
|
||
|
{
|
||
|
pAcfSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".acf",
|
||
|
(char *)NULL );
|
||
|
}
|
||
|
|
||
|
// if the header switch is not set, set it
|
||
|
|
||
|
if(!IsSwitchDefined( SWITCH_HEADER ) )
|
||
|
{
|
||
|
pHeaderSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".h",
|
||
|
(char *)NULL );
|
||
|
}
|
||
|
else
|
||
|
pHeaderSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
|
||
|
// set up the cpp options.
|
||
|
|
||
|
if( !IsSwitchDefined( SWITCH_CPP_CMD ) )
|
||
|
{
|
||
|
pCppCmdSwitch = new onetime_switch( C_PREPROCESSOR_NAME() );
|
||
|
}
|
||
|
|
||
|
if( !IsSwitchDefined( SWITCH_MSC_VER ) )
|
||
|
{
|
||
|
pMSCVerSwitch = new onetime_switch( "1100" );
|
||
|
MSCVersion = 1100;
|
||
|
}
|
||
|
|
||
|
// set up the cpp_opt and cc_opt. If he did not specify a cpp_opt
|
||
|
// then we will pass onto the preprocessor the /I , /D and /U options.
|
||
|
// if he did specify a cpp_opt, then he knows best, take his options
|
||
|
// and dont make your own assumptions.
|
||
|
|
||
|
if ( ! IsSwitchDefined( SWITCH_CPP_OPT ) )
|
||
|
{
|
||
|
int Len = 0;
|
||
|
char * pTemp,
|
||
|
* pTemp1;
|
||
|
|
||
|
Len += (int) strlen( ADDITIONAL_CPP_OPT() );
|
||
|
if( !pISwitch && IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
|
||
|
Len += (int) strlen( "-I." ) + 1;
|
||
|
|
||
|
if( pISwitch ) Len += pISwitch->GetConsolidatedLength( true ); // Room for quotes
|
||
|
if( pDSwitch ) Len += pDSwitch->GetConsolidatedLength();
|
||
|
if( pUSwitch ) Len += pUSwitch->GetConsolidatedLength();
|
||
|
|
||
|
|
||
|
pTemp = new char[ Len + 1 ]; pTemp[0] = '\0';
|
||
|
|
||
|
if( !pISwitch && IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
|
||
|
{
|
||
|
strcat( pTemp, "-I." );
|
||
|
}
|
||
|
|
||
|
if( pISwitch )
|
||
|
{
|
||
|
strcat( pTemp, pTemp1 = pISwitch->GetConsolidatedOptions( true ) ); // Get quotes
|
||
|
delete pTemp1;
|
||
|
}
|
||
|
|
||
|
if( pDSwitch )
|
||
|
{
|
||
|
strcat( pTemp, pTemp1 = pDSwitch->GetConsolidatedOptions() );
|
||
|
delete pTemp1;
|
||
|
}
|
||
|
|
||
|
if( pUSwitch )
|
||
|
{
|
||
|
strcat( pTemp, pTemp1 = pUSwitch->GetConsolidatedOptions() );
|
||
|
delete pTemp1;
|
||
|
}
|
||
|
|
||
|
strcat( pTemp, ADDITIONAL_CPP_OPT() );
|
||
|
|
||
|
pCppOptSwitch = new onetime_switch( pTemp );
|
||
|
|
||
|
delete pTemp;
|
||
|
}
|
||
|
|
||
|
// if he specified the cpp_cmd or cpp_opt switches, then no_cpp
|
||
|
// overrides them if specified.
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_NO_CPP ) )
|
||
|
{
|
||
|
if( IsSwitchDefined( SWITCH_CPP_CMD) ||
|
||
|
IsSwitchDefined( SWITCH_CPP_OPT) )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
NO_CPP_OVERRIDES,
|
||
|
(char *)NULL );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// if the client switch is not defined, define it
|
||
|
|
||
|
if( !IsSwitchDefined( SWITCH_CLIENT ) )
|
||
|
{
|
||
|
fClient = CLNT_STUB;
|
||
|
}
|
||
|
|
||
|
// if warnlevel and no_warn is defined, then errors
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_W ) &&
|
||
|
(IsSwitchDefined( SWITCH_NO_WARN ) || (WLevel == 0) ) )
|
||
|
{
|
||
|
//
|
||
|
// if we set the no_warn switch already then this warning will itself
|
||
|
// not be emitted. Make the current warning level 1 so that this warning
|
||
|
// will be spit out. WLevel is made 0 anyways after that.
|
||
|
//
|
||
|
|
||
|
WLevel = 1;
|
||
|
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
NO_WARN_OVERRIDES,
|
||
|
(char *)NULL );
|
||
|
WLevel = 0;
|
||
|
}
|
||
|
|
||
|
// if the error switch is not defined, define it.
|
||
|
|
||
|
if( !IsSwitchDefined( SWITCH_ERROR ) )
|
||
|
{
|
||
|
ErrorOption = ERROR_ALL;
|
||
|
}
|
||
|
else if ( GetNdrVersionControl().TargetIsNT40OrLater() )
|
||
|
{
|
||
|
if ( ERROR_ALL != ErrorOption )
|
||
|
{
|
||
|
RpcError(
|
||
|
NULL,
|
||
|
0,
|
||
|
CONTRADICTORY_SWITCHES,
|
||
|
"-error vs. -target" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// if he defined env, then he may want to compile for a platform different
|
||
|
// from what he is building for. Take care of platform dependent switches
|
||
|
// for the proper platforms.
|
||
|
|
||
|
// 64 bit additions:
|
||
|
// -append64 means forcing the appending on the current run
|
||
|
// .. it should be the second run, but it always forces with win32 or 64
|
||
|
// -win32 or -win64 means 32 or 64 bit run only, respectively.
|
||
|
//
|
||
|
|
||
|
if ( !IsSwitchDefined( SWITCH_ENV )
|
||
|
&& NT40 == GetNdrVersionControl().GetTargetSystem() )
|
||
|
{
|
||
|
SetEnv( ENV_WIN32 );
|
||
|
SwitchDefined( SWITCH_ENV );
|
||
|
}
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_ENV ) )
|
||
|
{
|
||
|
if( !IsSwitchDefined( SWITCH_ZP ) )
|
||
|
{
|
||
|
switch( GetEnv() )
|
||
|
{
|
||
|
case ENV_WIN32: ZeePee = DEFAULT_ZEEPEE; break;
|
||
|
case ENV_WIN64: ZeePee = DEFAULT_ZEEPEE; break;
|
||
|
default: ZeePee = DEFAULT_ZEEPEE; break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// EnumSize is set to 4 by default
|
||
|
}
|
||
|
|
||
|
if ( NT40 == GetNdrVersionControl().GetTargetSystem()
|
||
|
&& ENV_WIN32 != GetEnv()
|
||
|
)
|
||
|
{
|
||
|
RpcError(
|
||
|
NULL,
|
||
|
0,
|
||
|
CONTRADICTORY_SWITCHES,
|
||
|
"-win64 vs. -target NT40" );
|
||
|
}
|
||
|
|
||
|
if ( !IsSwitchDefined ( SWITCH_TRANSFER_SYNTAX ) )
|
||
|
{
|
||
|
if ( GetNdrVersionControl().TargetIsNT51OrLater() )
|
||
|
TargetSyntax = SYNTAX_BOTH;
|
||
|
else
|
||
|
TargetSyntax = SYNTAX_DCE;
|
||
|
}
|
||
|
|
||
|
if ( GetNdrVersionControl().TargetIsNT51OrLater() )
|
||
|
{
|
||
|
if ( SYNTAX_BOTH != TargetSyntax )
|
||
|
{
|
||
|
RpcError(
|
||
|
NULL,
|
||
|
0,
|
||
|
CONTRADICTORY_SWITCHES,
|
||
|
"-protocol vs. -target NT51" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// we support ndr64 on 32bit platform only when -internal is specified.
|
||
|
if ( ( TargetSyntax == SYNTAX_NDR64 ) &&
|
||
|
( GetEnv() == ENV_WIN32 ) &&
|
||
|
!IsSwitchDefined( SWITCH_INTERNAL ) )
|
||
|
{
|
||
|
RpcError( NULL, 0, UNSUPPORT_NDR64_FEATURE, 0 );
|
||
|
}
|
||
|
|
||
|
// ndr64 is not supported in /Osf mode
|
||
|
if ( IsSwitchDefined(SWITCH_OSF) && TargetSyntax != SYNTAX_DCE )
|
||
|
{
|
||
|
RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-osf vs. -protocol ndr64 or -protocol all" );
|
||
|
}
|
||
|
|
||
|
if ( GetEnv() == ENV_WIN64 || GetEnv() == ENV_WIN32 )
|
||
|
{
|
||
|
if ( IsSwitchDefined( SWITCH_APPEND64 ) )
|
||
|
{
|
||
|
SetHasAppend64( TRUE );
|
||
|
SetEnv( ENV_WIN64 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( GetEnv() == ENV_WIN64 )
|
||
|
{
|
||
|
// -ms_ext64 is set by default in 64bit.
|
||
|
SwitchDefined( SWITCH_MS_EXT64 );
|
||
|
}
|
||
|
|
||
|
if ( IsSwitchDefined( SWITCH_MS_EXT64 ) )
|
||
|
GetNdrVersionControl().SetHasMsExt64();
|
||
|
|
||
|
|
||
|
if ( IsSwitchDefined(SWITCH_OSF) && IsSwitchDefined(SWITCH_C_EXT) ||
|
||
|
IsSwitchDefined(SWITCH_OSF) && IsSwitchDefined(SWITCH_MS_EXT) )
|
||
|
{
|
||
|
RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-osf vs. -ms_ext or -c_ext" );
|
||
|
}
|
||
|
|
||
|
// The default optimization level is -Os for dce only mode when -target
|
||
|
// is not used. With target or in ndr64 or "all" protocol use -Oicf.
|
||
|
|
||
|
if ( !IsSwitchDefined( SWITCH_O ) )
|
||
|
{
|
||
|
if ( GetNdrVersionControl().TargetIsNT40OrLater() )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OICF;
|
||
|
SwitchDefined( SWITCH_O );
|
||
|
}
|
||
|
else if ( TargetSyntax == SYNTAX_DCE )
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_SIZE );
|
||
|
OptimLevel = OPT_LEVEL_OS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OICF;
|
||
|
}
|
||
|
}
|
||
|
else if ( GetNdrVersionControl().TargetIsNT40OrLater() )
|
||
|
{
|
||
|
if ( OptimLevel != OPT_LEVEL_OICF )
|
||
|
{
|
||
|
RpcError(
|
||
|
NULL,
|
||
|
0,
|
||
|
CONTRADICTORY_SWITCHES,
|
||
|
"-Os/Oi/Oic vs. -target" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( GetEnv() == ENV_WIN64 )
|
||
|
{
|
||
|
SetPostDefaults64();
|
||
|
}
|
||
|
|
||
|
if ( ( GetOptimizationFlags() != OPTIMIZE_ALL_I2_FLAGS ) &&
|
||
|
( TargetSyntax != SYNTAX_DCE ) )
|
||
|
{
|
||
|
RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-Os/Oi/Oic vs. -protocol ndr64 or -protocol all" );
|
||
|
}
|
||
|
|
||
|
// Force /Oicf when ( /Oi or /Os ) are used with /robust
|
||
|
|
||
|
if ( GetNdrVersionControl().TargetIsNT50OrLater() )
|
||
|
{
|
||
|
if ( IsSwitchDefined( SWITCH_NO_ROBUST ) )
|
||
|
RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-no_robust vs. -target" );
|
||
|
else
|
||
|
SwitchDefined( SWITCH_ROBUST );
|
||
|
}
|
||
|
|
||
|
if ( IsSwitchDefined( SWITCH_ROBUST ) )
|
||
|
{
|
||
|
if ( IsSwitchDefined( SWITCH_NO_ROBUST ) )
|
||
|
RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-robust vs. -no_robust" );
|
||
|
|
||
|
if ( NT40 == GetNdrVersionControl().GetTargetSystem() )
|
||
|
RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-robust vs. -target NT40" );
|
||
|
|
||
|
GetNdrVersionControl().SetHasDOA();
|
||
|
|
||
|
if ( ( GetOptimizationFlags() & OPTIMIZE_ALL_I2_FLAGS ) != OPTIMIZE_ALL_I2_FLAGS )
|
||
|
{
|
||
|
RpcError( 0, 0, ROBUST_REQUIRES_OICF, 0 );
|
||
|
}
|
||
|
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
}
|
||
|
|
||
|
if ( !IsSwitchDefined( SWITCH_INTERNAL ) )
|
||
|
{
|
||
|
// Make sure netmon switches also use -internal
|
||
|
if ( IsSwitchDefined( SWITCH_NETMON ) )
|
||
|
{
|
||
|
ReportUnimplementedSwitch( SWITCH_NETMON );
|
||
|
}
|
||
|
else if ( IsSwitchDefined( SWITCH_NETMON_STUB_OUTPUT_FILE ) )
|
||
|
{
|
||
|
ReportUnimplementedSwitch( SWITCH_NETMON_STUB_OUTPUT_FILE );
|
||
|
}
|
||
|
else if ( IsSwitchDefined( SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE ) )
|
||
|
{
|
||
|
ReportUnimplementedSwitch( SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Make sure -netmon is only used with -Oicf and setup output files
|
||
|
|
||
|
if ( IsSwitchDefined( SWITCH_NETMON ))
|
||
|
{
|
||
|
if ( ! ( ( GetOptimizationFlags() & OPTIMIZE_ALL_I2_FLAGS ) &&
|
||
|
OptimLevel == OPT_LEVEL_OICF ) )
|
||
|
{
|
||
|
RpcError( 0, 0, NETMON_REQUIRES_OICF, 0 );
|
||
|
}
|
||
|
|
||
|
if (!IsSwitchDefined (SWITCH_NETMON_STUB_OUTPUT_FILE))
|
||
|
{
|
||
|
pNetmonStubSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".c",
|
||
|
"_netmon_stub" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pNetmonStubSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
}
|
||
|
|
||
|
if (!IsSwitchDefined (SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE))
|
||
|
{
|
||
|
pNetmonStubObjSwitch = new filename_switch( agDrive,
|
||
|
agPath,
|
||
|
agBaseName,
|
||
|
".c",
|
||
|
"_netmon_stub_obj" );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pNetmonStubObjSwitch->TransformFileNameForOut( agDrive, agPath );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// Check if the target system is consistent with other switches.
|
||
|
|
||
|
if ( TargetSystem < NT40 && IsSwitchDefined( SWITCH_NETMON) )
|
||
|
RpcError( NULL, 0, CMD_REQUIRES_NT40, "netmon" );
|
||
|
|
||
|
// If the -no_default_epv switch is specified then -epv switch is auto
|
||
|
// enabled.
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_NO_DEFAULT_EPV ) )
|
||
|
SwitchDefined( SWITCH_USE_EPV );
|
||
|
|
||
|
// if he specified all, set them all
|
||
|
if ( IsSwitchDefined( SWITCH_PREFIX ) )
|
||
|
{
|
||
|
char * pAll = pSwitchPrefix->GetUserDefinedEquivalent( PREFIX_ALL );
|
||
|
if ( pAll )
|
||
|
{
|
||
|
for ( short j = 0; j < PREFIX_ALL; j++ )
|
||
|
{
|
||
|
if ( !pSwitchPrefix->GetUserDefinedEquivalent( j ) )
|
||
|
pSwitchPrefix->AddPair( j, pAll );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetModeSwitchConfigMask();
|
||
|
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CommandLine::SetPostDefaults64()
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Set switch defaults for 64 bit runs
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
GetNdrVersionControl().SetHas64BitSupport();
|
||
|
|
||
|
if ( IsSwitchDefined( SWITCH_O ) )
|
||
|
{
|
||
|
// For 64b force any interpreter mode to be -Oicf.
|
||
|
//
|
||
|
if ( OptimFlags == OPTIMIZE_SIZE )
|
||
|
{
|
||
|
// RpcError( NULL, 0, WIN64_INTERPRETED, "-Oicf" );
|
||
|
}
|
||
|
else if ( OptimLevel != OPT_LEVEL_OICF )
|
||
|
{
|
||
|
RpcError( NULL, 0, WIN64_INTERPRETED, ": -Oicf" );
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OICF;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Default for the -O switch is -Oicf on 64b
|
||
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
||
|
OptimLevel = OPT_LEVEL_OICF;
|
||
|
}
|
||
|
|
||
|
// Disable -no_robust switch for 277.
|
||
|
// if ( ! IsSwitchDefined( SWITCH_NO_ROBUST ) &&
|
||
|
|
||
|
if ( GetOptimizationFlags() & OPTIMIZE_ALL_I2_FLAGS )
|
||
|
{
|
||
|
// Default 64b processing to robust, when -Oicf, unless -no_robust
|
||
|
GetNdrVersionControl().SetHasDOA();
|
||
|
SwitchDefined( SWITCH_ROBUST );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* utility functions
|
||
|
*****************************************************************************/
|
||
|
void
|
||
|
ReportUnimplementedSwitch(
|
||
|
short SWValue
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
report an unimplemented switch error.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SWValue - switch value.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
char buf[ 50 ];
|
||
|
sprintf( buf, "%s", SwitchStringForValue( SWValue ) );
|
||
|
RpcError((char *)NULL,0,UNIMPLEMENTED_SWITCH, buf);
|
||
|
}
|
||
|
|
||
|
STATUS_T
|
||
|
SelectChoice(
|
||
|
const CHOICE * pCh,
|
||
|
char * pUserInput,
|
||
|
short * pChoice)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Search for the given multiple choice table for the given choice.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pCh - pointer to multiple choice table.
|
||
|
pUserInput - user input string.
|
||
|
pChoice - return the choice value.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
ILLEGAL_ARGUMENT if the user input did not represent a valid choice
|
||
|
for the switch.
|
||
|
|
||
|
STATUS_OK if everything is hunky dory.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
|
||
|
char * pChStr;
|
||
|
|
||
|
while ( pCh && ( pChStr = (char *) pCh->pChoice ) != 0 )
|
||
|
{
|
||
|
if( strcmp( pChStr, pUserInput ) == 0 )
|
||
|
{
|
||
|
*pChoice = pCh->Choice;
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
pCh++;
|
||
|
}
|
||
|
return ILLEGAL_ARGUMENT;
|
||
|
}
|
||
|
|
||
|
enum _swenum
|
||
|
SearchForSwitch(
|
||
|
char ** ppArg )
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Search for the switch, given the users input as switch name.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ppArg - pointer to users input pointer.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
the switch value, if found, SWITCH_NOTHING otherwise.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
search for exact switch name match, and if found, bump the pointer to
|
||
|
point to the character after the switch name, so that any input to the
|
||
|
switch can be looked at after the switch string is out of the way.
|
||
|
|
||
|
Checking the exact length may be a problem, because some switches like
|
||
|
-I can take no space between the arg. In these cases, ignore the length
|
||
|
match.
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
short Len , LenArg, iIndex = 0;
|
||
|
BOOL fLengthIsOk;
|
||
|
char * pSrc;
|
||
|
struct sw_desc * pSwDesc = (struct sw_desc*) &switch_desc[0];
|
||
|
|
||
|
LenArg = (short)strlen( *ppArg );
|
||
|
|
||
|
while( iIndex < (sizeof(switch_desc) / sizeof( struct sw_desc ) ) )
|
||
|
{
|
||
|
pSrc = (char *) pSwDesc->pSwitchName;
|
||
|
Len = (short)strlen( pSrc );
|
||
|
fLengthIsOk =
|
||
|
((pSwDesc->flag & ARG_SPACE_OPTIONAL) || (Len==LenArg));
|
||
|
|
||
|
if(fLengthIsOk && strncmp( pSrc, *ppArg, Len ) == 0 )
|
||
|
{
|
||
|
*ppArg += Len;
|
||
|
return (_swenum) iIndex;
|
||
|
}
|
||
|
iIndex++;
|
||
|
pSwDesc++;
|
||
|
}
|
||
|
return SWITCH_NOTHING;
|
||
|
}
|
||
|
|
||
|
char*
|
||
|
SwitchStringForValue(
|
||
|
unsigned short SWValue
|
||
|
)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
return the switch string given the value of the switch.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
SWValue - switch value.
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
pointer to the switch string. pointer to a null string if not found.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
#define SWITCH_DESC_SIZE (sizeof(switch_desc) / sizeof(struct sw_desc))
|
||
|
struct sw_desc * pDesc = (struct sw_desc*) &switch_desc[0],
|
||
|
* pDescEnd = (struct sw_desc*) &switch_desc[0] + SWITCH_DESC_SIZE;
|
||
|
|
||
|
while( pDesc < pDescEnd )
|
||
|
{
|
||
|
if( pDesc->SwitchValue == (enum _swenum ) SWValue)
|
||
|
return (char *) pDesc->pSwitchName;
|
||
|
pDesc++;
|
||
|
}
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
inline
|
||
|
char *
|
||
|
YesOrNoString( BOOL Yes )
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
return "Yes" for true, "No" for false
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
return Yes ? "Yes" : "No";
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CommandLine::Confirm()
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
confirm the arguments by dumping onto the screen
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
short Option;
|
||
|
char * p;
|
||
|
char Buffer[100];
|
||
|
|
||
|
fprintf( stdout, "%s bit arguments",
|
||
|
(Is64BitEnv() ? "64" : "32" )
|
||
|
);
|
||
|
|
||
|
PrintArg( BASE_FILENAME, GetInputFileName() , 0 );
|
||
|
if( IsSwitchDefined( SWITCH_ACF ) )
|
||
|
PrintArg( SWITCH_ACF , GetAcfFileName(), 0);
|
||
|
|
||
|
PrintArg( SWITCH_APP_CONFIG,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_APP_CONFIG)), 0);
|
||
|
|
||
|
PrintArg( SWITCH_C_EXT,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_C_EXT)), 0);
|
||
|
|
||
|
Option = GetClientSwitchValue();
|
||
|
PrintArg( SWITCH_CLIENT,
|
||
|
(Option == CLNT_STUB) ? "stub" : "none", 0);
|
||
|
|
||
|
Option = GetCharOption();
|
||
|
|
||
|
PrintArg( SWITCH_CHAR, (Option == CHAR_SIGNED ) ? "signed" :
|
||
|
(Option == CHAR_UNSIGNED ) ? "unsigned" : "ascii7",0);
|
||
|
|
||
|
if( IsSwitchDefined(SWITCH_CONFIRM) )
|
||
|
PrintArg( SWITCH_CONFIRM, "Yes" , 0);
|
||
|
|
||
|
PrintArg( SWITCH_CPP_CMD, GetCPPCmd() , 0);
|
||
|
PrintArg( SWITCH_CPP_OPT, GetCPPOpt() , 0);
|
||
|
_itoa( GetMSCVer(), Buffer, 10 );
|
||
|
PrintArg( SWITCH_MSC_VER, Buffer , 0);
|
||
|
|
||
|
if ( ( p = GetCstubFName() ) != 0 )
|
||
|
PrintArg( SWITCH_CSTUB, p , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_D ) )
|
||
|
PrintArg( SWITCH_D, pDSwitch->GetConsolidatedOptions(), 0 );
|
||
|
|
||
|
Option = GetEnv();
|
||
|
PrintArg( SWITCH_ENV,
|
||
|
(Option == ENV_WIN64) ? "win64"
|
||
|
: "win32",
|
||
|
0 );
|
||
|
|
||
|
PrintArg( SWITCH_APPEND64,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_APPEND64)), 0);
|
||
|
|
||
|
Option = GetErrorOption();
|
||
|
|
||
|
Option = (short)IsRpcSSAllocateEnabled();
|
||
|
|
||
|
PrintArg( SWITCH_RPCSS,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_RPCSS)), 0);
|
||
|
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
PrintArg( SWITCH_NETMON,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_NETMON)), 0);
|
||
|
#endif
|
||
|
|
||
|
PrintArg( SWITCH_USE_EPV, YesOrNoString(IsSwitchDefined( SWITCH_USE_EPV )), 0);
|
||
|
|
||
|
PrintArg( SWITCH_NO_DEFAULT_EPV, YesOrNoString(IsSwitchDefined( SWITCH_NO_DEFAULT_EPV )), 0);
|
||
|
|
||
|
//
|
||
|
// error options.
|
||
|
//
|
||
|
|
||
|
|
||
|
Buffer[0] = '\0';
|
||
|
|
||
|
if( ErrorOption != ERROR_NONE )
|
||
|
{
|
||
|
if( ErrorOption & ERROR_ALLOCATION )
|
||
|
strcat( Buffer, "allocation ");
|
||
|
if( ErrorOption & ERROR_REF )
|
||
|
strcat( Buffer, "ref ");
|
||
|
if( ErrorOption & ERROR_BOUNDS_CHECK )
|
||
|
strcat( Buffer, "bounds_check ");
|
||
|
if( ErrorOption & ERROR_ENUM )
|
||
|
strcat( Buffer, "enum ");
|
||
|
if( ErrorOption & ERROR_STUB_DATA )
|
||
|
strcat( Buffer, "stub_data ");
|
||
|
}
|
||
|
else
|
||
|
strcat( Buffer, "none" );
|
||
|
|
||
|
PrintArg( SWITCH_ERROR, Buffer, 0 );
|
||
|
|
||
|
|
||
|
if ( ( p = GetHeader() ) != 0 )
|
||
|
PrintArg( SWITCH_HEADER, p , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_I ) )
|
||
|
PrintArg( SWITCH_I, pISwitch->GetConsolidatedOptions(), 0 );
|
||
|
|
||
|
PrintArg( SWITCH_NOLOGO,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_NOLOGO)), 0);
|
||
|
|
||
|
PrintArg( SWITCH_MS_EXT,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_MS_EXT)), 0);
|
||
|
|
||
|
PrintArg( SWITCH_MS_UNION,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_MS_UNION)), 0);
|
||
|
|
||
|
PrintArg( SWITCH_NO_FMT_OPT,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_NO_FMT_OPT)), 0);
|
||
|
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
PrintArg( SWITCH_GUARD_DEFS,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_GUARD_DEFS)), 0);
|
||
|
#endif
|
||
|
|
||
|
PrintArg( SWITCH_OLDNAMES,
|
||
|
YesOrNoString(IsSwitchDefined( SWITCH_OLDNAMES)), 0);
|
||
|
|
||
|
if ( 0 != WireCompatOption)
|
||
|
{
|
||
|
Buffer[0] = '\0';
|
||
|
|
||
|
if( ErrorOption & WIRE_COMPAT_ENUM16UNIONALIGN )
|
||
|
strcat( Buffer, "enum16unionalign ");
|
||
|
|
||
|
PrintArg( SWITCH_WIRE_COMPAT, Buffer, 0 );
|
||
|
}
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_NO_CPP ) )
|
||
|
PrintArg( SWITCH_NO_CPP, "Yes" , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
|
||
|
PrintArg( SWITCH_NO_DEF_IDIR, "Yes", 0 );
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_NO_WARN ) )
|
||
|
PrintArg( SWITCH_NO_WARN, "Yes" , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_USE_EPV ) )
|
||
|
PrintArg( SWITCH_USE_EPV, "Yes" , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_NO_DEFAULT_EPV ) )
|
||
|
PrintArg( SWITCH_NO_DEFAULT_EPV, "Yes" , 0);
|
||
|
|
||
|
|
||
|
if ( ( p = GetOutputPath() ) != 0 )
|
||
|
PrintArg( SWITCH_OUT, GetOutputPath(), 0 );
|
||
|
|
||
|
Option = GetZeePee();
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_PACK ) )
|
||
|
PrintArg( SWITCH_PACK,
|
||
|
(Option == 1) ? "1" :
|
||
|
(Option == 2) ? "2" :
|
||
|
(Option == 4) ? "4" : "8" , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_PREFIX ) )
|
||
|
{
|
||
|
char * pSys;
|
||
|
char * pUser;
|
||
|
char * pAll = pSwitchPrefix->GetUserDefinedEquivalent( PREFIX_ALL );
|
||
|
short Cur;
|
||
|
while( (Cur = pSwitchPrefix->GetNext( &pSys, &pUser ) ) >= 0 )
|
||
|
{
|
||
|
// if he specified all, don't report others that are the same
|
||
|
if ( ( Cur == PREFIX_ALL ) ||
|
||
|
!pAll ||
|
||
|
strcmp( pAll, pUser ) )
|
||
|
{
|
||
|
PrintArg( SWITCH_PREFIX,
|
||
|
pSys,
|
||
|
pUser );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Option = GetServerSwitchValue();
|
||
|
|
||
|
PrintArg( SWITCH_SERVER,
|
||
|
(Option == SRVR_STUB) ? "stub" : "none" , 0 );
|
||
|
|
||
|
if ( ( p = GetSstubFName() ) != 0 )
|
||
|
PrintArg( SWITCH_SSTUB, p , 0);
|
||
|
|
||
|
if ( IsSwitchDefined( SWITCH_SYNTAX_CHECK ) )
|
||
|
PrintArg( SWITCH_SYNTAX_CHECK, "Yes", 0 );
|
||
|
|
||
|
if ( IsSwitchDefined( SWITCH_U ) )
|
||
|
PrintArg( SWITCH_U, pUSwitch->GetConsolidatedOptions(), 0 );
|
||
|
|
||
|
PrintArg( SWITCH_O,
|
||
|
GetOptimizationFlags() == OPTIMIZE_SIZE
|
||
|
? "inline stubs"
|
||
|
: "interpreted stubs",
|
||
|
0 );
|
||
|
|
||
|
Option = GetWarningLevel();
|
||
|
PrintArg( SWITCH_W,
|
||
|
(Option == 0 ) ? "0" :
|
||
|
(Option == 1 ) ? "1" :
|
||
|
(Option == 2 ) ? "2" :
|
||
|
(Option == 3 ) ? "3" :
|
||
|
(Option == 4 ) ? "4" :
|
||
|
(Option == 5 ) ? "5" : "6" , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_WX ) )
|
||
|
PrintArg( SWITCH_WX, "Yes", 0 );
|
||
|
|
||
|
Option = GetZeePee();
|
||
|
|
||
|
PrintArg( SWITCH_ZP,
|
||
|
(Option == 1) ? "1" :
|
||
|
(Option == 2) ? "2" :
|
||
|
(Option == 4) ? "4" : "8" , 0);
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_ZS ) )
|
||
|
PrintArg( SWITCH_ZS, "Yes", 0 );
|
||
|
|
||
|
if( IsSwitchDefined( SWITCH_MS_CONF_STRUCT ) )
|
||
|
PrintArg( SWITCH_MS_CONF_STRUCT, "Yes", 0 );
|
||
|
|
||
|
fprintf(stdout, "\n" );
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
CommandLine::GetCompilerVersion()
|
||
|
{
|
||
|
if ( !szCompilerVersion[0] )
|
||
|
{
|
||
|
sprintf( szCompilerVersion, "%d.%02d.%04d", rmj, rmm, rup );
|
||
|
}
|
||
|
return szCompilerVersion;
|
||
|
}
|
||
|
|
||
|
// note that this string ends with a newline.
|
||
|
char *
|
||
|
CommandLine::GetCompileTime()
|
||
|
{
|
||
|
if ( !szCompileTime[0] )
|
||
|
{
|
||
|
time_t LocalTime;
|
||
|
// fetch the time
|
||
|
time( &LocalTime );
|
||
|
// convert to a string
|
||
|
strcpy( szCompileTime, ctime( &LocalTime ) );
|
||
|
}
|
||
|
return szCompileTime;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// The help screen(s)
|
||
|
//
|
||
|
|
||
|
const char *HelpArray[] = {
|
||
|
" -MIDL COMPILER OPTIONS-"
|
||
|
," -MODE-"
|
||
|
,"/ms_ext Microsoft extensions to the IDL language (default)"
|
||
|
,"/c_ext Allow Microsoft C extensions in the IDL file (default)"
|
||
|
,"/osf OSF mode - disables /ms_ext and /c_ext options"
|
||
|
,"/app_config Allow selected ACF attributes in the IDL file"
|
||
|
,"/mktyplib203 MKTYPLIB Version 2.03 compatiblity mode"
|
||
|
,""
|
||
|
," -INPUT-"
|
||
|
,"/acf filename Specify the attribute configuration file"
|
||
|
,"/I directory-list Specify one or more directories for include path"
|
||
|
,"/no_def_idir Ignore the current and the INCLUDE directories"
|
||
|
,""
|
||
|
," -OUTPUT FILE GENERATION-"
|
||
|
,"/client none Do not generate client files"
|
||
|
,"/client stub Generate client stub file only"
|
||
|
,"/out directory Specify destination directory for output files"
|
||
|
,"/server none Generate no server files"
|
||
|
,"/server stub Generate server stub file only"
|
||
|
,"/syntax_check Check syntax only; do not generate output files"
|
||
|
,"/Zs Check syntax only; do not generate output files"
|
||
|
,"/oldtlb Generate old format type libraries"
|
||
|
,"/newtlb Generate new format type libraries (default)"
|
||
|
,"/notlb Don't generate the tlb file"
|
||
|
,""
|
||
|
," -OUTPUT FILE NAMES-"
|
||
|
,"/cstub filename Specify client stub file name"
|
||
|
,"/dlldata filename Specify dlldata file name"
|
||
|
,"/h filename Specify header file name"
|
||
|
,"/header filename Specify header file name"
|
||
|
,"/iid filename Specify interface UUID file name"
|
||
|
,"/proxy filename Specify proxy file name"
|
||
|
,"/sstub filename Specify server stub file name"
|
||
|
,"/tlb filename Specify type library file name"
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
,"/netmonstub filename Specify Netmon classic interface stub file name"
|
||
|
,"/netmonobjstub filename Specify Netmon object interface stub file name"
|
||
|
#endif // MIDL_INTERNAL
|
||
|
,""
|
||
|
," -C COMPILER AND PREPROCESSOR OPTIONS-"
|
||
|
,"/cpp_cmd cmd_line Specify name of C preprocessor (default: cl.exe)"
|
||
|
,"/cpp_opt options Specify additional C preprocessor options"
|
||
|
,"/D name[=def] Pass #define name, optional value to C preprocessor"
|
||
|
,"/no_cpp Turn off the C preprocessing option"
|
||
|
,"/nocpp Turn off the C preprocessing option"
|
||
|
,"/U name Remove any previous definition (undefine)"
|
||
|
,"/msc_ver <nnnn> Microsoft C/C++ compiler version"
|
||
|
,"/savePP Save the preprocessed temporary file(s)"
|
||
|
,""
|
||
|
," -ENVIRONMENT-"
|
||
|
,"/char signed C compiler default char type is signed"
|
||
|
,"/char unsigned C compiler default char type is unsigned"
|
||
|
,"/char ascii7 Char values limited to 0-127"
|
||
|
,"/env win32 Target environment is Microsoft Windows 32-bit (NT)"
|
||
|
,"/env win64 Target environment is Microsoft Windows 64-bit (NT)"
|
||
|
,"/lcid Locale id for international locales"
|
||
|
,"/ms_union Use Midl 1.0 non-DCE wire layout for non-encapsulated unions"
|
||
|
,"/oldnames Do not mangle version number into names"
|
||
|
,"/rpcss Automatically activate rpc_sm_enable_allocate"
|
||
|
,"/use_epv Generate server side application calls via entry-pt vector"
|
||
|
,"/no_default_epv Do not generate a default entry-point vector"
|
||
|
,"/prefix client str Add \"str\" prefix to client-side entry points"
|
||
|
,"/prefix server str Add \"str\" prefix to server-side manager routines"
|
||
|
,"/prefix switch str Add \"str\" prefix to switch routine prototypes"
|
||
|
,"/prefix all str Add \"str\" prefix to all routines"
|
||
|
,"/win32 Target environment is Microsoft Windows 32-bit (NT)"
|
||
|
,"/win64 Target environment is Microsoft Windows 64-bit (NT)"
|
||
|
,"/protocol dce Use DCE NDR transfer syntax (default for 32b)"
|
||
|
,"/protocol all Use all supported transfer syntaxes"
|
||
|
,"/protocol ndr64 Use Microsoft extension NDR64 transfer syntax"
|
||
|
,"/target {system} Set the minimum target system"
|
||
|
|
||
|
,""
|
||
|
," -RUNTIME ERROR CHECKING BY STUBS-"
|
||
|
,"/error all Turn on all the error checking options, the best flavor"
|
||
|
,"/error none Turn off all the error checking options"
|
||
|
,"/error allocation Check for out of memory errors"
|
||
|
,"/error bounds_check Check size vs transmission length specification"
|
||
|
,"/error enum Check enum values to be in allowable range"
|
||
|
,"/error ref Check ref pointers to be non-null"
|
||
|
,"/error stub_data Emit additional check for server side stub data validity"
|
||
|
,"/robust Generate additonal information to validate parameters"
|
||
|
,""
|
||
|
," -OPTIMIZATION-"
|
||
|
,"/align {N} Designate packing level of structures"
|
||
|
,"/pack {N} Designate packing level of structures"
|
||
|
,"/Zp {N} Designate packing level of structures"
|
||
|
,"/no_format_opt Skip format string reusage optimization"
|
||
|
,"/Oi Generate fully interpreted stubs, old style"
|
||
|
," -Oicf is usually better"
|
||
|
,"/Oic Generate fully interpreted stubs for standard interfaces and"
|
||
|
," stubless proxies for object interfaces as of NT 3.51 release"
|
||
|
," using -Oicf instead is usually better"
|
||
|
,"/Oicf Generate fully interpreted stubs with extensions and"
|
||
|
," stubless proxies for object interfaces as of NT 4.0 release"
|
||
|
,"/Oif Same as -Oicf"
|
||
|
,"/Os Generate inline stubs"
|
||
|
#ifdef MIDL_INTERNAL
|
||
|
,"/netmon Generate stubs for Netmon debugging (requires -Oicf)"
|
||
|
#endif // MIDL_INTERNAL
|
||
|
,""
|
||
|
," -MISCELLANEOUS-"
|
||
|
,"@response_file Accept input from a response file"
|
||
|
,"/? Display a list of MIDL compiler switches"
|
||
|
,"/confirm Display options without compiling MIDL source"
|
||
|
,"/help Display a list of MIDL compiler switches"
|
||
|
,"/nologo Supress displaying of the banner lines"
|
||
|
,"/o filename Redirects output from screen to a file"
|
||
|
,"/W{0|1|2|3|4} Specify warning level 0-4 (default = 1)"
|
||
|
,"/WX Report warnings at specified /W level as errors"
|
||
|
,"/no_warn Suppress compiler warning messages"
|
||
|
};
|
||
|
|
||
|
STATUS_T
|
||
|
CommandLine::Help()
|
||
|
{
|
||
|
int i,LineCount,MaxLineCount = 23;
|
||
|
|
||
|
for(i = 0; i < sizeof(HelpArray)/sizeof(char *) ;)
|
||
|
{
|
||
|
for( LineCount = 0;
|
||
|
(LineCount < MaxLineCount) && (i < sizeof(HelpArray)/sizeof(char *)) ;
|
||
|
LineCount++,++i )
|
||
|
{
|
||
|
fprintf(stdout, "%s\n", HelpArray[i] );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// if all the help strings are displayed, then no need for user input.
|
||
|
//
|
||
|
|
||
|
if( i < (sizeof( HelpArray ) / sizeof( char *)) )
|
||
|
{
|
||
|
if( _isatty( MIDL_FILENO( stdout ) ) )
|
||
|
{
|
||
|
fprintf( stdout, "[ Press <return> to continue ]" );
|
||
|
MIDL_FGETCHAR();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return STATUS_OK;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
PrintArg(
|
||
|
enum _swenum Switch,
|
||
|
char * pFirst,
|
||
|
char * pSecond )
|
||
|
{
|
||
|
char * pL = "",
|
||
|
* pR = "",
|
||
|
* pComma = "";
|
||
|
char * pSwString = (Switch == BASE_FILENAME) ? "input file" :
|
||
|
SwitchStringForValue( (unsigned short)Switch );
|
||
|
|
||
|
if( pSecond )
|
||
|
{
|
||
|
pL = "(";
|
||
|
pR = ")";
|
||
|
pComma = ",";
|
||
|
}
|
||
|
else
|
||
|
pSecond = "";
|
||
|
|
||
|
fprintf( stdout, "\n%20s - %s %s %s %s %s"
|
||
|
, pSwString
|
||
|
, pL
|
||
|
, pFirst
|
||
|
, pComma
|
||
|
, pSecond
|
||
|
, pR );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CmdProcess(
|
||
|
pair_switch* pPair,
|
||
|
CommandLine* pCmdAna,
|
||
|
char* pFirstOfPair)
|
||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
pair_switch command analyzer
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pCmdAna - a ptr to the command analyser object calling this.
|
||
|
pFirstOfPair - the first argument after the -prefix switch.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NA
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
Use the GetNextArg and UndoGetNextArg functions as necessary.
|
||
|
|
||
|
1. We start with the input argument, which is the first of the
|
||
|
arguments to the prefix switch, ie first of the first pair.
|
||
|
|
||
|
2. If we find an argument starting with a '-' or '/' it is definitely the
|
||
|
end of the prefix specification. If the switch starter is seen at the end
|
||
|
of a pair it is a proper end of the prefix switch, else the prefix switch
|
||
|
pair specification is illegal.
|
||
|
|
||
|
3. In either case, as soon as a switch starter is seen, we must
|
||
|
UndoGetNextArg.
|
||
|
|
||
|
This class needs a pointer to the command analyser object that is calling
|
||
|
it, since it has to get and undoget argument from there
|
||
|
|
||
|
----------------------------------------------------------------------------*/
|
||
|
{
|
||
|
short PairCheck = 0;
|
||
|
char * pNextOfPair;
|
||
|
char * pTemp;
|
||
|
STATUS_T Status = STATUS_OK;
|
||
|
short i;
|
||
|
|
||
|
|
||
|
while( pFirstOfPair && (*pFirstOfPair != '-') && (*pFirstOfPair != '/' ) )
|
||
|
{
|
||
|
|
||
|
// the first of the pair is a system defined string. Is it a valid one?
|
||
|
|
||
|
if( (i = pPair->GetIndex( pFirstOfPair )) >= 0 )
|
||
|
{
|
||
|
|
||
|
// we know the first of the pair is valid. Check the next before
|
||
|
// allocating any memory.
|
||
|
|
||
|
PairCheck++;
|
||
|
pTemp = pCmdAna->GetNextArg();
|
||
|
|
||
|
if( pTemp && (*pTemp != '-') && (*pTemp != '/') )
|
||
|
{
|
||
|
pNextOfPair = new char [ strlen( pTemp ) + 1 ];
|
||
|
strcpy( pNextOfPair, pTemp );
|
||
|
|
||
|
// update the list
|
||
|
|
||
|
pPair->AddPair( i, pNextOfPair );
|
||
|
PairCheck++;
|
||
|
}
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
break;
|
||
|
pFirstOfPair = pCmdAna->GetNextArg();
|
||
|
|
||
|
if( PairCheck == 0 )
|
||
|
{
|
||
|
Status = ILLEGAL_ARGUMENT;
|
||
|
}
|
||
|
else if( (PairCheck % 2) != 0 )
|
||
|
{
|
||
|
Status = MISMATCHED_PREFIX_PAIR;
|
||
|
}
|
||
|
|
||
|
if( Status != STATUS_OK )
|
||
|
{
|
||
|
RpcError( (char *)NULL,
|
||
|
0,
|
||
|
Status,
|
||
|
SwitchStringForValue( SWITCH_PREFIX ) );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// if we read ahead, push the argument back
|
||
|
if ( pFirstOfPair )
|
||
|
pCmdAna->UndoGetNextArg();
|
||
|
}
|
||
|
|
||
|
|
||
|
|