Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

523 lines
10 KiB

/*** strlib.c - string functions
*
* Copyright (c) 1996,1997 Microsoft Corporation
* Author: Michael Tsang (MikeTs)
* Created 09/09/96
*
* MODIFICATION HISTORY
*/
#include "pch.h"
#ifdef LOCKABLE_PRAGMA
#pragma ACPI_LOCKABLE_DATA
#pragma ACPI_LOCKABLE_CODE
#endif
/***EP StrLen - determine string length
*
* ENTRY
* psz -> string
* n - limiting length
*
* EXIT
* returns string length
*/
ULONG EXPORT StrLen(PSZ psz, ULONG n)
{
TRACENAME("STRLEN")
ULONG dwLen;
ENTER(5, ("StrLen(str=%s,n=%d)\n", psz, n));
ASSERT(psz != NULL);
if (n != (ULONG)-1)
n++;
for (dwLen = 0; (dwLen <= n) && (*psz != '\0'); psz++)
dwLen++;
EXIT(5, ("StrLen=%u\n", dwLen));
return dwLen;
} //StrLen
/***EP StrCpy - copy string
*
* ENTRY
* pszDst -> destination string
* pszSrc -> source string
* n - number of bytes to copy
*
* EXIT
* returns pszDst
*/
PSZ EXPORT StrCpy(PSZ pszDst, PSZ pszSrc, ULONG n)
{
TRACENAME("STRCPY")
ULONG dwSrcLen;
ENTER(5, ("StrCpy(Dst=%s,Src=%s,n=%d)\n", pszDst, pszSrc, n));
ASSERT(pszDst != NULL);
ASSERT(pszSrc != NULL);
dwSrcLen = StrLen(pszSrc, n);
if ((n == (ULONG)(-1)) || (n > dwSrcLen))
n = dwSrcLen;
MEMCPY(pszDst, pszSrc, n);
pszDst[n] = '\0';
EXIT(5, ("StrCpy=%s\n", pszDst));
return pszDst;
} //StrCpy
/***EP StrCat - concatenate strings
*
* ENTRY
* pszDst -> destination string
* pszSrc -> source string
* n - number of bytes to concatenate
*
* EXIT
* returns pszDst
*/
PSZ EXPORT StrCat(PSZ pszDst, PSZ pszSrc, ULONG n)
{
TRACENAME("STRCAT")
ULONG dwSrcLen, dwDstLen;
ENTER(5, ("StrCat(Dst=%s,Src=%s,n=%d)\n", pszDst, pszSrc, n));
ASSERT(pszDst != NULL);
ASSERT(pszSrc != NULL);
dwSrcLen = StrLen(pszSrc, n);
if ((n == (ULONG)(-1)) || (n > dwSrcLen))
n = dwSrcLen;
dwDstLen = StrLen(pszDst, (ULONG)(-1));
MEMCPY(&pszDst[dwDstLen], pszSrc, n);
pszDst[dwDstLen + n] = '\0';
EXIT(5, ("StrCat=%s\n", pszDst));
return pszDst;
} //StrCat
/***EP StrCmp - compare strings
*
* ENTRY
* psz1 -> string 1
* psz2 -> string 2
* n - number of bytes to compare
* fMatchCase - TRUE if case sensitive
*
* EXIT
* returns 0 if string 1 == string 2
* <0 if string 1 < string 2
* >0 if string 1 > string 2
*/
LONG EXPORT StrCmp(PSZ psz1, PSZ psz2, ULONG n, BOOLEAN fMatchCase)
{
TRACENAME("STRCMP")
LONG rc;
ULONG dwLen1, dwLen2;
ULONG i;
ENTER(5, ("StrCmp(s1=%s,s2=%s,n=%d,fMatchCase=%d)\n",
psz1, psz2, n, fMatchCase));
ASSERT(psz1 != NULL);
ASSERT(psz2 != NULL);
dwLen1 = StrLen(psz1, n);
dwLen2 = StrLen(psz2, n);
if (n == (ULONG)(-1))
n = (dwLen1 > dwLen2)? dwLen1: dwLen2;
if (fMatchCase)
{
for (i = 0, rc = 0;
(rc == 0) && (i < n) && (i < dwLen1) && (i < dwLen2);
++i)
{
rc = (LONG)(psz1[i] - psz2[i]);
}
}
else
{
for (i = 0, rc = 0;
(rc == 0) && (i < n) && (i < dwLen1) && (i < dwLen2);
++i)
{
rc = (LONG)(TOUPPER(psz1[i]) - TOUPPER(psz2[i]));
}
}
if ((rc == 0) && (i < n))
{
if (i < dwLen1)
rc = (LONG)psz1[i];
else if (i < dwLen2)
rc = (LONG)(-psz2[i]);
}
EXIT(5, ("StrCmp=%d\n", rc));
return rc;
} //StrCmp
/***EP StrChr - look for a character in a string
*
* ENTRY
* psz -> string
* c - character to look for
*
* EXIT-SUCCESS
* returns a pointer to the character found
* EXIT-FAILURE
* returns NULL
*/
PSZ EXPORT StrChr(PSZ pszStr, CHAR c)
{
TRACENAME("STRCHR")
PSZ psz;
ENTER(5, ("StrChr(s=%s,c=%c)\n", pszStr, c));
ASSERT(pszStr != NULL);
for (psz = pszStr; (*psz != c) && (*psz != '\0'); psz++)
;
if (*psz != c)
psz = NULL;
EXIT(5, ("StrChr=%x\n", psz));
return psz;
} //StrChr
/***EP StrRChr - look for a character in a string in reverse direction
*
* ENTRY
* psz -> string
* c - character to look for
*
* EXIT-SUCCESS
* returns a pointer to the character found
* EXIT-FAILURE
* returns NULL
*/
PSZ EXPORT StrRChr(PSZ pszStr, CHAR c)
{
TRACENAME("STRRCHR")
PSZ psz;
ENTER(5, ("StrChr(s=%s,c=%c)\n", pszStr, c));
ASSERT(pszStr != NULL);
for (psz = &pszStr[StrLen(pszStr, (ULONG)-1)];
(*psz != c) && (psz > pszStr);
psz--)
{
}
if (*psz != c)
psz = NULL;
EXIT(5, ("StrRChr=%x\n", psz));
return psz;
} //StrRChr
/***EP StrTok - find the next token in string
*
* ENTRY
* pszStr -> string containing tokens
* pszSep -> string containing delimiters
*
* EXIT-SUCCESS
* returns the pointer to the beginning of the token
* EXIT-FAILURE
* returns NULL
*/
PSZ EXPORT StrTok(PSZ pszStr, PSZ pszSep)
{
TRACENAME("STRTOK")
static PSZ pszNext = NULL;
ENTER(5, ("StrTok(Str=%s,Sep=%s)\n", pszStr, pszSep));
ASSERT(pszSep != NULL);
if (pszStr == NULL)
pszStr = pszNext;
if (pszStr != NULL)
{
//
// Skip leading delimiter characters
//
while ((*pszStr != '\0') && (StrChr(pszSep, *pszStr) != NULL))
pszStr++;
for (pszNext = pszStr;
(*pszNext != '\0') && (StrChr(pszSep, *pszNext) == NULL);
pszNext++)
;
if (*pszStr == '\0')
pszStr = NULL;
else if (*pszNext != '\0')
{
*pszNext = '\0';
pszNext++;
}
}
EXIT(5, ("StrTok=%s (Next=%s)\n",
pszStr? pszStr: "(null)", pszNext? pszNext: "(null)"));
return pszStr;
} //StrTok
/***EP StrToUL - convert the number in a string to a unsigned long integer
*
* ENTRY
* psz -> string
* ppszEnd -> string pointer to the end of the number (can be NULL)
* dwBase - the base of the number (if 0, auto-detect base)
*
* EXIT
* returns the converted number
*/
ULONG EXPORT StrToUL(PSZ psz, PSZ *ppszEnd, ULONG dwBase)
{
TRACENAME("STRTOUL")
ULONG n = 0;
ULONG m;
ENTER(5, ("StrToUL(Str=%s,ppszEnd=%x,Base=%x)\n", psz, ppszEnd, dwBase));
if (dwBase == 0)
{
if (psz[0] == '0')
{
if ((psz[1] == 'x') || (psz[1] == 'X'))
{
dwBase = 16;
psz += 2;
}
else
{
dwBase = 8;
psz++;
}
}
else
dwBase = 10;
}
while (*psz != '\0')
{
if ((*psz >= '0') && (*psz <= '9'))
m = *psz - '0';
else if ((*psz >= 'A') && (*psz <= 'Z'))
m = *psz - 'A' + 10;
else if ((*psz >= 'a') && (*psz <= 'z'))
m = *psz - 'a' + 10;
else
break;
if (m < dwBase)
{
n = (n*dwBase) + m;
psz++;
}
else
break;
}
if (ppszEnd != NULL)
*ppszEnd = psz;
EXIT(5, ("StrToUL=%x (pszEnd=%x)\n", n, ppszEnd? *ppszEnd: 0));
return n;
} //StrToUL
/***EP StrToL - convert the number in a string to a long integer
*
* ENTRY
* psz -> string
* ppszEnd -> string pointer to the end of the number (can be NULL)
* dwBase - the base of the number (if 0, auto-detect base)
*
* EXIT
* returns the converted number
*/
LONG EXPORT StrToL(PSZ psz, PSZ *ppszEnd, ULONG dwBase)
{
TRACENAME("STRTOL")
LONG n = 0;
BOOLEAN fMinus;
ENTER(5, ("StrToL(Str=%s,ppszEnd=%x,Base=%x)\n", psz, ppszEnd, dwBase));
if (*psz == '-')
{
fMinus = TRUE;
psz++;
}
else
fMinus = FALSE;
n = (LONG)StrToUL(psz, ppszEnd, dwBase);
if (fMinus)
n = -n;
EXIT(5, ("StrToL=%x (pszEnd=%x)\n", n, ppszEnd? *ppszEnd: 0));
return n;
} //StrToL
/***EP StrStr - find a substring in a given string
*
* ENTRY
* psz1 -> string to be searched
* psz2 -> substring to find
*
* EXIT-SUCCESS
* returns pointer to psz1 where the substring is found
* EXIT-FAILURE
* returns NULL
*/
PSZ EXPORT StrStr(PSZ psz1, PSZ psz2)
{
TRACENAME("STRSTR")
PSZ psz = psz1;
ULONG dwLen;
ENTER(5, ("StrStr(psz1=%s,psz2=%s)\n", psz1, psz2));
dwLen = StrLen(psz2, (ULONG)-1);
while ((psz = StrChr(psz, *psz2)) != NULL)
{
if (StrCmp(psz, psz2, dwLen, TRUE) == 0)
break;
else
psz++;
}
EXIT(5, ("StrStr=%s\n", psz));
return psz;
} //StrStr
/***EP StrUpr - convert string to upper case
*
* ENTRY
* pszStr -> string
*
* EXIT
* returns pszStr
*/
PSZ EXPORT StrUpr(PSZ pszStr)
{
TRACENAME("STRUPR")
PSZ psz;
ENTER(5, ("StrUpr(Str=%s)\n", pszStr));
for (psz = pszStr; *psz != '\0'; psz++)
{
*psz = TOUPPER(*psz);
}
EXIT(5, ("StrUpr=%s\n", pszStr));
return pszStr;
} //StrUpr
/***EP StrLwr - convert string to lower case
*
* ENTRY
* pszStr -> string
*
* EXIT
* returns pszStr
*/
PSZ EXPORT StrLwr(PSZ pszStr)
{
TRACENAME("STRLWR")
PSZ psz;
ENTER(5, ("StrLwr(Str=%s)\n", pszStr));
for (psz = pszStr; *psz != '\0'; psz++)
{
*psz = TOLOWER(*psz);
}
EXIT(5, ("StrLwr=%s\n", pszStr));
return pszStr;
} //StrLwr
/***EP UlToA - convert an unsigned long value to a string
*
* ENTRY
* dwValue - data
* pszStr -> string
* dwRadix - radix
*
* EXIT
* returns pszStr
*/
PSZ EXPORT UlToA(ULONG dwValue, PSZ pszStr, ULONG dwRadix)
{
TRACENAME("ULTOA")
PSZ psz;
char ch;
ENTER(5, ("UlToA(Value=%x,pszStr=%x,Radix=%d\n", dwValue, pszStr, dwRadix));
for (psz = pszStr; dwValue != 0; dwValue/=dwRadix, psz++)
{
ch = (char)(dwValue%dwRadix);
if (ch <= 9)
{
*psz = (char)(ch + '0');
}
else
{
*psz = (char)(ch - 10 + 'A');
}
}
if (psz == pszStr)
{
pszStr[0] = '0';
pszStr[1] = '\0';
}
else
{
PSZ psz2;
*psz = '\0';
for (psz2 = pszStr, psz--; psz2 < psz; psz2++, psz--)
{
ch = *psz2;
*psz2 = *psz;
*psz = ch;
}
}
EXIT(5, ("UlToA=%s\n", pszStr));
return pszStr;
} //UlToA