1 /* Copyright (C) 2018 by John Schember <[email protected]>
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.h"
22 #include "ares_private.h"
23
ares__strsplit_free(char ** elms,size_t num_elm)24 void ares__strsplit_free(char **elms, size_t num_elm)
25 {
26 size_t i;
27
28 if (elms == NULL)
29 return;
30
31 for (i=0; i<num_elm; i++)
32 ares_free(elms[i]);
33 ares_free(elms);
34 }
35
ares__strsplit(const char * in,const char * delms,size_t * num_elm)36 char **ares__strsplit(const char *in, const char *delms, size_t *num_elm) {
37 const char *p;
38 char **table;
39 void *tmp;
40 size_t i, j, k, count;
41
42 if (in == NULL || delms == NULL || num_elm == NULL)
43 return NULL;
44
45 *num_elm = 0;
46
47 /* count non-empty delimited substrings */
48 count = 0;
49 p = in;
50 do {
51 i = strcspn(p, delms);
52 if (i != 0) {
53 /* string is non-empty */
54 count++;
55 p += i;
56 }
57 } while (*p++ != 0);
58
59 if (count == 0)
60 return NULL;
61 table = ares_malloc(count * sizeof(*table));
62 if (table == NULL)
63 return NULL;
64
65 j = 0; /* current table entry */
66 /* re-calculate indices and allocate new strings for table */
67 for (p = in; j < count; p += i + 1) {
68 i = strcspn(p, delms);
69 if (i != 0) {
70 for (k = 0; k < j; k++) {
71 if (strncasecmp(table[k], p, i) == 0 && table[k][i] == 0)
72 break;
73 }
74 if (k == j) {
75 /* copy unique strings only */
76 table[j] = ares_malloc(i + 1);
77 if (table[j] == NULL) {
78 ares__strsplit_free(table, j);
79 return NULL;
80 }
81 strncpy(table[j], p, i);
82 table[j++][i] = 0;
83 } else
84 count--;
85 }
86 }
87
88 tmp = ares_realloc(table, count * sizeof (*table));
89 if (tmp != NULL)
90 table = tmp;
91
92 *num_elm = count;
93 return table;
94 }
95