mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3807 lines
90 KiB
3807 lines
90 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989 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.
|
|
----------------------------------------------------------------------------*/
|
|
|
|
/****************************************************************************
|
|
* include files
|
|
***************************************************************************/
|
|
|
|
#include "nulldefs.h"
|
|
|
|
extern "C"
|
|
{
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <assert.h>
|
|
#include <direct.h>
|
|
#include <io.h>
|
|
#include <time.h>
|
|
}
|
|
#include "midlvers.h"
|
|
#include "idict.hxx"
|
|
#include "common.hxx"
|
|
#include "errors.hxx"
|
|
#include "cmdana.hxx"
|
|
#include "filehndl.hxx"
|
|
#include "control.hxx"
|
|
#include "helptext.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 }
|
|
// , { "MIDLDEBUG", ARG_NONE , SWITCH_MIDLDEBUG }
|
|
, { "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 }
|
|
, { "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 }
|
|
, { "cstub", ARG_CC_ETC , SWITCH_CSTUB }
|
|
, { "nocstub", ARG_NONE , SWITCH_NO_CLIENT }
|
|
|
|
#ifdef MIDL_INTERNAL
|
|
, { "dump", ARG_NONE , SWITCH_DUMP }
|
|
#endif // MIDL_INTERNAL
|
|
|
|
, { "dlldata", ARG_CC_ETC , SWITCH_DLLDATA }
|
|
, { "env", ARG_SPACED , SWITCH_ENV }
|
|
, { "error", ARG_SPACED , SWITCH_ERROR }
|
|
, { "header", ARG_CC_ETC , SWITCH_HEADER }
|
|
, { "help", ARG_NONE , SWITCH_HELP }
|
|
, { "iid", ARG_CC_ETC , SWITCH_IID }
|
|
, { "mktyplib203", ARG_NONE , SWITCH_MKTYPLIB }
|
|
, { "new", 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 }
|
|
, { "oldnames", ARG_NONE , SWITCH_OLDNAMES }
|
|
, { "old", 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 }
|
|
|
|
#ifdef MIDL_INTERNAL
|
|
, { "savepp", ARG_NONE , SWITCH_SAVEPP }
|
|
#endif // MIDL_INTERNAL
|
|
|
|
, { "server", ARG_SPACED , SWITCH_SERVER }
|
|
, { "sstub", ARG_CC_ETC , SWITCH_SSTUB }
|
|
, { "nosstub", ARG_NONE , SWITCH_NO_SERVER }
|
|
, { "syntax_check", ARG_NONE , SWITCH_SYNTAX_CHECK }
|
|
#if defined(TARGET_RKK)
|
|
, { "target", ARG_SPACED , SWITCH_TARGET_SYSTEM }
|
|
#endif
|
|
, { "warn", ARG_SPACED , SWITCH_W }
|
|
|
|
#ifdef MIDL_INTERNAL
|
|
, { "x", ARG_NONE , SWITCH_X }
|
|
#endif // MIDL_INTERNAL
|
|
|
|
, { "ms_ext", ARG_NONE , SWITCH_MS_EXT }
|
|
, { "ms_union", ARG_NONE , SWITCH_MS_UNION }
|
|
, { "idlbase", ARG_NONE , SWITCH_IDLBASE }
|
|
, { "no_format_opt",ARG_NONE , SWITCH_NO_FMT_OPT }
|
|
, { "app_config", ARG_NONE , SWITCH_APP_CONFIG }
|
|
, { "ccg", ARG_NONE , SWITCH_COM_CLASS }
|
|
, { "rpcss", ARG_NONE , SWITCH_RPCSS }
|
|
, { "hookole", ARG_NONE , SWITCH_HOOKOLE }
|
|
// 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 }
|
|
, { "wi", ARG_SPACE_NONE , SWITCH_ODL_ENV } // win16 or win32
|
|
, { "do", ARG_SPACE_NONE , SWITCH_ODL_ENV } // dos
|
|
, { "ma", ARG_SPACE_NONE , SWITCH_ODL_ENV } // mac
|
|
, { "po", ARG_SPACE_NONE , SWITCH_ODL_ENV } // powermac
|
|
};
|
|
|
|
|
|
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_DOS }
|
|
,{ "win16" , ENV_WIN16 }
|
|
,{ "win32" , ENV_WIN32 }
|
|
,{ "mac" , ENV_MAC }
|
|
,{ "powermac" , ENV_MPPC }
|
|
,{ 0 , 0 }
|
|
};
|
|
|
|
const CHOICE TargetChoice[] =
|
|
{
|
|
{ "NT35" , NT35 }
|
|
,{ "NT351" , NT351 }
|
|
,{ "NT40" , NT40 }
|
|
,{ 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 PrefixChoices[] =
|
|
{
|
|
{ "client", PREFIX_CLIENT_STUB }
|
|
,{ "server", PREFIX_SERVER_MGR }
|
|
,{ "switch", PREFIX_SWICH_PROTOTYPE }
|
|
,{ "cstub", PREFIX_CLIENT_STUB }
|
|
,{ "sstub", PREFIX_SERVER_MGR }
|
|
,{ "all", PREFIX_ALL }
|
|
,{ 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 unsigned short EnumSize;
|
|
|
|
extern void ReportUnimplementedSwitch( short );
|
|
extern char * SwitchStringForValue( unsigned short );
|
|
extern _swenum SearchForSwitch( char ** );
|
|
extern STATUS_T SelectChoice( const CHOICE *, char *, short *);
|
|
extern CCONTROL * pCompiler;
|
|
extern short CompileMode;
|
|
extern IDICT * PPCmdEngine( int argc, char *argv[], IDICT * );
|
|
|
|
extern void PrintArg( enum _swenum, char *, char * );
|
|
/****************************************************************************/
|
|
|
|
char * pVersionStr = NULL;
|
|
char * pTimeStr = NULL;
|
|
|
|
void SetVersionStr()
|
|
{
|
|
pVersionStr = new char[ 12 ];
|
|
if ( rup == 0 )
|
|
sprintf( pVersionStr, "%d.%02d", rmj, rmm );
|
|
else if ( rup <= 99 )
|
|
sprintf( pVersionStr, "%d.%02d.%02d", rmj, rmm, rup );
|
|
else
|
|
sprintf( pVersionStr, "%d.%02d.%04d", rmj, rmm, rup );
|
|
}
|
|
|
|
void SetTimeStr()
|
|
{
|
|
time_t LocalTime;
|
|
|
|
// fetch the time
|
|
time( &LocalTime );
|
|
|
|
// convert to a string
|
|
pTimeStr = _strdup( ctime( &LocalTime ) );
|
|
}
|
|
|
|
|
|
_cmd_arg::_cmd_arg()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
The constructor
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
NA.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
switch_def_vector[0] = switch_def_vector[1] = switch_def_vector[2] =
|
|
switch_def_vector[3] = 0;
|
|
fClient = CLNT_STUB;
|
|
|
|
cArgs = 0;
|
|
WLevel = 1;
|
|
ErrorOption = ERROR_NONE;
|
|
|
|
Env = ENV_WIN32;
|
|
TargetSystem = TARGET_DEFAULT;
|
|
OptimLevel = OPT_LEVEL_OS_DEFAULT;
|
|
ZeePee = 8;
|
|
CharOption = CHAR_SIGNED;
|
|
fServer = SRVR_STUB;
|
|
|
|
pSwitchPrefix = new pair_switch( &PrefixChoices[0] );
|
|
pSwitchSuffix = (pair_switch *)0;
|
|
pInputFNSwitch =
|
|
pOutputPathSwitch =
|
|
pCStubSwitch =
|
|
pSStubSwitch =
|
|
pHeaderSwitch =
|
|
pAcfSwitch = (filename_switch *)NULL;
|
|
|
|
pDSwitch =
|
|
pISwitch =
|
|
pUSwitch = (multiple_switch *)NULL;
|
|
|
|
pCppCmdSwitch =
|
|
pCppOptSwitch = (onetime_switch *) NULL;
|
|
|
|
MajorVersion = rmj;
|
|
MinorVersion = rmm;
|
|
UpdateNumber = rup;
|
|
|
|
OptimFlags = OPTIMIZE_NONE;
|
|
|
|
ConfigMask = 0;
|
|
fMintRun = FALSE;
|
|
|
|
}
|
|
|
|
void
|
|
_cmd_arg::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 );
|
|
PPCmdEngine( cArguments, pArgs, pArgDict );
|
|
cArgs = pArgDict->GetCurrentSize();
|
|
}
|
|
|
|
char *
|
|
_cmd_arg::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
|
|
_cmd_arg::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.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
assert( iArgV > 0 );
|
|
|
|
if(iArgV == 0)
|
|
return;
|
|
cArgs++;
|
|
iArgV--;
|
|
}
|
|
|
|
STATUS_T
|
|
_cmd_arg::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() )
|
|
{
|
|
|
|
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 = switch_desc[ iSwitch ].SwitchValue;
|
|
|
|
Status = BumpThisArg( &pThisArg, switch_desc[ iSwitch ].flag );
|
|
|
|
if( Status != STATUS_OK )
|
|
{
|
|
RpcError( (char *)NULL,
|
|
0,
|
|
Status,
|
|
pThisArgSave );
|
|
continue;
|
|
}
|
|
|
|
// 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:
|
|
Status = ProcessFilenameSwitch( SwitchValue, pThisArg );
|
|
break;
|
|
|
|
case SWITCH_PACK:
|
|
case SWITCH_ZP:
|
|
case SWITCH_NO_WARN:
|
|
case SWITCH_USE_EPV:
|
|
case SWITCH_NO_DEFAULT_EPV:
|
|
case SWITCH_MIDLDEBUG:
|
|
case SWITCH_SYNTAX_CHECK:
|
|
case SWITCH_ZS:
|
|
case SWITCH_NO_CPP:
|
|
case SWITCH_CLIENT:
|
|
case SWITCH_SERVER:
|
|
case SWITCH_ENV:
|
|
#if defined(TARGET_RKK)
|
|
case SWITCH_TARGET_SYSTEM:
|
|
#endif
|
|
case SWITCH_RPCSS:
|
|
case SWITCH_HOOKOLE:
|
|
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_APP_CONFIG:
|
|
case SWITCH_MS_EXT:
|
|
case SWITCH_MS_UNION:
|
|
case SWITCH_OLDNAMES:
|
|
case SWITCH_IDLBASE:
|
|
case SWITCH_NO_FMT_OPT:
|
|
case SWITCH_GUARD_DEFS:
|
|
case SWITCH_INTERNAL:
|
|
case SWITCH_C_EXT:
|
|
case SWITCH_OSF:
|
|
case SWITCH_MKTYPLIB:
|
|
case SWITCH_OLD_TLB:
|
|
case SWITCH_NEW_TLB:
|
|
Status = ProcessOrdinarySwitch( SwitchValue, pThisArg );
|
|
break;
|
|
|
|
case SWITCH_ODL_ENV:
|
|
Status = ProcessOrdinarySwitch( SwitchValue, pThisArg );
|
|
SwitchValue = SWITCH_ENV;
|
|
break;
|
|
|
|
case SWITCH_ERROR:
|
|
|
|
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_CPP_CMD:
|
|
case SWITCH_CPP_OPT:
|
|
|
|
Status = ProcessOnetimeSwitch( SwitchValue, pThisArg );
|
|
break;
|
|
|
|
case SWITCH_PREFIX:
|
|
|
|
pSwitchPrefix->CmdProcess(this, pThisArg );
|
|
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))
|
|
{
|
|
freopen(pRedirectOutputSwitch->GetFileName(), "w", stdout);
|
|
}
|
|
|
|
// 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
|
|
CMD_ARG::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
|
|
_cmd_arg::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;
|
|
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
|
|
_cmd_arg::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.
|
|
|
|
if( ( pActualArg - (pThisArg+2) ) != 0 )
|
|
{
|
|
|
|
// we need a space
|
|
|
|
pTemp = new char [ strlen( pThisArg ) +
|
|
strlen( pActualArg ) +
|
|
1 + // 1 for space
|
|
1 // 1 for terminator.
|
|
];
|
|
sprintf( pTemp, "%s %s", pThisArg, pActualArg );
|
|
}
|
|
|
|
if(!(*ppMSwitch) )
|
|
*ppMSwitch = new multiple_switch( pTemp );
|
|
else
|
|
(*ppMSwitch)->Add( pTemp );
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|
|
STATUS_T
|
|
_cmd_arg::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_CLASS_METHODS: ppFNSwitch = &pServerFileSwitch; break;
|
|
case SWITCH_CLASS_HEADER: ppFNSwitch = &pServerHeaderFileSwitch; break;
|
|
case SWITCH_CLASS_IUNKNOWN: ppFNSwitch = &pServerUnkFileSwitch; break;
|
|
case SWITCH_PROXY_DEF: ppFNSwitch = &pProxyDefSwitch; break;
|
|
case SWITCH_DLL_SERVER_DEF: ppFNSwitch = &pDllServerDefSwitch; break;
|
|
case SWITCH_DLL_SERVER_CLASS_GEN: ppFNSwitch = &pDllClassGenSwitch; break;
|
|
case SWITCH_SERVER_REG: ppFNSwitch = &pServerRegSwitch; break;
|
|
case SWITCH_EXE_SERVER: ppFNSwitch = &pExeServerMainSwitch; break;
|
|
case SWITCH_EXE_SERVER_MAIN: ppFNSwitch = &pTestFileSwitch; break;
|
|
case SWITCH_TESTCLIENT: ppFNSwitch = &pTestFileSwitch; break;
|
|
case SWITCH_DLLDATA: ppFNSwitch = &pDllDataSwitch; break;
|
|
case SWITCH_TLIB: ppFNSwitch = &pTlibSwitch; break;
|
|
case SWITCH_REDIRECT_OUTPUT: ppFNSwitch = &pRedirectOutputSwitch; 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
|
|
CMD_ARG::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;
|
|
char cThisCh;
|
|
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:
|
|
|
|
// Zp can take only 1, 2 , 4, 8 as input.
|
|
|
|
Temp = *pThisArg - '0';
|
|
|
|
if( ( !IS_NUMERIC_1( pThisArg ) ) ||
|
|
((Temp != 1) &&
|
|
(Temp != 2) &&
|
|
(Temp != 4) &&
|
|
(Temp != 8) ) )
|
|
goto illarg;
|
|
ZeePee = Temp;
|
|
break;
|
|
|
|
case SWITCH_W:
|
|
|
|
// warning level of 0 specifies no warnings.
|
|
|
|
Temp = *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_DEFAULT;
|
|
}
|
|
else if ( strcmp( pThisArg, "i" ) == 0 )
|
|
{
|
|
SetOptimizationFlags( OPTIMIZE_INTERPRETER );
|
|
OptimLevel = OPT_LEVEL_I0;
|
|
}
|
|
else if ( strcmp( pThisArg, "ic" ) == 0 )
|
|
{
|
|
SetOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
|
|
OptimLevel = OPT_LEVEL_I1;
|
|
}
|
|
else if ( strcmp( pThisArg, "i1" ) == 0 )
|
|
{
|
|
SetOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
|
|
OptimLevel = OPT_LEVEL_I1;
|
|
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_I2;
|
|
}
|
|
else if ( strcmp( pThisArg, "i2" ) == 0 )
|
|
{
|
|
SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
|
OptimLevel = OPT_LEVEL_I2;
|
|
RpcError( NULL, 0, CMD_OI2_OBSOLETE, "Oi2");
|
|
}
|
|
#if defined(TARGET_RKK)
|
|
else if ( strcmp( pThisArg, "x" ) == 0 )
|
|
{
|
|
SetOptimizationFlags( OPTIMIZE_INTERPRETER_IX );
|
|
OptimLevel = OPT_LEVEL_IX;
|
|
}
|
|
#endif
|
|
else
|
|
goto illarg;
|
|
|
|
}
|
|
break;
|
|
|
|
case SWITCH_ODL_ENV:
|
|
pThisArg -= 2; // back up past the first three characters of the switch "win", "dos" or "mac"
|
|
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;
|
|
break;
|
|
|
|
#if defined(TARGET_RKK)
|
|
case SWITCH_TARGET_SYSTEM:
|
|
|
|
if( SelectChoice( TargetChoice, pThisArg, &Temp ) != STATUS_OK )
|
|
goto illarg;
|
|
TargetSystem = (TARGET_ENUM) Temp;
|
|
break;
|
|
#endif
|
|
|
|
case SWITCH_NO_WARN:
|
|
|
|
WLevel = 0; // was WARN_LEVEL_MAX
|
|
break;
|
|
|
|
case SWITCH_HOOKOLE:
|
|
case SWITCH_MIDLDEBUG:
|
|
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_APP_CONFIG:
|
|
case SWITCH_MS_EXT:
|
|
case SWITCH_MS_UNION:
|
|
case SWITCH_OLDNAMES:
|
|
case SWITCH_IDLBASE:
|
|
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_INTERNAL:
|
|
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:
|
|
|
|
SwitchDefined( SWValue );
|
|
break;
|
|
|
|
case SWITCH_CPP_CMD:
|
|
case SWITCH_CPP_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:
|
|
|
|
assert( FALSE );
|
|
}
|
|
|
|
return Status;
|
|
|
|
illarg:
|
|
RpcError( (char *)NULL,
|
|
0,
|
|
Status = ILLEGAL_ARGUMENT,
|
|
SwitchStringForValue( SWValue ) );
|
|
return Status;
|
|
}
|
|
|
|
STATUS_T
|
|
CMD_ARG::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:
|
|
|
|
if( pThisArg )
|
|
{
|
|
if( SelectChoice( ErrorChoice, pThisArg ,&Temp ) != STATUS_OK )
|
|
goto illarg;
|
|
}
|
|
|
|
if( Temp == ERROR_NONE)
|
|
ErrorOption = ERROR_NONE;
|
|
else
|
|
ErrorOption |= Temp;
|
|
break;
|
|
|
|
default:
|
|
|
|
assert( FALSE );
|
|
}
|
|
|
|
return Status;
|
|
|
|
illarg:
|
|
RpcError( (char *)NULL,
|
|
0,
|
|
Status = ILLEGAL_ARGUMENT,
|
|
SwitchStringForValue( SWValue ) );
|
|
return Status;
|
|
}
|
|
|
|
STATUS_T
|
|
CMD_ARG::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 ];
|
|
BOOL fNoCPPOpt;
|
|
|
|
|
|
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 the Proxy def switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_PROXY_DEF ) )
|
|
{
|
|
pProxyDefSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
"proxydef",
|
|
".def",
|
|
"" );
|
|
}
|
|
else
|
|
pProxyDefSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the dll server def switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_DLL_SERVER_DEF ) )
|
|
{
|
|
pDllServerDefSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
"dllsrvr",
|
|
".def",
|
|
"" );
|
|
}
|
|
else
|
|
pDllServerDefSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the dll server main switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_DLL_SERVER_CLASS_GEN ) )
|
|
{
|
|
pDllClassGenSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".cxx",
|
|
"_g" );
|
|
}
|
|
else
|
|
pDllClassGenSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the com server reg file switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_SERVER_REG ) )
|
|
{
|
|
pServerRegSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".reg",
|
|
"" );
|
|
}
|
|
else
|
|
pServerRegSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the com exe server support file switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_EXE_SERVER ) )
|
|
{
|
|
pExeServerSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".cxx",
|
|
"_e" );
|
|
}
|
|
else
|
|
pExeServerSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the com exe server main file switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_EXE_SERVER_MAIN ) )
|
|
{
|
|
pExeServerMainSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".cxx",
|
|
"" );
|
|
}
|
|
else
|
|
pExeServerMainSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the test client switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_TESTCLIENT ) )
|
|
{
|
|
pTestFileSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".cxx",
|
|
"_t" );
|
|
}
|
|
else
|
|
pTestFileSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
if (!IsSwitchDefined( SWITCH_TLIB ) )
|
|
{
|
|
pTlibSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".tlb",
|
|
"" );
|
|
}
|
|
else
|
|
pTlibSwitch->TransformFileNameForOut(agDrive, agPath);
|
|
|
|
// if the com class methods switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_CLASS_METHODS ) )
|
|
{
|
|
pServerFileSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".cxx",
|
|
"_m" );
|
|
}
|
|
else
|
|
pServerFileSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the com class IUnknown switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_CLASS_IUNKNOWN ) )
|
|
{
|
|
pServerUnkFileSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".cxx",
|
|
"_u" );
|
|
}
|
|
else
|
|
pServerUnkFileSwitch->TransformFileNameForOut( agDrive, agPath );
|
|
|
|
// if the com class header switch is not set, set it
|
|
if(!IsSwitchDefined( SWITCH_CLASS_HEADER ) )
|
|
{
|
|
pServerHeaderFileSwitch = new filename_switch( agDrive,
|
|
agPath,
|
|
agBaseName,
|
|
".h",
|
|
"_d" );
|
|
}
|
|
else
|
|
pServerHeaderFileSwitch->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() );
|
|
}
|
|
|
|
// 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( fNoCPPOpt = (BOOL) !IsSwitchDefined( SWITCH_CPP_OPT ) )
|
|
{
|
|
|
|
|
|
int Len = 0;
|
|
char * pTemp,
|
|
* pTemp1;
|
|
|
|
if( fNoCPPOpt)
|
|
{
|
|
Len += strlen( ADDITIONAL_CPP_OPT() );
|
|
if( !pISwitch && IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
|
|
Len += strlen( "-I." ) + 1;
|
|
}
|
|
|
|
if( pISwitch ) Len += pISwitch->GetConsolidatedLength();
|
|
if( pDSwitch ) Len += pDSwitch->GetConsolidatedLength();
|
|
if( pUSwitch ) Len += pUSwitch->GetConsolidatedLength();
|
|
|
|
|
|
pTemp = new char[ Len + 1 ]; pTemp[0] = '\0';
|
|
|
|
if(fNoCPPOpt && !pISwitch && IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
|
|
{
|
|
strcat( pTemp, "-I." );
|
|
}
|
|
|
|
if( pISwitch )
|
|
{
|
|
strcat( pTemp, pTemp1 = pISwitch->GetConsolidatedOptions() );
|
|
delete pTemp1;
|
|
}
|
|
|
|
if( pDSwitch )
|
|
{
|
|
strcat( pTemp, pTemp1 = pDSwitch->GetConsolidatedOptions() );
|
|
delete pTemp1;
|
|
}
|
|
|
|
if( pUSwitch )
|
|
{
|
|
strcat( pTemp, pTemp1 = pUSwitch->GetConsolidatedOptions() );
|
|
delete pTemp1;
|
|
}
|
|
|
|
|
|
if(fNoCPPOpt)
|
|
{
|
|
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 the env is set to DOS or Win16, then dont emit the server files
|
|
// by setting server = none. If the user did specify server file names,
|
|
// they are ignored.
|
|
//
|
|
|
|
if( !IsSwitchDefined( SWITCH_SERVER ) )
|
|
{
|
|
if( (GetEnv() == ENV_DOS ) ||
|
|
(GetEnv() == ENV_WIN16) ||
|
|
(GetEnv() == ENV_MAC) ||
|
|
(GetEnv() == ENV_MPPC) )
|
|
{
|
|
fServer = SRVR_NONE;
|
|
}
|
|
}
|
|
|
|
|
|
// 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_NONE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// 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.
|
|
|
|
if( IsSwitchDefined( SWITCH_ENV ) )
|
|
{
|
|
if( !IsSwitchDefined( SWITCH_ZP ) )
|
|
{
|
|
switch( GetEnv() )
|
|
{
|
|
case ENV_DOS: ZeePee = 2; break;
|
|
case ENV_WIN16: ZeePee = 2; break;
|
|
case ENV_MAC: ZeePee = 2; break;
|
|
case ENV_MPPC: ZeePee = 2; break;
|
|
case ENV_WIN32: ZeePee = 8; break;
|
|
default: ZeePee = 8; break;
|
|
}
|
|
}
|
|
|
|
switch( GetEnv() )
|
|
{
|
|
case ENV_DOS:
|
|
case ENV_WIN16:
|
|
EnumSize = 2;
|
|
break;
|
|
default:
|
|
EnumSize = 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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" );
|
|
}
|
|
|
|
if ( !IsSwitchDefined( SWITCH_O ) )
|
|
{
|
|
OptimFlags = OPTIMIZE_SIZE;
|
|
OptimLevel = OPT_LEVEL_OS_DEFAULT;
|
|
}
|
|
|
|
if ( IsSwitchDefined( SWITCH_HOOKOLE ) && OptimLevel != OPT_LEVEL_I2 )
|
|
RpcError( NULL, 0, CMD_REQUIRES_I2, "hookole" );
|
|
|
|
|
|
// Check if the target system is consistent with other switches.
|
|
|
|
#if defined(TARGET_RKK)
|
|
if ( TargetSystem < NT40 && IsSwitchDefined( SWITCH_HOOKOLE ) )
|
|
RpcError( NULL, 0, CMD_REQUIRES_NT40, "hookole" );
|
|
|
|
if ( TargetSystem < NT40 && OptimLevel == OPT_LEVEL_I2 )
|
|
RpcError( NULL, 0, CMD_REQUIRES_NT40, "Oi2" );
|
|
|
|
if ( TargetSystem < NT351 && OptimLevel == OPT_LEVEL_I1 )
|
|
RpcError( NULL, 0, CMD_REQUIRES_NT351, "Oi1" );
|
|
|
|
if( OptimLevel == OPT_LEVEL_OS_DEFAULT )
|
|
{
|
|
switch ( TargetSystem )
|
|
{
|
|
case NT35:
|
|
OptimLevel = OPT_LEVEL_S0;
|
|
break;
|
|
|
|
case NT351:
|
|
OptimLevel = OPT_LEVEL_S1;
|
|
break;
|
|
|
|
case NT40:
|
|
OptimLevel = OPT_LEVEL_S2;
|
|
break;
|
|
}
|
|
|
|
}
|
|
else if( OptimLevel == OPT_LEVEL_IX )
|
|
{
|
|
switch ( TargetSystem )
|
|
{
|
|
case NT35:
|
|
OptimLevel = OPT_LEVEL_I0;
|
|
AddOptimizationFlags( OPTIMIZE_INTERPRETER );
|
|
break;
|
|
|
|
case NT351:
|
|
OptimLevel = OPT_LEVEL_I1;
|
|
AddOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
|
|
break;
|
|
|
|
case NT40:
|
|
OptimLevel = OPT_LEVEL_I2;
|
|
AddOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
|
|
break;
|
|
}
|
|
}
|
|
#endif // Target
|
|
|
|
|
|
// 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
|
|
CMD_ARG::SwitchDefined(
|
|
short sw
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Set switch to be defined.
|
|
|
|
Arguments:
|
|
|
|
sw - switch number.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
set the switch definition vector bit.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
switch_def_vector[ sw / 32 ] |=
|
|
(ulong)( (ulong)0x1 << (ulong)( (ulong)sw % 32 ) );
|
|
}
|
|
|
|
char *
|
|
CMD_ARG::GetOutputPath()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get the output path.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
Reconstitute the path name from the outputpath switch, if nothing
|
|
was specified, put in a path and a slash at the end.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
char agName[ _MAX_DRIVE + _MAX_PATH + _MAX_FNAME + _MAX_EXT + 1];
|
|
char * pOut;
|
|
char flag = 0;
|
|
|
|
strcpy( agName, pOut = pOutputPathSwitch->GetFileName() );
|
|
|
|
if( agName[0] == '\0' )
|
|
{
|
|
strcpy(agName, ".\\"), flag = 1;
|
|
}
|
|
|
|
if( flag )
|
|
{
|
|
pOut = new char [strlen( agName ) + 1];
|
|
strcpy( pOut , agName );
|
|
pOutputPathSwitch->SetFileName( pOut );
|
|
}
|
|
return pOut;
|
|
}
|
|
|
|
char *
|
|
CMD_ARG::GetCPPCmd()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
get cpp command.
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
pointer to cpp command line.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
return pCppCmdSwitch->GetOption();
|
|
}
|
|
|
|
char *
|
|
CMD_ARG::GetCPPOpt()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
get cpp options.
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
pointer to cpp options.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
return pCppOptSwitch->GetOption();
|
|
}
|
|
|
|
char *
|
|
CMD_ARG::GetMinusISpecification()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
get the consolidate -i specification, without the -I characters in them
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
pointer to a buffer containing the consolidated -i options. If the -i
|
|
is not specified, then return a null.
|
|
|
|
the returned area (if the pointer returned is not null) can be deleted
|
|
by the caller.
|
|
|
|
Notes:
|
|
|
|
GetConsolidatedLength will always return a buffer size including the -I
|
|
characters. We can safely assume, that since we are stripping those
|
|
characters, the length returned is sufficient, even if we are appending
|
|
a ; after each -I option
|
|
|
|
Also assume that the -I specification buffer always has the -I to start
|
|
with.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
char * pMinusI;
|
|
char * pTemp;
|
|
|
|
if( IsSwitchDefined( SWITCH_I ) )
|
|
{
|
|
pMinusI = new char[ pISwitch->GetConsolidatedLength() + 1];
|
|
pMinusI[0] = '\0';
|
|
|
|
pISwitch->Init();
|
|
|
|
while( pTemp = pISwitch->GetNext() )
|
|
{
|
|
strcat( pMinusI, pTemp+2 );
|
|
strcat( pMinusI, ";");
|
|
}
|
|
return pMinusI;
|
|
}
|
|
else
|
|
return (char *)0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* 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) )
|
|
{
|
|
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 = strlen( *ppArg );
|
|
|
|
while( iIndex < (sizeof(switch_desc) / sizeof( struct sw_desc ) ) )
|
|
{
|
|
pSrc = (char *) pSwDesc->pSwitchName;
|
|
Len = 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))
|
|
short cCount = 0;
|
|
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 "";
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* filename_switch member functions
|
|
*****************************************************************************/
|
|
filename_switch::filename_switch(
|
|
char * pThisArg
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
constructor
|
|
|
|
Arguments:
|
|
|
|
pointer to the filename argument.
|
|
|
|
Return Value:
|
|
|
|
NA.
|
|
|
|
Notes:
|
|
|
|
set the filename.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
pFullName = (char *)NULL;
|
|
if( pThisArg )
|
|
{
|
|
SetFileName( pThisArg );
|
|
}
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
consructor.
|
|
|
|
Arguments:
|
|
|
|
filename components.
|
|
|
|
Return Value:
|
|
|
|
NA.
|
|
|
|
Notes:
|
|
|
|
set the file names.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
filename_switch::filename_switch(
|
|
char * pD,
|
|
char * pP,
|
|
char * pN,
|
|
char * pE,
|
|
char * pS )
|
|
{
|
|
pFullName = (char *)NULL;
|
|
SetFileName( pD, pP, pN, pE, pS );
|
|
}
|
|
|
|
filename_switch::~filename_switch()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
KABOOOM !
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Huh ?
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
if( pFullName )
|
|
delete pFullName;
|
|
}
|
|
|
|
|
|
void
|
|
filename_switch::SetFileName(
|
|
char * pName
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
set filename
|
|
|
|
Arguments:
|
|
|
|
pName - filename
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
if( pFullName )
|
|
delete pFullName;
|
|
pFullName = new char [strlen(pName) + 1];
|
|
strcpy( pFullName, pName );
|
|
}
|
|
|
|
void
|
|
filename_switch::SetFileName(
|
|
char * pD,
|
|
char * pP,
|
|
char * pN,
|
|
char * pE,
|
|
char * pS
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
set file name, given its components.
|
|
|
|
Arguments:
|
|
|
|
pD - pointer to drive name ( can be null );
|
|
pP - pointer to path name ( can be null );
|
|
pN - pointer to name ( can be null );
|
|
pE - pointer to extension name ( can be null );
|
|
pS - pointer to suffix.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
The suffix is added to the filename if necesary. This routine is useful
|
|
if we need to set the filename in partial name set operations. Any
|
|
filename components previously set are overriden.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
char agDrive[ _MAX_DRIVE ];
|
|
char agPath[ _MAX_DIR ];
|
|
char agBaseName[ _MAX_FNAME ];
|
|
char agExt[ _MAX_EXT ];
|
|
short len = 0;
|
|
|
|
|
|
if( pFullName )
|
|
{
|
|
// modify only those portions of the filename that the
|
|
// caller passed in
|
|
|
|
_splitpath( pFullName, agDrive, agPath, agBaseName, agExt );
|
|
|
|
delete pFullName;
|
|
}
|
|
else
|
|
{
|
|
|
|
// this is the first time the name is being set up.
|
|
|
|
agDrive[0] = agPath[0] = agBaseName[0] = agExt[0] = '\0';
|
|
|
|
}
|
|
|
|
if(!pD) pD = agDrive;
|
|
if(!pP) pP = agPath;
|
|
if(!pN) pN = agBaseName;
|
|
if(!pS) pS = "";
|
|
if(!pE) pE = agExt;
|
|
|
|
|
|
len = strlen( pD ) + strlen( pP ) + strlen( pN ) + strlen( pS ) +
|
|
strlen( pE ) + 1;
|
|
|
|
pFullName = new char[ len ];
|
|
|
|
strcpy( pFullName, pD );
|
|
strcat( pFullName, pP );
|
|
strcat( pFullName, pN );
|
|
strcat( pFullName, pS );
|
|
strcat( pFullName, pE );
|
|
|
|
}
|
|
|
|
void
|
|
filename_switch::TransformFileNameForOut(
|
|
char * pD,
|
|
char * pP)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
transform file name to incorporate the output path, given its drive
|
|
and path components.
|
|
|
|
Arguments:
|
|
|
|
pD - pointer to drive name ( can be null );
|
|
pP - pointer to path name ( can be null );
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
If the filename switch does not have the path component, the path specified
|
|
by pP overrides it. If it does not have the drive component, the the drive
|
|
specified by pD overrides it.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
char agDrive[ _MAX_DRIVE ];
|
|
char agPath[ _MAX_DIR ];
|
|
char agPath1[ _MAX_DIR ];
|
|
char agName[ _MAX_FNAME ];
|
|
char agExt[ _MAX_EXT ];
|
|
BOOL fTransformed = FALSE;
|
|
|
|
if( pFullName )
|
|
{
|
|
_splitpath( pFullName, agDrive, agPath, agName, agExt );
|
|
|
|
// if the original name did not have the drive component, derive it
|
|
// from the specified one.
|
|
|
|
if( (agDrive[0] == '\0') &&
|
|
(agPath[0] != '\\' ) &&
|
|
(agPath[0] != '/' ) )
|
|
{
|
|
if( pD && (*pD) )
|
|
strcpy( agDrive, pD );
|
|
if( pP && (*pP ) )
|
|
{
|
|
strcpy( agPath1, pP );
|
|
strcat( agPath1, agPath );
|
|
}
|
|
else
|
|
strcpy( agPath1, agPath );
|
|
|
|
fTransformed = TRUE;
|
|
}
|
|
}
|
|
|
|
if( fTransformed )
|
|
{
|
|
delete pFullName;
|
|
pFullName = new char [ strlen( agDrive ) +
|
|
strlen( agPath1 ) +
|
|
strlen( agName ) +
|
|
strlen( agExt ) +
|
|
1 ];
|
|
strcpy( pFullName, agDrive );
|
|
strcat( pFullName, agPath1 );
|
|
strcat( pFullName, agName );
|
|
strcat( pFullName, agExt );
|
|
}
|
|
}
|
|
|
|
char *
|
|
filename_switch::GetFileName()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Getfile name.
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
the filename.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
return pFullName;
|
|
}
|
|
|
|
void
|
|
filename_switch::GetFileNameComponents(
|
|
char * pD,
|
|
char * pP,
|
|
char * pN,
|
|
char * pE
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
get file name components.
|
|
|
|
Arguments:
|
|
|
|
pD - pointer to drive name area.
|
|
pP - pointer to path name area.
|
|
pN - pointer to name area.
|
|
pE - pointer to extension area.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
Assume that all pointers pass the right size buffers. I dont check here.
|
|
Useful to get the filename components desired.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
char agDrive[ _MAX_DRIVE ];
|
|
char agPath[ _MAX_DIR ];
|
|
char agBaseName[ _MAX_FNAME ];
|
|
char agExt[ _MAX_EXT ];
|
|
|
|
|
|
_splitpath( pFullName ? pFullName : "" ,
|
|
agDrive, agPath, agBaseName, agExt );
|
|
|
|
if( pD ) strcpy( pD , agDrive );
|
|
if( pP ) strcpy( pP , agPath );
|
|
if( pN ) strcpy( pN , agBaseName );
|
|
if( pE ) strcpy( pE , agExt );
|
|
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* multiple_switch member functions
|
|
*****************************************************************************/
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
constructor.
|
|
|
|
Arguments:
|
|
|
|
argument to switch.
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
multiple_switch::multiple_switch(
|
|
char * pArg)
|
|
{
|
|
pFirst = pCurrent = (OptList *)NULL;
|
|
Add( pArg );
|
|
}
|
|
|
|
void
|
|
multiple_switch::Add(
|
|
char * pValue
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Add another argument to the multiple specification switch.
|
|
|
|
Arguments:
|
|
|
|
pValue - the argument.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
OptList * pOpt = pFirst;
|
|
OptList * pNew = new OptList;
|
|
|
|
pNew->pNext = (OptList *)NULL;
|
|
pNew->pStr = pValue;
|
|
|
|
// link it up
|
|
|
|
while( pOpt && pOpt->pNext ) pOpt = pOpt->pNext;
|
|
|
|
if( !pOpt )
|
|
pCurrent = pFirst = pNew;
|
|
else
|
|
pOpt->pNext = pNew;
|
|
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Init a walk of the multiple input switch.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void
|
|
multiple_switch::Init()
|
|
{
|
|
pCurrent = pFirst;
|
|
}
|
|
|
|
char *
|
|
multiple_switch::GetNext()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get the next argument to theis switch.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
pointer to the next argument.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
char * pValue = (char *)NULL;
|
|
|
|
if(pCurrent)
|
|
{
|
|
pValue = pCurrent->pStr;
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
return pValue;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get all the options to the multiple options switch, consolidated into
|
|
a buffer.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
pointer to a buffer containing all the concatenated arguments.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
char *
|
|
multiple_switch::GetConsolidatedOptions()
|
|
{
|
|
#define OPTION_GAP_STRING() (" ")
|
|
#define OPTION_GAP_LENGTH() (1)
|
|
|
|
int len;
|
|
char * pReturn;
|
|
|
|
len = GetConsolidatedLength();
|
|
|
|
// consolidate the options into 1
|
|
|
|
if( len && (pReturn = new char[ len + 1] ))
|
|
{
|
|
char * pTemp;
|
|
|
|
*pReturn = '\0';
|
|
Init();
|
|
while( (pTemp = GetNext() ) )
|
|
{
|
|
strcat( pReturn, pTemp );
|
|
strcat( pReturn, OPTION_GAP_STRING() );
|
|
}
|
|
}
|
|
|
|
return pReturn;
|
|
}
|
|
|
|
short
|
|
multiple_switch::GetConsolidatedLength()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get the length of the consolidated options.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
length of the options.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
char * pReturn;
|
|
short len = 0;
|
|
|
|
Init();
|
|
while( pReturn = GetNext() )
|
|
{
|
|
len += strlen( pReturn ) + OPTION_GAP_LENGTH();
|
|
}
|
|
return len;
|
|
}
|
|
|
|
#undef OPTION_GAP_STRING
|
|
#undef OPTION_GAP_LENGTH
|
|
|
|
/*****************************************************************************
|
|
* onetime_switch member functions
|
|
*****************************************************************************/
|
|
onetime_switch::onetime_switch(
|
|
char * pArg
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
constructor.
|
|
|
|
Arguments:
|
|
|
|
pArg - pointer to switch argument.
|
|
|
|
Return Value:
|
|
|
|
NA.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
if( pArg )
|
|
{
|
|
pOpt = new char[ strlen( pArg ) + 1];
|
|
strcpy( pOpt, pArg );
|
|
}
|
|
else
|
|
pOpt = (char *)NULL;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
destructor.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
NA.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
onetime_switch::~onetime_switch()
|
|
{
|
|
if( pOpt )
|
|
delete pOpt;
|
|
}
|
|
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get the option string.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
the option string.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
char *
|
|
onetime_switch::GetOption()
|
|
{
|
|
return pOpt;
|
|
}
|
|
|
|
short
|
|
onetime_switch::GetLength()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
get length of the option.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
the length of the option.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
return (short)strlen( pOpt );
|
|
}
|
|
|
|
pair_switch::pair_switch(
|
|
const CHOICE * pValidChoices )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
pair_switch_constructor
|
|
|
|
Arguments:
|
|
|
|
pValidChoiceArray - the array of valid choices (this is assumed
|
|
pre-allocated).
|
|
|
|
Return Value:
|
|
|
|
NA
|
|
|
|
Notes:
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
short MaxIndex = 0;
|
|
CHOICE * pCurChoice = (CHOICE *) pValidChoices;
|
|
|
|
typedef char * PSTR;
|
|
|
|
pArrayOfChoices = pCurChoice;
|
|
|
|
// find the size of the pair array
|
|
while ( pCurChoice->pChoice )
|
|
{
|
|
if ( pCurChoice->Choice > MaxIndex )
|
|
MaxIndex = pCurChoice->Choice;
|
|
pCurChoice++;
|
|
}
|
|
|
|
ArraySize = MaxIndex + 1;
|
|
pUserStrings = new PSTR [ ArraySize ];
|
|
|
|
for ( int i = 0; i <= MaxIndex; i++ )
|
|
pUserStrings[i] = NULL;
|
|
|
|
}
|
|
|
|
void
|
|
pair_switch::CmdProcess(
|
|
CMD_ARG * 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 = 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
|
|
|
|
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();
|
|
}
|
|
|
|
void
|
|
pair_switch::AddPair(
|
|
short Sys,
|
|
char * pUsr )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
add another prefix pair
|
|
|
|
Arguments:
|
|
|
|
Sys - the system-defined string key
|
|
pUsr - the user-defined string value.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
assert ( Sys < ArraySize );
|
|
|
|
pUserStrings[ Sys ] = pUsr;
|
|
}
|
|
|
|
char *
|
|
pair_switch::GetUserDefinedEquivalent(
|
|
short Sys )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
get the user defined prefix corresponding to the system defined prefix.
|
|
|
|
Arguments:
|
|
|
|
pSystemDefined - the system defined prefix for which the user defined
|
|
prefix is being searched.
|
|
|
|
Return Value:
|
|
|
|
The user defined prefix , if it is defined. If not, return the input
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
assert ( Sys < ArraySize );
|
|
|
|
return pUserStrings[ Sys ];
|
|
|
|
}
|
|
short
|
|
pair_switch::GetIndex(
|
|
char * pGivenString )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
search is the array of choices, if this string is a valid system known
|
|
string
|
|
|
|
Arguments:
|
|
|
|
pGivenString - the string to be searched for.
|
|
|
|
Return Value:
|
|
|
|
an index into the array of choice , -1 if the given string is not found.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
int i;
|
|
char * p;
|
|
|
|
for( i = 0; p = (char *)pArrayOfChoices[ i ].pChoice; ++i )
|
|
{
|
|
if( strcmp( p, pGivenString ) == 0 )
|
|
return pArrayOfChoices[ i ].Choice;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
BOOL
|
|
CMD_ARG::IsPrefixDifferentForStubs()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
see if any prefix for client or server or switch are different
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
BOOL - true if different prefix strings.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
char * pCPrefix;
|
|
char * pSPrefix;
|
|
char * pSwPrefix;
|
|
|
|
pCPrefix = GetUserPrefix( PREFIX_CLIENT_STUB );
|
|
pSPrefix = GetUserPrefix( PREFIX_SERVER_MGR );
|
|
pSwPrefix = GetUserPrefix( PREFIX_SWICH_PROTOTYPE );
|
|
|
|
if ( !pCPrefix )
|
|
pCPrefix = "";
|
|
if ( !pSPrefix )
|
|
pSPrefix = "";
|
|
if ( !pSwPrefix )
|
|
pSwPrefix = "";
|
|
|
|
return (BOOL) strcmp( pCPrefix, pSPrefix ) ||
|
|
(BOOL) strcmp( pCPrefix, pSwPrefix ) ||
|
|
(BOOL) strcmp( pSPrefix, pSwPrefix );
|
|
|
|
}
|
|
|
|
short
|
|
pair_switch::GetNext( char ** pSys, char ** pUser )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get the Next pair of system & user values
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
index in array of user value
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
// find the next non-null user string
|
|
Current++;
|
|
|
|
while ( ( Current < ArraySize) && !pUserStrings[ Current ] )
|
|
Current++;
|
|
|
|
if ( Current == ArraySize )
|
|
return FALSE;
|
|
|
|
// search for the first choice that matches this index
|
|
*pUser = pUserStrings[Current];
|
|
for ( short i = 0; i < ArraySize; i++ )
|
|
{
|
|
if ( pArrayOfChoices[i].Choice = Current )
|
|
{
|
|
*pSys = (char *)pArrayOfChoices[i].pChoice;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
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
|
|
_cmd_arg::Confirm()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
confirm the arguments by dumping onto the screen
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
short Option;
|
|
char * p;
|
|
char Buffer[100];
|
|
|
|
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);
|
|
|
|
if( p = GetCstubFName() )
|
|
PrintArg( SWITCH_CSTUB, p , 0);
|
|
|
|
if( IsSwitchDefined( SWITCH_D ) )
|
|
PrintArg( SWITCH_D, pDSwitch->GetConsolidatedOptions(), 0 );
|
|
|
|
Option = GetEnv();
|
|
PrintArg( SWITCH_ENV,
|
|
(Option == ENV_DOS) ? "dos" :
|
|
(Option == ENV_WIN16) ? "win16" :
|
|
(Option == ENV_MAC) ? "mac" :
|
|
(Option == ENV_MPPC) ? "powermac" : "win32", 0 );
|
|
|
|
Option = GetErrorOption();
|
|
|
|
Option = IsRpcSSAllocateEnabled();
|
|
|
|
PrintArg( SWITCH_RPCSS,
|
|
YesOrNoString(IsSwitchDefined( SWITCH_RPCSS)), 0);
|
|
|
|
PrintArg( SWITCH_HOOKOLE,
|
|
YesOrNoString(IsSwitchDefined( SWITCH_HOOKOLE)), 0);
|
|
|
|
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() )
|
|
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);
|
|
|
|
#ifdef MIDL_INTERNAL
|
|
PrintArg( SWITCH_IDLBASE,
|
|
YesOrNoString(IsSwitchDefined( SWITCH_IDLBASE)), 0);
|
|
#endif
|
|
|
|
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( 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() )
|
|
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() )
|
|
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 );
|
|
|
|
fprintf(stdout, "\n" );
|
|
}
|
|
|
|
|
|
const char *
|
|
GetOptimLevelName( _opt_level_enum Level )
|
|
{
|
|
|
|
const char * OptimLevelNames[] =
|
|
{
|
|
"s", // s0
|
|
"s", // s1
|
|
"s", // s2
|
|
"i0",
|
|
"i1",
|
|
"i2",
|
|
"ix"
|
|
};
|
|
|
|
if ( OPT_LEVEL_S0 <= Level &&
|
|
Level < sizeof(OptimLevelNames)/sizeof(char*) )
|
|
return OptimLevelNames[ Level ];
|
|
else
|
|
return "??" ;
|
|
}
|
|
|
|
void
|
|
_cmd_arg::EmitConfirm(
|
|
ISTREAM * pStream )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Emit confirm the arguments by dumping onto a stream in a more concise
|
|
format.
|
|
|
|
Arguments:
|
|
|
|
pStream - the stream to dump it to.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
short Option;
|
|
char *pEnvName, *pOptFlagName;
|
|
char Buffer[100];
|
|
|
|
pStream->Write( "/* Compiler settings for " );
|
|
pStream->Write( GetInputFileName() );
|
|
if ( IsSwitchDefined( SWITCH_ACF ) )
|
|
{
|
|
pStream->Write( ", " );
|
|
pStream->Write( GetAcfFileName() );
|
|
}
|
|
pStream->Write( ":" );
|
|
pStream->NewLine();
|
|
|
|
pOptFlagName = "Os";
|
|
if( GetOptimizationFlags() & OPTIMIZE_INTERPRETER )
|
|
{
|
|
if( OptimFlags & OPTIMIZE_INTERPRETER_IX )
|
|
pOptFlagName= "Ox";
|
|
else if( GetOptimizationFlags() & OPTIMIZE_INTERPRETER_V2 )
|
|
pOptFlagName= "Oicf";
|
|
else if( GetOptimizationFlags() & OPTIMIZE_STUBLESS_CLIENT )
|
|
pOptFlagName= "Oic";
|
|
else
|
|
pOptFlagName= "Oi";
|
|
}
|
|
|
|
pEnvName = (GetEnv() == ENV_DOS) ? "Dos" :
|
|
(GetEnv() == ENV_WIN16) ? "Win16" :
|
|
(GetEnv() == ENV_MAC) ? "Mac" :
|
|
(GetEnv() == ENV_MPPC) ? "PowerMac" : "Win32";
|
|
|
|
sprintf( Buffer, " %s (OptLev=%s), W%d, Zp%d, env=%s",
|
|
pOptFlagName,
|
|
GetOptimLevelName( OptimLevel ),
|
|
GetWarningLevel(),
|
|
GetZeePee(),
|
|
pEnvName );
|
|
pStream->Write( Buffer );
|
|
|
|
if ( IsSwitchDefined( SWITCH_MS_EXT))
|
|
pStream->Write( ", ms_ext" );
|
|
if ( IsSwitchDefined( SWITCH_APP_CONFIG))
|
|
pStream->Write( ", app_config" );
|
|
if ( IsSwitchDefined( SWITCH_C_EXT))
|
|
pStream->Write( ", c_ext" );
|
|
if ( IsSwitchDefined( SWITCH_MS_UNION))
|
|
pStream->Write( ", ms_union" );
|
|
if ( IsSwitchDefined( SWITCH_OLDNAMES))
|
|
pStream->Write( ", oldnames" );
|
|
|
|
pStream->NewLine();
|
|
|
|
strcpy( Buffer, " error checks: " );
|
|
Option = GetErrorOption();
|
|
if( Option != ERROR_NONE )
|
|
{
|
|
if( Option & ERROR_ALLOCATION )
|
|
strcat( Buffer, "allocation ");
|
|
if( Option & ERROR_REF )
|
|
strcat( Buffer, "ref ");
|
|
if( Option & ERROR_BOUNDS_CHECK )
|
|
strcat( Buffer, "bounds_check ");
|
|
if( Option & ERROR_ENUM )
|
|
strcat( Buffer, "enum ");
|
|
if( Option & ERROR_STUB_DATA )
|
|
strcat( Buffer, "stub_data ");
|
|
}
|
|
else
|
|
strcat( Buffer, "none" );
|
|
pStream->Write( Buffer );
|
|
|
|
if ( IsSwitchDefined( SWITCH_NO_FMT_OPT))
|
|
pStream->Write( ", no_format_optimization" );
|
|
if ( IsSwitchDefined( SWITCH_RPCSS))
|
|
pStream->Write( ", memory management on" );
|
|
if ( IsSwitchDefined( SWITCH_HOOKOLE))
|
|
pStream->Write( ", HookOle" );
|
|
if ( IsSwitchDefined( SWITCH_USE_EPV))
|
|
pStream->Write( ", use_epv" );
|
|
if ( IsSwitchDefined( SWITCH_NO_DEFAULT_EPV))
|
|
pStream->Write( ", no_default_epv" );
|
|
|
|
pStream->NewLine();
|
|
|
|
#if defined(TARGET_RKK)
|
|
switch ( TargetSystem )
|
|
{
|
|
case NT35:
|
|
pTarget = "NT 3.5";
|
|
break;
|
|
case NT351:
|
|
pTarget = "NT 3.51 and Win95";
|
|
break;
|
|
case NT40:
|
|
pTarget = "NT 4.0";
|
|
break;
|
|
default:
|
|
pTarget = "NT ???";
|
|
}
|
|
|
|
pStream->Write( " Release: this stub is compatible with " );
|
|
pStream->Write( pTarget );
|
|
pStream->Write( " release" );
|
|
pStream->NewLine();
|
|
pStream->Write( " or a later version of MIDL and RPC" );
|
|
pStream->NewLine();
|
|
#endif
|
|
|
|
pStream->Write( "*/" );
|
|
pStream->NewLine();
|
|
|
|
}
|
|
|
|
STATUS_T
|
|
_cmd_arg::Help()
|
|
{
|
|
int i,LineCount;
|
|
BOOL fFinish = FALSE;
|
|
|
|
|
|
for(i = 0; i < sizeof(HelpArray)/sizeof(char *) ;)
|
|
{
|
|
for( LineCount = 0;
|
|
(LineCount < 23) && (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 );
|
|
}
|