Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / cares / cares / ares_strsplit.c
diff --git a/legacy-libs/grpc-cloned/deps/grpc/third_party/cares/cares/ares_strsplit.c b/legacy-libs/grpc-cloned/deps/grpc/third_party/cares/cares/ares_strsplit.c
new file mode 100644 (file)
index 0000000..b57a30f
--- /dev/null
@@ -0,0 +1,174 @@
+/* Copyright (C) 2018 by John Schember <john@nachtimwald.com>
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include "ares_strsplit.h"
+#include "ares.h"
+#include "ares_private.h"
+
+static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
+{
+  size_t len;
+  size_t i;
+
+  len = strlen(str);
+  for (i=0; i<num_elem; i++)
+  {
+    if (insensitive)
+    {
+#ifdef WIN32
+      if (strnicmp(list[i], str, len) == 0)
+#else
+      if (strncasecmp(list[i], str, len) == 0)
+#endif
+        return 1;
+    }
+    else
+    {
+      if (strncmp(list[i], str, len) == 0)
+        return 1;
+    }
+  }
+
+  return 0;
+}
+
+static int is_delim(char c, const char *delims, size_t num_delims)
+{
+  size_t i;
+
+  for (i=0; i<num_delims; i++)
+  {
+    if (c == delims[i])
+      return 1;
+  }
+  return 0;
+}
+
+
+void ares_strsplit_free(char **elms, size_t num_elm)
+{
+  size_t i;
+
+  if (elms == NULL)
+    return;
+
+  for (i=0; i<num_elm; i++)
+    ares_free(elms[i]);
+  ares_free(elms);
+}
+
+
+char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm)
+{
+  char *parsestr;
+  char **temp;
+  char **out;
+  size_t cnt;
+  size_t nelms;
+  size_t in_len;
+  size_t num_delims;
+  size_t i;
+
+  if (in == NULL || delms == NULL || num_elm == NULL)
+    return NULL;
+
+  *num_elm = 0;
+
+  in_len = strlen(in);
+  num_delims = strlen(delms);
+
+  /* Figure out how many elements. */
+  nelms = 1;
+  for (i=0; i<in_len; i++)
+  {
+    if (is_delim(in[i], delms, num_delims))
+    {
+      nelms++;
+    }
+  }
+
+  /* Copy of input so we can cut it up. */
+  parsestr = ares_strdup(in);
+  if (parsestr == NULL)
+    return NULL;
+
+  /* Temporary array to store locations of start of each element
+   * within parsestr. */
+  temp = ares_malloc(nelms * sizeof(*temp));
+  if (temp == NULL)
+  {
+    ares_free(parsestr);
+    return NULL;
+  }
+  temp[0] = parsestr;
+  cnt = 1;
+  for (i=0; i<in_len && cnt<nelms; i++)
+  {
+    if (!is_delim(parsestr[i], delms, num_delims))
+      continue;
+
+    /* Replace sep with NULL. */
+    parsestr[i] = '\0';
+    /* Add the pointer to the array of elements */
+    temp[cnt] = parsestr+i+1;
+    cnt++;
+  }
+
+  /* Copy each element to our output array. */
+  out = ares_malloc(nelms * sizeof(*out));
+  if (out == NULL)
+  {
+    ares_free(parsestr);
+    ares_free(temp);
+    return NULL;
+  }
+
+  nelms = 0;
+  for (i=0; i<cnt; i++)
+  {
+    if (temp[i][0] == '\0')
+      continue;
+
+    if (make_set && list_contains(out, nelms, temp[i], 1))
+      continue;
+
+    out[nelms] = ares_strdup(temp[i]);
+    if (out[nelms] == NULL)
+    {
+      ares_strsplit_free(out, nelms);
+      ares_free(parsestr);
+      ares_free(temp);
+      return NULL;
+    }
+    nelms++;
+  }
+
+
+  /* If there are no elements don't return an empty allocated
+   * array. */
+  if (nelms == 0)
+  {
+    ares_strsplit_free(out, nelms);
+    out = NULL;
+  }
+
+  /* Get the true number of elements (recalculated because of make_set) */
+  *num_elm = nelms;
+
+  ares_free(parsestr);
+  ares_free(temp);
+  return out;
+}