]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/String/Searching.c
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / StdLib / LibC / String / Searching.c
CommitLineData
2aa62f2b 1/** @file\r
2 Search Functions for <string.h>.\r
3\r
4 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials are licensed and made available under\r
6 the terms and conditions of the BSD License that accompanies this distribution.\r
7 The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12**/\r
13#include <Uefi.h>\r
14#include <Library/BaseLib.h>\r
15#include <Library/BaseMemoryLib.h>\r
16\r
17#include <LibConfig.h>\r
18#include <limits.h>\r
19#include <string.h>\r
20\r
21/** The memchr function locates the first occurrence of c (converted to an\r
22 unsigned char) in the initial n characters (each interpreted as\r
23 unsigned char) of the object pointed to by s.\r
24\r
25 @return The memchr function returns a pointer to the located character,\r
26 or a null pointer if the character does not occur in the object.\r
27**/\r
28void *\r
29memchr(const void *s, int c, size_t n)\r
30{\r
31 return ScanMem8( s, (UINTN)n, (UINT8)c);\r
32}\r
33\r
34/** The strchr function locates the first occurrence of c (converted to a char)\r
35 in the string pointed to by s. The terminating null character is considered\r
36 to be part of the string.\r
37\r
38 @return The strchr function returns a pointer to the located character,\r
39 or a null pointer if the character does not occur in the string.\r
40**/\r
41char *\r
42strchr(const char *s, int c)\r
43{\r
44 char tgt = (char)c;\r
45\r
46 do {\r
47 if( *s == tgt) {\r
48 return (char *)s;\r
49 }\r
50 } while(*s++ != '\0');\r
51 return NULL;\r
52}\r
53\r
54static UINT8 BitMask[] = {\r
55 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80\r
56 };\r
57\r
58#define WHICH8(c) ((unsigned char)(c) >> 3)\r
59#define WHICH_BIT(c) (BitMask[((c) & 0x7)])\r
60#define BITMAP64 ((UINT64 *)bitmap)\r
61\r
62static\r
63void\r
64BuildBitmap(unsigned char * bitmap, const char *s2, int n)\r
65{\r
66 unsigned char bit;\r
67 int index;\r
68\r
69 // Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'\r
70 for (BITMAP64[0] = index = 1; index < n; index++)\r
71 BITMAP64[index] = 0;\r
72\r
73 // Set bits in bitmap corresponding to the characters in s2\r
74 for (; *s2 != '\0'; s2++) {\r
75 index = WHICH8(*s2);\r
76 bit = WHICH_BIT(*s2);\r
77 bitmap[index] = bitmap[index] | bit;\r
78 }\r
79}\r
80\r
81/** The strcspn function computes the length of the maximum initial segment of\r
82 the string pointed to by s1 which consists entirely of characters not from\r
83 the string pointed to by s2.\r
84\r
85 @return The strcspn function returns the length of the segment.\r
86**/\r
87size_t\r
88strcspn(const char *s1, const char *s2)\r
89{\r
90 UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];\r
91 const char *str;\r
92 UINT8 bit;\r
93 int index;\r
94\r
95 if(*s1 == '\0') return 0;\r
96\r
97 BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));\r
98\r
99 for(str = s1; ; str++) {\r
100 index = WHICH8(*str);\r
101 bit = WHICH_BIT(*str);\r
102 if ((bitmap[index] & bit) != 0)\r
103 break;\r
104 }\r
105 return (str - s1);\r
106}\r
107\r
108/** The strpbrk function locates the first occurrence in the string pointed to\r
109 by s1 of any character from the string pointed to by s2.\r
110\r
111 @return The strpbrk function returns a pointer to the character, or a\r
112 null pointer if no character from s2 occurs in s1.\r
113**/\r
114char *\r
115strpbrk(const char *s1, const char *s2)\r
116{\r
117 UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];\r
118 UINT8 bit;\r
119 int index;\r
120\r
121 BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));\r
122\r
123 for( ; *s1 != '\0'; ++s1) {\r
124 index = WHICH8(*s1);\r
125 bit = WHICH_BIT(*s1);\r
126 if( (bitmap[index] & bit) != 0) {\r
127 return (char *)s1;\r
128 }\r
129 }\r
130 return NULL;\r
131}\r
132\r
133/** The strrchr function locates the last occurrence of c (converted to a char)\r
134 in the string pointed to by s. The terminating null character is considered\r
135 to be part of the string.\r
136\r
137 @return The strrchr function returns a pointer to the character, or a\r
138 null pointer if c does not occur in the string.\r
139**/\r
140char *\r
141strrchr(const char *s, int c)\r
142{\r
143 char *found = NULL;\r
144 char tgt = (char)c;\r
145\r
146 do {\r
147 if( *s == tgt) found = (char *)s;\r
148 } while( *s++ != '\0');\r
149\r
150 return found;\r
151}\r
152\r
153/** The strspn function computes the length of the maximum initial segment of\r
154 the string pointed to by s1 which consists entirely of characters from the\r
155 string pointed to by s2.\r
156\r
157 @return The strspn function returns the length of the segment.\r
158**/\r
159size_t\r
160strspn(const char *s1 , const char *s2)\r
161{\r
162 UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];\r
163 size_t length = 0;\r
164 int index;\r
165 UINT8 bit;\r
166\r
167 BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));\r
168\r
169 for( ; *s1 != '\0'; ++s1) {\r
170 index = WHICH8(*s1);\r
171 bit = WHICH_BIT(*s1);\r
172 if( (bitmap[index] & bit) == 0) break;\r
173 ++length;\r
174 }\r
175 return length;\r
176}\r
177\r
178/** The strstr function locates the first occurrence in the string pointed to\r
179 by s1 of the sequence of characters (excluding the terminating null\r
180 character) in the string pointed to by s2.\r
181\r
182 @return The strstr function returns a pointer to the located string, or a\r
183 null pointer if the string is not found. If s2 points to a string\r
184 with zero length, the function returns s1.\r
185**/\r
186char *\r
187strstr(const char *s1 , const char *s2)\r
188{\r
189 return AsciiStrStr( s1, s2);\r
190}\r
191\r
192/** A sequence of calls to the strtok function breaks the string pointed to by\r
193 s1 into a sequence of tokens, each of which is delimited by a character\r
194 from the string pointed to by s2. The first call in the sequence has a\r
195 non-null first argument; subsequent calls in the sequence have a null first\r
196 argument. The separator string pointed to by s2 may be different from call\r
197 to call.\r
198\r
199 The first call in the sequence searches the string pointed to by s1 for the\r
200 first character that is not contained in the current separator string\r
201 pointed to by s2. If no such character is found, then there are no tokens\r
202 in the string pointed to by s1 and the strtok function returns a null\r
203 pointer. If such a character is found, it is the start of the first token.\r
204\r
205 The strtok function then searches from there for a character that is\r
206 contained in the current separator string. If no such character is found,\r
207 the current token extends to the end of the string pointed to by s1, and\r
208 subsequent searches for a token will return a null pointer. If such a\r
209 character is found, it is overwritten by a null character, which terminates\r
210 the current token. The strtok function saves a pointer to the following\r
211 character, from which the next search for a token will start.\r
212\r
213 Each subsequent call, with a null pointer as the value of the first\r
214 argument, starts searching from the saved pointer and behaves as\r
215 described above.\r
216\r
217 @return The strtok function returns a pointer to the first character of a\r
218 token, or a null pointer if there is no token.\r
219**/\r
220char *\r
221strtok(char * __restrict s1, const char * __restrict s2)\r
222{\r
223 static char *Next = NULL;\r
224 UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];\r
225 char *Token = NULL;\r
226 int index;\r
227 UINT8 bit;\r
228\r
229 if( (s1 == NULL)\r
230 && ((s1 = Next) == NULL))\r
231 {\r
232 return NULL;\r
233 }\r
234\r
235 // s2 can be different on each call, so build the bitmap each time.\r
236 BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64));\r
237\r
238 // skip leading delimiters: all chars in s2\r
239 for( ; *s1 != '\0'; ++s1) {\r
240 index = WHICH8(*s1);\r
241 bit = WHICH_BIT(*s1);\r
242 if( (bitmap[index] & bit) == 0) break;\r
243 }\r
244 if( *s1 != 0)\r
245 {\r
246 // Remember this point, it is the start of the token\r
247 Token = s1++;\r
248\r
249 // find the next delimiter and replace it with a '\0'\r
250 for( ; *s1 != '\0'; ++s1) {\r
251 index = WHICH8(*s1);\r
252 bit = WHICH_BIT(*s1);\r
253 if( (bitmap[index] & bit) != 0) {\r
254 *s1++ = '\0';\r
255 Next = s1;\r
256 return Token;\r
257 }\r
258 }\r
259 }\r
260 Next = NULL;\r
261 return Token;\r
262}\r