CNDP  22.08.0
cne_strings.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2019-2022 Intel Corporation.
3  */
4 
11 #ifndef _M_STRINGS_H_
12 #define _M_STRINGS_H_
13 
14 #include <stdio.h> // for NULL, snprintf
15 #include <ctype.h>
16 #include <stdint.h> // for uint8_t, UINT16_MAX, UINT8_MAX, uint32_t
17 #include <stdlib.h> // for strtoul
18 #include <string.h>
19 #include <sys/types.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h> // for inet_ntop
22 #include <bsd/bsd.h>
23 #include <errno.h> // for errno
24 #include <bsd/string.h> // for strlcpy
25 #include <sys/socket.h> // for AF_INET
26 
27 #include <cne_common.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 enum {
36 };
37 
52 static __inline__ char *
53 strtrimset(char *str, const char *set)
54 {
55  if (!str || !*str || !set || (strlen(set) != 2))
56  return NULL;
57 
58  /* Find the beginning set character, while trimming white space */
59  while ((*str == set[0]) || isspace(*str))
60  str++;
61 
62  if (*str) {
63  char *p = &str[strlen(str) - 1];
64 
65  while ((p >= str) && (isspace(*p) || (*p == set[1])))
66  p--;
67 
68  p[1] = '\0';
69  }
70 
71  return str;
72 }
73 
82 static __inline__ char *
83 strtrim_quotes(char *str)
84 {
85  if (strlen(str) >= 2) {
86  if (str[0] == '"')
87  return strtrimset(str, "\"\"");
88  else if (str[0] == '\'')
89  return strtrimset(str, "''");
90  }
91  return str;
92 }
93 
103 static __inline__ char *
104 strtrim(char *str)
105 {
106  if (!str || !*str)
107  return str;
108 
109  /* trim white space characters at the front */
110  while (isspace(*str))
111  str++;
112 
113  /* Make sure the string is not empty */
114  if (*str) {
115  char *p = &str[strlen(str) - 1];
116 
117  /* trim trailing white space characters */
118  while ((p >= str) && isspace(*p))
119  p--;
120 
121  p[1] = '\0';
122  }
123  return str;
124 }
125 
141 static __inline__ int
142 cne_strtok(char *str, const char *delim, char *entries[], int maxtokens)
143 {
144  int i = 0;
145  char *saved;
146 
147  if (!str || !delim || !strlen(delim) || !entries || !maxtokens)
148  return -1;
149  if (!strlen(str))
150  return 0;
151 
152  do {
153  entries[i] = strtrim(strtok_r(str, delim, &saved));
154  str = NULL;
155  } while (entries[i] && (++i < maxtokens));
156 
157  return i;
158 }
159 
175 static __inline__ int
176 cne_strqtok(char *str, const char *delim, char *argv[], int maxtokens)
177 {
178  char *p, *start_of_word, *s;
179  int argc = 0;
180  enum { INIT, WORD, STRING_QUOTE, STRING_TICK, STRING_BRACKET } state = WORD;
181 
182  if (!str || !delim || !argv || maxtokens == 0)
183  return -1;
184 
185  /* Remove white space from start and end of string */
186  s = strtrim(str);
187 
188  start_of_word = s;
189  for (p = s; (argc < maxtokens) && (*p != '\0'); p++) {
190  int c = (unsigned char)*p;
191 
192  if (c == '\\') {
193  start_of_word = ++p;
194  continue;
195  }
196 
197  switch (state) {
198  case INIT:
199  if (c == '"') {
200  state = STRING_QUOTE;
201  start_of_word = p + 1;
202  } else if (c == '\'') {
203  state = STRING_TICK;
204  start_of_word = p + 1;
205  } else if (c == '{') {
206  state = STRING_BRACKET;
207  start_of_word = p + 1;
208  } else if (!strchr(delim, c)) {
209  state = WORD;
210  start_of_word = p;
211  }
212  break;
213 
214  case STRING_QUOTE:
215  if (c == '"') {
216  *p = 0;
217  argv[argc++] = start_of_word;
218  state = INIT;
219  }
220  break;
221 
222  case STRING_TICK:
223  if (c == '\'') {
224  *p = 0;
225  argv[argc++] = start_of_word;
226  state = INIT;
227  }
228  break;
229 
230  case STRING_BRACKET:
231  if (c == '}') {
232  *p = 0;
233  argv[argc++] = start_of_word;
234  state = INIT;
235  }
236  break;
237 
238  case WORD:
239  if (strchr(delim, c)) {
240  *p = 0;
241  argv[argc++] = start_of_word;
242  state = INIT;
243  start_of_word = p + 1;
244  }
245  break;
246 
247  default:
248  break;
249  }
250  }
251 
252  if ((state != INIT) && (argc < maxtokens))
253  argv[argc++] = start_of_word;
254 
255  if ((argc == 0) && (p != str))
256  argv[argc++] = str;
257 
258  argv[argc] = NULL;
259 
260  return argc;
261 }
262 
271 static __inline__ char *
272 cne_strtolower(char *str)
273 {
274  if (!str)
275  return NULL;
276 
277  for (int i = 0; i <= (int)(strlen(str)); i++)
278  str[i] = tolower(str[i]);
279 
280  return str;
281 }
282 
292 static __inline__ char *
293 cne_strtoupper(char *str)
294 {
295  if (!str)
296  return NULL;
297 
298  for (int i = 0; i <= (int)(strlen(str)); i++)
299  str[i] = toupper(str[i]);
300 
301  return str;
302 }
303 
316 static __inline__ int
317 cne_stropt(const char *list, char *str, const char *delim)
318 {
319  char *argv[STR_MAX_ARGVS + 1], *buf;
320 
321  if (!list || !str || !delim)
322  return -1;
323 
324  if ((list[0] == '%') && (list[1] == '|'))
325  list += 2;
326 
327  if (!*list)
328  return -1;
329 
330  size_t n = strlen(list) + 2;
331 
332  buf = (char *)alloca(n);
333  if (buf) {
334  snprintf(buf, n, "%s", list);
335 
336  int nb = cne_strtok(buf, delim, argv, STR_MAX_ARGVS);
337  if (nb < 0)
338  return -1;
339  for (int i = 0; i < nb; i++)
340  if (!strcmp(argv[i], str))
341  return i;
342  }
343 
344  return -1;
345 }
346 
351 static __inline__ char *
352 cne_strdupf(char *str, char *newstr)
353 {
354  if (str)
355  free(str);
356  return (newstr == NULL) ? NULL : strdup(newstr);
357 }
358 
369 static __inline__ int
370 cne_strcnt(char *s, char c)
371 {
372  return (s == NULL || *s == '\0') ? 0 : cne_strcnt(s + 1, c) + (*s == c);
373 }
374 
375 #ifndef _MASK_SIZE_
376 #define _MASK_SIZE_
387 static __inline__ int
388 mask_size(uint32_t mask)
389 {
390  if (mask == 0)
391  return 0;
392  else if (mask == 0xFF000000)
393  return 8;
394  else if (mask == 0xFFFF0000)
395  return 16;
396  else if (mask == 0xFFFFFF00)
397  return 24;
398  else if (mask == 0xFFFFFFFF)
399  return 32;
400  else {
401  int i;
402  for (i = 0; i < 32; i++)
403  if ((mask & (1 << (31 - i))) == 0)
404  break;
405  return i;
406  }
407 }
408 #endif
409 
410 #ifdef __cplusplus
411 }
412 #endif
413 
414 #endif /* _M_STRINGS_H_ */
static __inline__ int cne_strtok(char *str, const char *delim, char *entries[], int maxtokens)
Definition: cne_strings.h:142
static __inline__ int mask_size(uint32_t mask)
Definition: cne_strings.h:388
static __inline__ int cne_strcnt(char *s, char c)
Definition: cne_strings.h:370
@ STR_MAX_ARGVS
Definition: cne_strings.h:34
@ STR_TOKEN_SIZE
Definition: cne_strings.h:35
static __inline__ char * strtrim(char *str)
Definition: cne_strings.h:104
static __inline__ int cne_stropt(const char *list, char *str, const char *delim)
Definition: cne_strings.h:317
static __inline__ char * cne_strtolower(char *str)
Definition: cne_strings.h:272
static __inline__ char * cne_strdupf(char *str, char *newstr)
Definition: cne_strings.h:352
static __inline__ char * cne_strtoupper(char *str)
Definition: cne_strings.h:293
static __inline__ char * strtrimset(char *str, const char *set)
Definition: cne_strings.h:53
static __inline__ char * strtrim_quotes(char *str)
Definition: cne_strings.h:83
static __inline__ int cne_strqtok(char *str, const char *delim, char *argv[], int maxtokens)
Definition: cne_strings.h:176