From 4bfaf462f0c864473faaca63cc4ba9e1a1b103a8 Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Wed, 26 Mar 2014 14:21:11 +0000 Subject: [PATCH 1/2] Added strtotimeval tests. Change-Id: I3dfd3647a8494490a2d549bdb915968063a7fb99 --- tests/time_test.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/time_test.cpp b/tests/time_test.cpp index 26b7775cc..c0557698c 100644 --- a/tests/time_test.cpp +++ b/tests/time_test.cpp @@ -387,3 +387,51 @@ TEST(time, timer_delete_from_timer_thread) { ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id)); #endif } + +TEST(time, strtotimeval) { +#if defined(__BIONIC__) + struct timeval tv1; + char* rest1 = strtotimeval("10.123456", &tv1); + ASSERT_EQ(10, tv1.tv_sec); + ASSERT_EQ(123456, tv1.tv_usec); + ASSERT_EQ('\0', *rest1); + + // strtotimeval interprets the fractional part as microseconds and thus will + // only consider its first 6 digits. Even so it should consume all valid + // digits. + struct timeval tv2; + char* rest2 = strtotimeval(".1234567", &tv2); + ASSERT_EQ(0, tv2.tv_sec); + ASSERT_EQ(123456, tv2.tv_usec); + ASSERT_EQ('\0', *rest2); + + struct timeval tv3; + char* rest3 = strtotimeval("1.1a", &tv3); + ASSERT_EQ(1, tv3.tv_sec); + ASSERT_EQ(100000, tv3.tv_usec); + ASSERT_EQ('a', *rest3); + + struct timeval tv4; + char* rest4 = strtotimeval("a", &tv4); + ASSERT_EQ(0, tv4.tv_sec); + ASSERT_EQ(0, tv4.tv_usec); + ASSERT_EQ('a', *rest4); + + struct timeval tv5; + char* rest5 = strtotimeval("0", &tv5); + ASSERT_EQ(0, tv5.tv_sec); + ASSERT_EQ(0, tv5.tv_usec); + ASSERT_EQ('\0', *rest5); + + // TODO: should we reject this case and just return '.'? + struct timeval tv6; + char* rest6 = strtotimeval(".", &tv6); + ASSERT_EQ(0, tv6.tv_sec); + ASSERT_EQ(0, tv6.tv_usec); + ASSERT_EQ('\0', *rest6); + +#else // __BIONIC__ + GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif // __BIONIC__ +} + From f1d7536dcfffadc91aabd0a14ec07334a334eea2 Mon Sep 17 00:00:00 2001 From: Weichuan Yan Date: Wed, 26 Mar 2014 03:41:15 +0000 Subject: [PATCH 2/2] Fix and clean up strtotimeval - parsing of fractional part was wrong (always parsed as 0) - return value was also wrong in the presence of fractional parts - general style clean up Change-Id: I1935a63db938dbed7cacb4b5646e993a52c27f1a Signed-off-by: Weichuan Yan --- libc/bionic/strtotimeval.c | 45 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/libc/bionic/strtotimeval.c b/libc/bionic/strtotimeval.c index 1c132ec3d..195381ba8 100644 --- a/libc/bionic/strtotimeval.c +++ b/libc/bionic/strtotimeval.c @@ -30,34 +30,29 @@ #include #include -char * strtotimeval (const char *str, struct timeval *ts) -{ - int n; - char *s, *s0; - long fs; /* Fractional seconds */ +char * strtotimeval(const char *str, struct timeval *ts) { + char *s; + long fs = 0; /* fractional seconds */ - ts->tv_sec = strtoumax(str, &s, 10); - fs = 0; + ts->tv_sec = strtoumax(str, &s, 10); - if ( *s == '.' ) { - int count; + if (*s == '.') { + s++; + int count = 0; - s0 = s+1; - - /* read up to 6 digits */ - fs = 0; - count = 0; - while ( *s && isdigit(*s) ) - { - if ( ++count < 7 ) - fs = fs*10 + (*s - '0'); - s++; - } - - for ( ; count < 6; count++ ) - fs *= 10; + /* read up to 6 digits (microseconds) */ + while (*s && isdigit(*s)) { + if (++count < 7) { + fs = fs*10 + (*s - '0'); + } + s++; } - ts->tv_usec = fs; - return s; + for (; count < 6; count++) { + fs *= 10; + } + } + + ts->tv_usec = fs; + return s; }