]> git.mdlowis.com Git - projs/tide.git/commitdiff
checkpoint commit
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 12 Jun 2020 11:47:23 +0000 (07:47 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 12 Jun 2020 11:47:23 +0000 (07:47 -0400)
runner.c [new file with mode: 0644]
src/tide.c
tools/atf

diff --git a/runner.c b/runner.c
new file mode 100644 (file)
index 0000000..bfa5521
--- /dev/null
+++ b/runner.c
@@ -0,0 +1,281 @@
+#include "atf.h"
+#undef main
+#include <setjmp.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <time.h>
+
+#define RUN(file, line, name, ntrials) \
+    void name(void); \
+    runtestn(file, line, #name, name, ntrials)
+
+static char* Curr_File = 0;
+static char* Curr_Test = 0;
+static char* Curr_Expr = 0;
+static unsigned int Curr_Line = 0;
+static Value* Curr_Values;
+static jmp_buf Jump_Buf;
+static unsigned long Total = 0;
+static unsigned long Failed = 0;
+static uintptr_t Heap_Buf[1024*1024];
+static uintptr_t* Heap_Top = Heap_Buf;
+static uintptr_t* Heap_Base = Heap_Buf;
+static uintptr_t* Heap_End = Heap_Buf + sizeof(Heap_Buf)/sizeof(uintptr_t) - 1;
+enum {
+    FAIL_ASSERT = 1,
+    FAIL_OOM = 2
+};
+
+/* Basic Runtime Functions
+ ****************************/
+static int print_results(void)
+{
+    printf("%lu/%lu tests passed\n" , Total - Failed, Total);
+    return Failed;
+}
+
+static void print_values(void)
+{
+    Value* values = 0;
+    while (Curr_Values)
+    {
+        Value* val = Curr_Values;
+        Curr_Values = val->next;
+        val->next = values;
+        values = val;
+    }
+
+    while (values)
+    {
+        printf("  -> arg: ");
+        values->showfn(values);
+        values = values->next;
+    }
+}
+
+void* malloc(size_t size)
+{
+    void* ptr = Heap_Top;
+    size_t num_words = ((size & ~0x7) + ((size & 7) ? 1 : 0)) / sizeof(uintptr_t) + 1;
+    *Heap_Top = size;
+    Heap_Top += num_words;
+    if (Heap_Top > Heap_End)
+    {
+        Heap_Top = Heap_Base; // Reset heap in case printf mallocs.
+        fprintf(stderr,"%s:%d: MEM %s out of memory\n", Curr_File, Curr_Line, Curr_Test);
+        longjmp(Jump_Buf, FAIL_OOM);
+    }
+    else
+    {
+        memset(ptr, 0, size);
+    }
+    return ptr;
+}
+
+void* calloc(size_t num, size_t size)
+{
+    return malloc(num * size);
+}
+
+void* realloc(void* ptr, size_t new_size)
+{
+    uintptr_t old_size = *((uintptr_t*)ptr - 1);
+    void* newptr = malloc(new_size);
+    memcpy(newptr, ptr, old_size);
+    return newptr;
+}
+
+void free(void* ptr)
+{
+    (void)ptr; /* simply reset the buffer after each test */
+}
+
+void Assert(int cond, char* condstr, char* file, int line)
+{
+    if (!cond)
+    {
+        Curr_File = file;
+        Curr_Line = line;
+        Curr_Expr = condstr;
+        longjmp(Jump_Buf, 1);
+    }
+}
+
+static int runtest(void (*fn)(void))
+{
+    Curr_Values = 0;
+    Heap_Top = Heap_Base;
+    int code = setjmp(Jump_Buf);
+    if (code == 0)
+    {
+        fn();
+    }
+    return code;
+}
+
+static void runtestn(char* file, int line, char* fnname, void (*fn)(void), int ntrials)
+{
+    Curr_File = file;
+    Curr_Line = line;
+    Curr_Test = fnname;
+    Total++;
+    for (int i = 0; i < ntrials; i++)
+    {
+        int fail = runtest(fn);
+        if (fail != 0)
+        {
+            Failed++;
+            if (fail == FAIL_ASSERT)
+            {
+                if (ntrials == 1)
+                {
+                    printf("%s:%d: FAIL for test %s \n  -> CHECK( %s )\n", Curr_File, Curr_Line, Curr_Test, Curr_Expr);
+                }
+                else
+                {
+                    printf("%s:%d: FAIL on trial %d/%d for test %s\n", Curr_File, Curr_Line, i, ntrials, Curr_Test);
+                    print_values();
+                }
+            }
+            break;
+        }
+    }
+}
+
+static void handle_signal(int sig)
+{
+    /* Determine the signal name */
+    char* sig_name = NULL;
+    switch(sig)
+    {
+        case SIGABRT: sig_name = "SIGABRT"; break;
+        case SIGBUS:  sig_name = "SIGBUS";  break;
+        case SIGFPE:  sig_name = "SIGFPE";  break;
+        case SIGILL:  sig_name = "SIGILL";  break;
+        case SIGSEGV: sig_name = "SIGSEGV"; break;
+        case SIGSYS:  sig_name = "SIGSYS";  break;
+        /* If we don't recognize it then just return and let the default handler
+           catch it. */
+        default:      return;
+    }
+    /* Error and exit. No summary will be printed but the user will know which
+       test has crashed. */
+    fprintf(stderr,"%s:%d: CRASH %s (signal: %d - %s)\n", Curr_File, Curr_Line, Curr_Test, sig, sig_name);
+    Failed++;
+    (void)print_results();
+    _Exit(1);
+}
+
+/* Property Testing Functions
+ ****************************/
+void* ValueAlloc(void (*showfn)(Value* val), size_t num, size_t sz, void* data)
+{
+    Value* value = calloc(num, sizeof(Value) + sz);
+    value->showfn = showfn;
+    value->ndata = num;
+    value->next = Curr_Values;
+    Curr_Values = value;
+    if (data)
+    {
+        memcpy(value->data, data, num * sz);
+    }
+    return &(value->data[0]);
+}
+
+long RandR(long from, long to)
+{
+    return ((rand() % (to - from + 1)) + from);
+}
+
+long Rand(void)
+{
+    return rand();
+}
+
+void ShowLong(Value* val)
+{
+    printf("%ld\n", (val->data[0]));
+}
+
+void ShowBool(Value* val)
+{
+    printf("%s\n", (val->data[0] ? "true" : "false"));
+}
+
+void ShowChar(Value* val)
+{
+    printf("'%c'\n", (char)(val->data[0]));
+}
+
+void ShowString(Value* val)
+{
+    printf("'%s'\n", (char*)(val->data));
+}
+
+long MkLongR(long from, long to)
+{
+    return *((long*)ValueAlloc(ShowLong, 1, sizeof(long), &(long){RandR(from, to)}));
+}
+
+long MkLong(void)
+{
+    return *((long*)ValueAlloc(ShowLong, 1, sizeof(long), &(long){Rand()}));
+}
+
+uint8_t MkU8(void)
+{
+    return MkLongR(0, UINT8_MAX);
+}
+
+uint16_t MkU16(void)
+{
+    return MkLongR(0, UINT16_MAX);
+}
+
+uint32_t MkU32(void)
+{
+    return MkLongR(0, UINT32_MAX);
+}
+
+bool MkBool(void)
+{
+    return *((bool*)ValueAlloc(ShowBool, 1, sizeof(bool), &(bool){RandR(0, 1)}));
+}
+
+char MkAsciiChar(void)
+{
+    return *((char*)ValueAlloc(ShowChar, 1, sizeof(char), &(char){RandR(32, 127)}));
+}
+
+char* MkAsciiStringL(size_t len) {
+    char* val = ValueAlloc(ShowString, len+1, sizeof(char), 0);
+    for (size_t i = 0; i < len; i++)
+    {
+        *(val++) = RandR(32, 127);
+    }
+    return val;
+}
+
+char* MkAsciiString(void) {
+    return MkAsciiStringL(RandR(1, 1024));
+}
+
+/* Main Routine
+ ****************************/
+int main(int argc, char** argv)
+{
+    (void)runtestn;
+    unsigned int seed = (argc >= 2 ? strtoul(argv[1], 0, 0) : (unsigned int)time(0));
+    printf("Seed: %u\n", seed);
+    srand(seed);
+    signal(SIGABRT, handle_signal);
+    signal(SIGBUS,  handle_signal);
+    signal(SIGFPE,  handle_signal);
+    signal(SIGILL,  handle_signal);
+    signal(SIGSEGV, handle_signal);
+    signal(SIGSYS,  handle_signal);
+    Heap_Base = Heap_Top;
index b31ff6510c22c436a696fc07414edaf0c9dcd3ac..cea4d2fbbfee157a9994e70bbec2eb6c29c8c97f 100644 (file)
@@ -222,13 +222,14 @@ static void xmousebtn(XConf* x, XEvent* e)
 
 static void xbtnmotion(XConf* x, XEvent* e)
 {
-    while (XCheckTypedEvent(x->display, MotionNotify, e));
+    XMotionEvent *ev = &e->xmotion;
+    while (XCheckTypedWindowEvent(x->display, ev->window, ev->type, e));
     size_t row, col;
-    int xpos = e->xbutton.x, ypos = e->xbutton.y;
+    int xpos = ev->x, ypos = ev->y;
     get_position(Focused, xpos, ypos, &row, &col);
     telem_send("BTNMOVE(reg: %d, btn: 0x%x, x: %d, y: %d, r: %d, c: %d)\n",
-        Focused, e->xbutton.state, xpos, ypos, row, col);
-    if (PRESSED(e->xbutton.state, MouseLeft))
+        Focused, ev->state, xpos, ypos, row, col);
+    if (PRESSED(ev->state, MouseLeft))
         view_setcursor(win_view(Focused), row, col, true);
 }
 
index aada39b535976638aaf675fdd3f032b937532514..a1b0538a565e62b21ea5f44f92e2ed374a4abd81 100755 (executable)
--- a/tools/atf
+++ b/tools/atf
@@ -350,4 +350,4 @@ EOF
 
 cc="${CC:-cc}"
 "$cc" -DATF_TEST -g -o runner -O0 "$@" "$runner" && ./runner
-#rm -f runner "$runner"
+rm -f runner "$runner"