diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-08-09 17:27:35 -0700 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-08-09 17:30:15 -0700 |
commit | 3886467f386732598647a2d3209777ba8d8d7baa (patch) | |
tree | cc240f735afa1073dbdc0bb442f015d358ff7a0c | |
parent | 6423091f071dc7c843d0fd02ac32b880b7754b24 (diff) | |
download | tor-3886467f386732598647a2d3209777ba8d8d7baa.tar.gz tor-3886467f386732598647a2d3209777ba8d8d7baa.zip |
Add a new tor_strtok_r for platforms that don't have one, plus tests.
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.
-rw-r--r-- | src/common/compat.c | 31 | ||||
-rw-r--r-- | src/common/compat.h | 7 | ||||
-rw-r--r-- | 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 d62b1ce1f4..29425c2492 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 4d5a016cf2..3d429486e8 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 3103eed828..67a9c381fe 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), |