2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 Copyright (c) 2006 Eliot Dresselhaus
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 #include <vppinfra/string.h>
39 #include <vppinfra/error.h>
43 * @brief String Handling routines, including a performant
44 * implementation of many c-11 "safe" string functions.
47 /* Exchanges source and destination. */
49 clib_memswap (void *_a, void *_b, uword bytes)
51 uword pa = pointer_to_uword (_a);
52 uword pb = pointer_to_uword (_b);
55 if (0 == ((pa | pb) & (sizeof (TYPE) - 1))) \
57 TYPE * a = uword_to_pointer (pa, TYPE *); \
58 TYPE * b = uword_to_pointer (pb, TYPE *); \
60 while (bytes >= 2*sizeof (TYPE)) \
62 TYPE a0, a1, b0, b1; \
63 bytes -= 2*sizeof (TYPE); \
66 a0 = a[-2]; a1 = a[-1]; \
67 b0 = b[-2]; b1 = b[-1]; \
68 a[-2] = b0; a[-1] = b1; \
69 b[-2] = a0; b[-1] = a1; \
71 pa = pointer_to_uword (a); \
72 pb = pointer_to_uword (b); \
75 if (BITS (uword) == BITS (u64))
86 u8 *a = uword_to_pointer (pa, u8 *);
87 u8 *b = uword_to_pointer (pb, u8 *);
88 u8 a0 = a[0], b0 = b[0];
95 clib_c11_violation (const char *s)
97 _clib_error (CLIB_ERROR_WARNING, (char *) __FUNCTION__, 0, (char *) s);
101 * @brief copy src to dest, at most n bytes, up to dmax
103 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
104 * Annex K; Bounds-checking interfaces
106 * @param *dest pointer to memory to copy to
107 * @param dmax maximum length of resulting dest
108 * @param *src pointer to memory to copy from
109 * @param n maximum number of characters to copy from src
111 * @constraints No null pointers
112 * n shall not be greater than dmax
113 * no memory overlap between src and dest
115 * @return EOK success
116 * EINVAL runtime constraint error
119 __clib_export errno_t
120 memcpy_s (void *__restrict__ dest, rsize_t dmax,
121 const void *__restrict__ src, rsize_t n)
123 return memcpy_s_inline (dest, dmax, src, n);
127 * @brief set n bytes starting at s to the specified c value
129 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
130 * Annex K; Bounds-checking interfaces
132 * @param *s pointer to memory to set the c value
133 * @param smax maximum length of resulting s
134 * @param c byte value
135 * @param n maximum number of characters to set in s
137 * @constraints No null pointers
138 * n shall not be greater than smax
140 * @return EOK success
141 * EINVAL runtime constraint error
144 __clib_export errno_t
145 memset_s (void *s, rsize_t smax, int c, rsize_t n)
147 return memset_s_inline (s, smax, c, n);
151 * @brief compare memory until they differ, and their difference is returned in
154 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
155 * Annex K; Bounds-checking interfaces
157 * @param *s1 pointer to memory to compare against
158 * @param s1max maximum length of s1
159 * @param *s2 pointer to memory to compare with s1
160 * @param s2max length of s2
161 * @param *diff pointer to the diff which is an integer greater than, equal to,
162 * or less than zero according to s1 is greater than, equal to,
165 * @constraints No null pointers
166 * s1max and s2max shall not be zero
167 * s2max shall not be greater than s1max
169 * @return EOK success
170 * diff when the return code is EOK
174 * EINVAL runtime constraint error
177 __clib_export errno_t
178 memcmp_s (const void *s1, rsize_t s1max, const void *s2, rsize_t s2max,
181 return memcmp_s_inline (s1, s1max, s2, s2max, diff);
185 * @brief compare string s2 to string s1, and their difference is returned in
188 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
189 * Annex K; Bounds-checking interfaces
191 * @param *s1 pointer to string to compare against
192 * @param s1max maximum length of s1, excluding null
193 * @param *s2 pointer to string to compare with s1
194 * @param *indicator pointer to the comparison result, which is an integer
195 * greater than, equal to, or less than zero according to
196 * s1 is greater than, equal to, or less than s2.
198 * @constraints No null pointers
199 * s1max shall not be zero
200 * s1 shall be null terminated
201 * n shall not be greater than the smaller of s1max and strlen
204 * @return EOK success
205 * indicator when the return code is EOK
209 * EINVAL runtime constraint error
212 __clib_export errno_t
213 strcmp_s (const char *s1, rsize_t s1max, const char *s2, int *indicator)
215 return strcmp_s_inline (s1, s1max, s2, indicator);
219 * @brief compare string s2 to string s1, no more than n characters, and their
220 * difference is returned in indicator
222 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
223 * Annex K; Bounds-checking interfaces
225 * @param *s1 pointer to string to compare against
226 * @param s1max maximum length of s1, excluding null
227 * @param *s2 pointer to string to compare with s1
228 * @param n maximum number of characters to compare
229 * @param *indicator pointer to the comparison result, which is an integer
230 * greater than, equal to, or less than zero according to
231 * s1 is greater than, equal to, or less than s2.
233 * @constraints No null pointers
234 * s1max shall not be zero
235 * s1 shall be null terminated
237 * @return EOK success
238 * indicator when the return code is EOK
242 * EINVAL runtime constraint error
245 __clib_export errno_t
246 strncmp_s (const char *s1, rsize_t s1max, const char *s2, rsize_t n,
249 return strncmp_s_inline (s1, s1max, s2, n, indicator);
253 * @brief copy src string to dest string
255 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
256 * Annex K; Bounds-checking interfaces
258 * @param *dest pointer to string to copy to
259 * @param dmax maximum length of resulting dest string, including null
260 * @param *src pointer to string to copy from
262 * @constraints No null pointers
263 * dmax shall not be zero
264 * dmax shall be greater than string length of src
265 * no memory overlap between src and dest
267 * @return EOK success
268 * EINVAL runtime constraint error
271 __clib_export errno_t
272 strcpy_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
274 return strcpy_s_inline (dest, dmax, src);
278 * @brief copy src string to dest string, no more than n characters
280 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
281 * Annex K; Bounds-checking interfaces
283 * @param *dest pointer to string to copy to
284 * @param dmax maximum length of resulting dest string, including null
285 * @param *src pointer to string to copy from
286 * @param n maximum number of characters to copy from src, excluding null
288 * @constraints No null pointers
289 * dmax shall not be zero
290 * no memory overlap between src and dest
292 * @return EOK success
293 * EINVAL runtime constraint error
294 * EOVERFLOW truncated operation. dmax - 1 characters were copied.
295 * dest is null terminated.
298 __clib_export errno_t
299 strncpy_s (char *__restrict__ dest, rsize_t dmax,
300 const char *__restrict__ src, rsize_t n)
302 return strncpy_s_inline (dest, dmax, src, n);
306 * @brief append src string to dest string, including null
308 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
309 * Annex K; Bounds-checking interfaces
311 * @param *dest pointer to string to append to
312 * @param dmax maximum length of resulting dest string, including null
313 * @param *src pointer to string to append from
315 * @constraints No null pointers
316 * dmax shall not be zero
317 * dest shall be null terminated
318 * given m = dmax - strnlen (dest, dmax)
319 * n = strnlen (src, m)
320 * n shall not be >= m
321 * no memory overlap between src and dest
323 * @return EOK success
324 * EINVAL runtime constraint error
327 __clib_export errno_t
328 strcat_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
330 return strcat_s_inline (dest, dmax, src);
334 * @brief append src string to dest string, including null, no more than n
337 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
338 * Annex K; Bounds-checking interfaces
340 * @param *dest pointer to string to append to
341 * @param dmax maximum length of resulting dest string, including null
342 * @param *src pointer to string to append from
343 * @param n maximum characters to append (excluding null)
345 * @constraints No null pointers
346 * dmax shall not be zero
347 * dest shall be null terminated
348 * dmax - strnlen (dest, dmax) shall not be zero
349 * no memory overlap between src and dest
351 * @return EOK success
352 * EINVAL runtime constraint error
353 * EOVERFLOW truncated operation. dmax - 1 characters were appended.
354 * dest is null terminated.
357 __clib_export errno_t
358 strncat_s (char *__restrict__ dest, rsize_t dmax,
359 const char *__restrict__ src, rsize_t n)
361 return strncat_s_inline (dest, dmax, src, n);
365 * @brief tokenize string s1 with delimiter specified in s2. This is a stateful
366 * API when it is iterately called, it returns the next token from s1
367 * which is delimited by s2. s1max and ptr maintain the stateful
368 * information for the same caller and must not be altered by the
369 * caller during the iteration for the correct result
371 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
372 * Annex K; Bounds-checking interfaces
374 * @param *s1 pointer to string to be searched for substring
375 * @param *s1max restricted maximum length of s1
376 * @param *s2 pointer to substring to search (16 characters max,
378 * @param **ptr in/out pointer which maintains the stateful information
380 * @constraints s2, s1max, and ptr shall not be null
381 * if s1 is null, contents of ptr shall not be null
382 * s1 and s2 shall be null terminated
384 * @return non-null pointer to the first character of a token
385 * s1max and ptr are modified to contain the state
386 * null runtime constraint error or token is not found
393 * char *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7;
395 * strncpy (str1, "brevity is the soul of wit", sizeof (str1));
396 * len = strlen (str1);
397 * tok1 = strtok_s (str1, &len, str2, &p2str);
398 * tok2 = strtok_s (0, &len, str2, &p2str);
399 * tok3 = strtok_s (0, &len, str2, &p2str);
400 * tok4 = strtok_s (0, &len, str2, &p2str);
401 * tok5 = strtok_s (0, &len, str2, &p2str);
402 * tok6 = strtok_s (0, &len, str2, &p2str);
403 * tok7 = strtok_s (0, &len, str2, &p2str);
405 * After the above series of calls,
406 * tok1 = "brevity", tok2 = "is", tok3 = "the", tok4 = "soul", tok5 = "of",
407 * tok6 = "wit", tok7 = null
410 strtok_s (char *__restrict__ s1, rsize_t * __restrict__ s1max,
411 const char *__restrict__ s2, char **__restrict__ ptr)
413 return strtok_s_inline (s1, s1max, s2, ptr);
417 * @brief compute the length in s, no more than maxsize
419 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
420 * Annex K; Bounds-checking interfaces
422 * @param *s pointer to string
423 * @param maxsize restricted maximum length
425 * @constraints No null pointers
426 * maxsize shall not be zero
428 * @return size_t the string length in s, excluding null character, and no
429 * more than maxsize or 0 if there is a constraint error
433 strnlen_s (const char *s, size_t maxsize)
435 return strnlen_s_inline (s, maxsize);
439 * @brief locate the first occurrence of the substring s2 in s1
441 * ISO/IEC 9899:2017(C11), Porgramming languages -- C
442 * Annex K; Bounds-checking interfaces
444 * @param *s1 pointer to string to be searched for substring
445 * @param s1max restricted maximum length of s1
446 * @param *s2 pointer to substring to search
447 * @param s2max restricted maximum length of s2
448 * @param **substring pointer to pointer substring to be returned
450 * @constraints No null pointers
451 * s1max and s2max shall not be zero
452 * s1 and s2 shall be null terminated
454 * @return EOK success
455 * substring when the return code is EOK, it contains the pointer which
456 * points to s1 that matches s2
457 * EINVAL runtime constraint error
462 * char *s1 = "success is not final, failure is not fatal.";
464 * strstr_s (s1, strlen (s1), "failure", strlen ("failure"), &sub);
466 * After the above call,
467 * sub = "failure is not fatal."
469 __clib_export errno_t
470 strstr_s (char *s1, rsize_t s1max, const char *s2, rsize_t s2max,
473 return strstr_s_inline (s1, s1max, s2, s2max, substring);
477 * fd.io coding-style-patch-verification: ON
480 * eval: (c-set-style "gnu")