ares_strsplit.c
Go to the documentation of this file.
1 /* Copyright (C) 2018 by John Schember <john@nachtimwald.com>
2  *
3  * Permission to use, copy, modify, and distribute this
4  * software and its documentation for any purpose and without
5  * fee is hereby granted, provided that the above copyright
6  * notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting
8  * documentation, and that the name of M.I.T. not be used in
9  * advertising or publicity pertaining to distribution of the
10  * software without specific, written prior permission.
11  * M.I.T. makes no representations about the suitability of
12  * this software for any purpose. It is provided "as is"
13  * without express or implied warranty.
14  */
15 
16 #if defined(__MVS__)
17 #include <strings.h>
18 #endif
19 
20 #include "ares_setup.h"
21 #include "ares_strsplit.h"
22 #include "ares.h"
23 #include "ares_private.h"
24 
25 static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
26 {
27  size_t len;
28  size_t i;
29 
30  len = strlen(str);
31  for (i=0; i<num_elem; i++)
32  {
33  if (insensitive)
34  {
35 #ifdef WIN32
36  if (strnicmp(list[i], str, len) == 0)
37 #else
38  if (strncasecmp(list[i], str, len) == 0)
39 #endif
40  return 1;
41  }
42  else
43  {
44  if (strncmp(list[i], str, len) == 0)
45  return 1;
46  }
47  }
48 
49  return 0;
50 }
51 
52 static int is_delim(char c, const char *delims, size_t num_delims)
53 {
54  size_t i;
55 
56  for (i=0; i<num_delims; i++)
57  {
58  if (c == delims[i])
59  return 1;
60  }
61  return 0;
62 }
63 
64 
65 void ares_strsplit_free(char **elms, size_t num_elm)
66 {
67  size_t i;
68 
69  if (elms == NULL)
70  return;
71 
72  for (i=0; i<num_elm; i++)
73  ares_free(elms[i]);
74  ares_free(elms);
75 }
76 
77 
78 char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm)
79 {
80  char *parsestr;
81  char **temp;
82  char **out;
83  size_t cnt;
84  size_t nelms;
85  size_t in_len;
86  size_t num_delims;
87  size_t i;
88 
89  if (in == NULL || delms == NULL || num_elm == NULL)
90  return NULL;
91 
92  *num_elm = 0;
93 
94  in_len = strlen(in);
95  num_delims = strlen(delms);
96 
97  /* Figure out how many elements. */
98  nelms = 1;
99  for (i=0; i<in_len; i++)
100  {
101  if (is_delim(in[i], delms, num_delims))
102  {
103  nelms++;
104  }
105  }
106 
107  /* Copy of input so we can cut it up. */
108  parsestr = ares_strdup(in);
109  if (parsestr == NULL)
110  return NULL;
111 
112  /* Temporary array to store locations of start of each element
113  * within parsestr. */
114  temp = ares_malloc(nelms * sizeof(*temp));
115  if (temp == NULL)
116  {
117  ares_free(parsestr);
118  return NULL;
119  }
120  temp[0] = parsestr;
121  cnt = 1;
122  for (i=0; i<in_len && cnt<nelms; i++)
123  {
124  if (!is_delim(parsestr[i], delms, num_delims))
125  continue;
126 
127  /* Replace sep with NULL. */
128  parsestr[i] = '\0';
129  /* Add the pointer to the array of elements */
130  temp[cnt] = parsestr+i+1;
131  cnt++;
132  }
133 
134  /* Copy each element to our output array. */
135  out = ares_malloc(nelms * sizeof(*out));
136  if (out == NULL)
137  {
138  ares_free(parsestr);
139  ares_free(temp);
140  return NULL;
141  }
142 
143  nelms = 0;
144  for (i=0; i<cnt; i++)
145  {
146  if (temp[i][0] == '\0')
147  continue;
148 
149  if (make_set && list_contains(out, nelms, temp[i], 1))
150  continue;
151 
152  out[nelms] = ares_strdup(temp[i]);
153  if (out[nelms] == NULL)
154  {
155  ares_strsplit_free(out, nelms);
156  ares_free(parsestr);
157  ares_free(temp);
158  return NULL;
159  }
160  nelms++;
161  }
162 
163 
164  /* If there are no elements don't return an empty allocated
165  * array. */
166  if (nelms == 0)
167  {
168  ares_strsplit_free(out, nelms);
169  out = NULL;
170  }
171 
172  /* Get the true number of elements (recalculated because of make_set) */
173  *num_elm = nelms;
174 
175  ares_free(parsestr);
176  ares_free(temp);
177  return out;
178 }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
fix_build_deps.temp
temp
Definition: fix_build_deps.py:488
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
strncasecmp
#define strncasecmp(p1, p2, n)
Definition: ares_private.h:119
ares.h
ares_strdup
char * ares_strdup(const char *s1)
Definition: ares_strdup.c:23
list_contains
static int list_contains(char *const *list, size_t num_elem, const char *str, int insensitive)
Definition: ares_strsplit.c:25
ares_strsplit
char ** ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm)
Definition: ares_strsplit.c:78
is_delim
static int is_delim(char c, const char *delims, size_t num_delims)
Definition: ares_strsplit.c:52
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
ares_malloc
void *(* ares_malloc)(size_t size)=default_malloc
Definition: ares_library_init.c:58
ares_strsplit.h
ares_setup.h
ares_strsplit_free
void ares_strsplit_free(char **elms, size_t num_elm)
Definition: ares_strsplit.c:65
ares_free
void(* ares_free)(void *ptr)=default_free
Definition: ares_library_init.c:60
ares_private.h
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:43