Line data Source code
1 : /*
2 : * FRR string processing utilities.
3 : * Copyright (C) 2018 Cumulus Networks, Inc.
4 : * Quentin Young
5 : *
6 : * This program is free software; you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by the Free
8 : * Software Foundation; either version 2 of the License, or (at your option)
9 : * any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 : * more details.
15 : *
16 : * You should have received a copy of the GNU General Public License along
17 : * with this program; see the file COPYING; if not, write to the Free Software
18 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : */
20 :
21 : #include "zebra.h"
22 :
23 : #include <string.h>
24 : #include <ctype.h>
25 : #include <sys/types.h>
26 : #ifdef HAVE_LIBPCRE2_POSIX
27 : #ifndef _FRR_PCRE2_POSIX
28 : #define _FRR_PCRE2_POSIX
29 : #include <pcre2posix.h>
30 : #endif /* _FRR_PCRE2_POSIX */
31 : #elif defined(HAVE_LIBPCREPOSIX)
32 : #include <pcreposix.h>
33 : #else
34 : #include <regex.h>
35 : #endif /* HAVE_LIBPCRE2_POSIX */
36 :
37 : #include "frrstr.h"
38 : #include "memory.h"
39 : #include "vector.h"
40 :
41 296 : void frrstr_split(const char *string, const char *delimiter, char ***result,
42 : int *argc)
43 : {
44 296 : if (!string)
45 0 : return;
46 :
47 296 : unsigned int sz = 4, idx = 0;
48 296 : char *copy, *copystart;
49 296 : *result = XCALLOC(MTYPE_TMP, sizeof(char *) * sz);
50 296 : copystart = copy = XSTRDUP(MTYPE_TMP, string);
51 296 : *argc = 0;
52 :
53 296 : const char *tok = NULL;
54 :
55 1497 : while (copy) {
56 1201 : tok = strsep(©, delimiter);
57 1201 : (*result)[idx] = XSTRDUP(MTYPE_TMP, tok);
58 1201 : if (++idx == sz)
59 161 : *result = XREALLOC(MTYPE_TMP, *result,
60 : (sz *= 2) * sizeof(char *));
61 1201 : (*argc)++;
62 : }
63 :
64 296 : XFREE(MTYPE_TMP, copystart);
65 : }
66 :
67 296 : vector frrstr_split_vec(const char *string, const char *delimiter)
68 : {
69 296 : char **result;
70 296 : int argc;
71 :
72 296 : if (!string)
73 : return NULL;
74 :
75 296 : frrstr_split(string, delimiter, &result, &argc);
76 :
77 296 : vector v = array_to_vector((void **)result, argc);
78 :
79 296 : XFREE(MTYPE_TMP, result);
80 :
81 296 : return v;
82 : }
83 :
84 10 : char *frrstr_join(const char **parts, int argc, const char *join)
85 : {
86 10 : int i;
87 10 : char *str;
88 10 : char *p;
89 10 : size_t len = 0;
90 10 : size_t joinlen = join ? strlen(join) : 0;
91 :
92 10 : if (!argc)
93 : return NULL;
94 :
95 20 : for (i = 0; i < argc; i++)
96 10 : len += strlen(parts[i]);
97 10 : len += argc * joinlen + 1;
98 :
99 10 : if (!len)
100 : return NULL;
101 :
102 10 : p = str = XMALLOC(MTYPE_TMP, len);
103 :
104 30 : for (i = 0; i < argc; i++) {
105 10 : size_t arglen = strlen(parts[i]);
106 :
107 10 : memcpy(p, parts[i], arglen);
108 10 : p += arglen;
109 10 : if (i + 1 != argc && join) {
110 0 : memcpy(p, join, joinlen);
111 0 : p += joinlen;
112 : }
113 : }
114 :
115 10 : *p = '\0';
116 :
117 10 : return str;
118 : }
119 :
120 0 : char *frrstr_join_vec(vector v, const char *join)
121 : {
122 0 : char **argv;
123 0 : int argc;
124 :
125 0 : vector_to_array(v, (void ***)&argv, &argc);
126 :
127 0 : char *ret = frrstr_join((const char **)argv, argc, join);
128 :
129 0 : XFREE(MTYPE_TMP, argv);
130 :
131 0 : return ret;
132 : }
133 :
134 0 : void frrstr_filter_vec(vector v, regex_t *filter)
135 : {
136 0 : regmatch_t ignored[1];
137 :
138 0 : for (unsigned int i = 0; i < vector_active(v); i++) {
139 0 : if (regexec(filter, vector_slot(v, i), 0, ignored, 0)) {
140 0 : XFREE(MTYPE_TMP, vector_slot(v, i));
141 0 : vector_unset(v, i);
142 : }
143 : }
144 0 : }
145 :
146 296 : void frrstr_strvec_free(vector v)
147 : {
148 296 : unsigned int i;
149 296 : char *cp;
150 :
151 296 : if (!v)
152 : return;
153 :
154 1389 : for (i = 0; i < vector_active(v); i++) {
155 1093 : cp = vector_slot(v, i);
156 1093 : XFREE(MTYPE_TMP, cp);
157 : }
158 :
159 296 : vector_free(v);
160 : }
161 :
162 0 : char *frrstr_replace(const char *str, const char *find, const char *replace)
163 : {
164 0 : char *ch;
165 0 : char *nustr = XSTRDUP(MTYPE_TMP, str);
166 :
167 0 : size_t findlen = strlen(find);
168 0 : size_t repllen = strlen(replace);
169 :
170 0 : while ((ch = strstr(nustr, find))) {
171 0 : if (repllen > findlen) {
172 0 : size_t nusz = strlen(nustr) + repllen - findlen + 1;
173 0 : nustr = XREALLOC(MTYPE_TMP, nustr, nusz);
174 0 : ch = strstr(nustr, find);
175 : }
176 :
177 0 : size_t nustrlen = strlen(nustr);
178 0 : size_t taillen = (nustr + nustrlen) - (ch + findlen);
179 :
180 0 : memmove(ch + findlen + (repllen - findlen), ch + findlen,
181 : taillen + 1);
182 0 : memcpy(ch, replace, repllen);
183 : }
184 :
185 0 : return nustr;
186 : }
187 :
188 0 : bool frrstr_startswith(const char *str, const char *prefix)
189 : {
190 0 : if (!str || !prefix)
191 : return false;
192 :
193 0 : size_t lenstr = strlen(str);
194 0 : size_t lenprefix = strlen(prefix);
195 :
196 0 : if (lenprefix > lenstr)
197 : return false;
198 :
199 0 : return strncmp(str, prefix, lenprefix) == 0;
200 : }
201 :
202 0 : bool frrstr_endswith(const char *str, const char *suffix)
203 : {
204 0 : if (!str || !suffix)
205 : return false;
206 :
207 0 : size_t lenstr = strlen(str);
208 0 : size_t lensuffix = strlen(suffix);
209 :
210 0 : if (lensuffix > lenstr)
211 : return false;
212 :
213 0 : return strncmp(&str[lenstr - lensuffix], suffix, lensuffix) == 0;
214 : }
215 :
216 0 : int all_digit(const char *str)
217 : {
218 0 : for (; *str != '\0'; str++)
219 0 : if (!isdigit((unsigned char)*str))
220 : return 0;
221 : return 1;
222 : }
223 :
224 :
225 0 : char *frrstr_hex(char *buff, size_t bufsiz, const uint8_t *str, size_t num)
226 : {
227 0 : if (bufsiz == 0)
228 : return buff;
229 :
230 0 : char tmp[3];
231 :
232 0 : buff[0] = '\0';
233 :
234 0 : for (size_t i = 0; i < num; i++) {
235 0 : snprintf(tmp, sizeof(tmp), "%02x", (unsigned char)str[i]);
236 0 : strlcat(buff, tmp, bufsiz);
237 : }
238 :
239 : return buff;
240 : }
|