//+---------------------------------------------------------------------------- // // File: strings.cpp // // Module: CMUTIL.DLL // // Synopsis: Basic string manipulation routines // // Copyright (c) 1997-1999 Microsoft Corporation // // Author: henryt Created 03/01/98 // //+---------------------------------------------------------------------------- #include "cmmaster.h" //+---------------------------------------------------------------------------- // // Function: WzToSz // // Synopsis: Standard conversion function for converting Wide Characters to // Ansi Characters // // Arguments: IN LPCWSTR pszwStrIn - Input Unicode string // OUT LPSTR pszStrOut - Ansi Ouput Buffer // IN int nOutBufferSize - number of Chars in pszStrOut // // Returns: int - 0 on failure, if return Value is > nOutBufferSize then the // buffer is too small. Otherwise the number of chars copied // to pszStrOut. // // History: Created Header 4/22/99 // //+---------------------------------------------------------------------------- CMUTILAPI int WzToSz(IN LPCWSTR pszwStrIn, OUT LPSTR pszStrOut, IN int nOutBufferSize) { int nReturn = 0; // // nOutBufferSize could be 0 and pszStrOut could be NULL (passing zero size and a NULL out // buffer causes WideCharToMultiByte to return the number of chars needed to convert the // input string. It is used as a sizing technique). Only check pszwStrIn // if (pszwStrIn) { nReturn = WideCharToMultiByte(CP_ACP, 0, pszwStrIn, -1, pszStrOut, nOutBufferSize, NULL, NULL); } else { SetLastError(ERROR_INVALID_PARAMETER); } return nReturn; } //+---------------------------------------------------------------------------- // // Function: SzToWz // // Synopsis: Standard Wrapper for converting from an Ansi string to a Wide String // // Arguments: IN LPCSTR pszInput - Ansi String to Convert // OUT LPWSTR pszwOutput - Wide string output buffer // IN int nBufferSize - number of chars in Wide String buffer // // Returns: int - 0 on failure, otherwise if return is < nBufferSize then insufficient // buffer space. Otherwise the number of chars copied to the buffer. // // History: quintinb Created 4/22/99 // //+---------------------------------------------------------------------------- CMUTILAPI int SzToWz(IN LPCSTR pszInput, OUT LPWSTR pszwOutput, IN int nBufferSize) { int nReturn = 0; if (pszInput) { return MultiByteToWideChar(CP_ACP, 0, pszInput, -1, pszwOutput, nBufferSize); } else { SetLastError(ERROR_INVALID_PARAMETER); } return nReturn; } //+---------------------------------------------------------------------------- // // Function: SzToWzWithAlloc // // Synopsis: Simple wrapper to encapsulate converting a string from // MultiByte To Wide Char that Allocates memory using the sizing // capabilities of the MultiByteToWideChar Api. // // Arguments: LPCSTR pszAnsiString - Source string to be converted. // // Returns: LPWSTR - returns NULL on failure, otherwise the converted string. // The caller is responsible for freeing the Alloc-ed Memory. // // History: quintinb Created 4/8/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR SzToWzWithAlloc(LPCSTR pszAnsiString) { LPWSTR pszwString = NULL; // // Find out how large the string is by calling MultiByteToWideChar with // Zero for the size field. // if (NULL != pszAnsiString) { DWORD dwSize = SzToWz(pszAnsiString, NULL, 0); CMASSERTMSG((dwSize != 0), TEXT("SzToWzWithAlloc -- First MultiByteToWideChar Failed.")); if (0 != dwSize) { pszwString = (LPWSTR)CmMalloc(dwSize*sizeof(WCHAR)); CMASSERTMSG(pszwString, TEXT("SzToWzWithAlloc -- CmMalloc of pszwString Failed.")); if (pszwString) { if (!SzToWz(pszAnsiString, pszwString, dwSize)) { // // Make sure to return a NULL string if we fail. // CMASSERTMSG(FALSE, TEXT("SzToWzWithAlloc -- Second MultiByteToWideChar Failed.")); CmFree(pszwString); pszwString = NULL; } #ifdef DEBUG else { // // If this is a debug build then we want to take the Wide string that we are going to // return, convert it to Ansi and compare it to the original ansi string passed in. // LPSTR pszString; DWORD dwSize = WzToSz(pszwString, NULL, 0); if (0 != dwSize) { pszString = (LPSTR)CmMalloc(dwSize*sizeof(CHAR)); CMASSERTMSG(pszString, TEXT("SzToWzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to allocate memory.")); if (pszString) { if (WzToSz(pszwString, pszString, dwSize)) { MYDBGASSERT(0 == lstrcmpA(pszString, pszAnsiString)); } else { CMASSERTMSG(FALSE, TEXT("SzToWzWithAlloc -- conversion of return value back to original Ansi string failed.")); } CmFree(pszString); } } else { CMASSERTMSG(FALSE, TEXT("SzToWzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to properly size the string.")); } } #endif } } } return pszwString; } //+---------------------------------------------------------------------------- // // Function: WzToSzWithAlloc // // Synopsis: Simple wrapper to encapsulate converting a string from // Unicode to MBCS that allocates memory using the sizing // capabilities of the WideCharToMultiByte Api. // // Arguments: LPCWSTR pszwWideString - Source string to be converted. // // Returns: LPSTR - returns NULL on failure, otherwise the converted string. // The caller is responsible for freeing the Alloc-ed Memory. // // History: quintinb Created 4/8/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR WzToSzWithAlloc(LPCWSTR pszwWideString) { LPSTR pszString = NULL; // // Find out how large the string is by calling WideCharToMultiByte with // Zero for the size field. // if (NULL != pszwWideString) { DWORD dwSize = WzToSz(pszwWideString, NULL, 0); CMASSERTMSG((0 != dwSize), TEXT("WzToSzWithAlloc -- First WzToSz Failed.")); if (0 != dwSize) { pszString = (LPSTR)CmMalloc(dwSize*sizeof(CHAR)); CMASSERTMSG(pszString, TEXT("WzToSzWithAlloc -- CmMalloc failed to alloc pszString.")); if (pszString) { if (!WzToSz(pszwWideString, pszString, dwSize)) { // // Make sure to return a NULL string if we fail. // CMASSERTMSG(FALSE, TEXT("WzToSzWithAlloc -- Second WzToSz Failed.")); CmFree(pszString); pszString = NULL; } #ifdef DEBUG else { // // If this is a debug build then we want to take the Ansi string that we are // going to return, convert it to Unicode and compare it to the original Unicode // string passed in. // LPWSTR pszwString; DWORD dwSize = SzToWz(pszString, NULL, 0); if (0 != dwSize) { pszwString = (LPWSTR)CmMalloc(dwSize*sizeof(WCHAR)); CMASSERTMSG(pszwString, TEXT("WzToSzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to allocate memory.")); if (pszwString) { if (SzToWz(pszString, pszwString, dwSize)) { MYDBGASSERT(0 == lstrcmpU(pszwString, pszwWideString)); } else { CMASSERTMSG(FALSE, TEXT("WzToSzWithAlloc -- conversion of return value back to original Ansi string failed.")); } CmFree(pszwString); } } else { CMASSERTMSG(FALSE, TEXT("WzToSzWithAlloc -- conversion of return value back to original Ansi string failed. Unable to properly size the string.")); } } #endif } } } return pszString; } //+---------------------------------------------------------------------------- // // Function: CmStrTrimA // // Synopsis: Helper function to trim leading and trailing blanks from a // string // // Arguments: LPTSTR pszStr - The string to be trimmed // // Returns: void WINAPI - Nothing // // History: nickball Created Header 3/11/98 // //+---------------------------------------------------------------------------- CMUTILAPI void WINAPI CmStrTrimA(LPSTR pszStr) { // // first, skip all the spaces at the begining of the string // MYDBGASSERT(pszStr); if (pszStr) { LPSTR pszTmp = pszStr; while (CmIsSpaceA(pszTmp)) { pszTmp = CharNextA(pszTmp); } if (pszTmp != pszStr) { CmMoveMemory(pszStr, pszTmp, lstrlenA(pszTmp)+1); } // // secondly, delete all the spaces at the end of the string // pszTmp = CmEndOfStrA(pszStr); while (pszTmp != pszStr) { pszTmp = CharPrevA(pszStr, pszTmp); if (!CmIsSpaceA(pszTmp)) { break; } *pszTmp = TEXT('\0'); } } } //+---------------------------------------------------------------------------- // // Function: CmStrTrimW // // Synopsis: Helper function to trim leading and trailing blanks from a // string. // // Arguments: LPTSTR pszStr - The string to be trimmed // // Returns: void WINAPI - Nothing // // History: quintinb Created 2/27/99 // //+---------------------------------------------------------------------------- CMUTILAPI void WINAPI CmStrTrimW(LPWSTR pszStr) { // // first, skip all the spaces at the begining of the string // MYDBGASSERT(pszStr); if (pszStr) { LPWSTR pszTmp = pszStr; while (CmIsSpaceW(pszTmp)) { pszTmp = CharNextU(pszTmp); } if (pszTmp != pszStr) { CmMoveMemory(pszStr, pszTmp, (lstrlenU(pszTmp)+1)*sizeof(WCHAR)); } // // secondly, delete all the spaces at the end of the string // pszTmp = CmEndOfStrW(pszStr); while (pszTmp != pszStr) { pszTmp = CharPrevU(pszStr, pszTmp); if (!CmIsSpaceW(pszTmp)) { break; } *pszTmp = TEXT('\0'); } } } //+---------------------------------------------------------------------------- // // Function: CmIsSpaceA // // Synopsis: Checks to see if the char is a space. Note that spaces, new line chars, // line feed chars, tabs, and most other forms of whitespace are considered // spaces. // // Arguments: psz - an ansi or dbcs char // // Returns: TRUE or FALSE // //+---------------------------------------------------------------------------- CMUTILAPI BOOL WINAPI CmIsSpaceA(LPSTR psz) { WORD wType = 0; MYDBGASSERT(psz); if (psz) { if (IsDBCSLeadByte(*psz)) { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); } else { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); } } return (wType & C1_SPACE); } //+---------------------------------------------------------------------------- // // Function: CmIsSpaceW // // Synopsis: Checks to see if the char is a space. Note that spaces, new line chars, // line feed chars, tabs, and most other forms of whitespace are considered // spaces. // // Arguments: psz - pointer to a string // // Returns: TRUE or FALSE // //+---------------------------------------------------------------------------- CMUTILAPI BOOL WINAPI CmIsSpaceW(LPWSTR pszwStr) { WORD wType = 0; LPWSTR pszwNextChar; int iCharCount; MYDBGASSERT(pszwStr); if (pszwStr) { pszwNextChar = CharNextU(pszwStr); iCharCount = (INT)(pszwNextChar - pszwStr); if (0 == GetStringTypeExU(LOCALE_USER_DEFAULT, CT_CTYPE1, pszwStr, iCharCount, &wType)) { CMTRACE3(TEXT("CmIsSpaceW -- GetStringTypeExW failed on %s, iCharCount is %d, GLE=%u"), pszwStr, iCharCount, GetLastError()); return FALSE; } } return (wType & C1_SPACE); } //+---------------------------------------------------------------------------- // // Function: CmIsDigitA // // Synopsis: Checks to see if the char is a digit. // // Arguments: psz - an ansi or dbcs char // // Returns: TRUE or FALSE // //+---------------------------------------------------------------------------- CMUTILAPI BOOL WINAPI CmIsDigitA(LPSTR psz) { WORD wType = 0; MYDBGASSERT(psz); if (psz) { if (IsDBCSLeadByte(*psz)) { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 2, &wType)); } else { MYVERIFY(GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, psz, 1, &wType)); } } return (wType & C1_DIGIT); } //+---------------------------------------------------------------------------- // // Function: CmIsDigitW // // Synopsis: Checks to see if the WCHAR is a digit. // // Arguments: pszwStr -- WCHAR string // // Returns: TRUE or FALSE // //+---------------------------------------------------------------------------- CMUTILAPI BOOL WINAPI CmIsDigitW(LPWSTR pszwStr) { WORD wType = 0; LPWSTR pszwNextChar; int iCharCount; MYDBGASSERT(pszwStr); if (pszwStr) { pszwNextChar = CharNextU(pszwStr); iCharCount = (INT)(pszwNextChar - pszwStr); if (0 == GetStringTypeExU(LOCALE_USER_DEFAULT, CT_CTYPE1, pszwStr, iCharCount, &wType)) { CMTRACE1(TEXT("CmIsDigitW -- GetStringTypeExU failed, GLE=%u"), GetLastError()); return FALSE; } } return (wType & C1_DIGIT); } //+---------------------------------------------------------------------------- // // Function: CmEndOfStrA // // Synopsis: Given a string, returns the ptr to the end of the string(null char). // // Arguments: psz - an ansi or dbcs char // // Returns: LPSTR ptr to null char // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR WINAPI CmEndOfStrA(LPSTR psz) { MYDBGASSERT(psz); if (psz) { while (*psz) { psz = CharNextA(psz); } } return psz; } //+---------------------------------------------------------------------------- // // Function: CmEndOfStrW // // Synopsis: Given a string, returns the ptr to the end of the string(null char). // // Arguments: pszwStr - a WCHAR // // Returns: LPWSTR ptr to null char // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR WINAPI CmEndOfStrW(LPWSTR pszwStr) { MYDBGASSERT(pszwStr); if (pszwStr) { while (*pszwStr) { pszwStr = CharNextU(pszwStr); } } return pszwStr; } //+---------------------------------------------------------------------------- // // Function: CmStrCpyAllocA // // Synopsis: Copies pszSrc into a newly allocated buffer (using CmMalloc) and // returns the buffer to its caller who is responsible for freeing // the buffer. // // Arguments: LPCSTR pszSrc - source string // // Returns: LPSTR - returns NULL if pszSrc is NULL or the Alloc fails, // otherwise it returns the newly allocated buffer with // a copy of pszSrc in it. // // History: quintinb Created Header and changed name to include Alloc 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR CmStrCpyAllocA(LPCSTR pszSrc) { LPSTR pszBuffer = NULL; if (pszSrc) { pszBuffer = (LPSTR) CmMalloc(lstrlenA(pszSrc) + 1); if (pszBuffer) { lstrcpyA(pszBuffer, pszSrc); } } return (pszBuffer); } //+---------------------------------------------------------------------------- // // Function: CmStrCpyAllocW // // Synopsis: Copies pszSrc into a newly allocated buffer (using CmMalloc) and // returns the buffer to its caller who is responsible for freeing // the buffer. // // Arguments: LPCSTR pszSrc - source string // // Returns: LPSTR - returns NULL if pszSrc is NULL or the Alloc fails, // otherwise it returns the newly allocated buffer with // a copy of pszSrc in it. // // History: quintinb Created Header and changed name to include Alloc 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR CmStrCpyAllocW(LPCWSTR pszSrc) { LPWSTR pszBuffer = NULL; if (pszSrc) { size_t nLen = lstrlenU(pszSrc) + 1; pszBuffer = (LPWSTR) CmMalloc(nLen*sizeof(WCHAR)); if (pszBuffer) { lstrcpyU(pszBuffer, pszSrc); } } return (pszBuffer); } //+---------------------------------------------------------------------------- // // Function: CmStrCatAllocA // // Synopsis: This function reallocs the passed in string to a size large enough // to hold the original data and the concatenates the new string onto // the original string. // // Arguments: LPSTR *ppszDst - original string // LPCSTR pszSrc - new piece of string to concatenate // // Returns: LPSTR - pointer to the concatenated string // // History: quintinb Created Header 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR CmStrCatAllocA(LPSTR *ppszDst, LPCSTR pszSrc) { if (!ppszDst) { return NULL; } if (pszSrc && *pszSrc) { DWORD dwSize = (lstrlenA(*ppszDst) + lstrlenA(pszSrc) + 1); LPSTR pszTmp = (LPSTR)CmRealloc((LPVOID)*ppszDst, dwSize); if (NULL != pszTmp) { lstrcatA(pszTmp, pszSrc); *ppszDst = pszTmp; } } return (*ppszDst); } //+---------------------------------------------------------------------------- // // Function: CmStrCatAllocW // // Synopsis: This function reallocs the passed in string to a size large enough // to hold the original data and the concatenates the new string onto // the original string. // // Arguments: LPWSTR *ppszDst - original string // LPCWSTR pszSrc - new piece of string to concatenate // // Returns: LPWSTR - pointer to the concatenated string // // History: quintinb Created Header 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR CmStrCatAllocW(LPWSTR *ppszDst, LPCWSTR pszSrc) { if (!ppszDst) { return NULL; } if (pszSrc && *pszSrc) { DWORD dwSize = (lstrlenU(*ppszDst) + lstrlenU(pszSrc) + 1)*sizeof(WCHAR); LPWSTR pszTmp = (LPWSTR)CmRealloc((LPVOID)*ppszDst, dwSize); if (NULL != pszTmp) { lstrcatU(pszTmp, pszSrc); *ppszDst = pszTmp; } } return (*ppszDst); } //+---------------------------------------------------------------------------- // // Function: CmStrchrA // // Synopsis: This function returns the first occurence of ch in the string pszString. // // Arguments: LPCSTR pszString - String to search in // CHAR ch - character to look for // // Returns: LPSTR - pointer to the first occurence of the Character ch in pszString // // History: quintinb Created Header 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR WINAPI CmStrchrA(LPCSTR pszString, const char ch) { LPSTR pszTmp = (LPSTR)pszString; if (NULL == pszTmp) { CMASSERTMSG(FALSE, TEXT("CmStrchr - NULL pointer passed")); return NULL; } while (*pszTmp && (*pszTmp != ch)) { pszTmp = CharNextA(pszTmp); } if (*pszTmp == ch) { return pszTmp; } return NULL; } //+---------------------------------------------------------------------------- // // Function: CmStrchrW // // Synopsis: This function returns the first occurence of ch in the string pszString. // // Arguments: LPCWSTR pszString - String to search in // WCHAR ch - character to look for // // Returns: LPWSTR - pointer to the first occurence of the Character ch in pszString // // History: quintinb Created Header 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR WINAPI CmStrchrW(LPCWSTR pszString, const WCHAR ch) { LPWSTR pszTmp = (LPWSTR)pszString; if (NULL == pszTmp) { CMASSERTMSG(FALSE, TEXT("CmStrchr - NULL pointer passed")); return NULL; } while (*pszTmp && (*pszTmp != ch)) { pszTmp = CharNextU(pszTmp); } if (*pszTmp == ch) { return pszTmp; } return NULL; } //+---------------------------------------------------------------------------- // // Function: CmStrrchrA // // Synopsis: Find the last occurence of a character in a string // // Arguments: LPCSTR pszString - string to search in // CHAR ch - character to look for // // Returns: LPSTR - NULL if the char is not found, a pointer to the char in // the string otherwise // // History: quintinb Created Header and cleaned up 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR CmStrrchrA (LPCSTR pszString, const char ch) { LPSTR pszTmp = NULL; LPSTR pszCurrent = (LPSTR)pszString; if (NULL == pszString) { CMASSERTMSG(FALSE, TEXT("CmStrrchr - NULL pointer passed")); } else { while (TEXT('\0') != *pszCurrent) { if (ch == (*pszCurrent)) { pszTmp = pszCurrent; } pszCurrent = CharNextA(pszCurrent); } } return pszTmp; } //+---------------------------------------------------------------------------- // // Function: CmStrrchrW // // Synopsis: Find the last occurence of a character in a string // // Arguments: LPCWSTR pszString - string to search in // WCHAR ch - character to look for // // Returns: LPWSTR - NULL if the char is not found, a pointer to the char in // the string otherwise // // History: quintinb Created Header and cleaned up 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR CmStrrchrW (LPCWSTR pszString, const WCHAR ch) { LPWSTR pszTmp = NULL; LPWSTR pszCurrent = (LPWSTR)pszString; if (NULL == pszString) { CMASSERTMSG(FALSE, TEXT("CmStrrchr - NULL pointer passed")); } else { while (TEXT('\0') != *pszCurrent) { if (ch == (*pszCurrent)) { pszTmp = pszCurrent; } pszCurrent = CharNextU(pszCurrent); } } return pszTmp; } //+---------------------------------------------------------------------------- // // Function: CmStrtokA // // Synopsis: CM implementation of strtok // // Arguments: LPSTR pszStr - string to tokenize or NULL if getting a second token // LPCSTR pszControl - set of token chars // // Returns: LPSTR - NULL if no token could be found or a pointer to a token string. // // History: quintinb Created Header and cleaned up for UNICODE conversion 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR CmStrtokA(LPSTR pszStr, LPCSTR pszControl) { LPSTR pszToken; LPSTR pszTmpStr; LPCSTR pszTmpCtl; LPSTR pszTmpDelim; // // If the pszStr param is NULL, then we need to retrieve the stored string // if (NULL != pszStr) { pszTmpStr = pszStr; } else { pszTmpStr = (LPSTR)TlsGetValue(g_dwTlsIndex); } // // Find beginning of token (skip over leading delimiters). Note that // there is no token if this loop sets string to point to the terminal // null (*string == '\0') // while (*pszTmpStr) { for (pszTmpCtl = pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextA(pszTmpCtl)) { ; // do nothing } if (!*pszTmpCtl) { break; } pszTmpStr = CharNextA(pszTmpStr); } pszToken = pszTmpStr; // // Find the end of the token. If it is not the end of the string, // put a null there. // for ( ; *pszTmpStr ; pszTmpStr = CharNextA(pszTmpStr)) { for (pszTmpCtl = pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextA(pszTmpCtl)) { ; // Do nothing } if (*pszTmpCtl) { pszTmpDelim = pszTmpStr; pszTmpStr = CharNextA(pszTmpStr); *pszTmpDelim = '\0'; break; } } // // Update nextoken (or the corresponding field in the per-thread data structure // TlsSetValue(g_dwTlsIndex, (LPVOID)pszTmpStr); // // Determine if a token has been found. // if (pszToken == pszTmpStr) { return NULL; } else { return pszToken; } } //+---------------------------------------------------------------------------- // // Function: CmStrtokW // // Synopsis: CM implementation of strtok // // Arguments: LPWSTR pszStr - string to tokenize or NULL if getting a second tokey // LPCWSTR pszControl - set of token chars // // Returns: LPWSTR - NULL if no token could be found or a pointer to a token string. // // History: quintinb Created Header and cleaned up for UNICODE conversion 4/9/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR CmStrtokW(LPWSTR pszStr, LPCWSTR pszControl) { LPWSTR pszToken; LPWSTR pszTmpStr; LPWSTR pszTmpCtl; LPWSTR pszTmpDelim; // // If the pszStr param is NULL, then we need to retrieve the stored string // if (NULL != pszStr) { pszTmpStr = pszStr; } else { pszTmpStr = (LPWSTR)TlsGetValue(g_dwTlsIndex); } // // Find beginning of token (skip over leading delimiters). Note that // there is no token iff this loop sets string to point to the terminal // null (*string == '\0') // while (*pszTmpStr) { for (pszTmpCtl = (LPWSTR)pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextU(pszTmpCtl)) { ; // do nothing } if (!*pszTmpCtl) { break; } pszTmpStr = CharNextU(pszTmpStr); } pszToken = pszTmpStr; // // Find the end of the token. If it is not the end of the string, // put a null there. // for ( ; *pszTmpStr ; pszTmpStr = CharNextU(pszTmpStr)) { for (pszTmpCtl = (LPWSTR)pszControl; *pszTmpCtl && *pszTmpCtl != *pszTmpStr; pszTmpCtl = CharNextU(pszTmpCtl)) { ; // Do nothing } if (*pszTmpCtl) { pszTmpDelim = pszTmpStr; pszTmpStr = CharNextU(pszTmpStr); *pszTmpDelim = L'\0'; break; } } // // Update nextoken (or the corresponding field in the per-thread data structure // TlsSetValue(g_dwTlsIndex, (LPVOID)pszTmpStr); // // Determine if a token has been found. // if (pszToken == pszTmpStr) { return NULL; } else { return pszToken; } } //+---------------------------------------------------------------------------- // // Function: CmStrStrA // // Synopsis: Simple replacement for StrStr from C runtime // // Arguments: LPCTSTR pszString - The string to search in // LPCTSTR pszSubString - The string to search for // // Returns: LPTSTR - Ptr to the first occurence of pszSubString in pszString. // NULL if pszSubString does not occur in pszString // // // History: nickball Created Header 04/01/98 // nickball Added ptr check 02/21/99 // quintinb rewrote for unicode conversion 04/08/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPSTR CmStrStrA(LPCSTR pszString, LPCSTR pszSubString) { // // Check the inputs // MYDBGASSERT(pszString); MYDBGASSERT(pszSubString); if (NULL == pszSubString || NULL == pszString) { return NULL; } // // Check to make sure we have something to look for // if (TEXT('\0') == pszSubString[0]) { return((LPSTR)pszString); } // // Okay, start looking for the string // LPSTR pszCurrent = (LPSTR)pszString; LPSTR pszTmp1; LPSTR pszTmp2; while (*pszCurrent) { pszTmp1 = pszCurrent; pszTmp2 = (LPSTR) pszSubString; while (*pszTmp1 && *pszTmp2 && ((*pszTmp1) == (*pszTmp2))) { pszTmp1 = CharNextA(pszTmp1); pszTmp2 = CharNextA(pszTmp2); } if (TEXT('\0') == *pszTmp2) { return pszCurrent; } pszCurrent = CharNextA(pszCurrent); } return NULL; } //+---------------------------------------------------------------------------- // // Function: CmStrStrW // // Synopsis: Simple replacement for StrStr from C runtime // // Arguments: LPCTSTR pszString - The string to search in // LPCTSTR pszSubString - The string to search for // // Returns: LPTSTR - Ptr to the first occurence of pszSubString in pszString. // NULL if pszSubString does not occur in pszString // // // History: nickball Created Header 04/01/98 // nickball Added ptr check 02/21/99 // quintinb rewrote for unicode conversion 04/08/99 // //+---------------------------------------------------------------------------- CMUTILAPI LPWSTR CmStrStrW(LPCWSTR pszString, LPCWSTR pszSubString) { // // Check the inputs // MYDBGASSERT(pszString); MYDBGASSERT(pszSubString); if (NULL == pszSubString || NULL == pszString) { return NULL; } // // Check to make sure we have something to look for // if (TEXT('\0') == pszSubString[0]) { return((LPWSTR)pszString); } // // Okay, start looking for the string // LPWSTR pszCurrent = (LPWSTR)pszString; LPWSTR pszTmp1; LPWSTR pszTmp2; while (*pszCurrent) { pszTmp1 = pszCurrent; pszTmp2 = (LPWSTR) pszSubString; while (*pszTmp1 && *pszTmp2 && ((*pszTmp1) == (*pszTmp2))) { pszTmp1 = CharNextU(pszTmp1); pszTmp2 = CharNextU(pszTmp2); } if (TEXT('\0') == *pszTmp2) { return pszCurrent; } pszCurrent = CharNextU(pszCurrent); } return NULL; }