mirror of https://github.com/tongzx/nt5src
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.
1179 lines
34 KiB
1179 lines
34 KiB
//+------------------------------------------------------------------
|
|
//
|
|
// File: cbasecmd.cxx
|
|
//
|
|
// Contents: implementation for CBaseCmdlineObj
|
|
//
|
|
// Synoposis: CBaseCmdlineObj encapsulates a single command line
|
|
// switch, eg. /username:lizch. It specifies the switch
|
|
// string (username) and stores the value (lizch) as
|
|
// a string. This class also provides methods for
|
|
// retrieving the value, displaying it and setting it
|
|
// to a default, and displaying usage for this switch.
|
|
//
|
|
// Classes: CBaseCmdlineObj
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 12/27/91 Lizch Created
|
|
// 04/17/92 Lizch Converted to NLS_STR
|
|
// 28 Aug 92 GeordiS changed nlsNULL to nlsNULLSTR
|
|
// 31 Aug 92 GeordiS changed nlsNULLSTR back.
|
|
// 09/09/92 Lizch Changed SUCCESS and NERR_Success
|
|
// to NO_ERROR
|
|
// 09/18/92 Lizch Precompile headers
|
|
// 11/14/92 DwightKr Updates for new version of NLS_STR
|
|
// 10/13/93 DeanE Converted to WCHAR
|
|
//
|
|
//-------------------------------------------------------------------
|
|
#include <comtpch.hxx>
|
|
#pragma hdrstop
|
|
|
|
#include <cmdlinew.hxx> // public cmdlinew stuff
|
|
#include "_clw.hxx" // private cmdlinew stuff
|
|
#include <ctype.h> // is functions
|
|
|
|
|
|
LPCNSTR nszCmdlineBase = _TEXTN("Takes a string ");
|
|
LPCNSTR nszLineArgBase = _TEXTN("<string> ");
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Function: CBaseCmdlineObj Constructor (1 of 2)
|
|
//
|
|
// Member: CBaseCmdlineObj
|
|
//
|
|
// Synoposis: Initialises switch string, usage values and whether the
|
|
// switch is mandatory. This constructor gives no default value
|
|
// for this switch.
|
|
//
|
|
// Arguments: [nszSwitch] - the expected switch string
|
|
// [nszUsage] - the usage statement to display
|
|
// [fMustHave] - whether the switch is mandatory or not.
|
|
// if it is, an error will be generated if
|
|
// the switch is not specified on the
|
|
// command line. Defaults to FALSE.
|
|
// [nszLineArg] - line arg
|
|
//
|
|
// Returns: none, but sets _iLastError
|
|
//
|
|
// History: Created 04/17/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
CBaseCmdlineObj::CBaseCmdlineObj(
|
|
LPCNSTR nszSwitch,
|
|
LPCNSTR nszUsage,
|
|
BOOL fMustHave,
|
|
LPCNSTR nszLineArg)
|
|
{
|
|
Init(nszSwitch, nszUsage, fMustHave, _TEXTN(""), nszLineArg);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Function: CBaseCmdlineObj Constructor (2 of 2)
|
|
//
|
|
// Member: CBaseCmdlineObj
|
|
//
|
|
// Synoposis: Initialises switch string, usage strings and default value.
|
|
// This constructor is only used if a switch is optional.
|
|
//
|
|
// Effects: Sets fMandatory to FALSE (ie. switch is optional)
|
|
//
|
|
// Arguments: [nszSwitch] - the expected switch string
|
|
// [nszUsage] - the usage statement to display
|
|
// [nszDefault] - the value to be used if no switch is
|
|
// specified on the command line.
|
|
// [nszLineArg] - line arg
|
|
//
|
|
// Returns: none, but sets _iLastError
|
|
//
|
|
// History: Created 04/17/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
CBaseCmdlineObj::CBaseCmdlineObj(
|
|
LPCNSTR nszSwitch,
|
|
LPCNSTR nszUsage,
|
|
LPCNSTR nszDefault,
|
|
LPCNSTR nszLineArg)
|
|
{
|
|
Init(nszSwitch, nszUsage, FALSE, nszDefault, nszLineArg);
|
|
_fDefaultSpecified = TRUE;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Function: Init
|
|
//
|
|
// Member: Private, called from constructors for CBaseCmdlineObj
|
|
//
|
|
// Synoposis: Sets defaults for members and allocates memory
|
|
// for switch string.
|
|
//
|
|
// Arguments: [nszSwitch] - the expected command line switch
|
|
// [nszUsage] - the usage statement for display
|
|
// [fMustHave] - whether the switch is mandatory or not.
|
|
// if it is, an error will be generated if
|
|
// the switch is not specified on the
|
|
// command line. Defaults to FALse
|
|
// [nszDefault] - the value to be used if no switch is
|
|
// specified on the command line.
|
|
// [nszLineArg] - line arg.
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Modifies: Out of memory error, or CMDLINE_NO_ERROR
|
|
//
|
|
// History: 12/29/91 Lizch Created.
|
|
// 04/17/92 Lizch Converted to NLS_STR
|
|
// 7/14/92 DeanE Initialized _fFoundSwitch
|
|
// 07/31/92 Davey Added _fSecondArg and _pnlsLineArgType,
|
|
// and added nlsLineArg parameter.
|
|
//
|
|
//-------------------------------------------------------------------
|
|
void CBaseCmdlineObj::Init(
|
|
LPCNSTR nszSwitch,
|
|
LPCNSTR nszUsage,
|
|
BOOL fMustHave,
|
|
LPCNSTR nszDefault,
|
|
LPCNSTR nszLineArg)
|
|
{
|
|
SetError(CMDLINE_NO_ERROR);
|
|
|
|
// Initialize member variables
|
|
_pValue = NULL;
|
|
_fMandatory = fMustHave;
|
|
_fDefaultSpecified = FALSE;
|
|
_fSecondArg = TRUE;
|
|
_fFoundSwitch = FALSE;
|
|
|
|
SetSeparator(nchDefaultSep);
|
|
SetEquater(nchDefaultEquater);
|
|
|
|
// Allocate space and initialize member strings
|
|
_pnszUsageString = new NCHAR[_ncslen(nszUsage)+1];
|
|
if (_pnszUsageString == NULL)
|
|
{
|
|
SetError(CMDLINE_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
else
|
|
{
|
|
_ncscpy(_pnszUsageString, nszUsage);
|
|
}
|
|
|
|
_pnszSwitch = new NCHAR[_ncslen(nszSwitch)+1];
|
|
if (_pnszSwitch == NULL)
|
|
{
|
|
SetError(CMDLINE_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
else
|
|
{
|
|
_ncscpy(_pnszSwitch, nszSwitch);
|
|
}
|
|
|
|
_pnszDefaultValue = new NCHAR[_ncslen(nszDefault)+1];
|
|
if (NULL == _pnszDefaultValue)
|
|
{
|
|
SetError(CMDLINE_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
else
|
|
{
|
|
_ncscpy(_pnszDefaultValue, nszDefault);
|
|
}
|
|
|
|
// if the passed in linearg is NULL then use default one, use
|
|
// NULL to keep arguments consistent in parameter lists.
|
|
//
|
|
if (nszLineArg == NULL)
|
|
{
|
|
_pnszLineArgType = NULL;
|
|
}
|
|
else
|
|
{
|
|
_pnszLineArgType = new NCHAR[_ncslen(nszLineArg)+1];
|
|
if (NULL == _pnszLineArgType)
|
|
{
|
|
SetError(CMDLINE_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
else
|
|
{
|
|
_ncscpy(_pnszLineArgType, nszLineArg);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj destructor
|
|
//
|
|
// Synoposis: Frees any memory associated with the object
|
|
//
|
|
// History: 12/27/91 Lizch Created.
|
|
// 04/17/92 Lizch Changed to NLS_STR.
|
|
// 08/03/92 Davey Added delete of _pnlsLineArgType
|
|
//
|
|
//-------------------------------------------------------------------
|
|
CBaseCmdlineObj::~CBaseCmdlineObj()
|
|
{
|
|
delete (NCHAR *)_pValue;
|
|
_pValue = NULL;
|
|
|
|
delete _pnszUsageString;
|
|
delete _pnszSwitch;
|
|
delete _pnszDefaultValue;
|
|
delete _pnszLineArgType;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::SetValue, public
|
|
//
|
|
// Synopsis: Stores the value specified after the switch string
|
|
// (eg: "lizch" from "/username:lizch").
|
|
//
|
|
// Arguments: [nszArg] - the string following the switch on
|
|
// the command line. Excludes the
|
|
// equator (eg. ':' in the above example)
|
|
//
|
|
// Returns: CMDLINE_NO_ERROR or out of memory
|
|
//
|
|
// History: 12/27/91 Lizch Created
|
|
// 04/17/92 Lizch Converted to NLS_STR
|
|
//
|
|
//-------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::SetValue(LPCNSTR nszArg)
|
|
{
|
|
INT nRet = CMDLINE_NO_ERROR;
|
|
|
|
// delete any existing pValue
|
|
delete (NCHAR *)_pValue;
|
|
_pValue = NULL;
|
|
|
|
_pValue = new NCHAR[_ncslen(nszArg)+1];
|
|
if (_pValue == NULL)
|
|
{
|
|
nRet = CMDLINE_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
_ncscpy((NCHAR *)_pValue, nszArg);
|
|
}
|
|
|
|
return(nRet);
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::ResetValue, public
|
|
//
|
|
// Synopsis: Deletes the value so the object becomes "clean" again.
|
|
//
|
|
//
|
|
// Returns: CMDLINE_NO_ERROR or out of memory
|
|
//
|
|
// History: 06/13/97 MariusB Created
|
|
//
|
|
//-------------------------------------------------------------------
|
|
void CBaseCmdlineObj::ResetValue()
|
|
{
|
|
if (NULL != _pValue)
|
|
{
|
|
delete _pValue;
|
|
_pValue = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::SetValueToDefault, public
|
|
//
|
|
// Synopsis: Sets the default value for the switch. This value is
|
|
// used if no switch is specified on the command line.
|
|
//
|
|
// Effects: This is the base implementation for the virtual
|
|
// method SetValueToDefault. It simply calls SetValue.
|
|
// Derived classes may need to do more complex things,
|
|
// eg, the default may be the name of the Domain Controller,
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: CMDLINE_NO_ERROR or out of memory
|
|
//
|
|
// History: Created 12/27/91 Lizch
|
|
// Converted to NLS_STR 04/17/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::SetValueToDefault()
|
|
{
|
|
return(SetValue(_pnszDefaultValue));
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::GetValue, public
|
|
//
|
|
// Synopsis: Returns a pointer to the switch value
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: a const CHAR pointer to the switch value, not including
|
|
// the equater character
|
|
//
|
|
// History: Created 05/27/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
LPCNSTR CBaseCmdlineObj::GetValue()
|
|
{
|
|
return((LPCNSTR)_pValue);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::IsFound, public
|
|
//
|
|
// Synopsis: Indicates whether this command line switch was found.
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: TRUE if the switch was found, FALSE otherwise
|
|
//
|
|
// History: Created 05/27/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
BOOL CBaseCmdlineObj::IsFound()
|
|
{
|
|
return(_fFoundSwitch);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::SetFoundFlag, public
|
|
//
|
|
// Synopsis: Sets whether this command line switch was found.
|
|
//
|
|
// Arguments: TRUE if switch is found, FALSE otherwise
|
|
//
|
|
// Returns: nothing
|
|
//
|
|
// History: Created 05/27/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
void CBaseCmdlineObj::SetFoundFlag(BOOL fFound)
|
|
{
|
|
_fFoundSwitch = fFound;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::IsRequired, public
|
|
//
|
|
// Synopsis: Indicates whether this command line switch is mandatory.
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: TRUE if the switch was manadatory, FALSE otherwise
|
|
//
|
|
// History: Created 05/27/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
BOOL CBaseCmdlineObj::IsRequired ()
|
|
{
|
|
return(_fMandatory);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::IsDefaultSpecified, public
|
|
//
|
|
// Synopsis: Indicates whether this command line switch has a default
|
|
// value.
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: TRUE if the switch has a default, FALSE otherwise
|
|
//
|
|
// History: Created 05/27/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
BOOL CBaseCmdlineObj::IsDefaultSpecified ()
|
|
{
|
|
return(_fDefaultSpecified);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::SetSeparator, public
|
|
//
|
|
// Synoposis: Sets the valid switch separator character, i.e.
|
|
// the '/' in /a:foo
|
|
//
|
|
// Arguments: [nchSeparator] - the new separator character
|
|
//
|
|
// Returns: Previous separator.
|
|
//
|
|
// History: 05/23/91 Lizch Created.
|
|
// 08/10/92 Davey Changed to take only one char., added
|
|
// return of error code
|
|
//
|
|
//-------------------------------------------------------------------
|
|
NCHAR CBaseCmdlineObj::SetSeparator(NCHAR nchSeparator)
|
|
{
|
|
NCHAR nchOld = _nchSeparator;
|
|
|
|
_nchSeparator = nchSeparator;
|
|
|
|
return(nchOld);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::SetEquater, public
|
|
//
|
|
// Synoposis: Sets the set of valid equater characters, i.e.
|
|
// the ':' in /a:foo
|
|
//
|
|
// Arguments: [nchEquater] - the new equater character
|
|
//
|
|
// Returns: Previous equater.
|
|
//
|
|
// History: 05/23/91 Lizch Created.
|
|
// 08/10/92 Davey Changed to take only one char., added
|
|
// return of error code
|
|
//
|
|
//-------------------------------------------------------------------
|
|
NCHAR CBaseCmdlineObj::SetEquater(NCHAR nchEquater)
|
|
{
|
|
NCHAR nchOld = _nchEquater;
|
|
|
|
_nchEquater = nchEquater;
|
|
|
|
return(nchOld);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::GetSeparator, public
|
|
//
|
|
// Synoposis: Returns the separator character for this object.
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: Current separator character.
|
|
//
|
|
// History: 10/17/93 DeanE Created
|
|
//
|
|
//-------------------------------------------------------------------
|
|
NCHAR CBaseCmdlineObj::GetSeparator()
|
|
{
|
|
return(_nchSeparator);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::GetEquater, public
|
|
//
|
|
// Synoposis: Returns the equater character for this object.
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: Current equater character.
|
|
//
|
|
// History: 10/17/93 DeanE Created
|
|
//
|
|
//-------------------------------------------------------------------
|
|
NCHAR CBaseCmdlineObj::GetEquater()
|
|
{
|
|
return(_nchEquater);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::QuerySwitchString, public
|
|
//
|
|
// Synopsis: Returns a pointer to the switch string, eg. the "mc" in
|
|
// /mc:foo
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: a const NCHAR pointer to the switch string
|
|
//
|
|
// History: Created 05/27/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
LPCNSTR CBaseCmdlineObj::QuerySwitchString()
|
|
{
|
|
return(_pnszSwitch);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::DisplayValue, public
|
|
//
|
|
// Synoposis: Prints the stored command line value according to
|
|
// current display method. Generally this will be to stdout.
|
|
//
|
|
// History: Created 12/27/91 Lizch
|
|
// Converted to NLS_STR 04/17/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
void CBaseCmdlineObj::DisplayValue()
|
|
{
|
|
if (_pValue != NULL)
|
|
{
|
|
_sNprintf(_nszErrorBuf,
|
|
_TEXTN("Command line switch %s has value %s\n"),
|
|
_pnszSwitch,
|
|
(NCHAR *)_pValue);
|
|
(*_pfnDisplay)(_nszErrorBuf);
|
|
}
|
|
else
|
|
{
|
|
DisplayNoValue();
|
|
}
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::DisplayNoValue, protected
|
|
//
|
|
// Synoposis: Displays a "no value set" message.
|
|
//
|
|
// History: Created 05/14/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
void CBaseCmdlineObj::DisplayNoValue()
|
|
{
|
|
_sNprintf(_nszErrorBuf,
|
|
_TEXTN("No value for command line switch %s\n"),
|
|
_pnszSwitch);
|
|
(*_pfnDisplay)(_nszErrorBuf);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Member: CBaseCmdlineObj::DisplaySpecialUsage, protected
|
|
//
|
|
// Synoposis: Outputs special usage - for base class there is none.
|
|
//
|
|
// History: Created 05/14/92 Lizch
|
|
//
|
|
//-------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::DisplaySpecialUsage(
|
|
USHORT usDisplayWidth,
|
|
USHORT usIndent,
|
|
USHORT *pusWidth)
|
|
{
|
|
return(CMDLINE_NO_ERROR);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::QueryCmdlineType, protected, const
|
|
//
|
|
// Synoposis: returns a character pointer to the cmdline type.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: const NCHAR * reference to string.
|
|
//
|
|
// History: 28-Jul-92 davey Created.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
LPCNSTR CBaseCmdlineObj::QueryCmdlineType() const
|
|
{
|
|
return(nszCmdlineBase);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::QueryLineArgType, protected, const
|
|
//
|
|
// Synoposis: returns a character pointer to the line arg type.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: const NCHAR *reference to string.
|
|
//
|
|
// History: 28-Jul-92 davey Created.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
LPCNSTR CBaseCmdlineObj::QueryLineArgType() const
|
|
{
|
|
// if user has not defined one then give default one
|
|
if (_pnszLineArgType == NULL)
|
|
{
|
|
return(nszLineArgBase);
|
|
}
|
|
else
|
|
{
|
|
return(_pnszLineArgType);
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::DisplayUsageLine, protected
|
|
//
|
|
// Synopsis: Displays line usage information
|
|
//
|
|
// Arguments: [pusWidth] - How much space is left on line to display
|
|
// the usage.
|
|
// [usDisplayWidth] - Max width allowed to display usage
|
|
// [usIndent] - Amount to indent for next line of usage
|
|
//
|
|
// History: 28-Jul-92 davey Created.
|
|
//
|
|
// Notes: Looks like:
|
|
//
|
|
// test2 /mc:<worker> [/ml:<log_server>] [/mt:<test>]
|
|
// [/mn:<tester-email>] [/mp:<path>] [/mo:<obj_name>]
|
|
// [/md:<dispatcher>] [/?]
|
|
//
|
|
//--------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::DisplayUsageLine(
|
|
USHORT *pusWidth,
|
|
USHORT usDisplayWidth,
|
|
USHORT usIndent)
|
|
{
|
|
INT nRet = CMDLINE_NO_ERROR;
|
|
LPNSTR pnszLine = NULL;
|
|
ULONG cchLine;
|
|
LPCNSTR nszLeftBracket = _TEXTN("[");
|
|
LPCNSTR nszRightBracket = _TEXTN("]");
|
|
LPCNSTR nszType = QueryLineArgType();
|
|
NCHAR nszSeparator[2];
|
|
NCHAR nszEquater[2];
|
|
|
|
// Initialize separator and equater strings
|
|
nszSeparator[0] = _nchSeparator;
|
|
nszSeparator[1] = nchClNull;
|
|
|
|
nszEquater[0] = _nchEquater;
|
|
nszEquater[1] = nchClNull;
|
|
|
|
// Determine length of the display line - Add one for terminating NULL
|
|
cchLine = 1 + _ncslen(nszSeparator) + _ncslen(_pnszSwitch);
|
|
|
|
if (FALSE == _fMandatory)
|
|
{
|
|
cchLine += _ncslen(nszLeftBracket) + _ncslen(nszRightBracket);
|
|
}
|
|
|
|
if (TRUE == _fSecondArg)
|
|
{
|
|
cchLine += _ncslen(nszEquater) + _ncslen(nszType);
|
|
}
|
|
|
|
// Build the display line
|
|
pnszLine = new NCHAR[cchLine];
|
|
if (NULL == pnszLine)
|
|
{
|
|
return(CMDLINE_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
|
|
*pnszLine = nchClNull;
|
|
if (FALSE == _fMandatory)
|
|
{
|
|
_ncscat(pnszLine, nszLeftBracket);
|
|
}
|
|
|
|
_ncscat(pnszLine, nszSeparator);
|
|
_ncscat(pnszLine, _pnszSwitch);
|
|
|
|
if (TRUE == _fSecondArg)
|
|
{
|
|
_ncscat(pnszLine, nszEquater);
|
|
_ncscat(pnszLine, nszType);
|
|
}
|
|
|
|
if (FALSE == _fMandatory)
|
|
{
|
|
_ncscat(pnszLine, nszRightBracket);
|
|
}
|
|
|
|
nRet = DisplayWord(pnszLine, usDisplayWidth, usIndent, pusWidth);
|
|
|
|
// Clean up and exit
|
|
delete pnszLine;
|
|
|
|
return(nRet);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::DisplayUsageDescr, protected
|
|
//
|
|
// Synopsis: Displays switch descriptions information
|
|
//
|
|
// Arguments: [usSwitchIndent] - Amount to indent for switches
|
|
// [usDisplayWidth] - Max width allowed to display usage
|
|
// [usUsageIndent] - Amount to indent for next line of usage
|
|
//
|
|
// History: 28-Jul-92 davey Created.
|
|
//
|
|
// Notes: looks like.
|
|
//
|
|
// /mc Takes a list of strings specifying worker names.
|
|
// These workers should have full names.
|
|
// Don't you think so?
|
|
// The strings in the list are separated by one of the following
|
|
// character(s): ",; ".
|
|
// /ml Takes a string specifying log server name.
|
|
// /mt Takes a string specifying name of the test.
|
|
// /mn Takes a string specifying email name of the tester.
|
|
// /mp Takes a string specifying path name to log to.
|
|
// /mo Takes a string specifying name of the object.
|
|
// /md Takes a string specifying name of the dispatcher to use.
|
|
// /? Flag specifying command line usage. It defaults to FALSE.
|
|
//
|
|
// Here's how the various indent values relate to each other:
|
|
//
|
|
// <-------------------------usDisplayWidth------------------------->
|
|
// <--usSwitchIndent-->/foo
|
|
// <--------usUsageIndent----->Takes a list...
|
|
//
|
|
//--------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::DisplayUsageDescr(
|
|
USHORT usSwitchIndent,
|
|
USHORT usDisplayWidth,
|
|
USHORT usUsageIndent)
|
|
{
|
|
INT iRC;
|
|
LPNSTR pnszSwitch;
|
|
LPNSTR pnszUsage;
|
|
LPNSTR pnszDefault = NULL;
|
|
USHORT cchUsage;
|
|
USHORT cchSwitch;
|
|
USHORT cchPaddedSwitch;
|
|
USHORT usLineSpaceLeft;
|
|
LPCNSTR nszSpecify = _TEXTN("specifying ");
|
|
LPCNSTR nszDefault = _TEXTN("It defaults to ");
|
|
LPCNSTR nszType = QueryCmdlineType();
|
|
NCHAR nszSeparator[2];
|
|
|
|
// Initialize separator string
|
|
nszSeparator[0] = _nchSeparator;
|
|
nszSeparator[1] = nchClNull;
|
|
|
|
// Calculate size of switch buffer - if this length is less than
|
|
// usUsageIndent then allocate extra room to pad spaces out to
|
|
// usUsageIndent and the usage will start on the same line; else
|
|
// the usage will start on the next line with an indent. Also,
|
|
// the null-terminator is NOT accounted for in this value.
|
|
//
|
|
cchSwitch = (USHORT) (usSwitchIndent + _ncslen(nszSeparator)
|
|
+ _ncslen(_pnszSwitch) ) ;
|
|
if (cchSwitch < usUsageIndent)
|
|
{
|
|
cchPaddedSwitch = usUsageIndent;
|
|
}
|
|
else
|
|
{
|
|
cchPaddedSwitch = (USHORT) (cchSwitch + usUsageIndent
|
|
+ _ncslen(nszClNewLine) );
|
|
}
|
|
|
|
// Calculate size of usage buffer - null-terminator NOT accounted for
|
|
//
|
|
cchUsage = (USHORT) (_ncslen(nszType) +
|
|
_ncslen(nszSpecify) +
|
|
_ncslen(_pnszUsageString) );
|
|
|
|
|
|
// Allocate buffers - add 1 for NULL-terminators
|
|
pnszSwitch = new NCHAR[cchPaddedSwitch+1];
|
|
pnszUsage = new NCHAR[cchUsage+1];
|
|
if (pnszSwitch == NULL || pnszUsage == NULL)
|
|
{
|
|
delete pnszSwitch;
|
|
delete pnszUsage;
|
|
return(CMDLINE_ERROR_OUT_OF_MEMORY);
|
|
}
|
|
|
|
// Initialize switch buffer - fill with usSwitchIndent spaces, then
|
|
// append the separator and switch, then pad with spaces out to
|
|
// usUsageIndent if necessary
|
|
//
|
|
for (USHORT i=0; i<usSwitchIndent; i++)
|
|
{
|
|
pnszSwitch[i] = nchClSpace;
|
|
}
|
|
|
|
pnszSwitch[usSwitchIndent] = nchClNull;
|
|
_ncscat(pnszSwitch, nszSeparator);
|
|
_ncscat(pnszSwitch, _pnszSwitch);
|
|
|
|
if ((USHORT)_ncslen(pnszSwitch) >= usUsageIndent)
|
|
{
|
|
// Pad a new line.
|
|
_ncscat(pnszSwitch, nszClNewLine);
|
|
}
|
|
// Pad spaces until usUsageIndemt
|
|
for (i = (USHORT) _ncslen(pnszSwitch); i < cchPaddedSwitch; i++)
|
|
{
|
|
pnszSwitch[i] = nchClSpace;
|
|
}
|
|
pnszSwitch[cchPaddedSwitch] = nchClNull;
|
|
|
|
// Initialize usage buffer
|
|
_ncscpy(pnszUsage, nszType);
|
|
_ncscat(pnszUsage, nszSpecify);
|
|
_ncscat(pnszUsage, _pnszUsageString);
|
|
|
|
// Now we're ready to output the strings - output the switch, then
|
|
// set up the values needed to output the usage line.
|
|
//
|
|
(*_pfnDisplay)(pnszSwitch);
|
|
usLineSpaceLeft = (USHORT) (usDisplayWidth - usUsageIndent);
|
|
|
|
// Output the usage
|
|
iRC = DisplayStringByWords(
|
|
pnszUsage,
|
|
usDisplayWidth,
|
|
usUsageIndent,
|
|
&usLineSpaceLeft);
|
|
if (iRC != CMDLINE_NO_ERROR)
|
|
{
|
|
delete pnszSwitch;
|
|
delete pnszUsage;
|
|
return(iRC);
|
|
}
|
|
|
|
|
|
// output the special usage
|
|
//
|
|
iRC = DisplaySpecialUsage(usDisplayWidth, usUsageIndent, &usLineSpaceLeft);
|
|
if (iRC != CMDLINE_NO_ERROR)
|
|
{
|
|
delete pnszSwitch;
|
|
delete pnszUsage;
|
|
return(iRC);
|
|
}
|
|
|
|
|
|
// output the default value string
|
|
//
|
|
if (_fDefaultSpecified)
|
|
{
|
|
// Default string is " " + nszDefault + _pnszDefaultValue + "."
|
|
pnszDefault = new NCHAR[_ncslen(_pnszDefaultValue) +
|
|
_ncslen(nszDefault) + 4];
|
|
if (pnszDefault == NULL)
|
|
{
|
|
iRC = CMDLINE_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
_ncscpy(pnszDefault, _TEXTN(" "));
|
|
_ncscat(pnszDefault, nszDefault);
|
|
_ncscat(pnszDefault, _pnszDefaultValue);
|
|
_ncscat(pnszDefault, _TEXTN("."));
|
|
|
|
iRC = DisplayStringByWords(
|
|
pnszDefault,
|
|
usDisplayWidth,
|
|
usUsageIndent,
|
|
&usLineSpaceLeft);
|
|
}
|
|
|
|
if (iRC != CMDLINE_NO_ERROR)
|
|
{
|
|
delete pnszDefault;
|
|
delete pnszSwitch;
|
|
delete pnszUsage;
|
|
return(iRC);
|
|
}
|
|
}
|
|
|
|
|
|
// Next thing output should go on a new line
|
|
//
|
|
(*_pfnDisplay)(nszClNewLine);
|
|
|
|
delete pnszSwitch;
|
|
delete pnszUsage;
|
|
delete pnszDefault;
|
|
|
|
return(iRC);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::DisplayStringByWords, protected
|
|
//
|
|
// Synopsis: Writes out the strings word by word following indentation
|
|
// and display width rules; words are delimeted by spaces.
|
|
// The string begins on the current line at the current
|
|
// location (usDisplayWidth-*pusSpaceLeft), including
|
|
// any leading space characters.
|
|
//
|
|
// Arguments: [nszString] - String to output.
|
|
// [usDisplayWidth] - Max width allowed to display usage
|
|
// [usIndent] - Amount to indent for next line of usage
|
|
// [pusSpaceLeft] - Space left on this line
|
|
//
|
|
// History: 28-Jul-92 davey Created.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::DisplayStringByWords(
|
|
LPCNSTR nszString,
|
|
USHORT usDisplayWidth,
|
|
USHORT usIndent,
|
|
USHORT *pusSpaceLeft)
|
|
{
|
|
INT iRC = CMDLINE_NO_ERROR;
|
|
BOOL fDone = FALSE;
|
|
LPNSTR pnszWord = NULL;
|
|
LPCNSTR pnchWord = nszString;
|
|
LPCNSTR pnchTrav = nszString;
|
|
USHORT i;
|
|
|
|
// Skip leading spaces, but they are part of the first word
|
|
while (nchClSpace == *pnchTrav)
|
|
{
|
|
pnchTrav++;
|
|
}
|
|
|
|
// Traverse the string until we get to the end
|
|
while (!fDone)
|
|
{
|
|
// Traverse until we find a space, newline, or null
|
|
switch(*pnchTrav)
|
|
{
|
|
case L' ':
|
|
// Retrieve the word from the string
|
|
iRC = CopyWord(pnchWord, pnchTrav-pnchWord, &pnszWord);
|
|
if (iRC == CMDLINE_NO_ERROR)
|
|
{
|
|
// Output the word
|
|
iRC = DisplayWord(
|
|
pnszWord,
|
|
usDisplayWidth,
|
|
usIndent,
|
|
pusSpaceLeft);
|
|
}
|
|
delete pnszWord;
|
|
|
|
//Set up the next word
|
|
pnchWord = pnchTrav++;
|
|
|
|
// traverse to next non-space character
|
|
while (nchClSpace == *pnchTrav)
|
|
{
|
|
pnchTrav++;
|
|
}
|
|
break;
|
|
|
|
case L'\n':
|
|
// Retrieve the word from the string, including the newline
|
|
iRC = CopyWord(pnchWord, ++pnchTrav-pnchWord, &pnszWord);
|
|
if (iRC == CMDLINE_NO_ERROR)
|
|
{
|
|
// Output the word
|
|
iRC = DisplayWord(
|
|
pnszWord,
|
|
usDisplayWidth,
|
|
usIndent,
|
|
pusSpaceLeft);
|
|
}
|
|
delete pnszWord;
|
|
|
|
// Output usIndent spaces
|
|
for (i=0; i<usIndent; i++)
|
|
{
|
|
(*_pfnDisplay)(nszClSpace);
|
|
}
|
|
*pusSpaceLeft = (USHORT) (usDisplayWidth - usIndent);
|
|
|
|
// traverse to next non-space character
|
|
while (nchClSpace == *pnchTrav)
|
|
{
|
|
pnchTrav++;
|
|
}
|
|
|
|
// Set up the next word - note leading blanks are skipped
|
|
// so the word will be aligned with the indent
|
|
//
|
|
pnchWord = pnchTrav;
|
|
break;
|
|
|
|
case L'\0':
|
|
// Output the current word
|
|
iRC = DisplayWord(
|
|
pnchWord,
|
|
usDisplayWidth,
|
|
usIndent,
|
|
pusSpaceLeft);
|
|
fDone = TRUE;
|
|
break;
|
|
|
|
default:
|
|
// Skip to next character
|
|
pnchTrav++;
|
|
break;
|
|
}
|
|
|
|
if (iRC != CMDLINE_NO_ERROR)
|
|
{
|
|
fDone = TRUE;
|
|
}
|
|
}
|
|
|
|
return(iRC);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::CopyWord, protected
|
|
//
|
|
// Synopsis: Copies cchWord characters starting at pnchWord into a
|
|
// null-terminated string buffer (which the caller must
|
|
// delete).
|
|
//
|
|
// Arguments: [pnchWord] - place to copy from.
|
|
// [cchWord] - number of characters to copy.
|
|
// [ppnszWord] - buffer returned to caller.
|
|
//
|
|
// History: 15-Oct-93 DeanE Created.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::CopyWord(
|
|
LPCNSTR pnchWord,
|
|
ULONG cchWord,
|
|
LPNSTR *ppnszWord)
|
|
{
|
|
INT iRC = CMDLINE_NO_ERROR;
|
|
|
|
*ppnszWord = new NCHAR[cchWord+1];
|
|
if (NULL == *ppnszWord)
|
|
{
|
|
iRC = CMDLINE_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
_ncsncpy(*ppnszWord, pnchWord, cchWord);
|
|
*(*ppnszWord + cchWord) = nchClNull;
|
|
}
|
|
|
|
return(iRC);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Method: CBaseCmdLineObj::DisplayWord, protected
|
|
//
|
|
// Synopsis: Writes out the given word according to the display
|
|
// parameters.
|
|
//
|
|
// Arguments: [nszWord] - word to output.
|
|
// [usDisplayWidth] - Max width allowed to display usage.
|
|
// [usIndent] - Amount to indent for next line of usage.
|
|
// [pusWidth] - Space left on this line.
|
|
//
|
|
// History: 28-Jul-92 davey Created.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
INT CBaseCmdlineObj::DisplayWord(
|
|
LPCNSTR nszWord,
|
|
USHORT usDisplayWidth,
|
|
USHORT usIndent,
|
|
USHORT *pusWidth)
|
|
{
|
|
INT nRet = CMDLINE_NO_ERROR;
|
|
LPCNSTR nszTmp = nszWord;
|
|
LPNSTR pnszBuf;
|
|
USHORT cchWord;
|
|
USHORT cchBuf;
|
|
USHORT cchLine = (USHORT) (usDisplayWidth - usIndent);
|
|
BOOL fDone = FALSE;
|
|
|
|
// Add one for leading space
|
|
cchWord = (USHORT) _ncslen(nszWord);
|
|
|
|
// if there is enough room left on the current line, output word
|
|
//
|
|
if (cchWord <= *pusWidth)
|
|
{
|
|
(*_pfnDisplay)(nszWord);
|
|
|
|
// update the remaining width
|
|
*pusWidth = (USHORT) (*pusWidth - cchWord);
|
|
}
|
|
else
|
|
{
|
|
// Spit the word out on the next line, traversing more than
|
|
// one line if necessary
|
|
do
|
|
{
|
|
// Calculate how much of the word can be output
|
|
if (_ncslen(nszTmp) <= cchLine)
|
|
{
|
|
cchBuf = (USHORT) _ncslen(nszTmp);
|
|
fDone = TRUE;
|
|
}
|
|
else
|
|
{
|
|
cchBuf = cchLine;
|
|
}
|
|
|
|
pnszBuf = new NCHAR[cchBuf+1];
|
|
if (NULL == pnszBuf)
|
|
{
|
|
fDone = TRUE;
|
|
nRet = CMDLINE_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
_ncsncpy(pnszBuf, nszTmp, cchBuf);
|
|
*(pnszBuf+cchBuf) = L'\0';
|
|
}
|
|
nszTmp += cchBuf;
|
|
|
|
// Output newline
|
|
(*_pfnDisplay)(nszClNewLine);
|
|
|
|
// Indent usIndent spaces
|
|
for (USHORT i=0; i<usIndent; i++)
|
|
{
|
|
(*_pfnDisplay)(nszClSpace);
|
|
}
|
|
|
|
// Output buffer
|
|
(*_pfnDisplay)(pnszBuf);
|
|
|
|
delete pnszBuf;
|
|
} while (!fDone);
|
|
|
|
// Calculate remaining width on the current line
|
|
*pusWidth = (USHORT) (usDisplayWidth - usIndent - cchBuf);
|
|
}
|
|
|
|
return(nRet);
|
|
}
|