From fa20763c07d329a9b25db4de82e40d8813319e02 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 12 Nov 2022 11:30:24 +0000 Subject: [PATCH] Corrected negative timers --- repl/lib_timer.c | 57 +++++++++++++++++++++++++++++++------- scripts/small.toy | 13 +++++++++ test/scripts/lib/timer.toy | 32 +++++++++++++++++++++ 3 files changed, 92 insertions(+), 10 deletions(-) diff --git a/repl/lib_timer.c b/repl/lib_timer.c index 0302fe0..24779ef 100644 --- a/repl/lib_timer.c +++ b/repl/lib_timer.c @@ -5,21 +5,43 @@ #include +//GOD DAMN IT: https://stackoverflow.com/questions/15846762/timeval-subtract-explanation +int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) { + //normallize + if (x->tv_usec > 999999) { + x->tv_sec += x->tv_usec / 1000000; + x->tv_usec %= 1000000; + } + + if (y->tv_usec > 999999) { + y->tv_sec += y->tv_usec / 1000000; + y->tv_usec %= 1000000; + } + + //calc + result->tv_sec = x->tv_sec - y->tv_sec; + + if ((result->tv_usec = x->tv_usec - y->tv_usec) < 0) { + if (result->tv_sec != 0) { //only works far from 0 + result->tv_usec += 1000000; + result->tv_sec--; // borrow + } + } + + return result->tv_sec < 0 || (result->tv_sec == 0 && result->tv_usec < 0); +} + //god damn it static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) { struct timeval* d = ALLOCATE(struct timeval, 1); - d->tv_sec = rhs->tv_sec - lhs->tv_sec; - d->tv_usec = rhs->tv_usec - lhs->tv_usec; - - if (d->tv_usec < 0) { - d->tv_sec--; - d->tv_usec += 1000 * 1000; - } + //I gave up, copied from SO + timeval_subtract(d, rhs, lhs); return d; } +//callbacks static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) { //no arguments if (arguments->count != 0) { @@ -107,6 +129,13 @@ static int nativeCreateTimer(Interpreter* interpreter, LiteralArray* arguments) return -1; } + if (AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || AS_INTEGER(microsecondLiteral) >= 1000 * 1000) { + interpreter->errorOutput("Microseconds out of range in createTimer\n"); + freeLiteral(secondLiteral); + freeLiteral(microsecondLiteral); + return -1; + } + //get the timeinfo from toy struct timeval* timeinfo = ALLOCATE(struct timeval, 1); timeinfo->tv_sec = AS_INTEGER(secondLiteral); @@ -259,9 +288,17 @@ static int nativeTimerToString(Interpreter* interpreter, LiteralArray* arguments struct timeval* timer = AS_OPAQUE(timeLiteral); //create the string literal - char buffer[128]; - snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec); - Literal resultLiteral = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer)); + Literal resultLiteral = TO_NULL_LITERAL; + if (timer->tv_sec == 0 && timer->tv_usec < 0) { //special case, for when the negative sign is encoded in the usec + char buffer[128]; + snprintf(buffer, 128, "-%ld.%06ld", timer->tv_sec, -timer->tv_usec); + resultLiteral = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer)); + } + else { //normal case + char buffer[128]; + snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec); + resultLiteral = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer)); + } pushLiteralArray(&interpreter->stack, resultLiteral); diff --git a/scripts/small.toy b/scripts/small.toy index e69de29..1ec8735 100644 --- a/scripts/small.toy +++ b/scripts/small.toy @@ -0,0 +1,13 @@ +import timer; + +var a = createTimer(1, 0); +var b = createTimer(2, 0); + +print a.compareTimer(b).timerToString(); +print b.compareTimer(a).timerToString(); + +var c = createTimer(0, 1); +var d = createTimer(0, 2); + +print c.compareTimer(d).timerToString(); +print d.compareTimer(c).timerToString(); diff --git a/test/scripts/lib/timer.toy b/test/scripts/lib/timer.toy index 928844f..31e1ee1 100644 --- a/test/scripts/lib/timer.toy +++ b/test/scripts/lib/timer.toy @@ -56,5 +56,37 @@ timer.destroyTimer(); } +{ + //test positive and negative values of timers + import timer; + + var a = createTimer(1, 0); + var b = createTimer(2, 0); + + var acmp = a.compareTimer(b); + var bcmp = b.compareTimer(a); + + var c = createTimer(0, 1); + var d = createTimer(0, 2); + + var ccmp = c.compareTimer(d); + var dcmp = d.compareTimer(c); + + assert acmp.timerToString() == "1.000000", "positive and negative tests failed (acmp)"; + assert bcmp.timerToString() == "-1.000000", "positive and negative tests failed (bcmp)"; + assert ccmp.timerToString() == "0.000001", "positive and negative tests failed (ccmp)"; + assert dcmp.timerToString() == "-0.000001", "positive and negative tests failed (dcmp)"; + + a.destroyTimer(); + b.destroyTimer(); + c.destroyTimer(); + d.destroyTimer(); + acmp.destroyTimer(); + bcmp.destroyTimer(); + ccmp.destroyTimer(); + dcmp.destroyTimer(); +} + print "All good"; +