301 lines
9.5 KiB
C++
301 lines
9.5 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Copyright (C) 1996-1997, Microsoft Corporation.
|
||
|
//
|
||
|
// File: varutil.cxx
|
||
|
//
|
||
|
// Contents: Utilities for variable replacement
|
||
|
//
|
||
|
// History: 96/Jan/3 DwightKr Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <pch.cxx>
|
||
|
#pragma hdrstop
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsAReplaceableParameter, public
|
||
|
//
|
||
|
// Synopsis: Determines whether parameter replacement needs to be done
|
||
|
// on a string.
|
||
|
//
|
||
|
// Arguments: [wcsString] - string to perform replacement on
|
||
|
//
|
||
|
// Returns: eIsSimpleString - if no replacement needs to be done
|
||
|
// eIsSimpleReplacement - if it's a simple string substitution
|
||
|
// eIsComplexReplacement - it's more complex than simple subst.
|
||
|
//
|
||
|
// History: 96-Apr-04 AlanW Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
EIsReplaceable IsAReplaceableParameter( WCHAR const * wcsString )
|
||
|
{
|
||
|
if ( wcsString == 0 || *wcsString == 0 )
|
||
|
return eIsSimpleString;
|
||
|
|
||
|
BOOL fStartWithPercent = *wcsString == L'%';
|
||
|
wcsString++;
|
||
|
|
||
|
while ( *wcsString )
|
||
|
{
|
||
|
if ( *wcsString == L'%' )
|
||
|
{
|
||
|
if ( !fStartWithPercent ||
|
||
|
wcsString[1] != L'\0' )
|
||
|
return eIsComplexReplacement;
|
||
|
else
|
||
|
return eIsSimpleReplacement;
|
||
|
}
|
||
|
if ( fStartWithPercent && iswspace( *wcsString ) )
|
||
|
break;
|
||
|
|
||
|
wcsString++;
|
||
|
}
|
||
|
|
||
|
return fStartWithPercent ? eIsComplexReplacement : eIsSimpleString;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ReplaceNumericParameter, public
|
||
|
//
|
||
|
// Synopsis: Returns the value of a numeric parameter.
|
||
|
//
|
||
|
// Arguments: [wcsVariableString] - string to perform replacement on
|
||
|
// [variableSet] - list of replaceable parameters
|
||
|
// [outputFormat] - format of numbers & dates
|
||
|
// [defaultVal] - default value for result
|
||
|
// [minVal] - minumum value for result
|
||
|
// [maxVal] - maxumum value for result
|
||
|
//
|
||
|
// Returns: ULONG - parameter value
|
||
|
//
|
||
|
// History: 96-Apr-04 AlanW Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
ULONG ReplaceNumericParameter( WCHAR const * wcsVariableString,
|
||
|
CVariableSet & variableSet,
|
||
|
COutputFormat & outputFormat,
|
||
|
ULONG defaultVal,
|
||
|
ULONG minVal,
|
||
|
ULONG maxVal )
|
||
|
{
|
||
|
ULONG ulValue = defaultVal;
|
||
|
|
||
|
if ( 0 == wcsVariableString )
|
||
|
ulValue = defaultVal;
|
||
|
else if ( IsAReplaceableParameter( wcsVariableString ) == eIsSimpleString )
|
||
|
ulValue = wcstoul( wcsVariableString, 0, 10 );
|
||
|
else
|
||
|
{
|
||
|
ULONG cchValue;
|
||
|
XPtrST<WCHAR> xStr( ReplaceParameters( wcsVariableString,
|
||
|
variableSet,
|
||
|
outputFormat,
|
||
|
cchValue ) );
|
||
|
|
||
|
if ( cchValue > 0 )
|
||
|
ulValue = wcstoul( xStr.GetPointer(), 0, 10 );
|
||
|
}
|
||
|
|
||
|
ulValue = min( max( minVal, ulValue ), maxVal );
|
||
|
|
||
|
return ulValue;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ReplaceParameters - public
|
||
|
//
|
||
|
// Synopsis: Generates a new string, replacing the replaceable
|
||
|
// parameters with their current values
|
||
|
//
|
||
|
// Arguments: [wcsVariableString] - string to perform replacement on
|
||
|
// [variableSet] - list of replaceable parameters
|
||
|
// [outputFormat] - format of numbers & dates
|
||
|
// [cwcOut] - returns length of returned string
|
||
|
//
|
||
|
// Returns: WCHAR * new string
|
||
|
//
|
||
|
// History: 96-Feb-14 DwightKr Created
|
||
|
// 96-Apr-04 AlanW Added simple string substitution
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
WCHAR * ReplaceParameters( WCHAR const * wcsVariableString,
|
||
|
CVariableSet & variableSet,
|
||
|
COutputFormat & outputFormat,
|
||
|
ULONG & cwcOut )
|
||
|
{
|
||
|
if ( 0 == wcsVariableString )
|
||
|
{
|
||
|
cwcOut = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
switch ( IsAReplaceableParameter( wcsVariableString ) )
|
||
|
{
|
||
|
case eIsSimpleString:
|
||
|
{
|
||
|
ULONG cwcString = wcslen( wcsVariableString ) + 1;
|
||
|
WCHAR * wcsString = new WCHAR[ cwcString ];
|
||
|
RtlCopyMemory( wcsString,
|
||
|
wcsVariableString,
|
||
|
cwcString * sizeof(WCHAR) );
|
||
|
|
||
|
cwcOut = cwcString - 1;
|
||
|
return wcsString;
|
||
|
}
|
||
|
|
||
|
case eIsSimpleReplacement:
|
||
|
{
|
||
|
ULONG cwcString = wcslen ( wcsVariableString );
|
||
|
Win4Assert( wcsVariableString[0] == L'%' &&
|
||
|
wcsVariableString[cwcString-1] == L'%' );
|
||
|
|
||
|
XPtrST<WCHAR> xStr( new WCHAR[ cwcString+1 ] );
|
||
|
RtlCopyMemory( xStr.GetPointer(),
|
||
|
wcsVariableString,
|
||
|
cwcString * sizeof(WCHAR) );
|
||
|
xStr.GetPointer()[ cwcString ] = L'\0';
|
||
|
//
|
||
|
// Null out '%' at end of variable name
|
||
|
//
|
||
|
xStr.GetPointer()[ cwcString-1 ] = L'\0';
|
||
|
|
||
|
_wcsupr( xStr.GetPointer() ); // var. lookup requires upper case
|
||
|
ULONG cwcValue = 0;
|
||
|
WCHAR const * wcsValue =
|
||
|
variableSet.GetStringValueRAW( xStr.GetPointer()+1,
|
||
|
ISAPIVariableNameHash( xStr.GetPointer()+1 ),
|
||
|
outputFormat,
|
||
|
cwcValue );
|
||
|
|
||
|
if ( 0 != wcsValue )
|
||
|
{
|
||
|
if (cwcValue > cwcString )
|
||
|
{
|
||
|
// Realloc string buffer for value replacement
|
||
|
delete xStr.Acquire();
|
||
|
xStr.Set( new WCHAR[ cwcValue+1 ] );
|
||
|
}
|
||
|
|
||
|
RtlCopyMemory( xStr.GetPointer(),
|
||
|
wcsValue,
|
||
|
cwcValue * sizeof(WCHAR) );
|
||
|
xStr.GetPointer()[ cwcValue ] = L'\0';
|
||
|
cwcOut = cwcValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Restore '%' at end of variable name
|
||
|
//
|
||
|
xStr.GetPointer()[ cwcString-1 ] = wcsVariableString[ cwcString-1 ];
|
||
|
cwcOut = cwcString;
|
||
|
}
|
||
|
ciGibDebugOut(( DEB_ITRACE, "Adding %ws as a simple replaceable parameter\n",
|
||
|
xStr.GetPointer() ));
|
||
|
return xStr.Acquire();
|
||
|
}
|
||
|
|
||
|
case eIsComplexReplacement:
|
||
|
{
|
||
|
CParameterReplacer varReplacer( wcsVariableString,
|
||
|
L"%",
|
||
|
L"%" );
|
||
|
|
||
|
varReplacer.ParseString( variableSet );
|
||
|
|
||
|
CVirtualString wcsVirtualString;
|
||
|
varReplacer.ReplaceParams( wcsVirtualString,
|
||
|
variableSet,
|
||
|
outputFormat );
|
||
|
|
||
|
ciGibDebugOut(( DEB_ITRACE, "Adding %ws as a complex replaceable parameter\n",
|
||
|
wcsVirtualString.Get() ));
|
||
|
|
||
|
cwcOut = wcsVirtualString.StrLen();
|
||
|
return wcsVirtualString.StrDup();
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
Win4Assert( !"Bad return from IsAReplaceableParameter" );
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The path given for the catalog should leave room for \Catalog.Wci\8.3
|
||
|
// Leave room for 2 8.3 names with a backslash.
|
||
|
//
|
||
|
const ULONG MAX_CAT_PATH = MAX_PATH - 13*2;
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: IsAValidCatalog
|
||
|
//
|
||
|
// Synopsis: Determines if the catalog specified is valid.
|
||
|
//
|
||
|
// Arguments: [wcsCatalog] - path to catalog or the catalog name
|
||
|
// [cwc] - length of the string
|
||
|
//
|
||
|
// History: 96-Mar-25 DwightKr Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL IsAValidCatalog(
|
||
|
WCHAR const * wcsCatalog,
|
||
|
ULONG cwc )
|
||
|
{
|
||
|
if ( cwc >= MAX_CAT_PATH ||
|
||
|
0 == cwc )
|
||
|
{
|
||
|
ciGibDebugOut(( DEB_ERROR, "length invalid for catalog (%ws)\n",
|
||
|
wcsCatalog ));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// Can't do additional checking since:
|
||
|
// 1) if the machine is remote, the catalog path is meaningless
|
||
|
// 2) it's probably a catalog name, not a path anyway
|
||
|
|
||
|
return TRUE;
|
||
|
} //IsAValidCatalog
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IDQ_wtol
|
||
|
//
|
||
|
// Synopsis: Super-strict long parser, inspired by Mihai
|
||
|
//
|
||
|
// Arguments: [pwcBuf] - the string containing the long
|
||
|
//
|
||
|
// History: 96-Jun-7 dlee Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
LONG IDQ_wtol( WCHAR const * pwcBuf )
|
||
|
{
|
||
|
WCHAR *pwcEnd = (WCHAR *) pwcBuf;
|
||
|
|
||
|
LONG l = wcstol( pwcBuf, &pwcEnd, 10 );
|
||
|
|
||
|
if ( pwcEnd == pwcBuf )
|
||
|
THROW( CException( STATUS_INVALID_PARAMETER ) );
|
||
|
|
||
|
while ( iswspace( *pwcEnd ) )
|
||
|
pwcEnd++;
|
||
|
|
||
|
if ( 0 != *pwcEnd )
|
||
|
THROW( CException( STATUS_INVALID_PARAMETER ) );
|
||
|
|
||
|
return l;
|
||
|
} // IDQ_wtol
|
||
|
|