Code

time: Added sdb_strpunit() to parse a time unit.
authorSebastian Harl <sh@tokkee.org>
Wed, 30 Jul 2014 08:24:30 +0000 (10:24 +0200)
committerSebastian Harl <sh@tokkee.org>
Wed, 30 Jul 2014 08:24:30 +0000 (10:24 +0200)
src/core/time.c
src/frontend/scanner.l
src/include/core/time.h
t/unit/core/time_test.c

index 762ffd0034fc3315c77e3951c0a41f5566fa2a3b..5d34e18b4fed99a8769ed9f17d226e6d9432db5d 100644 (file)
@@ -41,7 +41,7 @@
  * public API
  */
 
-/* 1 second (in micro-seconds) */
+/* 1 second (in nano-seconds) */
 #define SEC 1000000000L
 
 const sdb_time_t SDB_INTERVAL_YEAR   = 3652425L   * 24L * 60L * 60L * 100000L;
@@ -147,5 +147,31 @@ sdb_strfinterval(char *s, size_t len, sdb_time_t interval)
        return n;
 } /* sdb_strfinterval */
 
+sdb_time_t
+sdb_strpunit(const char *s)
+{
+       struct {
+               const char *s;
+               sdb_time_t unit;
+       } units[] = {
+               { "Y", SDB_INTERVAL_YEAR },
+               { "M", SDB_INTERVAL_MONTH },
+               { "D", SDB_INTERVAL_DAY },
+               { "h", SDB_INTERVAL_HOUR },
+               { "m", SDB_INTERVAL_MINUTE },
+               { "s", SDB_INTERVAL_SECOND },
+               { "ms", SDB_INTERVAL_SECOND / 1000L },
+               { "us", SDB_INTERVAL_SECOND / 1000000L },
+               { "ns", 1 },
+       };
+
+       size_t i;
+
+       for (i = 0; i < SDB_STATIC_ARRAY_LEN(units); ++i)
+               if (! strcmp(s, units[i].s))
+                       return units[i].unit;
+       return 0;
+} /* sdb_strpunit */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */
 
index 5e80368d532872198edb7ea7bfb45dd60a9f0225..f45fbe76bdbb86370e27cf4d4583275414831d34 100644 (file)
@@ -75,10 +75,16 @@ csc_start   \/\*
 csc_inside     ([^*/]+|[^*]\/|\*[^/])
 csc_end                \*\/
 
+/*
+ * Strings and identifiers.
+ */
 identifier     ([A-Za-z_][A-Za-z_0-9$]*)
 /* TODO: fully support SQL strings */
 string         ('[^']*')
 
+/*
+ * Numeric constants.
+ */
 dec                    ([\+\-]?[0-9]+)
 exp                    ([\+\-]?[0-9]+[Ee]\+?[0-9]+)
 integer                ({dec}|{exp})
index 7515af3244720513a8b32d5628b718866a2d4d2b..c97e121ad7d4dddc0d243b421e597a434b1fedd0 100644 (file)
@@ -79,6 +79,19 @@ sdb_strftime(char *s, size_t len, const char *format, sdb_time_t);
 size_t
 sdb_strfinterval(char *s, size_t len, sdb_time_t interval);
 
+/*
+ * sdb_strpunit:
+ * Parse the specified string as a time unit.
+ * "Y" (year), "M" (month), "D" (day), "h" (hour), "m" (minute), "s" (second),
+ * "ms" (milli-second), "us" (micro-second), "ns" (nano-second).
+ *
+ * Returns:
+ *  - the time interval corresponding to the specified unit on success
+ *  - 0 else
+ */
+sdb_time_t
+sdb_strpunit(const char *s);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index f1f4c94663018b0305f364e333e3fd07d8141fd0..8be221498ccadfdea534ef9e8b4326eacccf5a49 100644 (file)
@@ -34,7 +34,6 @@ START_TEST(test_strfinterval)
 {
        char buf[1024];
        size_t check;
-       size_t i;
 
        struct {
                sdb_time_t  interval;
@@ -59,6 +58,8 @@ START_TEST(test_strfinterval)
                  + 1234,               "1Y1M1D1h1m1.000001234s" },
        };
 
+       size_t i;
+
        /* this should return the number of bytes which would have been written;
         * most notably, it should not segfault ;-) */
        check = sdb_strfinterval(NULL, 0, 4711); /* expected: .000004711s */
@@ -82,6 +83,41 @@ START_TEST(test_strfinterval)
 }
 END_TEST
 
+START_TEST(test_strpunit)
+{
+       struct {
+               const char *s;
+               sdb_time_t expected;
+       } golden_data[] = {
+               { "Y",  SDB_INTERVAL_YEAR },
+               { "M",  SDB_INTERVAL_MONTH },
+               { "D",  SDB_INTERVAL_DAY },
+               { "h",  SDB_INTERVAL_HOUR },
+               { "m",  SDB_INTERVAL_MINUTE },
+               { "s",  SDB_INTERVAL_SECOND },
+               { "ms", 1000000L },
+               { "us", 1000L },
+               { "ns", 1L },
+               /* invalid units */
+               { "y",  0 },
+               { "d",  0 },
+               { "H",  0 },
+               { "S",  0 },
+               { "ps", 0 },
+       };
+
+       size_t i;
+
+       for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
+               sdb_time_t check = sdb_strpunit(golden_data[i].s);
+
+               fail_unless(check == golden_data[i].expected,
+                               "sdb_strpunit(%s) = %"PRIsdbTIME"; expected: %"PRIsdbTIME,
+                               golden_data[i].s, check, golden_data[i].expected);
+       }
+}
+END_TEST
+
 Suite *
 core_time_suite(void)
 {
@@ -90,6 +126,7 @@ core_time_suite(void)
 
        tc = tcase_create("core");
        tcase_add_test(tc, test_strfinterval);
+       tcase_add_test(tc, test_strpunit);
        suite_add_tcase(s, tc);
 
        return s;