]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
util: add function to split string into words
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 9 Apr 2020 07:59:39 +0000 (09:59 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 9 Apr 2020 14:42:20 +0000 (16:42 +0200)
test/unit/util.c
util.c
util.h

index 824f3a814245035b720c901aad70b986ca0d2d07..e597d97af4aba835fae6af37c38dc26455bf05b0 100644 (file)
@@ -30,7 +30,7 @@ void test_unit(void) {
   Timespec tspec;
   Float f;
   int i, j, c;
-  char buf[16], *s;
+  char buf[16], *s, *words[3];
   uid_t uid;
   gid_t gid;
   struct stat st;
@@ -333,4 +333,37 @@ void test_unit(void) {
   TEST_CHECK(UTI_BytesToHex("\xAB\x12\x34\x56\x78\x00\x01", 7, buf, 14) == 0);
   TEST_CHECK(UTI_BytesToHex("\xAB\x12\x34\x56\x78\x00\x01", 7, buf, 15) == 1);
   TEST_CHECK(strcmp(buf, "AB123456780001") == 0);
+
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", "") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 3) == 0);
+  TEST_CHECK(!words[0]);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", "     ") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 3) == 0);
+  TEST_CHECK(!words[0]);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", "a  \n ") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 3) == 1);
+  TEST_CHECK(words[0] == buf + 0);
+  TEST_CHECK(strcmp(words[0], "a") == 0);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", "  a  ") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 3) == 1);
+  TEST_CHECK(words[0] == buf + 2);
+  TEST_CHECK(strcmp(words[0], "a") == 0);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", " \n  a") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 3) == 1);
+  TEST_CHECK(words[0] == buf + 4);
+  TEST_CHECK(strcmp(words[0], "a") == 0);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", "a   b") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 1) == 2);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", "a   b") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 2) == 2);
+  TEST_CHECK(words[0] == buf + 0);
+  TEST_CHECK(words[1] == buf + 4);
+  TEST_CHECK(strcmp(words[0], "a") == 0);
+  TEST_CHECK(strcmp(words[1], "b") == 0);
+  TEST_CHECK(snprintf(buf, sizeof (buf), "%s", " a b ") < sizeof (buf));
+  TEST_CHECK(UTI_SplitString(buf, words, 3) == 2);
+  TEST_CHECK(words[0] == buf + 1);
+  TEST_CHECK(words[1] == buf + 3);
+  TEST_CHECK(strcmp(words[0], "a") == 0);
+  TEST_CHECK(strcmp(words[1], "b") == 0);
 }
diff --git a/util.c b/util.c
index 7cd043ff7fab93b334088837c48fc9ee7c90cf20..8f18a216b7435c251232b614122ab334a1341e30 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1402,3 +1402,33 @@ UTI_HexToBytes(const char *hex, void *buf, unsigned int len)
 
   return *hex == '\0' ? i : 0;
 }
+
+/* ================================================== */
+
+int
+UTI_SplitString(char *string, char **words, int max_saved_words)
+{
+  char *s = string;
+  int i;
+
+  for (i = 0; i < max_saved_words; i++)
+    words[i] = NULL;
+
+  for (i = 0; ; i++) {
+    /* Zero white-space characters before the word */
+    while (*s != '\0' && isspace((unsigned char)*s))
+      *s++ = '\0';
+
+    if (*s == '\0')
+      break;
+
+    if (i < max_saved_words)
+      words[i] = s;
+
+    /* Find the next word */
+    while (*s != '\0' && !isspace((unsigned char)*s))
+      s++;
+  }
+
+  return i;
+}
diff --git a/util.h b/util.h
index 3552f78be8a4286c722b21bcda0a1eb5920bb5ea..1e28b26fc15e55ddeae4df28194fbcd8ac635c0d 100644 (file)
--- a/util.h
+++ b/util.h
@@ -220,6 +220,11 @@ extern int UTI_BytesToHex(const void *buf, unsigned int buf_len, char *hex, unsi
    is supported. */
 extern unsigned int UTI_HexToBytes(const char *hex, void *buf, unsigned int len);
 
+/* Split a string into words separated by whitespace characters.  It returns
+   the number of words found in the string, but saves only up to the specified
+   number of pointers to the words. */
+extern int UTI_SplitString(char *string, char **words, int max_saved_words);
+
 /* Macros to get maximum and minimum of two values */
 #ifdef MAX
 #undef MAX