//--------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation 1993-1994 // // File: string.c // // This files contains common string routines // // History: // 10-09-93 ScottH Created // //--------------------------------------------------------------------------- ///////////////////////////////////////////////////// INCLUDES #include "brfprv.h" // common headers #include "strings.h" #ifdef NOTUSED #pragma data_seg(DATASEG_PERINSTANCE) static LPTSTR s_pszNextToken = NULL; #pragma data_seg() #endif // NOTUSED // Some of these are replacements for the C runtime routines. // This is so we don't have to link to the CRT libs. // // WARNING: all of these APIs do not setup DS, so you can not access // any data in the default data seg of this DLL. // // do not create any global variables... talk to chrisg if you don't // understand this #ifdef DBCS #define FASTCALL #else #define FASTCALL _fastcall #endif /*---------------------------------------------------------- Purpose: Case sensitive character comparison for DBCS Returns: FALSE if they match, TRUE if no match Cond: -- */ BOOL FASTCALL ChrCmp( WORD w1, WORD wMatch) { /* Most of the time this won't match, so test it first for speed. */ if (LOBYTE(w1) == LOBYTE(wMatch)) { if (IsDBCSLeadByte(LOBYTE(w1))) { return(w1 != wMatch); } return FALSE; } return TRUE; } /*---------------------------------------------------------- Purpose: Case insensitive character comparison for DBCS Returns: FALSE if match, TRUE if not Cond: -- */ BOOL FASTCALL ChrCmpI( WORD w1, WORD wMatch) { TCHAR sz1[3], sz2[3]; if (IsDBCSLeadByte(sz1[0] = LOBYTE(w1))) { sz1[1] = HIBYTE(w1); sz1[2] = TEXT('\0'); } else sz1[1] = TEXT('\0'); *(WORD *)sz2 = wMatch; sz2[2] = TEXT('\0'); return lstrcmpi(sz1, sz2); } #ifdef NOTUSED // BUGBUG: this is not DBCS aware /*---------------------------------------------------------- Purpose: strtok Swiped from the C 7.0 runtime sources. Returns: Cond: */ LPTSTR PUBLIC StrTok( LPTSTR psz, LPCTSTR rgchTokens) { TUCHAR map[32]; LPTSTR pszToken; ZeroInit(map, map); do { map[*rgchTokens >> 3] |= (1 << (*rgchTokens & 7)); } while (*rgchTokens++); if (!psz) { ENTEREXCLUSIVE() { psz = s_pszNextToken; } LEAVEEXCLUSIVE() } while (map[*psz >> 3] & (1 << (*psz & 7)) && *psz) psz++; pszToken = psz; for (;; psz++) { if (map[*psz >> 3] & (1 << (*psz & 7))) { if (!*psz && psz == pszToken) return(NULL); if (*psz) *psz++ = TEXT('\0'); ENTEREXCLUSIVE() { g_pszNextToken = psz; } LEAVEEXCLUSIVE() return pszToken; } } } #endif #if 0 /*---------------------------------------------------------- Purpose: Find first occurrence of character in string Returns: Pointer to the first occurrence of ch in Cond: -- */ LPTSTR PUBLIC StrChr( LPCTSTR psz, WORD wMatch) { for ( ; *psz; psz = CharNext(psz)) { if (!ChrCmp(*(WORD *)psz, wMatch)) return (LPTSTR)psz; } return NULL; } #endif /*---------------------------------------------------------- Purpose: strnicmp Swiped from the C 7.0 runtime sources. Returns: Cond: */ int PUBLIC lstrnicmp( LPCTSTR psz1, LPCTSTR psz2, UINT count) { int ch1; int ch2; int result = 0; if (count) { do { ch1 = (int)CharLower((LPTSTR)MAKELONG(*psz1, 0)); ch2 = (int)CharLower((LPTSTR)MAKELONG(*psz2, 0)); psz1 = CharNext(psz1); psz2 = CharNext(psz2); } while (--count && ch1 && ch2 && !ChrCmp((WORD)ch1, (WORD)ch2)); result = ch1 - ch2; } return(result); } /*---------------------------------------------------------- Purpose: Get a string from the resource string table. Returned ptr is a ptr to static memory. The next call to this function will wipe out the prior contents. Returns: Ptr to string Cond: -- */ LPTSTR PUBLIC SzFromIDS( UINT ids, // resource ID LPTSTR pszBuf, UINT cchBuf) { ASSERT(pszBuf); *pszBuf = NULL_CHAR; LoadString(g_hinst, ids, pszBuf, cchBuf); return pszBuf; } /*---------------------------------------------------------- Purpose: Formats a string by allocating a buffer and loading the given resource strings to compose the string. Returns: the count of characters Cond: Caller should free the allocated buffer using GFree. */ BOOL PUBLIC FmtString( LPCTSTR * ppszBuf, UINT idsFmt, LPUINT rgids, UINT cids) { UINT cch = 0; UINT cchMax; LPTSTR pszBuf; ASSERT(ppszBuf); ASSERT(rgids); ASSERT(cids > 0); cchMax = (1+cids) * MAXPATHLEN; pszBuf = GAlloc(CbFromCch(cchMax)); if (pszBuf) { // The first cids DWORDS are the addresses of the offset strings // in the buffer (passed to wvsprintf) LPTSTR pszMsgs = GAlloc((cids * sizeof(DWORD)) + (cids * CbFromCch(MAXPATHLEN))); if (pszMsgs) { TCHAR szFmt[MAXPATHLEN]; LPDWORD rgpsz = (LPDWORD)pszMsgs; LPTSTR pszT = pszMsgs + (cids * sizeof(DWORD)); UINT i; // Load the series of strings for (i = 0; i < cids; i++, pszT += MAXPATHLEN) { rgpsz[i] = (DWORD)pszT; SzFromIDS(rgids[i], pszT, MAXPATHLEN); } // Compose the string SzFromIDS(idsFmt, szFmt, ARRAYSIZE(szFmt)); cch = FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFmt, 0, 0, pszBuf, cchMax, (va_list *)&rgpsz); ASSERT(cch <= cchMax); GFree(pszMsgs); } // pszBuf is freed by caller } *ppszBuf = pszBuf; return cch; }