changeset 1365:b02cb9da5686

Changed uw_Basis_time to store microseconds
author Adam Chlipala <adam@chlipala.net>
date Fri, 24 Dec 2010 18:08:29 -0500
parents 0dec38af601c
children 1595a738e4e9
files include/types.h include/urweb.h src/c/urweb.c src/monoize.sml
diffstat 4 files changed, 80 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/include/types.h	Fri Dec 24 17:18:28 2010 -0500
+++ b/include/types.h	Fri Dec 24 18:08:29 2010 -0500
@@ -9,7 +9,10 @@
 typedef double uw_Basis_float;
 typedef char* uw_Basis_string;
 typedef char uw_Basis_char;
-typedef time_t uw_Basis_time;
+typedef struct {
+  time_t seconds;
+  unsigned microseconds;
+} uw_Basis_time;
 typedef struct {
   size_t size;
   char *data;
--- a/include/urweb.h	Fri Dec 24 17:18:28 2010 -0500
+++ b/include/urweb.h	Fri Dec 24 18:08:29 2010 -0500
@@ -305,4 +305,8 @@
 
 uw_Basis_string uw_Basis_crypt(uw_context, uw_Basis_string key, uw_Basis_string salt);
 
+uw_Basis_bool uw_Basis_eq_time(uw_context, uw_Basis_time, uw_Basis_time);
+uw_Basis_bool uw_Basis_lt_time(uw_context, uw_Basis_time, uw_Basis_time);
+uw_Basis_bool uw_Basis_le_time(uw_context, uw_Basis_time, uw_Basis_time);
+
 #endif
--- a/src/c/urweb.c	Fri Dec 24 17:18:28 2010 -0500
+++ b/src/c/urweb.c	Fri Dec 24 18:08:29 2010 -0500
@@ -1774,7 +1774,7 @@
 }
 
 uw_Basis_string uw_Basis_urlifyTime(uw_context ctx, uw_Basis_time t) {
-  return uw_Basis_urlifyInt(ctx, t);
+  return uw_Basis_urlifyInt(ctx, t.seconds * 1000000 + t.microseconds);
 }
 
 uw_unit uw_Basis_urlifyString_w(uw_context ctx, uw_Basis_string s) {
@@ -1845,7 +1845,9 @@
 }
 
 uw_Basis_time uw_Basis_unurlifyTime(uw_context ctx, char **s) {
-  return uw_Basis_unurlifyInt(ctx, s);
+  uw_Basis_int n = uw_Basis_unurlifyInt(ctx, s);
+  uw_Basis_time r = {n / 1000000, n % 1000000};
+  return r;
 }
 
 static uw_Basis_string uw_unurlifyString_to(int fromClient, uw_context ctx, char *r, char *s) {
@@ -2007,18 +2009,18 @@
   return uw_unit_v;
 }
 
