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