mirror of https://github.com/acidanthera/audk.git
263 lines
8.1 KiB
C
263 lines
8.1 KiB
C
|
/** @file
|
||
|
Search Functions for <string.h>.
|
||
|
|
||
|
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||
|
This program and the accompanying materials are licensed and made available under
|
||
|
the terms and conditions of the BSD License that accompanies this distribution.
|
||
|
The full text of the license may be found at
|
||
|
http://opensource.org/licenses/bsd-license.php.
|
||
|
|
||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||
|
**/
|
||
|
#include <Uefi.h>
|
||
|
#include <Library/BaseLib.h>
|
||
|
#include <Library/BaseMemoryLib.h>
|
||
|
|
||
|
#include <LibConfig.h>
|
||
|
#include <limits.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/** The memchr function locates the first occurrence of c (converted to an
|
||
|
unsigned char) in the initial n characters (each interpreted as
|
||
|
unsigned char) of the object pointed to by s.
|
||
|
|
||
|
@return The memchr function returns a pointer to the located character,
|
||
|
or a null pointer if the character does not occur in the object.
|
||
|
**/
|
||
|
void *
|
||
|
memchr(const void *s, int c, size_t n)
|
||
|
{
|
||
|
return ScanMem8( s, (UINTN)n, (UINT8)c);
|
||
|
}
|
||
|
|
||
|
/** The strchr function locates the first occurrence of c (converted to a char)
|
||
|
in the string pointed to by s. The terminating null character is considered
|
||
|
to be part of the string.
|
||
|
|
||
|
@return The strchr function returns a pointer to the located character,
|
||
|
or a null pointer if the character does not occur in the string.
|
||
|
**/
|
||
|
char *
|
||
|
strchr(const char *s, int c)
|
||
|
{
|
||
|
char tgt = (char)c;
|
||
|
|
||
|
do {
|
||
|
if( *s == tgt) {
|
||
|
return (char *)s;
|
||
|
}
|
||
|
} while(*s++ != '\0');
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
static UINT8 BitMask[] = {
|
||
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
|
||
|
};
|
||
|
|
||
|
#define WHICH8(c) ((unsigned char)(c) >> 3)
|
||
|
#define WHICH_BIT(c) (BitMask[((c) & 0x7)])
|
||
|
#define BITMAP64 ((UINT64 *)bitmap)
|
||
|
|
||
|
static
|
||
|
void
|
||
|
BuildBitmap(unsigned char * bitmap, const char *s2, int n)
|
||
|
{
|
||
|
unsigned char bit;
|
||
|
int index;
|
||
|
|
||
|
// Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'
|
||
|
for (BITMAP64[0] = index = 1; index < n; index++)
|
||
|
BITMAP64[index] = 0;
|
||
|
|
||
|
// Set bits in bitmap corresponding to the characters in s2
|
||
|
for (; *s2 != '\0'; s2++) {
|
||
|
index = WHICH8(*s2);
|
||
|
bit = WHICH_BIT(*s2);
|
||
|
bitmap[index] = bitmap[index] | bit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** The strcspn function computes the length of the maximum initial segment of
|
||
|
the string pointed to by s1 which consists entirely of characters not from
|
||
|
the string pointed to by s2.
|
||
|
|
||
|
@return The strcspn function returns the length of the segment.
|
||
|
**/
|
||
|
size_t
|
||
|
strcspn(const char *s1, const char *s2)
|
||
|
{
|
||
|
UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
|
||
|
const char *str;
|
||
|
UINT8 bit;
|
||
|
int index;
|
||
|
|
||
|
if(*s1 == '\0') return 0;
|
||
|
|
||
|
BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
|
||
|
|
||
|
for(str = s1; ; str++) {
|
||
|
index = WHICH8(*str);
|
||
|
bit = WHICH_BIT(*str);
|
||
|
if ((bitmap[index] & bit) != 0)
|
||
|
break;
|
||
|
}
|
||
|
return (str - s1);
|
||
|
}
|
||
|
|
||
|
/** The strpbrk function locates the first occurrence in the string pointed to
|
||
|
by s1 of any character from the string pointed to by s2.
|
||
|
|
||
|
@return The strpbrk function returns a pointer to the character, or a
|
||
|
null pointer if no character from s2 occurs in s1.
|
||
|
**/
|
||
|
char *
|
||
|
strpbrk(const char *s1, const char *s2)
|
||
|
{
|
||
|
UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
|
||
|
UINT8 bit;
|
||
|
int index;
|
||
|
|
||
|
BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
|
||
|
|
||
|
for( ; *s1 != '\0'; ++s1) {
|
||
|
index = WHICH8(*s1);
|
||
|
bit = WHICH_BIT(*s1);
|
||
|
if( (bitmap[index] & bit) != 0) {
|
||
|
return (char *)s1;
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/** The strrchr function locates the last occurrence of c (converted to a char)
|
||
|
in the string pointed to by s. The terminating null character is considered
|
||
|
to be part of the string.
|
||
|
|
||
|
@return The strrchr function returns a pointer to the character, or a
|
||
|
null pointer if c does not occur in the string.
|
||
|
**/
|
||
|
char *
|
||
|
strrchr(const char *s, int c)
|
||
|
{
|
||
|
char *found = NULL;
|
||
|
char tgt = (char)c;
|
||
|
|
||
|
do {
|
||
|
if( *s == tgt) found = (char *)s;
|
||
|
} while( *s++ != '\0');
|
||
|
|
||
|
return found;
|
||
|
}
|
||
|
|
||
|
/** The strspn function computes the length of the maximum initial segment of
|
||
|
the string pointed to by s1 which consists entirely of characters from the
|
||
|
string pointed to by s2.
|
||
|
|
||
|
@return The strspn function returns the length of the segment.
|
||
|
**/
|
||
|
size_t
|
||
|
strspn(const char *s1 , const char *s2)
|
||
|
{
|
||
|
UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
|
||
|
size_t length = 0;
|
||
|
int index;
|
||
|
UINT8 bit;
|
||
|
|
||
|
BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
|
||
|
|
||
|
for( ; *s1 != '\0'; ++s1) {
|
||
|
index = WHICH8(*s1);
|
||
|
bit = WHICH_BIT(*s1);
|
||
|
if( (bitmap[index] & bit) == 0) break;
|
||
|
++length;
|
||
|
}
|
||
|
return length;
|
||
|
}
|
||
|
|
||
|
/** The strstr function locates the first occurrence in the string pointed to
|
||
|
by s1 of the sequence of characters (excluding the terminating null
|
||
|
character) in the string pointed to by s2.
|
||
|
|
||
|
@return The strstr function returns a pointer to the located string, or a
|
||
|
null pointer if the string is not found. If s2 points to a string
|
||
|
with zero length, the function returns s1.
|
||
|
**/
|
||
|
char *
|
||
|
strstr(const char *s1 , const char *s2)
|
||
|
{
|
||
|
return AsciiStrStr( s1, s2);
|
||
|
}
|
||
|
|
||
|
/** A sequence of calls to the strtok function breaks the string pointed to by
|
||
|
s1 into a sequence of tokens, each of which is delimited by a character
|
||
|
from the string pointed to by s2. The first call in the sequence has a
|
||
|
non-null first argument; subsequent calls in the sequence have a null first
|
||
|
argument. The separator string pointed to by s2 may be different from call
|
||
|
to call.
|
||
|
|
||
|
The first call in the sequence searches the string pointed to by s1 for the
|
||
|
first character that is not contained in the current separator string
|
||
|
pointed to by s2. If no such character is found, then there are no tokens
|
||
|
in the string pointed to by s1 and the strtok function returns a null
|
||
|
pointer. If such a character is found, it is the start of the first token.
|
||
|
|
||
|
The strtok function then searches from there for a character that is
|
||
|
contained in the current separator string. If no such character is found,
|
||
|
the current token extends to the end of the string pointed to by s1, and
|
||
|
subsequent searches for a token will return a null pointer. If such a
|
||
|
character is found, it is overwritten by a null character, which terminates
|
||
|
the current token. The strtok function saves a pointer to the following
|
||
|
character, from which the next search for a token will start.
|
||
|
|
||
|
Each subsequent call, with a null pointer as the value of the first
|
||
|
argument, starts searching from the saved pointer and behaves as
|
||
|
described above.
|
||
|
|
||
|
@return The strtok function returns a pointer to the first character of a
|
||
|
token, or a null pointer if there is no token.
|
||
|
**/
|
||
|
char *
|
||
|
strtok(char * __restrict s1, const char * __restrict s2)
|
||
|
{
|
||
|
static char *Next = NULL;
|
||
|
UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
|
||
|
char *Token = NULL;
|
||
|
int index;
|
||
|
UINT8 bit;
|
||
|
|
||
|
if( (s1 == NULL)
|
||
|
&& ((s1 = Next) == NULL))
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// s2 can be different on each call, so build the bitmap each time.
|
||
|
BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));
|
||
|
|
||
|
// skip leading delimiters: all chars in s2
|
||
|
for( ; *s1 != '\0'; ++s1) {
|
||
|
index = WHICH8(*s1);
|
||
|
bit = WHICH_BIT(*s1);
|
||
|
if( (bitmap[index] & bit) == 0) break;
|
||
|
}
|
||
|
if( *s1 != 0)
|
||
|
{
|
||
|
// Remember this point, it is the start of the token
|
||
|
Token = s1++;
|
||
|
|
||
|
// find the next delimiter and replace it with a '\0'
|
||
|
for( ; *s1 != '\0'; ++s1) {
|
||
|
index = WHICH8(*s1);
|
||
|
bit = WHICH_BIT(*s1);
|
||
|
if( (bitmap[index] & bit) != 0) {
|
||
|
*s1++ = '\0';
|
||
|
Next = s1;
|
||
|
return Token;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Next = NULL;
|
||
|
return Token;
|
||
|
}
|