FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
string.c
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 /*
16  Copyright (c) 2006 Eliot Dresselhaus
17 
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:
25 
26  The above copyright notice and this permission notice shall be
27  included in all copies or substantial portions of the Software.
28 
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.
36 */
37 
38 #include <vppinfra/string.h>
39 #include <vppinfra/error.h>
40 
41 /**
42  * @file
43  * @brief String Handling routines, including a performant
44  * implementation of many c-11 "safe" string functions.
45  */
46 
47 /* Exchanges source and destination. */
48 void
49 clib_memswap (void *_a, void *_b, uword bytes)
50 {
51  uword pa = pointer_to_uword (_a);
52  uword pb = pointer_to_uword (_b);
53 
54 #define _(TYPE) \
55  if (0 == ((pa | pb) & (sizeof (TYPE) - 1))) \
56  { \
57  TYPE * a = uword_to_pointer (pa, TYPE *); \
58  TYPE * b = uword_to_pointer (pb, TYPE *); \
59  \
60  while (bytes >= 2*sizeof (TYPE)) \
61  { \
62  TYPE a0, a1, b0, b1; \
63  bytes -= 2*sizeof (TYPE); \
64  a += 2; \
65  b += 2; \
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; \
70  } \
71  pa = pointer_to_uword (a); \
72  pb = pointer_to_uword (b); \
73  }
74 
75  if (BITS (uword) == BITS (u64))
76  _(u64);
77  _(u32);
78  _(u16);
79  _(u8);
80 
81 #undef _
82 
83  ASSERT (bytes < 2);
84  if (bytes)
85  {
86  u8 *a = uword_to_pointer (pa, u8 *);
87  u8 *b = uword_to_pointer (pb, u8 *);
88  u8 a0 = a[0], b0 = b[0];
89  a[0] = b0;
90  b[0] = a0;
91  }
92 }
93 
94 void
95 clib_c11_violation (const char *s)
96 {
97  _clib_error (CLIB_ERROR_WARNING, (char *) __FUNCTION__, 0, (char *) s);
98 }
99 
100 /**
101  * @brief copy src to dest, at most n bytes, up to dmax
102  *
103  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
104  * Annex K; Bounds-checking interfaces
105  *
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
110  *
111  * @constraints No null pointers
112  * n shall not be greater than dmax
113  * no memory overlap between src and dest
114  *
115  * @return EOK success
116  * EINVAL runtime constraint error
117  *
118  */
119 errno_t
120 memcpy_s (void *__restrict__ dest, rsize_t dmax,
121  const void *__restrict__ src, rsize_t n)
122 {
123  return memcpy_s_inline (dest, dmax, src, n);
124 }
125 
126 /**
127  * @brief set n bytes starting at s to the specified c value
128  *
129  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
130  * Annex K; Bounds-checking interfaces
131  *
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
136  *
137  * @constraints No null pointers
138  * n shall not be greater than smax
139  *
140  * @return EOK success
141  * EINVAL runtime constraint error
142  *
143  */
144 errno_t
145 memset_s (void *s, rsize_t smax, int c, rsize_t n)
146 {
147  return memset_s_inline (s, smax, c, n);
148 }
149 
150 /**
151  * @brief compare memory until they differ, and their difference is returned in
152  * diff
153  *
154  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
155  * Annex K; Bounds-checking interfaces
156  *
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,
163  * or less than s2.
164  *
165  * @constraints No null pointers
166  * s1max and s2max shall not be zero
167  * s2max shall not be greater than s1max
168  *
169  * @return EOK success
170  * diff when the return code is EOK
171  * >0 s1 greater s2
172  * 0 s1 == s2
173  * <0 s1 < s2
174  * EINVAL runtime constraint error
175  *
176  */
177 errno_t
178 memcmp_s (const void *s1, rsize_t s1max, const void *s2, rsize_t s2max,
179  int *diff)
180 {
181  return memcmp_s_inline (s1, s1max, s2, s2max, diff);
182 }
183 
184 /**
185  * @brief compare string s2 to string s1, and their difference is returned in
186  * indicator
187  *
188  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
189  * Annex K; Bounds-checking interfaces
190  *
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.
197  *
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
202  * of s1
203  *
204  * @return EOK success
205  * indicator when the return code is EOK
206  * >0 s1 greater s2
207  * 0 s1 == s2
208  * <0 s1 < s2
209  * EINVAL runtime constraint error
210  *
211  */
212 errno_t
213 strcmp_s (const char *s1, rsize_t s1max, const char *s2, int *indicator)
214 {
215  return strcmp_s_inline (s1, s1max, s2, indicator);
216 }
217 
218 /**
219  * @brief compare string s2 to string s1, no more than n characters, and their
220  * difference is returned in indicator
221  *
222  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
223  * Annex K; Bounds-checking interfaces
224  *
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.
232  *
233  * @constraints No null pointers
234  * s1max shall not be zero
235  * s1 shall be null terminated
236  *
237  * @return EOK success
238  * indicator when the return code is EOK
239  * >0 s1 greater s2
240  * 0 s1 == s2
241  * <0 s1 < s2
242  * EINVAL runtime constraint error
243  *
244  */
245 errno_t
246 strncmp_s (const char *s1, rsize_t s1max, const char *s2, rsize_t n,
247  int *indicator)
248 {
249  return strncmp_s_inline (s1, s1max, s2, n, indicator);
250 }
251 
252 /**
253  * @brief copy src string to dest string
254  *
255  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
256  * Annex K; Bounds-checking interfaces
257  *
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
261  *
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
266  *
267  * @return EOK success
268  * EINVAL runtime constraint error
269  *
270  */
271 errno_t
272 strcpy_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
273 {
274  return strcpy_s_inline (dest, dmax, src);
275 }
276 
277 /**
278  * @brief copy src string to dest string, no more than n characters
279  *
280  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
281  * Annex K; Bounds-checking interfaces
282  *
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
287  *
288  * @constraints No null pointers
289  * dmax shall not be zero
290  * no memory overlap between src and dest
291  *
292  * @return EOK success
293  * EINVAL runtime constraint error
294  * EOVERFLOW truncated operation. dmax - 1 characters were copied.
295  * dest is null terminated.
296  *
297  */
298 errno_t
299 strncpy_s (char *__restrict__ dest, rsize_t dmax,
300  const char *__restrict__ src, rsize_t n)
301 {
302  return strncpy_s_inline (dest, dmax, src, n);
303 }
304 
305 /**
306  * @brief append src string to dest string, including null
307  *
308  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
309  * Annex K; Bounds-checking interfaces
310  *
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
314  *
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
322  *
323  * @return EOK success
324  * EINVAL runtime constraint error
325  *
326  */
327 errno_t
328 strcat_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
329 {
330  return strcat_s_inline (dest, dmax, src);
331 }
332 
333 /**
334  * @brief append src string to dest string, including null, no more than n
335  * characters
336  *
337  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
338  * Annex K; Bounds-checking interfaces
339  *
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)
344  *
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
350  *
351  * @return EOK success
352  * EINVAL runtime constraint error
353  * EOVERFLOW truncated operation. dmax - 1 characters were appended.
354  * dest is null terminated.
355  *
356  */
357 errno_t
358 strncat_s (char *__restrict__ dest, rsize_t dmax,
359  const char *__restrict__ src, rsize_t n)
360 {
361  return strncat_s_inline (dest, dmax, src, n);
362 }
363 
364 /**
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
370  *
371  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
372  * Annex K; Bounds-checking interfaces
373  *
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,
377  * including null)
378  * @param **ptr in/out pointer which maintains the stateful information
379  *
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
383  *
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
387  *
388  * Example:
389  * char *str2 = " ";
390  * char str1[100];
391  * uword len;
392  * char *p2str = 0;
393  * char *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7;
394  *
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);
404  *
405  * After the above series of calls,
406  * tok1 = "brevity", tok2 = "is", tok3 = "the", tok4 = "soul", tok5 = "of",
407  * tok6 = "wit", tok7 = null
408  */
409 char *
410 strtok_s (char *__restrict__ s1, rsize_t * __restrict__ s1max,
411  const char *__restrict__ s2, char **__restrict__ ptr)
412 {
413  return strtok_s_inline (s1, s1max, s2, ptr);
414 }
415 
416 /**
417  * @brief compute the length in s, no more than maxsize
418  *
419  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
420  * Annex K; Bounds-checking interfaces
421  *
422  * @param *s pointer to string
423  * @param maxsize restricted maximum length
424  *
425  * @constraints No null pointers
426  * maxsize shall not be zero
427  *
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
430  *
431  */
432 size_t
433 strnlen_s (const char *s, size_t maxsize)
434 {
435  return strnlen_s_inline (s, maxsize);
436 }
437 
438 /**
439  * @brief locate the first occurrence of the substring s2 in s1
440  *
441  * ISO/IEC 9899:2017(C11), Porgramming languages -- C
442  * Annex K; Bounds-checking interfaces
443  *
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
449  *
450  * @constraints No null pointers
451  * s1max and s2max shall not be zero
452  * s1 and s2 shall be null terminated
453  *
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
458  * ESRCH no match
459  *
460  * Example:
461  * char *sub = 0;
462  * char *s1 = "success is not final, failure is not fatal.";
463  *
464  * strstr_s (s1, strlen (s1), "failure", strlen ("failure"), &sub);
465  *
466  * After the above call,
467  * sub = "failure is not fatal."
468  */
469 errno_t
470 strstr_s (char *s1, rsize_t s1max, const char *s2, rsize_t s2max,
471  char **substring)
472 {
473  return strstr_s_inline (s1, s1max, s2, s2max, substring);
474 }
475 
476 /*
477  * fd.io coding-style-patch-verification: ON
478  *
479  * Local Variables:
480  * eval: (c-set-style "gnu")
481  * End:
482  */
void clib_memswap(void *_a, void *_b, uword bytes)
Definition: string.c:49
errno_t strcat_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
append src string to dest string, including null
Definition: string.c:328
static errno_t memcmp_s_inline(const void *s1, rsize_t s1max, const void *s2, rsize_t s2max, int *diff)
Definition: string.h:747
char * strtok_s(char *__restrict__ s1, rsize_t *__restrict__ s1max, const char *__restrict__ s2, char **__restrict__ ptr)
tokenize string s1 with delimiter specified in s2.
Definition: string.c:410
a
Definition: bitmap.h:538
errno_t strncat_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
append src string to dest string, including null, no more than n characters
Definition: string.c:358
static errno_t strcmp_s_inline(const char *s1, rsize_t s1max, const char *s2, int *indicator)
Definition: string.h:836
Optimized string handling code, including c11-compliant "safe C library" variants.
unsigned long u64
Definition: types.h:89
errno_t strncpy_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
copy src string to dest string, no more than n characters
Definition: string.c:299
static errno_t strcat_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
Definition: string.h:1080
static errno_t strncpy_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
Definition: string.h:1002
errno_t memcmp_s(const void *s1, rsize_t s1max, const void *s2, rsize_t s2max, int *diff)
compare memory until they differ, and their difference is returned in diff
Definition: string.c:178
static errno_t strstr_s_inline(char *s1, rsize_t s1max, const char *s2, rsize_t s2max, char **substring)
Definition: string.h:1377
unsigned char u8
Definition: types.h:56
static errno_t memcpy_s_inline(void *__restrict__ dest, rsize_t dmax, const void *__restrict__ src, rsize_t n)
Definition: string.h:121
static errno_t memset_s_inline(void *s, rsize_t smax, int c, rsize_t n)
Definition: string.h:185
unsigned int u32
Definition: types.h:88
size_t strnlen_s(const char *s, size_t maxsize)
compute the length in s, no more than maxsize
Definition: string.c:433
void clib_c11_violation(const char *s)
Definition: string.c:95
static errno_t strncat_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src, rsize_t n)
Definition: string.h:1141
unsigned short u16
Definition: types.h:57
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
errno_t strncmp_s(const char *s1, rsize_t s1max, const char *s2, rsize_t n, int *indicator)
compare string s2 to string s1, no more than n characters, and their difference is returned in indica...
Definition: string.c:246
svmdb_client_t * c
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n)
set n bytes starting at s to the specified c value
Definition: string.c:145
errno_t strstr_s(char *s1, rsize_t s1max, const char *s2, rsize_t s2max, char **substring)
locate the first occurrence of the substring s2 in s1
Definition: string.c:470
#define uword_to_pointer(u, type)
Definition: types.h:136
#define ASSERT(truth)
errno_t strcpy_s(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
copy src string to dest string
Definition: string.c:272
static errno_t strcpy_s_inline(char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
Definition: string.h:944
static uword pointer_to_uword(const void *p)
Definition: types.h:131
static char * strtok_s_inline(char *__restrict__ s1, rsize_t *__restrict__ s1max, const char *__restrict__ s2, char **__restrict__ ptr)
Definition: string.h:1223
errno_t memcpy_s(void *__restrict__ dest, rsize_t dmax, const void *__restrict__ src, rsize_t n)
copy src to dest, at most n bytes, up to dmax
Definition: string.c:120
static errno_t strncmp_s_inline(const char *s1, rsize_t s1max, const char *s2, rsize_t n, int *indicator)
Definition: string.h:890
u64 uword
Definition: types.h:112
static size_t strnlen_s_inline(const char *s, size_t maxsize)
Definition: string.h:790
#define BITS(x)
Definition: clib.h:61
uword rsize_t
Definition: string.h:114
errno_t strcmp_s(const char *s1, rsize_t s1max, const char *s2, int *indicator)
compare string s2 to string s1, and their difference is returned in indicator
Definition: string.c:213
int errno_t
Definition: string.h:113