NT4/private/windows/win4help/common/common.cpp
2020-09-30 17:12:29 +02:00

416 lines
8.4 KiB
C++

/****************************************************************************
*
* COMMON.CPP
*
* Copyright (C) Microsoft Corporation 1993-1994
* All Rights reserved.
*
*****************************************************************************/
#include "stdafx.h"
#pragma hdrstop
#ifndef _COMMON_H
#include "..\common\common.h"
#endif
#ifndef _INC_CTYPE
#include <ctype.h>
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/***************************************************************************
FUNCTION: stristr
PURPOSE: Case-insensitive search for a sub string in a main string
PARAMETERS:
pszMain
pszSub
RETURNS:
COMMENTS:
Not tested
MODIFICATION DATES:
28-Mar-1994 [ralphw]
***************************************************************************/
PSTR STDCALL stristr(PCSTR pszMain, PCSTR pszSub)
{
PSTR pszCur = (PSTR) pszMain;
char ch = tolower(*pszSub);
int cb = strlen(pszSub) - 1; // -1 to ignore leading character
for (;;) {
while (tolower(*pszCur) != ch && *pszCur)
pszCur++;
if (!*pszCur)
return NULL;
if (_strnicmp(pszCur + 1, pszSub + 1, cb) == 0)
return pszCur;
pszCur++;
}
}
/***************************************************************************
FUNCTION: IsThereMore
PURPOSE: Given a pointer to an argument, or the space after an argument,
return a pointer to the next argument if there is one, or
NULL if there is no additional argument
RETURNS: Pointer to second item, NULL if none found.
COMMENTS:
Normally a dot command such as .list is passed to this to determine
if there is additional text on the same line. If there is, a pointer
to the second item is returned.
MODIFICATION DATES:
03-Apr-1989 [ralphw]
05-Jul-1989 [ralphw]
If the current pointer is to a quote, then skip everything until
the next quote.
***************************************************************************/
PSTR STDCALL IsThereMore(PCSTR psz)
{
if (!psz)
return NULL;
// If the current argument is quoted, skip to next quote
if (*psz == CH_QUOTE || *psz == CH_START_QUOTE) {
char chEnd = (*psz == CH_QUOTE) ? CH_QUOTE : CH_END_QUOTE;
KeepTrying:
for (psz++; *psz != chEnd && *psz; psz++);
if (psz[-1] == CH_BACKSLASH) {
psz++;
goto KeepTrying;
}
if (*psz == chEnd)
psz++;
}
// find the first space or EOL
while (*psz > CH_SPACE && *psz)
psz++;
// find the first non-space
while (isspace(*psz))
psz++;
return (*psz) ? (PSTR) psz : NULL;
}
/***************************************************************************
FUNCTION: FirstNonSpace
PURPOSE: Return a pointer to the first non-space character
RETURNS:
COMMENTS:
MODIFICATION DATES:
30-May-1989 [ralphw]
***************************************************************************/
#ifndef _INC_CTYPE
#include <ctype.h>
#endif
PSTR STDCALL FirstNonSpace(PCSTR psz, BOOL fDBCS)
{
if (fDBCS) {
while (!IsDBCSLeadByte(*psz) && IsDbcsSpace(*psz, TRUE))
psz++;
return (PSTR) psz;
}
while(IsDbcsSpace(*psz, FALSE))
psz++;
return (PSTR) psz;
}
/***************************************************************************
FUNCTION: IsDbcsSpace
PURPOSE: DBCS-aware version of isspace
PARAMETERS:
ch
fDBCS
RETURNS:
COMMENTS:
MODIFICATION DATES:
14-Jan-1995 [ralphw]
***************************************************************************/
BOOL STDCALL IsDbcsSpace(char ch, BOOL fDBCS)
{
if (fDBCS)
return (!IsDBCSLeadByte(ch) && (ch == CH_SPACE || ch == CH_TAB));
else
return ((ch == CH_SPACE || ch == CH_TAB));
}
/***************************************************************************
FUNCTION: ChangeExtension
PURPOSE: Changes the extension of a filename
RETURNS:
COMMENTS:
The extension can be specified with or without the leading period.
MODIFICATION DATES:
25-May-1990 [ralphw]
04-Aug-1990 [ralphw]
NULL for an extension means remove any existing extension
***************************************************************************/
void STDCALL ChangeExtension(PSTR pszDest, PCSTR pszExt)
{
PSTR psz;
static BOOL fDBCSSystem = IsDbcsSystem();
ASSERT(pszDest);
ASSERT(!pszExt || *pszExt != '.'); // don't specify leading period
// If NULL is specified, simply remove any existing extension
if (pszExt == NULL || !*pszExt) {
if ((psz = StrRChr(pszDest, '.', fDBCSSystem)) != NULL)
*psz = '\0';
return;
}
if ((psz = StrRChr(pszDest, '.', fDBCSSystem)) == NULL)
psz = pszDest + strlen(pszDest); // filename didn't have an extension
if (*pszExt != '.')
*psz++ = '.';
strcpy(psz, pszExt);
}
/***************************************************************************
FUNCTION: StrChr
PURPOSE: DBCS-capable version of strchr
PARAMETERS:
pszString
ch
fDBCS
RETURNS: pointer to the character
COMMENTS: This can NOT find a DBCS character. It can only be used to
find a SBCS character imbedded in a DBCS character string.
MODIFICATION DATES:
29-Jul-1994 [ralphw]
***************************************************************************/
PSTR STDCALL StrChr(PCSTR pszString, char ch, BOOL fDBCS)
{
if (!fDBCS)
return strchr(pszString, ch);
while (*pszString) {
while (IsDBCSLeadByte(*pszString))
pszString += 2;
if (*pszString == ch)
return (PSTR) pszString;
pszString++;
}
return NULL;
}
/***************************************************************************
FUNCTION: StrRChr
PURPOSE: DBCS-enabled version of strrchr
PARAMETERS:
pszString
ch
fDBCS
RETURNS:
COMMENTS:
MODIFICATION DATES:
14-Jan-1995 [ralphw]
***************************************************************************/
PSTR STDCALL StrRChr(PCSTR pszString, char ch, BOOL fDBCS)
{
if (!fDBCS)
return strrchr(pszString, ch);
PSTR pszLast = StrChr(pszString, ch, fDBCS);
if (!pszLast)
return NULL;
PSTR pszNext;
while ((pszNext = StrChr(pszLast + 1, ch, fDBCS)))
pszLast = pszNext;
return pszLast;
}
/***************************************************************************
FUNCTION: IsDbcsSystem
PURPOSE: Determine if this is a DBCS system
PARAMETERS:
void
RETURNS:
COMMENTS:
MODIFICATION DATES:
14-Jan-1995 [ralphw]
***************************************************************************/
BOOL STDCALL IsDbcsSystem(void)
{
switch (GetSystemDefaultLangID()) {
case 0x0411: // Japanese
case 0x0404: // Taiwan
case 0x1004: // Singapore
case 0x0C04: // Hong Kong
return TRUE;
default:
return FALSE;
}
}
/***************************************************************************
FUNCTION: RemoveObject
PURPOSE: Unlike DeleteObject (which this function calls), this
function not only deletes the object, but zeros-out the
handle of the object.
PARAMETERS:
phobj
RETURNS:
COMMENTS:
It's perfectly fine to call this with a NULL handle -- the function
will return immediately without attempting to delete the object.
When compiling the debugging version, this function will confirm
that the object was deleted.
MODIFICATION DATES:
05-Feb-1992 [ralphw]
***************************************************************************/
void STDCALL RemoveObject(HGDIOBJ *phobj)
{
if (*phobj == NULL)
return; // object has already been deleted
VERIFY(DeleteObject(*phobj));
*phobj = NULL;
}
BOOL STDCALL IsThisChicago(void)
{
// handles both version 4.00 and 3.99.
if (HIBYTE(LOWORD(GetVersion())) >= 90 ||
LOBYTE(LOWORD(GetVersion())) >= 4)
return TRUE;
else
return FALSE;
}
#if 0
PSTR STDCALL StrRChrDBCS(PCSTR pszString, char ch)
{
PSTR psz = StrChrDBCS(pszString, ch);
PSTR pszLast;
if (!psz)
return NULL;
do {
pszLast = psz;
psz = StrChrDBCS(pszLast + 1, ch);
} while (psz);
return pszLast;
}
#endif
// We create a static implementation of this class so that we always know
// that _fDBCSSystem and _lcidSystem have been set.
static CDbcs _cdbcs;
BOOL _fDBCSSystem;
LCID _lcidSystem;
BOOL _fDualCPU;
#include <winreg.h>
CDbcs::CDbcs()
{
_fDBCSSystem = IsDbcsSystem();
_lcidSystem = GetUserDefaultLCID();
HKEY hkey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\1", 0,
KEY_READ, &hkey) == ERROR_SUCCESS) {
_fDualCPU = TRUE;
RegCloseKey(hkey);
}
}
BOOL STDCALL nstrisubcmp(PCSTR mainstring, PCSTR substring)
{
int cb = lstrlen(substring);
int cbMain = lstrlen(mainstring);
if (cb > cbMain)
return FALSE;
return (CompareString(_lcidSystem, NORM_IGNORECASE,
mainstring, cb, substring, cb) == 2);
}