windows-nt/Source/XPSP1/NT/enduser/stuff/itircl/svmgr/cmdint/ciutil.cpp
2020-09-26 16:20:57 +08:00

327 lines
8.1 KiB
C++

/********************************************************************
TITLE: UTILIB.CPP
OWNER: johnrush (John C. Rush)
DATE CREATED: January 29, 1997
DESCRIPTION:
This is the source file for the utility library; its
associated header is utilib.h. This module will contain
all sorts of general purpose utility functions.
*********************************************************************/
#include <mvopsys.h>
#ifdef _DEBUG
static char * s_aszModule = __FILE__; /* For error report */
#endif
#include <orkin.h>
#include <iterror.h>
#include <_mvutil.h> // BlockCopy
#include "cmdint.h"
#include "cierror.h"
#include "..\svutil.h"
extern HINSTANCE _hInstITCC;
/**************************************************
DESCRIPTION:
This routine strips the trailing blanks from
a null-terminated string. It then returns
the string so that this routine will have the
side effect of actually altering its parameter.
The rationale for the approach used here -- begin
at the front of the string and count through,
rather than start at the end and count down until
a non-blank character is hit, and then back up --
is that in order to start at the end of the string,
strlen() must already have counted through it
once. This way, we only have to look at the
characters in the string once.
MATTSMI 5/21/92 -- ENHANCED TO ALSO STRIP TABS.
***************************************************/
LPWSTR WINAPI StripTrailingBlanks(LPWSTR sz)
{
LPWSTR pChar;
LPWSTR pSpace=NULL;
pChar=sz;
while (*pChar) {
if ( *pChar == L' ' || *pChar == L'\t' || *pChar == 0x1A /*CTL_Z*/)
{
if (!pSpace)
pSpace=pChar;
}
else
pSpace=NULL;
++pChar;
}
if (pSpace)
*pSpace = L'\0';
return(sz);
} /* StripTrailingBlanks */
/**************************************************
DATE DOCUMENTED: April 3, 1992
@doc INTERNAL
@api LPWSTR | SkipWhitespace | incrementes the
passed-in pointer past all leading blanks.
@parm LPWSTR | pch | pointer to be incremented.
@comm
MATTSMI 5/21/92 enhanced to also increment past tabs.
***************************************************/
LPWSTR WINAPI SkipWhitespace(LPWSTR lpwstrIn)
{
while (*lpwstrIn == L' ' || *lpwstrIn == L'\t')
++lpwstrIn;
return lpwstrIn;
} /* SkipWhitespace */
/**************************************************
DESCRIPTION:
This routine strips all Leading blanks from
a string and then scoots it over so that it
begins at the original address.
Note: obviously, a side effect of this routine
is that the original string parameter is altered.
***************************************************/
VOID WINAPI StripLeadingBlanks(LPWSTR pchSource)
{ /*** StripLeadingBlanks ***/
LPWSTR pchSeeker;
pchSeeker=pchSource;
/****************************
* FIND FIRST NON-BLANK CHAR
****************************/
while (*pchSeeker == L' ' || *pchSeeker == L'\t')
++pchSeeker;
/************************
IF THE FIRST NON-BLANK IS
NOT THE FIRST CHARACTER . . .
*************************/
if (pchSeeker != pchSource) {
/********************
SCOOT ALL BYTES DOWN
********************/
for (;;) {
if ((*pchSource=*pchSeeker) == 0)
break;
++pchSource;
++pchSeeker;
}
}
} /* StripLeadingBlanks */
/**************************************************
AUTHOR: Matthew Warren Smith.
January 17, 1992
DESCRIPTION:
This routine scans a null-terminated string
attempting to determine if it consists entirely
of digits -- ie it will be able to be converted
into a number by atol without error.
***************************************************/
BOOL WINAPI IsStringOfDigits(char *szNumericString)
{
int i=0;
while (szNumericString[i])
{
if (!isdigit( (int)(szNumericString[i])))
return(FALSE);
else
i++;
}
return(TRUE);
} /* IsStringOfDigits */
/*--------------------------------------------------------------------------*/
LONG WINAPI StrToLong (LPWSTR lszBuf)
{
register LONG Result; // Returned result
register int i; // Scratch variable
char fGetSign = 1;
/* Skip all blanks, tabs, <CR> */
if (*lszBuf == '-') {
fGetSign = -1;
lszBuf++;
}
else if (*lszBuf == '+')
lszBuf++;
Result = 0;
/* The credit of this piece of code goes to Leon */
while (i = *lszBuf - '0', i >= 0 && i <= 9) {
Result = Result * 10 + i;
lszBuf++;
}
return (Result * fGetSign);
}
#if 0
BOOL WINAPI IgnoreWarning (int errCode, PWARNIGNORE pWarnIgnore)
{
int fRet = FALSE;
WORD i;
LPWORD pwWarnings;
if (NULL == pWarnIgnore || NULL == pWarnIgnore->hMem)
return FALSE;
if (NULL == (pwWarnings = (LPWORD)_GLOBALLOCK (pWarnIgnore->hMem)))
return FALSE;
for (i = 0; i < pWarnIgnore->cbWarning && fRet == FALSE; i++)
if (*(pwWarnings + i) == (WORD)errCode)
fRet = TRUE;
_GLOBALUNLOCK (pWarnIgnore->hMem);
return fRet;
}
#endif
int WINAPI ReportError (IStream *piistm, ERRC &errc)
{
if (NULL == piistm)
return S_OK;
int errCode = errc.errCode, iLevel;
ULONG ulCount;
char rgchLocalBuf[1024];
/***************************
MODULO THE ERROR NUMBER WITH
5 TO GET THE WARNING LEVEL,
BUT SET FATAL ERRORS TO -1
SO THAT THEY ALWAYS APPEAR.
****************************/
if (errCode > 30000)
iLevel = -2; // Status message
else
{
iLevel = (errCode % 5);
if (iLevel == 4 || (errCode % 1000 == 0))
iLevel = -1; // Error message
}
switch (iLevel)
{
case -2:
STRCPY (rgchLocalBuf, "\n");
break;
case -1:
wsprintf (rgchLocalBuf, "\nError %d: ", errCode);
break;
default:
wsprintf (rgchLocalBuf, "\nWarning %d: ", errCode);
break;
}
piistm->Write
(rgchLocalBuf, (DWORD) STRLEN (rgchLocalBuf), &ulCount);
if (LoadString (_hInstITCC, errCode, rgchLocalBuf, 1024 * sizeof (char)))
wsprintf (rgchLocalBuf, rgchLocalBuf, errc.var1, errc.var2, errc.var3);
else
STRCPY (rgchLocalBuf,
"Error string could not be loaded from resource file.");
piistm->Write (rgchLocalBuf, (DWORD) STRLEN (rgchLocalBuf), &ulCount);
piistm->Write (".\r\n", (DWORD) STRLEN (".\r\n"), &ulCount);
return (errCode);
} /* ReportError */
LPWSTR GetNextDelimiter(LPWSTR pwstrStart, WCHAR wcDelimiter)
{
for (; *pwstrStart; pwstrStart++)
{
if(*pwstrStart == wcDelimiter)
return pwstrStart;
}
return NULL;
} /* GetNextDelimiter */
HRESULT ParseKeyAndValue(LPVOID pBlockMgr, LPWSTR pwstrLine, KEYVAL **ppkvOut)
{
ITASSERT(pwstrLine);
// Extract key
LPWSTR pwstrKey = SkipWhitespace(pwstrLine);
LPWSTR pwstrValue = GetNextDelimiter(pwstrKey, TOKEN_EQUAL);
if (NULL == pwstrValue)
// No delimiter!
return E_FAIL;
if (NULL == (*ppkvOut = (KEYVAL *)
BlockCopy(pBlockMgr, NULL, sizeof(KEYVAL), 0)))
return E_OUTOFMEMORY;
KEYVAL *pkvOut = *ppkvOut;
if (NULL == (pkvOut->pwstrKey = (LPWSTR)BlockCopy(pBlockMgr,
(LPB)pwstrKey, sizeof (WCHAR) * (DWORD)(pwstrValue - pwstrKey + 1), 0)))
return SetErrReturn(E_OUTOFMEMORY);
pkvOut->pwstrKey[pwstrValue - pwstrKey] = TOKEN_NULL;
StripTrailingBlanks(pkvOut->pwstrKey);
LPWSTR pwstrNextValue;
LPWSTR *plpv = (LPWSTR *)pkvOut->vaValue.Argv;
for (DWORD dwArgCount = 1; ;
dwArgCount++, pwstrValue = pwstrNextValue, plpv++)
{
pwstrValue = SkipWhitespace(pwstrValue + 1);
pwstrNextValue = GetNextDelimiter(pwstrValue, TOKEN_DELIM);
if (NULL == pwstrNextValue)
break;
if (NULL == (*plpv =
(LPWSTR)BlockCopy(pBlockMgr, (LPB)pwstrValue,
sizeof (WCHAR) * (DWORD)(pwstrNextValue - pwstrValue + 1), 0)))
return SetErrReturn(E_OUTOFMEMORY);
(*plpv)[pwstrNextValue - pwstrValue] = TOKEN_NULL;
StripTrailingBlanks(*plpv);
}
if (NULL == (*plpv = (LPWSTR)BlockCopy
(pBlockMgr, (LPB)pwstrValue, (DWORD) WSTRCB(pwstrValue), 0)))
return SetErrReturn(E_OUTOFMEMORY);
StripTrailingBlanks(*plpv);
pkvOut->vaValue.dwArgc = dwArgCount;
return S_OK;
} /* ParseKeyAndValue */