summaryrefslogtreecommitdiff
path: root/StdLib/LibC/String
diff options
context:
space:
mode:
authordarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>2011-04-27 21:42:16 +0000
committerdarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>2011-04-27 21:42:16 +0000
commit2aa62f2bc9a9654687b377d9ca8a8c2c860a3852 (patch)
tree62a0991a44327154fb88bf95bd6f7522053db7bb /StdLib/LibC/String
parent98790d814871cc30bbd536673d3a0948047cd2f0 (diff)
downloadedk2-platforms-2aa62f2bc9a9654687b377d9ca8a8c2c860a3852.tar.xz
Standard Libraries for EDK II.
This set of three packages: AppPkg, StdLib, StdLibPrivateInternalFiles; contains the implementation of libraries based upon non-UEFI standards such as ISO/IEC-9899, the library portion of the C Language Standard, POSIX, etc. AppPkg contains applications that make use of the standard libraries defined in the StdLib Package. StdLib contains header (include) files and the implementations of the standard libraries. StdLibPrivateInternalFiles contains files for the exclusive use of the library implementations in StdLib. These files should never be directly referenced from applications or other code. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11600 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'StdLib/LibC/String')
-rw-r--r--StdLib/LibC/String/Comparison.c118
-rw-r--r--StdLib/LibC/String/Concatenation.c83
-rw-r--r--StdLib/LibC/String/Copying.c141
-rw-r--r--StdLib/LibC/String/ErrorList.c144
-rw-r--r--StdLib/LibC/String/Misc.c99
-rw-r--r--StdLib/LibC/String/Searching.c262
-rw-r--r--StdLib/LibC/String/String.inf62
7 files changed, 909 insertions, 0 deletions
diff --git a/StdLib/LibC/String/Comparison.c b/StdLib/LibC/String/Comparison.c
new file mode 100644
index 0000000000..e656fe73f5
--- /dev/null
+++ b/StdLib/LibC/String/Comparison.c
@@ -0,0 +1,118 @@
+/** @file
+ Comparison Functions for <string.h>.
+
+ Copyright (c) 2010, 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 <ctype.h>
+#include <string.h>
+
+/** The memcmp function compares the first n characters of the object pointed
+ to by s1 to the first n characters of the object pointed to by s2.
+
+ @return The memcmp function returns an integer greater than, equal to, or
+ less than zero, accordingly as the object pointed to by s1 is
+ greater than, equal to, or less than the object pointed to by s2.
+**/
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+ return (int)CompareMem( s1, s2, n);
+}
+
+/** The strcmp function compares the string pointed to by s1 to the string
+ pointed to by s2.
+
+ @return The strcmp function returns an integer greater than, equal to, or
+ less than zero, accordingly as the string pointed to by s1 is
+ greater than, equal to, or less than the string pointed to by s2.
+**/
+int strcmp(const char *s1, const char *s2)
+{
+ return (int)AsciiStriCmp( s1, s2);
+}
+
+/** The strcoll function compares the string pointed to by s1 to the string
+ pointed to by s2, both interpreted as appropriate to the LC_COLLATE
+ category of the current locale.
+
+ @return The strcoll function returns an integer greater than, equal to,
+ or less than zero, accordingly as the string pointed to by s1 is
+ greater than, equal to, or less than the string pointed to by s2
+ when both are interpreted as appropriate to the current locale.
+**/
+int strcoll(const char *s1, const char *s2)
+{
+ /* LC_COLLATE is unimplemented, hence always "C" */
+ return (strcmp(s1, s2));
+}
+
+/** The strncmp function compares not more than n characters (characters that
+ follow a null character are not compared) from the array pointed to by s1
+ to the array pointed to by s2.
+
+ @return The strncmp function returns an integer greater than, equal to,
+ or less than zero, accordingly as the possibly null-terminated
+ array pointed to by s1 is greater than, equal to, or less than
+ the possibly null-terminated array pointed to by s2.
+**/
+int strncmp(const char *s1, const char *s2, size_t n)
+{
+ return (int)AsciiStrnCmp( s1, s2, n);
+}
+
+/** The strxfrm function transforms the string pointed to by s2 and places the
+ resulting string into the array pointed to by s1. The transformation is
+ such that if the strcmp function is applied to two transformed strings, it
+ returns a value greater than, equal to, or less than zero, corresponding to
+ the result of the strcoll function applied to the same two original
+ strings. No more than n characters are placed into the resulting array
+ pointed to by s1, including the terminating null character. If n is zero,
+ s1 is permitted to be a null pointer. If copying takes place between
+ objects that overlap, the behavior is undefined.
+
+ @return The strxfrm function returns the length of the transformed string
+ (not including the terminating null character). If the value
+ returned is n or more, the contents of the array pointed to by s1
+ are indeterminate.
+**/
+size_t strxfrm(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ size_t srclen, copysize;
+
+ /*
+ * Since locales are unimplemented, this is just a copy.
+ */
+ srclen = strlen(s2);
+ if (n != 0) {
+ copysize = srclen < n ? srclen : n - 1;
+ (void)memcpy(s1, s2, copysize);
+ s1[copysize] = 0;
+ }
+ return (srclen);
+}
+
+/** Case agnostic string comparison for NetBSD compatibility. **/
+int
+strcasecmp(const char *s1, const char *s2)
+{
+ const unsigned char *us1 = (const unsigned char *)s1,
+ *us2 = (const unsigned char *)s2;
+
+ while (tolower(*us1) == tolower(*us2++))
+ if (*us1++ == '\0')
+ return (0);
+ return (tolower(*us1) - tolower(*--us2));
+}
+
diff --git a/StdLib/LibC/String/Concatenation.c b/StdLib/LibC/String/Concatenation.c
new file mode 100644
index 0000000000..e76bea0bf8
--- /dev/null
+++ b/StdLib/LibC/String/Concatenation.c
@@ -0,0 +1,83 @@
+/** @file
+ Concatenation Functions for <string.h>.
+
+ Copyright (c) 2010, 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 <LibConfig.h>
+
+#include <string.h>
+
+/** The strcat function appends a copy of the string pointed to by s2
+ (including the terminating null character) to the end of the string pointed
+ to by s1. The initial character of s2 overwrites the null character at the
+ end of s1. If copying takes place between objects that overlap, the
+ behavior is undefined.
+
+ @return The strcat function returns the value of s1.
+**/
+char *
+strcat(char * __restrict s1, const char * __restrict s2)
+{
+ return AsciiStrCat( s1, s2);
+}
+
+/** The strncat function appends not more than n characters (a null character
+ and characters that follow it are not appended) from the array pointed to
+ by s2 to the end of the string pointed to by s1. The initial character of
+ s2 overwrites the null character at the end of s1. A terminating null
+ character is always appended to the result. If copying takes place
+ between objects that overlap, the behavior is undefined.
+
+ @return The strncat function returns the value of s1.
+**/
+char *
+strncat(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ return AsciiStrnCat( s1, s2, n);
+}
+
+/** The strncatX function appends not more than n characters (a null character
+ and characters that follow it are not appended) from the array pointed to
+ by s2 to the end of the string pointed to by s1. The initial character of
+ s2 overwrites the null character at the end of s1. The result is always
+ terminated with a null character. If copying takes place between objects
+ that overlap, the behavior is undefined.
+
+ strncatX exists because normal strncat does not indicate if the operation
+ was terminated because of exhausting n or reaching the end of s2.
+
+ @return The strncatX function returns 0 if the operation was terminated
+ because it reached the end of s1. Otherwise, a non-zero value is
+ returned indicating how many characters remain in s1.
+**/
+int
+strncatX(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ int NumLeft;
+
+ // Find s1's terminating NUL
+ for( ; n != 0; --n) {
+ if( *s1++ == '\0') break;
+ }
+
+ // Now copy *s2 into s1, overwriting s1's terminating NUL
+ for( --s1; n != 0; --n) {
+ if((*s1++ = *s2++) == '\0') break;
+ }
+ NumLeft = (int)n;
+
+ // Guarantee that s1 is NUL terminated.
+ *--s1 = '\0';
+
+ return NumLeft; // Zero if we ran out of buffer ( strlen(s1) < strlen(s2) )
+}
diff --git a/StdLib/LibC/String/Copying.c b/StdLib/LibC/String/Copying.c
new file mode 100644
index 0000000000..2d5200e3c5
--- /dev/null
+++ b/StdLib/LibC/String/Copying.c
@@ -0,0 +1,141 @@
+/** @file
+ Copying Functions for <string.h>.
+
+ Copyright (c) 2010, 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 <sys/EfiCdefs.h>
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+/** The memcpy function copies n characters from the object pointed to by s2
+ into the object pointed to by s1.
+
+ The implementation is reentrant and handles the case where s2 overlaps s1.
+
+ @return The memcpy function returns the value of s1.
+**/
+void *
+memcpy(void * __restrict s1, const void * __restrict s2, size_t n)
+{
+ return CopyMem( s1, s2, n);
+}
+
+/** The memmove function copies n characters from the object pointed to by s2
+ into the object pointed to by s1. Copying takes place as if the n
+ characters from the object pointed to by s2 are first copied into a
+ temporary array of n characters that does not overlap the objects pointed
+ to by s1 and s2, and then the n characters from the temporary array are
+ copied into the object pointed to by s1.
+
+ This is a version of memcpy that is guaranteed to work when s1 and s2
+ overlap. Since our implementation of memcpy already handles overlap,
+ memmove can be identical to memcpy.
+
+ @return The memmove function returns the value of s1.
+**/
+void *
+memmove(void *s1, const void *s2, size_t n)
+{
+ return CopyMem( s1, s2, n);
+}
+
+/** The strcpy function copies the string pointed to by s2 (including the
+ terminating null character) into the array pointed to by s1. If copying
+ takes place between objects that overlap, the behavior is undefined.
+
+ @return The strcpy function returns the value of s1.
+**/
+char *
+strcpy(char * __restrict s1, const char * __restrict s2)
+{
+ //char *s1ret = s1;
+
+ //while ( *s1++ = *s2++) /* Empty Body */;
+ //return(s1ret);
+ return AsciiStrCpy( s1, s2);
+}
+
+/** The strncpy function copies not more than n characters (characters that
+ follow a null character are not copied) from the array pointed to by s2 to
+ the array pointed to by s1. If copying takes place between objects that
+ overlap, the behavior is undefined.
+
+ If the array pointed to by s2 is a string that is shorter than n
+ characters, null characters are appended to the copy in the array pointed
+ to by s1, until n characters in all have been written.
+
+ @return The strncpy function returns the value of s1.
+**/
+char *strncpy(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ return AsciiStrnCpy( s1, s2, n);
+ //char *dest = s1;
+
+ //while(n != 0) {
+ // --n;
+ // if((*dest++ = *s2++) == '\0') break;
+ //}
+ //while(n != 0) {
+ // *dest++ = '\0';
+ // --n;
+ //}
+ //return (s1);
+}
+
+/** The strncpyX function copies not more than n-1 characters (characters that
+ follow a null character are not copied) from the array pointed to by s2 to
+ the array pointed to by s1. Array s1 is guaranteed to be NULL terminated.
+ If copying takes place between objects that overlap,
+ the behavior is undefined.
+
+ strncpyX exists because normal strncpy does not indicate if the copy was
+ terminated because of exhausting the buffer or reaching the end of s2.
+
+ @return The strncpyX function returns 0 if the copy operation was
+ terminated because it reached the end of s1. Otherwise,
+ a non-zero value is returned indicating how many characters
+ remain in s1.
+**/
+int strncpyX(char * __restrict s1, const char * __restrict s2, size_t n)
+{
+ int NumLeft;
+
+ for( ; n != 0; --n) {
+ if((*s1++ = *s2++) == '\0') break;
+ }
+ NumLeft = (int)n;
+
+ for( --s1; n != 0; --n) {
+ *s1++ = '\0';
+ }
+
+ return NumLeft; // Zero if we ran out of buffer ( strlen(s1) < strlen(s2) )
+}
+
+/** NetBSD Compatibility Function strdup creates a duplicate copy of a string. **/
+char *
+strdup(const char *str)
+{
+ size_t len;
+ char *copy;
+
+ len = strlen(str) + 1;
+ if ((copy = malloc(len)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ return (copy);
+}
diff --git a/StdLib/LibC/String/ErrorList.c b/StdLib/LibC/String/ErrorList.c
new file mode 100644
index 0000000000..56c286011f
--- /dev/null
+++ b/StdLib/LibC/String/ErrorList.c
@@ -0,0 +1,144 @@
+/** @file
+ This header defines the human readable descriptions of the errors declared
+ in errno.h.
+
+ The string literals defined in this file must be kept in sync with the
+ error numbers declared in <errno.h>. This is because the error numbers are
+ used to index into the sys_errlist array to retrieve its associated
+ string literal.
+
+ Copyright (c) 2010, 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 <LibConfig.h>
+#include <sys/EfiCdefs.h>
+
+/* Describe the error numbers, sequentially, beginning at 0. */
+const char *const
+sys_errlist[] = {
+ "No Error Detected", /* 0 errno reset or no error yet detected */
+ "Operation not permitted", /* 1 EPERM */
+ "No such file or directory", /* 2 ENOENT */
+ "No such process", /* 3 ESRCH */
+ "Interrupted system call", /* 4 EINTR */
+ "Input/output error", /* 5 EIO */
+ "Device not configured", /* 6 ENXIO */
+ "Argument list too long", /* 7 E2BIG */
+ "Exec format error", /* 8 ENOEXEC */
+ "Bad file descriptor", /* 9 EBADF */
+ "No child processes", /* 10 ECHILD */
+ "Resource deadlock avoided", /* 11 EDEADLK */
+ "Cannot allocate memory", /* 12 ENOMEM */
+ "Permission denied", /* 13 EACCES */
+ "Bad address", /* 14 EFAULT */
+ "Block device required", /* 15 ENOTBLK */
+ "Device busy", /* 16 EBUSY */
+ "File exists", /* 17 EEXIST */
+ "Cross-device link", /* 18 EXDEV */
+ "Operation not supported by device", /* 19 ENODEV */
+ "Not a directory", /* 20 ENOTDIR */
+ "Is a directory", /* 21 EISDIR */
+ "Invalid argument", /* 22 EINVAL */
+ "Too many open files in system", /* 23 ENFILE */
+ "Too many open files", /* 24 EMFILE */
+ "Inappropriate ioctl for device", /* 25 ENOTTY */
+ "Text file busy", /* 26 ETXTBSY */
+ "File too large", /* 27 EFBIG */
+ "No space left on device", /* 28 ENOSPC */
+ "Illegal seek", /* 29 ESPIPE */
+ "Read-only filesystem", /* 30 EROFS */
+ "Too many links", /* 31 EMLINK */
+ "Broken pipe", /* 32 EPIPE */
+
+ /* math software -- these are the only two values required by the C Standard */
+ "Numerical argument out of domain", /* 33 EDOM */
+ "Result too large", /* 34 ERANGE */
+
+ /* non-blocking and interrupt i/o */
+ "Resource temporarily unavailable", /* 35 EAGAIN or EWOULDBLOCK */
+ "Operation now in progress", /* 36 EINPROGRESS */
+ "Operation already in progress", /* 37 EALREADY */
+
+ /* ipc/network software -- argument errors */
+ "Socket operation on non-socket", /* 38 ENOTSOCK */
+ "Destination address required", /* 39 EDESTADDRREQ */
+ "Message too long", /* 40 EMSGSIZE */
+ "Protocol wrong type for socket", /* 41 EPROTOTYPE */
+ "Protocol not available", /* 42 ENOPROTOOPT */
+ "Protocol not supported", /* 43 EPROTONOSUPPORT */
+ "Socket type not supported", /* 44 ESOCKTNOSUPPORT */
+ "Operation not supported", /* 45 EOPNOTSUPP or ENOTSUP */
+ "Protocol family not supported", /* 46 EPFNOSUPPORT */
+ "Address family not supported by protocol family", /* 47 EAFNOSUPPORT */
+ "Address already in use", /* 48 EADDRINUSE */
+ "Can't assign requested address", /* 49 EADDRNOTAVAIL */
+
+ /* ipc/network software -- operational errors */
+ "Network is down", /* 50 ENETDOWN */
+ "Network is unreachable", /* 51 ENETUNREACH */
+ "Network dropped connection on reset", /* 52 ENETRESET */
+ "Software caused connection abort", /* 53 ECONNABORTED */
+ "Connection reset by peer", /* 54 ECONNRESET */
+ "No buffer space available", /* 55 ENOBUFS */
+ "Socket is already connected", /* 56 EISCONN */
+ "Socket is not connected", /* 57 ENOTCONN */
+ "Can't send after socket shutdown", /* 58 ESHUTDOWN */
+ "Too many references: can't splice", /* 59 ETOOMANYREFS */
+ "Operation timed out", /* 60 ETIMEDOUT */
+ "Connection refused", /* 61 ECONNREFUSED */
+ "Too many levels of symbolic links", /* 62 ELOOP */
+ "File name too long", /* 63 ENAMETOOLONG */
+ "Host is down", /* 64 EHOSTDOWN */
+ "No route to host", /* 65 EHOSTUNREACH */
+ "Directory not empty", /* 66 ENOTEMPTY */
+
+ /* quotas, etc. */
+ "Too many processes", /* 67 EPROCLIM */
+ "Too many users", /* 68 EUSERS */
+ "Disc quota exceeded", /* 69 EDQUOT */
+
+ /* Network File System */
+ "Stale NFS file handle", /* 70 ESTALE */
+ "Too many levels of remote in path", /* 71 EREMOTE */
+ "RPC struct is bad", /* 72 EBADRPC */
+ "RPC version wrong", /* 73 ERPCMISMATCH */
+ "RPC prog. not avail", /* 74 EPROGUNAVAIL */
+ "Program version wrong", /* 75 EPROGMISMATCH */
+ "Bad procedure for program", /* 76 EPROCUNAVAIL */
+ "No locks available", /* 77 ENOLCK */
+ "Function not implemented", /* 78 ENOSYS */
+ "Inappropriate file type or format", /* 79 EFTYPE */
+ "Authentication error", /* 80 EAUTH */
+ "Need authenticator", /* 81 ENEEDAUTH */
+ "Identifier removed", /* 82 EIDRM */
+ "No message of desired type", /* 83 ENOMSG */
+ "Value too large to be stored in data type", /* 84 EOVERFLOW */
+ "Illegal byte sequence", /* 85 EILSEQ */
+ "Bad errno 86", /* 86 ENOTHING_1 */
+ "Operation canceled", /* 87 ECANCELED */
+
+ "Bad message", /* 88 EBADMSG */
+ "No message available", /* 89 ENODATA */
+ "No STREAM resources", /* 90 ENOSR */
+ "Not a STREAM", /* 91 ENOSTR */
+ "STREAM ioctl timeout", /* 92 ETIME */
+
+ "Attribute not found", /* 93 ENOATTR */
+
+ "Programming error", /* 94 EDOOFUS */
+
+ "Multihop attempted", /* 95 EMULTIHOP */
+ "Link has been severed", /* 96 ENOLINK */
+ "Protocol error", /* 97 EPROTO */
+
+ "Buffer too small to hold result", /* 98 EBUFSIZE */
+
+ "System Error list and errno.h are out-of-sync" /* EMAXERRORVAL - Should always be last. */
+};
diff --git a/StdLib/LibC/String/Misc.c b/StdLib/LibC/String/Misc.c
new file mode 100644
index 0000000000..99328252ed
--- /dev/null
+++ b/StdLib/LibC/String/Misc.c
@@ -0,0 +1,99 @@
+/** @file
+ Miscellaneous Functions for <string.h>.
+
+ Copyright (c) 2010, 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 <sys/EfiCdefs.h>
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+
+extern char *sys_errlist[];
+
+/** The memset function copies the value of c (converted to an unsigned char)
+ into each of the first n characters of the object pointed to by s.
+
+ @return The memset function returns the value of s.
+**/
+void *
+memset(void *s, int c, size_t n)
+{
+ return SetMem( s, (UINTN)n, (UINT8)c);
+}
+
+int
+strerror_r(int errnum, char *buf, size_t buflen)
+{
+ const char *estring;
+ INTN i;
+ int retval = 0;
+
+ if( (errnum < 0) || (errnum >= EMAXERRORVAL)) {
+ (void) AsciiSPrint( buf, ASCII_STRING_MAX, "Unknown Error: %d.", errnum);
+ retval = EINVAL;
+ }
+ else {
+ estring = sys_errlist[errnum];
+ for( i = buflen; i > 0; --i) {
+ if( (*buf++ = *estring++) == '\0') {
+ break;
+ }
+ }
+ if(i == 0) {
+ retval = ERANGE;
+ }
+ }
+ return retval;
+}
+
+/** The strerror function maps the number in errnum to a message string.
+ Typically, the values for errnum come from errno, but strerror shall map
+ any value of type int to a message.
+
+ The implementation shall behave as if no library function calls the
+ strerror function.
+
+ @return The strerror function returns a pointer to the string, the
+ contents of which are locale specific. The array pointed to
+ shall not be modified by the program, but may be overwritten by
+ a subsequent call to the strerror function.
+**/
+char *
+strerror(int errnum)
+{
+ static char errorbuf[ASCII_STRING_MAX];
+ int status;
+
+ status = strerror_r(errnum, errorbuf, sizeof(errorbuf));
+ if(status != 0) {
+ errno = status;
+ }
+ return errorbuf;
+}
+
+/** The strlen function computes the length of the string pointed to by s.
+
+ @return The strlen function returns the number of characters that
+ precede the terminating null character.
+**/
+size_t
+strlen(const char *s)
+{
+ return (size_t)AsciiStrLen( s);
+}
diff --git a/StdLib/LibC/String/Searching.c b/StdLib/LibC/String/Searching.c
new file mode 100644
index 0000000000..e22655621c
--- /dev/null
+++ b/StdLib/LibC/String/Searching.c
@@ -0,0 +1,262 @@
+/** @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;
+}
diff --git a/StdLib/LibC/String/String.inf b/StdLib/LibC/String/String.inf
new file mode 100644
index 0000000000..1614b1cb11
--- /dev/null
+++ b/StdLib/LibC/String/String.inf
@@ -0,0 +1,62 @@
+## @file
+# Standard C library: Miscelaneous implementations.
+#
+# Copyright (c) 2010, 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
+# which 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.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibString
+ FILE_GUID = caee2f3b-3191-4da0-ad10-a5c07e636cd1
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibString
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Misc.c
+ Copying.c
+ Concatenation.c
+ Comparison.c
+ Searching.c
+ ErrorList.c
+
+[Packages]
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ PrintLib # Used for strerror()
+ PcdLib
+ LibC
+ LibCType
+ LibStdLib
+
+################################################################
+#
+# The Build Options, below, are only used when building the C library.
+# DO NOT use them when building your application!
+# Nasty things could happen if you do.
+#
+# /Oi- is required for Microsoft VC++ to allow "intrinsic" functions to be
+# defined in this library.
+# /GL- is required so that LTCG generated references to functions in this library,
+# such as memcpy(), can be resolved.
+#
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /Oi- /GL-