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.
677 lines
21 KiB
677 lines
21 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: strings.c
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* This module contains all the string handling APIs and functions. Since
|
|
* they don't access server-specific data they belong here in the client DLL.
|
|
*
|
|
* History:
|
|
* 10-18-90 DarrinM Created.
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
/* LATER these should be in a public header file!!!
|
|
* Assorted defines used to support the standard Windows ANSI code page
|
|
* (now known as code page 1252 and officially registered by IBM).
|
|
* This is intended only for the PDK release. Subsequent releases will
|
|
* use the NLSAPI and Unicode.
|
|
*/
|
|
#define LATIN_CAPITAL_LETTER_A_GRAVE (CHAR)0xc0
|
|
#define LATIN_CAPITAL_LETTER_THORN (CHAR)0xde
|
|
#define LATIN_SMALL_LETTER_SHARP_S (CHAR)0xdf
|
|
#define LATIN_SMALL_LETTER_Y_DIAERESIS (CHAR)0xff
|
|
#define DIVISION_SIGN (CHAR)0xf7
|
|
#define MULTIPLICATION_SIGN (CHAR)0xd7
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharLowerA (API)
|
|
*
|
|
* Convert either a single character or an entire string to lower case. The
|
|
* two cases are differentiated by checking the high-word of psz. If it is
|
|
* 0 then we just convert the low-word of psz.
|
|
*
|
|
* History:
|
|
* 11-26-90 DarrinM Created non-NLS version.
|
|
* 06-22-91 GregoryW Modified to support code page 1252. This is for
|
|
* the PDK release only. After the PDK this routine
|
|
* will be modified to use the NLSAPI. Also renamed
|
|
* API to conform to new naming conventions. AnsiLower
|
|
* is now a #define which resolves to this routine.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, LPSTR, WINAPI, CharLowerA, LPSTR, psz)
|
|
LPSTR WINAPI CharLowerA(
|
|
LPSTR psz)
|
|
{
|
|
NTSTATUS st;
|
|
|
|
/*
|
|
* Early out for NULL string or '\0'
|
|
*/
|
|
if (psz == NULL) {
|
|
return psz;
|
|
}
|
|
|
|
if (!IS_PTR(psz)) {
|
|
WCHAR wch;
|
|
|
|
#ifdef FE_SB // CharLowerA()
|
|
/*
|
|
* if only DBCS Leadbyte was passed, just return the character.
|
|
* Same behavior as Windows 3.1J and Windows 95 FarEast version.
|
|
*/
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte((BYTE)(ULONG_PTR)psz)) {
|
|
return psz;
|
|
}
|
|
#endif // FE_SB
|
|
|
|
//
|
|
// LATER 14 Feb 92 GregoryW
|
|
// For DBCS code pages is a double byte character ever
|
|
// passed in the low word of psz or is the high nibble
|
|
// of the low word always ignored?
|
|
//
|
|
st = RtlMultiByteToUnicodeN(&wch, sizeof(WCHAR), NULL, (PCH)&psz, sizeof(CHAR));
|
|
if (!NT_SUCCESS(st)) {
|
|
/*
|
|
* Failed! Caller is not expecting failure, CharLowerA does not
|
|
* have a failure indicator, so just return the original character.
|
|
*/
|
|
RIPMSG1(RIP_WARNING, "CharLowerA(%#p) failed\n", psz);
|
|
} else {
|
|
/*
|
|
* The next two calls never fail.
|
|
*/
|
|
LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, &wch, 1, &wch, 1);
|
|
RtlUnicodeToMultiByteN((PCH)&psz, sizeof(CHAR), NULL, &wch, sizeof(WCHAR));
|
|
}
|
|
return psz;
|
|
|
|
}
|
|
|
|
/*
|
|
* psz is a null-terminated string
|
|
*/
|
|
CharLowerBuffA(psz, strlen(psz)+1);
|
|
return psz;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharUpperA (API)
|
|
*
|
|
* Convert either a single character or an entire string to upper case. The
|
|
* two cases are differentiated by checking the high-word of psz. If it is
|
|
* 0 then we just convert the low-word of psz.
|
|
*
|
|
* History:
|
|
* 12-03-90 IanJa derived from DarrinM's non-NLS AnsiLower
|
|
* 06-22-91 GregoryW Modified to support code page 1252. This is for
|
|
* the PDK release only. After the PDK this routine
|
|
* will be modified to use the NLSAPI. Also renamed
|
|
* API to conform to new naming conventions. AnsiUpper
|
|
* is now a #define which resolves to this routine.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, LPSTR, WINAPI, CharUpperA, LPSTR, psz)
|
|
LPSTR WINAPI CharUpperA(
|
|
LPSTR psz)
|
|
{
|
|
NTSTATUS st;
|
|
|
|
/*
|
|
* Early out for NULL string or '\0'
|
|
*/
|
|
if (psz == NULL) {
|
|
return psz;
|
|
}
|
|
|
|
if (!IS_PTR(psz)) {
|
|
WCHAR wch;
|
|
|
|
#ifdef FE_SB // CharLowerA()
|
|
/*
|
|
* if only DBCS Leadbyte was passed, just return the character.
|
|
* Same behavior as Windows 3.1J and Windows 95 FarEast version.
|
|
*/
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte((BYTE)(ULONG_PTR)psz)) {
|
|
return psz;
|
|
}
|
|
#endif // FE_SB
|
|
|
|
//
|
|
// LATER 14 Feb 92 GregoryW
|
|
// For DBCS code pages is a double byte character ever
|
|
// passed in the low word of psz or is the high nibble
|
|
// of the low word always ignored?
|
|
//
|
|
st = RtlMultiByteToUnicodeN(&wch, sizeof(WCHAR), NULL, (PCH)&psz, sizeof(CHAR));
|
|
if (!NT_SUCCESS(st)) {
|
|
/*
|
|
* Failed! Caller is not expecting failure, CharUpperA does not
|
|
* have a failure indicator, so return the original character.
|
|
*/
|
|
RIPMSG1(RIP_WARNING, "CharUpperA(%#p) failed\n", psz);
|
|
} else {
|
|
/*
|
|
* The next two calls never fail.
|
|
*/
|
|
LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE, &wch, 1, &wch, 1);
|
|
RtlUnicodeToMultiByteN((PCH)&psz, sizeof(CHAR), NULL, &wch, sizeof(WCHAR));
|
|
}
|
|
return psz;
|
|
|
|
}
|
|
|
|
/*
|
|
* psz is a null-terminated string
|
|
*/
|
|
CharUpperBuffA(psz, strlen(psz)+1);
|
|
return psz;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharNextA (API)
|
|
*
|
|
* Move to next character in string unless already at '\0' terminator
|
|
* DOES NOT WORK CORRECTLY FOR DBCS (eg: Japanese)
|
|
*
|
|
* History:
|
|
* 12-03-90 IanJa Created non-NLS version.
|
|
* 06-22-91 GregoryW Renamed API to conform to new naming conventions.
|
|
* AnsiNext is now a #define which resolves to this
|
|
* routine. This routine is only intended to support
|
|
* code page 1252 for the PDK release.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, LPSTR, WINAPI, CharNextA, LPCSTR, lpCurrentChar)
|
|
LPSTR WINAPI CharNextA(
|
|
LPCSTR lpCurrentChar)
|
|
{
|
|
#ifdef FE_SB // CharNextA(): dbcs enabling
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte(*lpCurrentChar)) {
|
|
lpCurrentChar++;
|
|
}
|
|
/*
|
|
* if we have only DBCS LeadingByte, we will point string-terminaler.
|
|
*/
|
|
#endif // FE_SB
|
|
|
|
if (*lpCurrentChar) {
|
|
lpCurrentChar++;
|
|
}
|
|
return (LPSTR)lpCurrentChar;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharNextExA (API)
|
|
*
|
|
* Move to next character in string unless already at '\0' terminator.
|
|
*
|
|
* History:
|
|
* 05-01-95 GregoryW Ported from Win95.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG3(LOG_GENERAL, LPSTR, WINAPI, CharNextExA, WORD, CodePage, LPCSTR, lpCurrentChar, DWORD, dwFlags)
|
|
LPSTR WINAPI CharNextExA(
|
|
WORD CodePage,
|
|
LPCSTR lpCurrentChar,
|
|
DWORD dwFlags)
|
|
{
|
|
if (lpCurrentChar == (LPSTR)NULL)
|
|
{
|
|
return (LPSTR)lpCurrentChar;
|
|
}
|
|
|
|
if (IsDBCSLeadByteEx(CodePage, *lpCurrentChar))
|
|
{
|
|
lpCurrentChar++;
|
|
}
|
|
|
|
if (*lpCurrentChar)
|
|
{
|
|
lpCurrentChar++;
|
|
}
|
|
return (LPSTR)lpCurrentChar;
|
|
|
|
UNREFERENCED_PARAMETER(dwFlags);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharPrevA (API)
|
|
*
|
|
* Move to previous character in string, unless already at start
|
|
* DOES NOT WORK CORRECTLY FOR DBCS (eg: Japanese)
|
|
*
|
|
* History:
|
|
* 12-03-90 IanJa Created non-NLS version.
|
|
* 06-22-91 GregoryW Renamed API to conform to new naming conventions.
|
|
* AnsiPrev is now a #define which resolves to this
|
|
* routine. This routine is only intended to support
|
|
* code page 1252 for the PDK release.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG2(LOG_GENERAL, LPSTR, WINAPI, CharPrevA, LPCSTR, lpStart, LPCSTR, lpCurrentChar)
|
|
LPSTR WINAPI CharPrevA(
|
|
LPCSTR lpStart,
|
|
LPCSTR lpCurrentChar)
|
|
{
|
|
#ifdef FE_SB // CharPrevA : dbcs enabling
|
|
if (lpCurrentChar > lpStart) {
|
|
if (IS_DBCS_ENABLED()) {
|
|
LPCSTR lpChar;
|
|
BOOL bDBC = FALSE;
|
|
|
|
for (lpChar = --lpCurrentChar - 1 ; lpChar >= lpStart ; lpChar--) {
|
|
if (!IsDBCSLeadByte(*lpChar))
|
|
break;
|
|
bDBC = !bDBC;
|
|
}
|
|
|
|
if (bDBC)
|
|
lpCurrentChar--;
|
|
}
|
|
else
|
|
lpCurrentChar--;
|
|
}
|
|
return (LPSTR)lpCurrentChar;
|
|
#else
|
|
if (lpCurrentChar > lpStart) {
|
|
lpCurrentChar--;
|
|
}
|
|
return (LPSTR)lpCurrentChar;
|
|
#endif // FE_SB
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* CharPrevExA (API)
|
|
*
|
|
* Move to previous character in string, unless already at start.
|
|
*
|
|
* History:
|
|
* 05-01-95 GregoryW Ported from Win95.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG4(LOG_GENERAL, LPSTR, WINAPI, CharPrevExA, WORD, CodePage, LPCSTR, lpStart, LPCSTR, lpCurrentChar, DWORD, dwFlags)
|
|
LPSTR WINAPI CharPrevExA(
|
|
WORD CodePage,
|
|
LPCSTR lpStart,
|
|
LPCSTR lpCurrentChar,
|
|
DWORD dwFlags)
|
|
{
|
|
if (lpCurrentChar > lpStart) {
|
|
LPCSTR lpChar;
|
|
BOOL bDBC = FALSE;
|
|
|
|
for (lpChar = --lpCurrentChar - 1 ; lpChar >= lpStart ; lpChar--) {
|
|
if (!IsDBCSLeadByteEx(CodePage, *lpChar))
|
|
break;
|
|
bDBC = !bDBC;
|
|
}
|
|
|
|
if (bDBC)
|
|
lpCurrentChar--;
|
|
}
|
|
return (LPSTR)lpCurrentChar;
|
|
|
|
UNREFERENCED_PARAMETER(dwFlags);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharLowerBuffA (API)
|
|
*
|
|
* History:
|
|
* 14-Jan-1991 mikeke from win 3.0
|
|
* 06-22-91 GregoryW Renamed API to conform to new naming conventions.
|
|
* AnsiLowerBuff is now a #define which resolves to this
|
|
* routine. This routine is only intended to support
|
|
* code page 1252 for the PDK release.
|
|
* 02-20-1992 GregoryW Modified to use NLS API.
|
|
\***************************************************************************/
|
|
#define CCH_LOCAL_BUFF 256
|
|
|
|
|
|
FUNCLOG2(LOG_GENERAL, DWORD, WINAPI, CharLowerBuffA, LPSTR, psz, DWORD, nLength)
|
|
DWORD WINAPI CharLowerBuffA(
|
|
LPSTR psz,
|
|
DWORD nLength)
|
|
{
|
|
ULONG cb;
|
|
WCHAR awchLocal[CCH_LOCAL_BUFF];
|
|
LPWSTR pwszT = awchLocal;
|
|
int cwch;
|
|
|
|
if (nLength == 0) {
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* Convert ANSI to Unicode.
|
|
* Use awchLocal if it is big enough, otherwise allocate space.
|
|
*/
|
|
cwch = MBToWCS(
|
|
psz, // ANSI buffer
|
|
nLength, // length of buffer
|
|
&pwszT, // address of Unicode string
|
|
(nLength > CCH_LOCAL_BUFF ? -1 : nLength),
|
|
(nLength > CCH_LOCAL_BUFF) );
|
|
|
|
if (cwch != 0) {
|
|
CharLowerBuffW(pwszT, cwch);
|
|
|
|
/*
|
|
* This can't fail
|
|
*/
|
|
RtlUnicodeToMultiByteN(
|
|
psz, // ANSI string
|
|
nLength, // given to us
|
|
&cb, // result length
|
|
pwszT, // Unicode string
|
|
cwch * sizeof(WCHAR)); // length IN BYTES
|
|
|
|
if (pwszT != awchLocal) {
|
|
UserLocalFree(pwszT);
|
|
}
|
|
|
|
return (DWORD)cb;
|
|
}
|
|
|
|
/*
|
|
* MBToWCS failed! The caller is not expecting failure,
|
|
* so we convert the string to lower case as best we can.
|
|
*/
|
|
RIPMSG2(RIP_WARNING,
|
|
"CharLowerBuffA(%#p, %lx) failed\n", psz, nLength);
|
|
|
|
for (cb=0; cb < nLength; cb++) {
|
|
#ifdef FE_SB // CharLowerBuffA(): skip double byte character
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte(psz[cb])) {
|
|
cb++;
|
|
} else if (IsCharUpperA(psz[cb])) {
|
|
psz[cb] += 'a'-'A';
|
|
}
|
|
#else
|
|
if (IsCharUpperA(psz[cb])) {
|
|
psz[cb] += 'a'-'A';
|
|
}
|
|
#endif // FE_SB
|
|
}
|
|
|
|
return nLength;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* CharUpperBuffA (API)
|
|
*
|
|
* History:
|
|
* 14-Jan-1991 mikeke from win 3.0
|
|
* 06-22-91 GregoryW Renamed API to conform to new naming conventions.
|
|
* AnsiUpperBuff is now a #define which resolves to this
|
|
* routine. This routine is only intended to support
|
|
* code page 1252 for the PDK release.
|
|
* 02-Feb-1992 GregoryW Modified to use NLS API.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG2(LOG_GENERAL, DWORD, WINAPI, CharUpperBuffA, LPSTR, psz, DWORD, nLength)
|
|
DWORD WINAPI CharUpperBuffA(
|
|
LPSTR psz,
|
|
DWORD nLength)
|
|
{
|
|
DWORD cb;
|
|
WCHAR awchLocal[CCH_LOCAL_BUFF];
|
|
LPWSTR pwszT = awchLocal;
|
|
int cwch;
|
|
|
|
if (nLength==0) {
|
|
return(0);
|
|
}
|
|
|
|
/*
|
|
* Convert ANSI to Unicode.
|
|
* Use awchLocal if it is big enough, otherwise allocate space.
|
|
*/
|
|
cwch = MBToWCS(
|
|
psz, // ANSI buffer
|
|
nLength, // length of buffer
|
|
&pwszT, // address of Unicode string
|
|
(nLength > CCH_LOCAL_BUFF ? -1 : nLength),
|
|
(nLength > CCH_LOCAL_BUFF) );
|
|
|
|
if (cwch != 0) {
|
|
CharUpperBuffW(pwszT, cwch);
|
|
|
|
RtlUnicodeToMultiByteN(
|
|
psz, // address of ANSI string
|
|
nLength, // given to us
|
|
&cb, // result length
|
|
pwszT, // Unicode string
|
|
cwch * sizeof(WCHAR)); // length IN BYTES
|
|
|
|
if (pwszT != awchLocal) {
|
|
UserLocalFree(pwszT);
|
|
}
|
|
|
|
return (DWORD)cb;
|
|
}
|
|
|
|
/*
|
|
* MBToWCS failed! The caller is not expecting failure,
|
|
* so we convert the string to upper case as best we can.
|
|
*/
|
|
RIPMSG2(RIP_WARNING,
|
|
"CharLowerBuffA(%#p, %lx) failed\n", psz, nLength);
|
|
|
|
for (cb=0; cb < nLength; cb++) {
|
|
#ifdef FE_SB // CharUpperBuffA(): skip double byte characters
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte(psz[cb])) {
|
|
cb++;
|
|
} else if (IsCharLowerA(psz[cb]) &&
|
|
/*
|
|
* Sometime, LATIN_xxxx code is DBCS LeadingByte depending on ACP.
|
|
* In that case, we never come here...
|
|
*/
|
|
(psz[cb] != LATIN_SMALL_LETTER_SHARP_S) &&
|
|
(psz[cb] != LATIN_SMALL_LETTER_Y_DIAERESIS)) {
|
|
psz[cb] += 'A'-'a';
|
|
}
|
|
#else
|
|
if (IsCharLowerA(psz[cb]) &&
|
|
(psz[cb] != LATIN_SMALL_LETTER_SHARP_S) &&
|
|
(psz[cb] != LATIN_SMALL_LETTER_Y_DIAERESIS)) {
|
|
psz[cb] += 'A'-'a';
|
|
}
|
|
#endif // FE_SB
|
|
}
|
|
|
|
return nLength;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* IsCharLowerA (API)
|
|
*
|
|
* History:
|
|
* 14-Jan-1991 mikeke from win 3.0
|
|
* 22-Jun-1991 GregoryW Modified to support code page 1252 (Windows ANSI
|
|
* code page). This is for the PDK only. After the
|
|
* PDK this routine will be rewritten to use the
|
|
* NLSAPI.
|
|
* 02-Feb-1992 GregoryW Modified to use NLS API.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, BOOL, WINAPI, IsCharLowerA, char, cChar)
|
|
BOOL WINAPI IsCharLowerA(
|
|
char cChar)
|
|
{
|
|
WORD ctype1info = 0;
|
|
WCHAR wChar = 0;
|
|
|
|
#ifdef FE_SB // IsCharLowerA()
|
|
/*
|
|
* if only DBCS Leadbyte was passed, just return FALSE.
|
|
* Same behavior as Windows 3.1J and Windows 95 FarEast version.
|
|
*/
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte(cChar)) {
|
|
return FALSE;
|
|
}
|
|
#endif // FE_SB
|
|
|
|
/*
|
|
* The following 2 calls cannot fail here
|
|
*/
|
|
RtlMultiByteToUnicodeN(&wChar, sizeof(WCHAR), NULL, &cChar, sizeof(CHAR));
|
|
GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info);
|
|
return (ctype1info & C1_LOWER) == C1_LOWER;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* IsCharUpperA (API)
|
|
*
|
|
* History:
|
|
* 22-Jun-1991 GregoryW Created to support code page 1252 (Windows ANSI
|
|
* code page). This is for the PDK only. After the
|
|
* PDK this routine will be rewritten to use the
|
|
* NLSAPI.
|
|
* 02-Feb-1992 GregoryW Modified to use NLS API.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, BOOL, WINAPI, IsCharUpperA, char, cChar)
|
|
BOOL WINAPI IsCharUpperA(
|
|
char cChar)
|
|
{
|
|
WORD ctype1info = 0;
|
|
WCHAR wChar = 0;
|
|
|
|
#ifdef FE_SB // IsCharUpperA()
|
|
/*
|
|
* if only DBCS Leadbyte was passed, just return FALSE.
|
|
* Same behavior as Windows 3.1J and Windows 95 FarEast version.
|
|
*/
|
|
if (IS_DBCS_ENABLED() && IsDBCSLeadByte(cChar)) {
|
|
return FALSE;
|
|
}
|
|
#endif // FE_SB
|
|
|
|
/*
|
|
* The following 2 calls cannot fail here
|
|
*/
|
|
RtlMultiByteToUnicodeN(&wChar, sizeof(WCHAR), NULL, &cChar, sizeof(CHAR));
|
|
GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info);
|
|
return (ctype1info & C1_UPPER) == C1_UPPER;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* IsCharAlphaNumericA (API)
|
|
*
|
|
* Returns TRUE if character is alphabetical or numerical, otherwise FALSE
|
|
*
|
|
* History:
|
|
* 12-03-90 IanJa Created non-NLS stub version.
|
|
* 06-22-91 GregoryW Modified to support code page 1252 (Windows ANSI
|
|
* code page). This is for the PDK only. After the
|
|
* PDK this routine will be rewritten to use the
|
|
* NLSAPI.
|
|
* 02-20-92 GregoryW Modified to use the NLS API.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, BOOL, WINAPI, IsCharAlphaNumericA, char, cChar)
|
|
BOOL WINAPI IsCharAlphaNumericA(
|
|
char cChar)
|
|
{
|
|
WORD ctype1info = 0;
|
|
WCHAR wChar = 0;
|
|
|
|
/*
|
|
* The following 2 calls cannot fail here
|
|
*/
|
|
RtlMultiByteToUnicodeN(&wChar, sizeof(WCHAR), NULL, &cChar, sizeof(CHAR));
|
|
GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info);
|
|
#ifdef FE_SB // IsCharAlphaNumericA()
|
|
if (ctype1info & C1_ALPHA) {
|
|
WORD ctype3info = 0;
|
|
if (!IS_DBCS_ENABLED()) {
|
|
return TRUE;
|
|
}
|
|
/*
|
|
* We don't want to return TRUE for halfwidth katakana.
|
|
* Katakana is linguistic character (C1_ALPHA), but it is not
|
|
* alphabet character.
|
|
*/
|
|
GetStringTypeW(CT_CTYPE3, &wChar, 1, &ctype3info);
|
|
return ((ctype3info & (C3_KATAKANA|C3_HIRAGANA)) ? FALSE : TRUE);
|
|
}
|
|
/* Otherwise, it might be digits ? */
|
|
return !!(ctype1info & C1_DIGIT);
|
|
#else
|
|
return (ctype1info & C1_ALPHA) || (ctype1info & C1_DIGIT);
|
|
#endif // FE_SB
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* IsCharAlphaA (API)
|
|
*
|
|
* Returns TRUE if character is alphabetical, otherwise FALSE
|
|
*
|
|
* History:
|
|
* 06-22-91 GregoryW Created to support code page 1252 (Windows ANSI
|
|
* code page). This is for the PDK only. After the
|
|
* PDK this routine will be rewritten to use the
|
|
* NLSAPI.
|
|
* 02-20-92 GregoryW Modified to use the NLS API.
|
|
\***************************************************************************/
|
|
|
|
|
|
FUNCLOG1(LOG_GENERAL, BOOL, WINAPI, IsCharAlphaA, char, cChar)
|
|
BOOL WINAPI IsCharAlphaA(
|
|
char cChar)
|
|
{
|
|
WORD ctype1info = 0;
|
|
WCHAR wChar = 0;
|
|
|
|
/*
|
|
* The following 2 calls cannot fail here
|
|
*/
|
|
RtlMultiByteToUnicodeN(&wChar, sizeof(WCHAR), NULL, &cChar, sizeof(CHAR));
|
|
GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info);
|
|
#ifdef FE_SB // IsCharAlphaA()
|
|
if ((ctype1info & C1_ALPHA) == C1_ALPHA) {
|
|
WORD ctype3info = 0;
|
|
if (!IS_DBCS_ENABLED()) {
|
|
return TRUE;
|
|
}
|
|
/*
|
|
* We don't want to return TRUE for halfwidth katakana.
|
|
* Katakana is linguistic character (C1_ALPHA), but it is not
|
|
* alphabet character.
|
|
*/
|
|
GetStringTypeW(CT_CTYPE3, &wChar, 1, &ctype3info);
|
|
return ((ctype3info & (C3_KATAKANA|C3_HIRAGANA)) ? FALSE : TRUE);
|
|
}
|
|
return (FALSE);
|
|
#else
|
|
return (ctype1info & C1_ALPHA) == C1_ALPHA;
|
|
#endif // FE_SB
|
|
}
|
|
|