-char *uw_Basis_jsifyTime(uw_context ctx, uw_Basis_time n) {
+char *uw_Basis_jsifyTime(uw_context ctx, uw_Basis_time t) {
   int len;
   char *r;
 
   uw_check_heap(ctx, INTS_MAX);
   r = ctx->heap.front;
-  sprintf(r, "%lld%n", (uw_Basis_int)n, &len);
+  sprintf(r, "%lld%n", (uw_Basis_int)(t.seconds * 1000000 + t.microseconds), &len);
   ctx->heap.front += len+1;
   return r;
 }
 
-uw_unit uw_Basis_jsifyInt_w(uw_context ctx, uw_Basis_time n) {
+uw_unit uw_Basis_jsifyInt_w(uw_context ctx, uw_Basis_int n) {
   int len;
 
   uw_check(ctx, INTS_MAX);
@@ -2105,7 +2107,7 @@
   char *r;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     uw_check_heap(ctx, TIMES_MAX);
     r = ctx->heap.front;
     len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
@@ -2120,7 +2122,7 @@
   char *r;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     uw_check(ctx, TIMES_MAX);
     r = ctx->page.front;
     len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
@@ -2511,7 +2513,7 @@
   char *r, *s;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     s = uw_malloc(ctx, TIMES_MAX);
     len = strftime(s, TIMES_MAX, TIME_FMT_PG, &stm);
     r = uw_malloc(ctx, len + 14);
@@ -2526,7 +2528,7 @@
   char *r;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     uw_check_heap(ctx, TIMES_MAX);
     r = ctx->heap.front;
     len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
@@ -2541,11 +2543,13 @@
   char *r;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     uw_check_heap(ctx, TIMES_MAX);
     r = ctx->heap.front;
-    len = strftime(r, TIMES_MAX, TIME_FMT_PG, &stm);
-    ctx->heap.front += len+1;
+    len = strftime(r, TIMES_MAX-7, TIME_FMT_PG, &stm);
+    ctx->heap.front += len;
+    sprintf(ctx->heap.front, ".%06u", t.microseconds);
+    ctx->heap.front += 8;
     return r;
   } else
     return "<Invalid time>";
@@ -2609,7 +2613,7 @@
   char *r;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     uw_check_heap(ctx, TIMES_MAX);
     r = ctx->heap.front;
     len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
@@ -2624,7 +2628,7 @@
   char *r;
   struct tm stm;
 
-  if (localtime_r(&t, &stm)) {
+  if (localtime_r(&t.seconds, &stm)) {
     uw_check_heap(ctx, TIMES_MAX);
     r = ctx->heap.front;
     len = strftime(r, TIMES_MAX, fmt, &stm);
@@ -2693,7 +2697,8 @@
     if (strptime(s, TIME_FMT_PG, &stm) == end) {
       *dot = '.';
       uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
-      *r = mktime(&stm);
+      r->seconds = mktime(&stm);
+      r->microseconds = 0;
       return r;
     }
     else {
@@ -2704,12 +2709,14 @@
   else {
     if (strptime(s, TIME_FMT_PG, &stm) == end) {
       uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
-      *r = mktime(&stm);
+      r->seconds = mktime(&stm);
+      r->microseconds = 0;
       return r;
     }
     else if (strptime(s, TIME_FMT, &stm) == end) {
       uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
-      *r = mktime(&stm);
+      r->seconds = mktime(&stm);
+      r->microseconds = 0;
       return r;
     }
     else
@@ -2723,7 +2730,8 @@
 
   if (strptime(s, fmt, &stm) == end) {
     uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
-    *r = mktime(&stm);
+    r->seconds = mktime(&stm);
+    r->microseconds = 0;
     return r;
   }
   else
@@ -2799,7 +2807,8 @@
     *dot = 0;
     if (strptime(s, TIME_FMT_PG, &stm)) {
       *dot = '.';
-      return mktime(&stm);
+      uw_Basis_time r = { mktime(&stm), atoi(dot+1) };
+      return r;
     }
     else {
       *dot = '.';
@@ -2808,9 +2817,11 @@
   }
   else {
     if (strptime(s, TIME_FMT_PG, &stm) == end) {
-      return mktime(&stm);
+      uw_Basis_time r = { mktime(&stm) };
+      return r;
     } else if (strptime(s, TIME_FMT, &stm) == end) {
-      return mktime(&stm);
+      uw_Basis_time r = { mktime(&stm) };
+      return r;
     } else
       uw_error(ctx, FATAL, "Can't parse time: %s", s);
   }
@@ -2824,7 +2835,10 @@
     *dot = 0;
     if (strptime(s, TIME_FMT_PG, &stm)) {
       *dot = '.';
-      return mktime(&stm);
+      {
+        uw_Basis_time r = { mktime(&stm) };
+        return r;
+      }
     }
     else {
       *dot = '.';
@@ -2832,11 +2846,13 @@
     }
   }
   else {
-    if (strptime(s, TIME_FMT_PG, &stm) == end)
-      return mktime(&stm);
-    else if (strptime(s, TIME_FMT, &stm) == end)
-      return mktime(&stm);
-    else
+    if (strptime(s, TIME_FMT_PG, &stm) == end) {
+      uw_Basis_time r = { mktime(&stm) };
+      return r;
+    } else if (strptime(s, TIME_FMT, &stm) == end) {
+      uw_Basis_time r = { mktime(&stm) };
+      return r;
+    } else
       uw_error(ctx, FATAL, "Can't parse time: %s", s);
   }
 }
@@ -2845,9 +2861,10 @@
   char *end = strchr(s, 0);
   struct tm stm = {};
 
-  if (strptime(s, fmt, &stm) == end)
-    return mktime(&stm);
-  else
+  if (strptime(s, fmt, &stm) == end) {
+    uw_Basis_time r = { mktime(&stm) };
+    return r;
+  } else
     uw_error(ctx, FATAL, "Can't parse time: %s", s);
 }
 
@@ -2942,7 +2959,7 @@
     char formatted[30];
     struct tm tm;
 
-    gmtime_r(expires, &tm);
+    gmtime_r(&expires->seconds, &tm);
 
     strftime(formatted, sizeof formatted, "%a, %d-%b-%Y %T GMT", &tm);
 
@@ -3430,14 +3447,16 @@
   return r;
 }
 
-const uw_Basis_time uw_Basis_minTime = 0;
+const uw_Basis_time uw_Basis_minTime = {};
 
 uw_Basis_time uw_Basis_now(uw_context ctx) {
-  return time(NULL);
+  uw_Basis_time r = { time(NULL) };
+  return r;
 }
 
 uw_Basis_time uw_Basis_minusSeconds(uw_context ctx, uw_Basis_time tm, uw_Basis_int n) {
-  return tm - n;
+  tm.seconds -= n;
+  return tm;
 }
 
 void *uw_get_global(uw_context ctx, char *name) {
@@ -3617,3 +3636,16 @@
 
   return uw_strdup(ctx, crypt_r(key, salt, data));
 }
+
+uw_Basis_bool uw_Basis_eq_time(uw_context ctx, uw_Basis_time t1, uw_Basis_time t2) {
+  return !!(t1.seconds == t2.seconds && t1.microseconds == t2.microseconds);
+}
+
+uw_Basis_bool uw_Basis_lt_time(uw_context ctx, uw_Basis_time t1, uw_Basis_time t2) {
+  return !!(t1.seconds < t2.seconds || t1.microseconds < t2.microseconds);
+}
+
+uw_Basis_bool uw_Basis_le_time(uw_context ctx, uw_Basis_time t1, uw_Basis_time t2) {
+  return !!(uw_Basis_eq_time(ctx, t1, t2) || uw_Basis_lt_time(ctx, t1, t2));
+}
+
--- a/src/monoize.sml	Fri Dec 24 17:18:28 2010 -0500
+++ b/src/monoize.sml	Fri Dec 24 18:08:29 2010 -0500
@@ -930,7 +930,7 @@
                        (L'.TFun ((L'.TFfi ("Basis", "time"), loc), (L'.TFfi ("Basis", "bool"), loc)), loc),
                        (L'.EAbs ("y", (L'.TFfi ("Basis", "time"), loc),
                                  (L'.TFfi ("Basis", "bool"), loc),
-                                 (L'.EBinop (L'.NotInt, "==", (L'.ERel 1, loc), (L'.ERel 0, loc)), loc)), loc)), loc),
+                                 (L'.EFfiApp ("Basis", "eq_time", [(L'.ERel 1, loc), (L'.ERel 0, loc)]), loc)), loc)), loc),
              fm)
 
           | L.ECApp ((L.EFfi ("Basis", "mkEq"), _), t) =>
