back to topotato report
topotato coverage report
Current view: top level - lib - frrstr.c (source / functions) Hit Total Coverage
Test: test_bgp_ecmp_enhe.py::BGP_Unnumbered_ECMP Lines: 31 118 26.3 %
Date: 2023-11-16 17:19:14 Functions: 3 24 12.5 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * FRR string processing utilities.
       4             :  * Copyright (C) 2018  Cumulus Networks, Inc.
       5             :  *                     Quentin Young
       6             :  * Copyright (c) 2023, LabN Consulting, L.L.C.
       7             :  */
       8             : 
       9             : #include "zebra.h"
      10             : 
      11             : #include <string.h>
      12             : #include <ctype.h>
      13             : #include <sys/types.h>
      14             : #ifdef HAVE_LIBPCRE2_POSIX
      15             : #ifndef _FRR_PCRE2_POSIX
      16             : #define _FRR_PCRE2_POSIX
      17             : #include <pcre2posix.h>
      18             : #endif /* _FRR_PCRE2_POSIX */
      19             : #elif defined(HAVE_LIBPCREPOSIX)
      20             : #include <pcreposix.h>
      21             : #else
      22             : #include <regex.h>
      23             : #endif /* HAVE_LIBPCRE2_POSIX */
      24             : 
      25             : #include "frrstr.h"
      26             : #include "memory.h"
      27             : #include "vector.h"
      28             : 
      29          79 : void frrstr_split(const char *string, const char *delimiter, char ***result,
      30             :                   int *argc)
      31             : {
      32          79 :         if (!string)
      33           0 :                 return;
      34             : 
      35          79 :         unsigned int sz = 4, idx = 0;
      36          79 :         char *copy, *copystart;
      37          79 :         *result = XCALLOC(MTYPE_TMP, sizeof(char *) * sz);
      38          79 :         copystart = copy = XSTRDUP(MTYPE_TMP, string);
      39          79 :         *argc = 0;
      40             : 
      41          79 :         const char *tok = NULL;
      42             : 
      43         338 :         while (copy) {
      44         259 :                 tok = strsep(&copy, delimiter);
      45         259 :                 (*result)[idx] = XSTRDUP(MTYPE_TMP, tok);
      46         259 :                 if (++idx == sz)
      47          33 :                         *result = XREALLOC(MTYPE_TMP, *result,
      48             :                                            (sz *= 2) * sizeof(char *));
      49         259 :                 (*argc)++;
      50             :         }
      51             : 
      52          79 :         XFREE(MTYPE_TMP, copystart);
      53             : }
      54             : 
      55          79 : vector frrstr_split_vec(const char *string, const char *delimiter)
      56             : {
      57          79 :         char **result;
      58          79 :         int argc;
      59             : 
      60          79 :         if (!string)
      61             :                 return NULL;
      62             : 
      63          79 :         frrstr_split(string, delimiter, &result, &argc);
      64             : 
      65          79 :         vector v = array_to_vector((void **)result, argc);
      66             : 
      67          79 :         XFREE(MTYPE_TMP, result);
      68             : 
      69          79 :         return v;
      70             : }
      71             : 
      72           0 : char *frrstr_join(const char **parts, int argc, const char *join)
      73             : {
      74           0 :         int i;
      75           0 :         char *str;
      76           0 :         char *p;
      77           0 :         size_t len = 0;
      78           0 :         size_t joinlen = join ? strlen(join) : 0;
      79             : 
      80           0 :         if (!argc)
      81             :                 return NULL;
      82             : 
      83           0 :         for (i = 0; i < argc; i++)
      84           0 :                 len += strlen(parts[i]);
      85           0 :         len += argc * joinlen + 1;
      86             : 
      87           0 :         if (!len)
      88             :                 return NULL;
      89             : 
      90           0 :         p = str = XMALLOC(MTYPE_TMP, len);
      91             : 
      92           0 :         for (i = 0; i < argc; i++) {
      93           0 :                 size_t arglen = strlen(parts[i]);
      94             : 
      95           0 :                 memcpy(p, parts[i], arglen);
      96           0 :                 p += arglen;
      97           0 :                 if (i + 1 != argc && join) {
      98           0 :                         memcpy(p, join, joinlen);
      99           0 :                         p += joinlen;
     100             :                 }
     101             :         }
     102             : 
     103           0 :         *p = '\0';
     104             : 
     105           0 :         return str;
     106             : }
     107             : 
     108           0 : char *frrstr_join_vec(vector v, const char *join)
     109             : {
     110           0 :         char **argv;
     111           0 :         int argc;
     112             : 
     113           0 :         vector_to_array(v, (void ***)&argv, &argc);
     114             : 
     115           0 :         char *ret = frrstr_join((const char **)argv, argc, join);
     116             : 
     117           0 :         XFREE(MTYPE_TMP, argv);
     118             : 
     119           0 :         return ret;
     120             : }
     121             : 
     122           0 : void frrstr_filter_vec(vector v, regex_t *filter)
     123             : {
     124           0 :         regmatch_t ignored[1];
     125             : 
     126           0 :         for (unsigned int i = 0; i < vector_active(v); i++) {
     127           0 :                 if (regexec(filter, vector_slot(v, i), 0, ignored, 0)) {
     128           0 :                         XFREE(MTYPE_TMP, vector_slot(v, i));
     129           0 :                         vector_unset(v, i);
     130             :                 }
     131             :         }
     132           0 : }
     133             : 
     134          79 : void frrstr_strvec_free(vector v)
     135             : {
     136          79 :         unsigned int i;
     137          79 :         char *cp;
     138             : 
     139          79 :         if (!v)
     140             :                 return;
     141             : 
     142         292 :         for (i = 0; i < vector_active(v); i++) {
     143         213 :                 cp = vector_slot(v, i);
     144         213 :                 XFREE(MTYPE_TMP, cp);
     145             :         }
     146             : 
     147          79 :         vector_free(v);
     148             : }
     149             : 
     150           0 : char *frrstr_replace(const char *str, const char *find, const char *replace)
     151             : {
     152           0 :         char *ch;
     153           0 :         char *nustr = XSTRDUP(MTYPE_TMP, str);
     154             : 
     155           0 :         size_t findlen = strlen(find);
     156           0 :         size_t repllen = strlen(replace);
     157             : 
     158           0 :         while ((ch = strstr(nustr, find))) {
     159           0 :                 if (repllen > findlen) {
     160           0 :                         size_t nusz = strlen(nustr) + repllen - findlen + 1;
     161           0 :                         nustr = XREALLOC(MTYPE_TMP, nustr, nusz);
     162           0 :                         ch = strstr(nustr, find);
     163             :                 }
     164             : 
     165           0 :                 size_t nustrlen = strlen(nustr);
     166           0 :                 size_t taillen = (nustr + nustrlen) - (ch + findlen);
     167             : 
     168           0 :                 memmove(ch + findlen + (repllen - findlen), ch + findlen,
     169             :                         taillen + 1);
     170           0 :                 memcpy(ch, replace, repllen);
     171             :         }
     172             : 
     173           0 :         return nustr;
     174             : }
     175             : 
     176           0 : bool frrstr_startswith(const char *str, const char *prefix)
     177             : {
     178           0 :         if (!str || !prefix)
     179             :                 return false;
     180             : 
     181           0 :         size_t lenstr = strlen(str);
     182           0 :         size_t lenprefix = strlen(prefix);
     183             : 
     184           0 :         if (lenprefix > lenstr)
     185             :                 return false;
     186             : 
     187           0 :         return strncmp(str, prefix, lenprefix) == 0;
     188             : }
     189             : 
     190           0 : bool frrstr_endswith(const char *str, const char *suffix)
     191             : {
     192           0 :         if (!str || !suffix)
     193             :                 return false;
     194             : 
     195           0 :         size_t lenstr = strlen(str);
     196           0 :         size_t lensuffix = strlen(suffix);
     197             : 
     198           0 :         if (lensuffix > lenstr)
     199             :                 return false;
     200             : 
     201           0 :         return strncmp(&str[lenstr - lensuffix], suffix, lensuffix) == 0;
     202             : }
     203             : 
     204           0 : int all_digit(const char *str)
     205             : {
     206           0 :         for (; *str != '\0'; str++)
     207           0 :                 if (!isdigit((unsigned char)*str))
     208             :                         return 0;
     209             :         return 1;
     210             : }
     211             : 
     212             : 
     213           0 : char *frrstr_hex(char *buff, size_t bufsiz, const uint8_t *str, size_t num)
     214             : {
     215           0 :         if (bufsiz == 0)
     216             :                 return buff;
     217             : 
     218           0 :         char tmp[3];
     219             : 
     220           0 :         buff[0] = '\0';
     221             : 
     222           0 :         for (size_t i = 0; i < num; i++) {
     223           0 :                 snprintf(tmp, sizeof(tmp), "%02x", (unsigned char)str[i]);
     224           0 :                 strlcat(buff, tmp, bufsiz);
     225             :         }
     226             : 
     227             :         return buff;
     228             : }
     229             : 
     230           0 : const char *frrstr_skip_over_char(const char *s, int skipc)
     231             : {
     232           0 :         int c, quote = 0;
     233             : 
     234           0 :         while ((c = *s++)) {
     235           0 :                 if (c == '\\') {
     236           0 :                         if (!*s++)
     237             :                                 return NULL;
     238           0 :                         continue;
     239             :                 }
     240           0 :                 if (quote) {
     241           0 :                         if (c == quote)
     242           0 :                                 quote = 0;
     243           0 :                         continue;
     244             :                 }
     245           0 :                 if (c == skipc)
     246           0 :                         return s;
     247           0 :                 if (c == '"' || c == '\'')
     248           0 :                         quote = c;
     249             :         }
     250             :         return NULL;
     251             : }

Generated by: LCOV version v1.16-topotato