[Coldstuff] mktime patch

Robert Bradley coldstuff@cold.org
Wed, 5 Jun 2002 20:59:47 -0600


--------------Boundary-00=_NBK9SH55AYGBADCDUXZY
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

The patch adds the mktime() native to $time.  It also, per request of Bru=
ce,=20
these natives to $time as well: ctime(), time(), mtime(), and localtime()=
=2E

mktime basically takes the same arguments you would pass to the C library=
=20
mktime function.  Here is description of paramenters, and an actual examp=
le=20
of a call:

Arg Description
1   Year
2   month (C call starts at 0=3DJan, I compensated in the coldc call, 1=3D=
Jan)
3   day of the month
4   hour
5   minutes
6   seconds
7   Boolean, for daylight savings time, true/false

Example:
;$time.mktime(73, 4, 11, 6, 17, 0, 0)
=3D> 103382220

I realize it's alot of arguments, but I really didn't see a way around it=
=2E =20
The other functions I added as natives operate exactly like the equivilen=
t=20
function calls.  If anyone finds any problem with these or has any=20
suggestions, please let me know.

Rob

--------------Boundary-00=_NBK9SH55AYGBADCDUXZY
Content-Type: text/x-diff;
  charset="us-ascii";
  name="time.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="time.patch"

diff -urN old/cdc.h new/cdc.h
--- Genesis-1.1.10-STABLE/src/modules/cdc.h	Wed Jun  5 20:41:35 2002
+++ Genesis-1.1.10-time/src/modules/cdc.h	Wed Jun  5 20:40:06 2002
@@ -37,6 +37,11 @@
 NATIVE_METHOD(join);
 NATIVE_METHOD(sort);
 NATIVE_METHOD(strftime);
+NATIVE_METHOD(mktime);
+NATIVE_METHOD(ctime);
+NATIVE_METHOD(localtime);
+NATIVE_METHOD(time);
+NATIVE_METHOD(mtime);
 NATIVE_METHOD(next_objnum);
 NATIVE_METHOD(status);
 NATIVE_METHOD(version);
diff -urN old/cdc.mod new/cdc.mod
--- Genesis-1.1.10-STABLE/src/modules/cdc.mod	Wed Jun  5 20:41:27 2002
+++ Genesis-1.1.10-time/src/modules/cdc.mod	Wed Jun  5 20:39:56 2002
@@ -51,6 +51,11 @@
 native $sys.status()                 status
 native $sys.version()                version
 native $time.format()                strftime
+native $time.mktime()                mktime
+native $time.ctime()                 ctime
+native $time.localtime()             localtime
+native $time.time()                  time
+native $time.mtime()                 mtime
 native $integer.and()                and
 native $integer.or()                 or
 native $integer.xor()                xor
diff -urN old/cdc_misc.c new/cdc_misc.c
--- Genesis-1.1.10-STABLE/src/modules/cdc_misc.c	Wed Jun  5 20:41:16 2002
+++ Genesis-1.1.10-time/src/modules/cdc_misc.c		Wed Jun  5 20:39:49 2002
@@ -17,6 +17,7 @@
 #include "dns.h"
 
 #ifdef __Win32__
+#include <windows.h>    /* for mtime() */
 #define FTIME _lstrftime
 #else
 #define FTIME strftime
@@ -62,7 +63,146 @@
 
     CLEAN_RETURN_STRING(string_from_chars(s, strlen(s)));
 }
