Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kernelbase/kernelbase.spec | 44 +++---- dlls/kernelbase/string.c | 226 ++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+), 22 deletions(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 8294c95282..6ff91518c3 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -109,20 +109,20 @@ @ stdcall CancelWaitableTimer(long) kernel32.CancelWaitableTimer # @ stub CeipIsOptedIn @ stdcall ChangeTimerQueueTimer(ptr ptr long long) kernel32.ChangeTimerQueueTimer -@ stdcall CharLowerA(str) user32.CharLowerA -@ stdcall CharLowerBuffA(str long) user32.CharLowerBuffA -@ stdcall CharLowerBuffW(wstr long) user32.CharLowerBuffW -@ stdcall CharLowerW(wstr) user32.CharLowerW -@ stdcall CharNextA(str) user32.CharNextA -@ stdcall CharNextExA(long str long) user32.CharNextExA -@ stdcall CharNextW(wstr) user32.CharNextW -@ stdcall CharPrevA(str str) user32.CharPrevA -@ stdcall CharPrevExA(long str str long) user32.CharPrevExA -@ stdcall CharPrevW(wstr wstr) user32.CharPrevW -@ stdcall CharUpperA(str) user32.CharUpperA -@ stdcall CharUpperBuffA(str long) user32.CharUpperBuffA -@ stdcall CharUpperBuffW(wstr long) user32.CharUpperBuffW -@ stdcall CharUpperW(wstr) user32.CharUpperW +@ stdcall CharLowerA(str) +@ stdcall CharLowerBuffA(str long) +@ stdcall CharLowerBuffW(wstr long) +@ stdcall CharLowerW(wstr) +@ stdcall CharNextA(str) +@ stdcall CharNextExA(long str long) +@ stdcall CharNextW(wstr) +@ stdcall CharPrevA(str str) +@ stdcall CharPrevExA(long str str long) +@ stdcall CharPrevW(wstr wstr) +@ stdcall CharUpperA(str) +@ stdcall CharUpperBuffA(str long) +@ stdcall CharUpperBuffW(wstr long) +@ stdcall CharUpperW(wstr) # @ stub CheckAllowDecryptedRemoteDestinationPolicy @ stub CheckGroupPolicyEnabled # @ stub CheckIfStateChangeNotificationExists @@ -839,20 +839,20 @@ # @ stub InternetTimeToSystemTimeW # @ stub InvalidateAppModelVersionCache @ stub InvalidateTzSpecificCache -@ stdcall IsCharAlphaA(long) user32.IsCharAlphaA -@ stdcall IsCharAlphaNumericA(long) user32.IsCharAlphaNumericA -@ stdcall IsCharAlphaNumericW(long) user32.IsCharAlphaNumericW -@ stdcall IsCharAlphaW(long) user32.IsCharAlphaW +@ stdcall IsCharAlphaA(long) +@ stdcall IsCharAlphaNumericA(long) +@ stdcall IsCharAlphaNumericW(long) +@ stdcall IsCharAlphaW(long) @ stdcall IsCharBlankW(long) @ stdcall IsCharCntrlW(long) @ stdcall IsCharDigitW(long) -@ stdcall IsCharLowerA(long) user32.IsCharLowerA -@ stdcall IsCharLowerW(long) user32.IsCharLowerW +@ stdcall IsCharLowerA(long) +@ stdcall IsCharLowerW(long) @ stdcall IsCharPunctW(long) @ stdcall IsCharSpaceA(long) @ stdcall IsCharSpaceW(long) -@ stdcall IsCharUpperA(long) user32.IsCharUpperA -@ stdcall IsCharUpperW(long) user32.IsCharUpperW +@ stdcall IsCharUpperA(long) +@ stdcall IsCharUpperW(long) @ stdcall IsCharXDigitW(long) @ stdcall IsDBCSLeadByte(long) kernel32.IsDBCSLeadByte @ stdcall IsDBCSLeadByteEx(long long) kernel32.IsDBCSLeadByteEx diff --git a/dlls/kernelbase/string.c b/dlls/kernelbase/string.c index 8b3d94a9e6..7e128765d8 100644 --- a/dlls/kernelbase/string.c +++ b/dlls/kernelbase/string.c @@ -24,6 +24,7 @@ #include "shlwapi.h"
#include "wine/debug.h" +#include "wine/exception.h" #include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(string); @@ -100,6 +101,54 @@ BOOL WINAPI IsCharXDigitW(WCHAR wc) return !!isxdigitW(wc); }
+BOOL WINAPI IsCharAlphaA(CHAR x) +{ + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharAlphaW(wch); +} + +BOOL WINAPI IsCharAlphaW(WCHAR ch) +{ + return !!(get_char_typeW(ch) & C1_ALPHA); +} + +BOOL WINAPI IsCharLowerA(CHAR x) +{ + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharLowerW(wch); +} + +BOOL WINAPI IsCharLowerW(WCHAR ch) +{ + return !!islowerW(ch); +} + +BOOL WINAPI IsCharAlphaNumericA(CHAR x) +{ + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharAlphaNumericW(wch); +} + +BOOL WINAPI IsCharAlphaNumericW(WCHAR ch) +{ + return !!(get_char_typeW(ch) & (C1_ALPHA | C1_DIGIT)); +} + +BOOL WINAPI IsCharUpperA(CHAR x) +{ + WCHAR wch; + MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1); + return IsCharUpperW(wch); +} + +BOOL WINAPI IsCharUpperW(WCHAR ch) +{ + return !!isupperW(ch); +} + WCHAR * WINAPI StrChrW(const WCHAR *str, WCHAR ch) { TRACE("%s, %#x\n", wine_dbgstr_w(str), ch); @@ -511,3 +560,180 @@ WCHAR * WINAPI StrCpyNXW(WCHAR *dst, const WCHAR *src, int len)
return dst; } + +LPSTR WINAPI CharLowerA(char *str) +{ + if (IS_INTRESOURCE(str)) + { + char ch = LOWORD(str); + CharLowerBuffA( &ch, 1 ); + return (LPSTR)(UINT_PTR)(BYTE)ch; + } + + __TRY + { + CharLowerBuffA( str, strlen(str) ); + } + __EXCEPT_PAGE_FAULT + { + SetLastError( ERROR_INVALID_PARAMETER ); + return NULL; + } + __ENDTRY + return str; +} + +DWORD WINAPI CharLowerBuffA(char *str, DWORD len) +{ + DWORD lenW; + WCHAR buffer[32]; + WCHAR *strW = buffer; + + if (!str) return 0; /* YES */ + + lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); + if (lenW > ARRAY_SIZE(buffer)) + { + strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR)); + if (!strW) return 0; + } + MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW); + CharLowerBuffW(strW, lenW); + len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL); + if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW); + return len; +} + +DWORD WINAPI CharLowerBuffW(WCHAR *str, DWORD len) +{ + if (!str) return 0; /* YES */ + return LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, str, len, str, len); +} + +LPWSTR WINAPI CharLowerW(WCHAR *str) +{ + if (!IS_INTRESOURCE(str)) + { + CharLowerBuffW(str, lstrlenW(str)); + return str; + } + else + { + WCHAR ch = LOWORD(str); + CharLowerBuffW(&ch, 1); + return (LPWSTR)(UINT_PTR)ch; + } +} + +LPSTR WINAPI CharNextA(const char *ptr) +{ + if (!*ptr) return (LPSTR)ptr; + if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2); + return (LPSTR)(ptr + 1); +} + +LPSTR WINAPI CharNextExA(WORD codepage, const char *ptr, DWORD flags) +{ + if (!*ptr) return (LPSTR)ptr; + if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2); + return (LPSTR)(ptr + 1); +} + +LPWSTR WINAPI CharNextW(const WCHAR *x) +{ + if (*x) x++; + + return (WCHAR *)x; +} + +LPSTR WINAPI CharPrevA(const char *start, const char *ptr) +{ + while (*start && (start < ptr)) + { + LPCSTR next = CharNextA(start); + if (next >= ptr) break; + start = next; + } + return (LPSTR)start; +} + +LPSTR WINAPI CharPrevExA(WORD codepage, const char *start, const char *ptr, DWORD flags) +{ + while (*start && (start < ptr)) + { + LPCSTR next = CharNextExA(codepage, start, flags); + if (next >= ptr) break; + start = next; + } + return (LPSTR)start; +} + +LPWSTR WINAPI CharPrevW(const WCHAR *start, const WCHAR *x) +{ + if (x > start) return (LPWSTR)(x - 1); + else return (LPWSTR)x; +} + +LPSTR WINAPI CharUpperA(LPSTR str) +{ + if (IS_INTRESOURCE(str)) + { + char ch = LOWORD(str); + CharUpperBuffA(&ch, 1); + return (LPSTR)(UINT_PTR)(BYTE)ch; + } + + __TRY + { + CharUpperBuffA(str, strlen(str)); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + __ENDTRY + return str; +} + +DWORD WINAPI CharUpperBuffA(LPSTR str, DWORD len) +{ + DWORD lenW; + WCHAR buffer[32]; + WCHAR *strW = buffer; + + if (!str) return 0; /* YES */ + + lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); + if (lenW > ARRAY_SIZE(buffer)) + { + strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR)); + if (!strW) return 0; + } + MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW); + CharUpperBuffW(strW, lenW); + len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL); + if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW); + return len; +} + +DWORD WINAPI CharUpperBuffW(WCHAR *str, DWORD len) +{ + if (!str) return 0; /* YES */ + return LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE, str, len, str, len); +} + +LPWSTR WINAPI CharUpperW(WCHAR *str) +{ + if (!IS_INTRESOURCE(str)) + { + CharUpperBuffW(str, lstrlenW(str)); + return str; + } + else + { + WCHAR ch = LOWORD(str); + CharUpperBuffW(&ch, 1); + return (LPWSTR)(UINT_PTR)ch; + } +}