@@ -1112,11 +1112,11 @@
                               (L'.TFun ((L'.TFfi ("Basis", "bool"), loc), (L'.TFfi ("Basis", "bool"), loc)), loc),
                               (L'.EAbs ("y", (L'.TFfi ("Basis", "bool"), loc),
                                         (L'.TFfi ("Basis", "bool"), loc),
-                                        (L'.EBinop (L'.NotInt, s, (L'.ERel 1, loc), (L'.ERel 0, loc)), loc)), loc)), loc)
+                                        (L'.EFfiApp ("Basis", s, [(L'.ERel 1, loc), (L'.ERel 0, loc)]), loc)), loc)), loc)
             in
                 ordEx ((L'.TFfi ("Basis", "bool"), loc),
-                       boolBin "<",
-                       boolBin "<=")
+                       boolBin "lt_time",
+                       boolBin "le_time")
             end
           | L.EFfi ("Basis", "ord_string") =>
             let
@@ -1158,8 +1158,8 @@
                                         (L'.EBinop (L'.NotInt, s, (L'.ERel 1, loc), (L'.ERel 0, loc)), loc)), loc)), loc)
             in
                 ordEx ((L'.TFfi ("Basis", "time"), loc),
-                       boolBin "<",
-                       boolBin "<=")
+                       boolBin "lt_time",
+                       boolBin "le_time")
             end
           | L.ECApp ((L.EFfi ("Basis", "mkOrd"), _), t) =>
             let