LCOV - code coverage report
Current view: top level - vppinfra - string.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 27 42 64.3 %
Date: 2023-07-05 22:20:52 Functions: 13 14 92.9 %

          Line data    Source code
       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           0 : clib_memswap (void *_a, void *_b, uword bytes)
      50             : {
      51           0 :   uword pa = pointer_to_uword (_a);
      52           0 :   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           0 :     _(u64);
      77           0 :   _(u32);
      78           0 :   _(u16);
      79           0 :   _(u8);
      80             : 
      81             : #undef _
      82             : 
      83           0 :   ASSERT (bytes < 2);
      84           0 :   if (bytes)
      85             :     {
      86           0 :       u8 *a = uword_to_pointer (pa, u8 *);
      87           0 :       u8 *b = uword_to_pointer (pb, u8 *);
      88           0 :       u8 a0 = a[0], b0 = b[0];
      89           0 :       a[0] = b0;
      90           0 :       b[0] = a0;
      91             :     }
      92           0 : }
      93             : 
      94             : __clib_export void
      95          72 : clib_c11_violation (const char *s)
      96             : {
      97          72 :   _clib_error (CLIB_ERROR_WARNING, (char *) __FUNCTION__, 0, (char *) s);
      98          72 : }
      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             : __clib_export errno_t
     120          25 : memcpy_s (void *__restrict__ dest, rsize_t dmax,
     121             :           const void *__restrict__ src, rsize_t n)
     122             : {
     123          25 :   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             : __clib_export errno_t
     145           5 : memset_s (void *s, rsize_t smax, int c, rsize_t n)
     146             : {
     147           5 :   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             : __clib_export errno_t
     178           5 : memcmp_s (const void *s1, rsize_t s1max, const void *s2, rsize_t s2max,
     179             :           int *diff)
     180             : {
     181           5 :   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             : __clib_export errno_t
     213          44 : strcmp_s (const char *s1, rsize_t s1max, const char *s2, int *indicator)
     214             : {
     215          44 :   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             : __clib_export errno_t
     246           8 : strncmp_s (const char *s1, rsize_t s1max, const char *s2, rsize_t n,
     247             :            int *indicator)
     248             : {
     249           8 :   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             : __clib_export errno_t
     272          17 : strcpy_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
     273             : {
     274          17 :   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             : __clib_export errno_t
     299     1046380 : strncpy_s (char *__restrict__ dest, rsize_t dmax,
     300             :            const char *__restrict__ src, rsize_t n)
     301             : {
     302     1046380 :   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             : __clib_export errno_t
     328           5 : strcat_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src)
     329             : {
     330           5 :   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             : __clib_export errno_t
     358           9 : strncat_s (char *__restrict__ dest, rsize_t dmax,
     359             :            const char *__restrict__ src, rsize_t n)
     360             : {
     361           9 :   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             : __clib_export char *
     410          12 : strtok_s (char *__restrict__ s1, rsize_t * __restrict__ s1max,
     411             :           const char *__restrict__ s2, char **__restrict__ ptr)
     412             : {
     413          12 :   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             : __clib_export size_t
     433           6 : strnlen_s (const char *s, size_t maxsize)
     434             : {
     435           6 :   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             : __clib_export errno_t
     470           4 : strstr_s (char *s1, rsize_t s1max, const char *s2, rsize_t s2max,
     471             :           char **substring)
     472             : {
     473           4 :   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             :  */

Generated by: LCOV version 1.14