[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [tor/master] Add a new tor_strtok_r for platforms that don't have one, plus tests.



Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Sun, 9 Aug 2009 17:27:35 -0700
Subject: Add a new tor_strtok_r for platforms that don't have one, plus tests.
Commit: 3886467f386732598647a2d3209777ba8d8d7baa

I don't think we actually use (or plan to use) strtok_r in a reentrant
way anywhere in our code, but would be nice not to have to think about
whether we're doing it.
---
 src/common/compat.c |   31 +++++++++++++++++++++++++++++++
 src/common/compat.h |    7 +++++++
 src/or/test.c       |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/src/common/compat.c b/src/common/compat.c
index d62b1ce..29425c2 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -398,6 +398,37 @@ const char TOR_TOLOWER_TABLE[256] = {
   240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
 };
 
+/** Implementation of strtok_r for platforms whose coders haven't figured out
+ * how to write one.  Hey guys!  You can use this code here for free! */
+char *
+tor_strtok_r_impl(char *str, const char *sep, char **lasts)
+{
+  char *cp, *start;
+  if (str)
+    start = cp = *lasts = str;
+  else if (!*lasts)
+    return NULL;
+  else
+    start = cp = *lasts;
+
+  tor_assert(*sep);
+  if (sep[1]) {
+    while (*cp && !strchr(sep, *cp))
+      ++cp;
+  } else {
+    tor_assert(strlen(sep) == 1);
+    cp = strchr(cp, *sep);
+  }
+
+  if (!cp || !*cp) {
+    *lasts = NULL;
+  } else {
+    *cp++ = '\0';
+    *lasts = cp;
+  }
+  return start;
+}
+
 #ifdef MS_WINDOWS
 /** Take a filename and return a pointer to its final element.  This
  * function is called on __FILE__ to fix a MSVC nit where __FILE__
diff --git a/src/common/compat.h b/src/common/compat.h
index 4d5a016..3d42948 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -267,6 +267,13 @@ extern const char TOR_TOLOWER_TABLE[];
 #define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c])
 #define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c])
 
+char *tor_strtok_r_impl(char *str, const char *sep, char **lasts);
+#ifdef HAVE_STRTOK_R
+#define tor_strok_r(str, sep, lasts) strtok_r(str, sep, lasts)
+#else
+#define tor_strok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts)
+#endif
+
 #ifdef MS_WINDOWS
 #define _SHORT_FILE_ (tor_fix_source_file(__FILE__))
 const char *tor_fix_source_file(const char *fname);
diff --git a/src/or/test.c b/src/or/test.c
index 3103eed..67a9c38 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -4284,6 +4284,39 @@ test_util_datadir(void)
   tor_free(f);
 }
 
+static void
+test_util_strtok(void)
+{
+  char buf[128];
+  char buf2[128];
+  char *cp1, *cp2;
+  strlcpy(buf, "Graved on the dark in gestures of descent", sizeof(buf));
+  strlcpy(buf2, "they.seemed;their!own;most.perfect;monument", sizeof(buf2));
+  /*  -- "Year's End", Richard Wilbur */
+
+  test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
+  test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
+#define S1() tor_strtok_r_impl(NULL, " ", &cp1)
+#define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
+  test_streq("on", S1());
+  test_streq("the", S1());
+  test_streq("dark", S1());
+  test_streq("seemed", S2());
+  test_streq("their", S2());
+  test_streq("own", S2());
+  test_streq("in", S1());
+  test_streq("gestures", S1());
+  test_streq("of", S1());
+  test_streq("most", S2());
+  test_streq("perfect", S2());
+  test_streq("descent", S1());
+  test_streq("monument", S2());
+  test_assert(NULL == S1());
+  test_assert(NULL == S2());
+ done:
+  ;
+}
+
 /** Test AES-CTR encryption and decryption with IV. */
 static void
 test_crypto_aes_iv(void)
@@ -4692,6 +4725,7 @@ static struct {
   SUBENT(util, threads),
   SUBENT(util, order_functions),
   SUBENT(util, sscanf),
+  SUBENT(util, strtok),
   ENT(onion_handshake),
   ENT(dir_format),
   ENT(dirutil),
-- 
1.5.6.5