Browse Source

time library additions

Kajetan Johannes Hammerle 3 years ago
parent
commit
df9434cc11
4 changed files with 128 additions and 9 deletions
  1. 13 5
      DataType.c
  2. 93 4
      libraries/Time.c
  3. 14 0
      tests/system/time
  4. 8 0
      tests/system/time.out

+ 13 - 5
DataType.c

@@ -35,7 +35,7 @@ const char* dtGetName(Structs* sts, DataType dt) {
         case DT_FLOAT: dtAppend("float"); break;
         case DT_BOOL: dtAppend("bool"); break;
         case DT_NULL: dtAppend("null"); break;
-        case DT_STRUCT: dtAppend(sts->data[dt.structId].name); break;
+        case DT_STRUCT: dtAppend(dtGetStruct(sts, dt)->name); break;
         case DT_VOID: dtAppend("void"); break;
         default: dtAppend("unknown");
     }
@@ -57,7 +57,7 @@ int dtGetSize(DataType dt, Structs* sts) {
         case DT_STRUCT:
             {
                 int size = 0;
-                Struct* st = sts->data + dt.structId;
+                Struct* st = dtGetStruct(sts, dt);
                 for(int i = 0; i < st->amount; i++) {
                     size += dtGetSize(st->vars[i].type, sts);
                 }
@@ -172,7 +172,13 @@ Struct* dtGetStruct(Structs* sts, DataType dt) {
     if(dt.type != DT_STRUCT) {
         return NULL;
     }
-    return sts->data + dt.structId;
+    if(dt.structId & 1) {
+        if(!useGlobals) {
+            return NULL;
+        }
+        return globalStructs.data + (dt.structId >> 1);
+    }
+    return sts->data + (dt.structId >> 1);
 }
 
 DataType dtToVariable(DataType dt) {
@@ -239,7 +245,7 @@ Struct* stsAdd(Structs* sts, const char* name) {
         sts->data = realloc(sts->data, sizeof(Struct) * sts->capacity);
     }
     int index = sts->entries++;
-    sts->data[index].id = index;
+    sts->data[index].id = index << 1;
     sts->data[index].amount = 0;
     sts->data[index].name = name;
     sts->data[index].vars = NULL;
@@ -261,5 +267,7 @@ Structs* gstsGet() {
 }
 
 Struct* gstsAdd(const char* name) {
-    return stsAdd(&globalStructs, name);
+    Struct* st = stsAdd(&globalStructs, name);
+    st->id |= 1;
+    return st;
 }

+ 93 - 4
libraries/Time.c

@@ -1,20 +1,26 @@
 #include <errno.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 
 #include "libraries/Time.h"
 #include "utils/Functions.h"
 
-static void lTimeGetMillis(Script* sc) {
+static void lGetMillis(Script* sc) {
     struct timespec time;
     if(clock_gettime(CLOCK_REALTIME, &time)) {
         sError(sc, "cannot get clock time: %s", strerror(errno));
         return;
     }
+
+    // time_t t = (time.tv_nsec / 1000000L + time.tv_sec * 1000L) / 1000l;
+    // struct tm* wusi = localtime(&t);
+    // wusi->printf("%d\n", wusi->tm_hour);
+
     sPushInt64(sc, time.tv_nsec / 1000000L + time.tv_sec * 1000L);
 }
 
-static void lTimeGetNanos(Script* sc) {
+static void lGetNanos(Script* sc) {
     struct timespec time;
     if(clock_gettime(CLOCK_BOOTTIME, &time)) {
         sError(sc, "cannot get clock time: %s", strerror(errno));
@@ -23,11 +29,94 @@ static void lTimeGetNanos(Script* sc) {
     sPushInt64(sc, time.tv_nsec + time.tv_sec * 1000000000L);
 }
 
+typedef struct {
+    int32 year;
+    int32 month;
+    int32 day;
+    int32 hours;
+    int32 minutes;
+    int32 seconds;
+    int32 millis;
+    int32 dst;
+} Time;
+
+static void lToTime(Script* sc) {
+    int64 millis;
+    Pointer p;
+    if(!sPopInt64(sc, &millis) || !sPopPointer(sc, &p)) {
+        return;
+    }
+    Time* time = sCheckAddress(sc, &p, sizeof(Time));
+    if(time == NULL) {
+        return;
+    }
+    time_t t = millis / 1000l;
+    struct tm* local = localtime(&t);
+    if(local == NULL) {
+        sError(sc, "cannot get local time: %s", strerror(errno));
+        return;
+    }
+    time->year = local->tm_year + 1900;
+    time->month = local->tm_mon;
+    time->day = local->tm_mday;
+    time->hours = local->tm_hour;
+    time->minutes = local->tm_min;
+    time->seconds = local->tm_sec;
+    time->millis = millis % 1000;
+    time->dst = local->tm_isdst;
+}
+
+static void lToMillis(Script* sc) {
+    Pointer p;
+    if(!sPopPointer(sc, &p)) {
+        return;
+    }
+    Time* time = sCheckAddress(sc, &p, sizeof(Time));
+    if(time == NULL) {
+        return;
+    }
+    struct tm local;
+    local.tm_year = time->year - 1900;
+    local.tm_mon = time->month;
+    local.tm_mday = time->day;
+    local.tm_hour = time->hours;
+    local.tm_min = time->minutes;
+    local.tm_sec = time->seconds;
+    local.tm_isdst = time->dst;
+    int64 seconds = mktime(&local);
+    if(seconds == -1) {
+        sError(sc, "cannot convert time: %s", strerror(errno));
+        return;
+    }
+    sPushInt64(sc, seconds * 1000L + time->millis);
+}
+
 void lTimeRegister() {
     Function f;
-    gfInit(&f, "getMillis", dtInt64(), lTimeGetMillis);
+    gfInit(&f, "getMillis", dtInt64(), lGetMillis);
+    gfsAdd(&f);
+
+    gfInit(&f, "getNanos", dtInt64(), lGetNanos);
+    gfsAdd(&f);
+
+    Struct* time = gstsAdd("Time");
+    stAddVariable(time, "year", dtInt32());
+    stAddVariable(time, "month", dtInt32());
+    stAddVariable(time, "day", dtInt32());
+    stAddVariable(time, "hours", dtInt32());
+    stAddVariable(time, "minutes", dtInt32());
+    stAddVariable(time, "seconds", dtInt32());
+    stAddVariable(time, "millis", dtInt32());
+    stAddVariable(time, "dst", dtInt32());
+    DataType timeType = dtStruct(time);
+    dtDereference(&timeType);
+
+    gfInit(&f, "toTime", dtVoid(), lToTime);
+    gfAddArgument(&f, timeType);
+    gfAddArgument(&f, dtInt64());
     gfsAdd(&f);
 
-    gfInit(&f, "getNanos", dtInt64(), lTimeGetNanos);
+    gfInit(&f, "toMillis", dtInt64(), lToMillis);
+    gfAddArgument(&f, timeType);
     gfsAdd(&f);
 }

+ 14 - 0
tests/system/time

@@ -10,4 +10,18 @@ void main() {
     l3 = getNanos();
     l4 = getNanos();
     test(l1 < l2 && l2 < l3 && l3 < l4);
+    
+    Time time;
+    long millis = getMillis();
+    toTime(&time, millis);
+    
+    test(time.year >= 2021);
+    test(time.month >= 0 && time.month <= 11);
+    test(time.day >= 1 && time.day <= 31);
+    test(time.hours >= 0 && time.hours <= 59);
+    test(time.minutes >= 0 && time.minutes <= 59);
+    test(time.seconds >= 0 && time.seconds <= 60);
+    test(time.millis >= 0 && time.millis <= 999);
+    
+    test(millis == toMillis(&time));
 }

+ 8 - 0
tests/system/time.out

@@ -1,2 +1,10 @@
 true
 true
+true
+true
+true
+true
+true
+true
+true
+true