+NATIVE_METHOD(mktime) {
+    time_t tt;
+    struct tm t;
+  
+    DEF_args; DEF_argc;
+    if (argc != 7)
+        THROW((numargs_id, "Function requires 7 arguments."))
+    CHECK_TYPE(0, INTEGER, "first");
+    CHECK_TYPE(1, INTEGER, "second");
+    CHECK_TYPE(2, INTEGER, "third");
+    CHECK_TYPE(3, INTEGER, "forth");
+    CHECK_TYPE(4, INTEGER, "fifth");
+    CHECK_TYPE(5, INTEGER, "sixth");
+    CHECK_TYPE(6, INTEGER, "seventh");
+    t.tm_year = args[0].u.val;
+    t.tm_mon = args[1].u.val - 1;
+    t.tm_mday = args[2].u.val;
+    t.tm_hour = args[3].u.val;
+    t.tm_min = args[4].u.val;
+    t.tm_sec = args[5].u.val;
+    t.tm_isdst = args[6].u.val;
+  
+    tt = mktime(&t);
+    CLEAN_RETURN_INTEGER(tt);
+} 
+
+NATIVE_METHOD(ctime) {
+    cStr *str;
+    char *timestr;
+    time_t tval;
+    INIT_0_OR_1_ARGS(INTEGER);
+    
+    tval = (argc) ? INT1 : time(NULL);
 
+#ifdef __BORLANDC__
+    if (tval < 18000)
+        THROW((type_id, "Borland's time util is broken, and requires time values above 18000"))
+#endif
+
+    timestr = ctime(&tval);
+    str = string_from_chars(timestr, 24);
+
+    CLEAN_RETURN_STRING(str);
+}                                  
+
+NATIVE_METHOD(localtime) {
+    struct tm * tms;
+    cData     * d;
+    cList     * l;
+    time_t      t;
+#ifndef HAVE_TM_GMTOFF
+    struct tm * gtms;
+#endif
+    INIT_0_OR_1_ARGS(INTEGER);        
+
+    if (argc)
+        t = (time_t) INT1;
+    else
+        time(&t);
+
+#ifdef __BORLANDC__
+    if (tval < 18000)
+        THROW((type_id, "Borland's time util is broken, and requires time value"))
+#endif
+
+    tms = localtime(&t);
+
+    l = list_new(12);
+    d = list_empty_spaces(l, 12);
+                                                        
+    /* Add one to certain elements to make them 1-x instead of 0-x */
+    d[0].type=INTEGER;
+    d[0].u.val = (cNum) t;
+    d[1].type=INTEGER;
+    d[1].u.val = tms->tm_sec;
+    d[2].type=INTEGER;
+    d[2].u.val = tms->tm_min;
+    d[3].type=INTEGER;
+    d[3].u.val = tms->tm_hour;
+    d[4].type=INTEGER;
+    d[4].u.val = tms->tm_mday;
+    d[5].type=INTEGER;
+    d[5].u.val = tms->tm_mon + 1;
+    d[6].type=INTEGER;
+    d[6].u.val = tms->tm_year;
+    d[7].type=INTEGER;
+    d[7].u.val = tms->tm_wday + 1;
+    d[8].type=INTEGER;
+    d[8].u.val = tms->tm_yday + 1;
+    d[9].type=INTEGER;
+    d[9].u.val = tms->tm_isdst;
+    d[10].type = STRING;
+    d[10].u.str= string_dup(str_tzname);
+    d[11].type=INTEGER;
+#ifdef HAVE_TM_GMTOFF
+    d[11].u.val = tms->tm_gmtoff;
+#else
+    if (last_gmtoffcheck != tms->tm_yday) {
+        int hour = tms->tm_hour; /* they use the same internal structure */
+        gtms = gmtime(&t);
+        gmt_offset = ((hour - gtms->tm_hour) * 60 * 60);
+        last_gmtoffcheck = tms->tm_yday;
+    }
+    d[11].u.val = gmt_offset;
+#endif
+    CLEAN_RETURN_LIST(l);
+}                                                    
+
+NATIVE_METHOD(time) {
+    INIT_NO_ARGS();
+    CLEAN_RETURN_INTEGER(time(NULL));
+}
+
+NATIVE_METHOD(mtime) {
+    Int rv;
+#ifdef HAVE_GETTIMEOFDAY
+    struct timeval tp;
+#endif
+#ifdef __Win32__
+    LARGE_INTEGER freq, cnt;
+#endif
+
+#ifndef __Win32__
+#ifdef HAVE_GETTIMEOFDAY
+    /* usec is microseconds */
+    gettimeofday(&tp, NULL);
+        
+    rv = (Int) tp.tv_usec;
+#else
+    rv = -1;
+#endif
+#else
+    // Win32 implementation
+    QueryPerformanceFrequency(&freq);
+    QueryPerformanceCounter(&cnt);
+    rv = (Int) (((cnt.QuadPart * 1000000) / freq.QuadPart) % 1000000);
+#endif
+    CLEAN_RETURN_INTEGER(rv);
+}
+                
 NATIVE_METHOD(next_objnum) {
     INIT_NO_ARGS();
 

--------------Boundary-00=_NBK9SH55AYGBADCDUXZY--