]> gitweb.ps.run Git - iftint/blobdiff - main2.c
screen size
[iftint] / main2.c
diff --git a/main2.c b/main2.c
index 47e11ee3227a53af2964fc8d182baf68318cd989..12f99d4f5daaf8d5ae6e27fd43c78822158ab214 100644 (file)
--- a/main2.c
+++ b/main2.c
@@ -2,6 +2,11 @@
 #include <stdarg.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdbool.h>
+
+/* TODO
+- whitelist input on GetStr/GetInt
+*/
 
 // Memory
 
@@ -85,14 +90,27 @@ void vt100CursorHome() { vt100Escape("[H"); }
 void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); }
 void vt100SaveCursor() { vt100Escape("7"); }
 void vt100RestoreCursor() { vt100Escape("8"); }
+void vt100GetScreenSize(int * v, int * h) {
+    *v = *h = 0;
+    vt100CursorPos(1000000, 1000000);
+    printf("\033[6n");
+    getch(); getch();
+    int c;
+    while ((c = getch()) != ';')
+        *v = (10*(*v)+(c-'0'));
+    while ((c = getch()) != 'R')
+        *h = (10*(*h)+(c-'0'));
+}
 
 
 // JSON
 
 typedef enum {
     JSONNodeKind_Nul,
+    JSONNodeKind_Int,
     JSONNodeKind_Str,
     JSONNodeKind_Obj,
+    JSONNodeKind_Arr,
 } JSONNodeKind;
 
 struct JSONNode;
@@ -112,6 +130,16 @@ JSONNodeNew(JSONNodeKind kind, size_t data) {
     return result;
 }
 
+JSONNode *
+JSONNodeNewNul() {
+    return JSONNodeNew(JSONNodeKind_Nul, (size_t)NULL);
+}
+
+JSONNode *
+JSONNodeNewInt(int i) {
+    return JSONNodeNew(JSONNodeKind_Int, (size_t)i);
+}
+
 JSONNode *
 JSONNodeNewStr(const char * str) {
     return JSONNodeNew(JSONNodeKind_Str, (size_t)str);
@@ -123,12 +151,12 @@ JSONNodeNewObj() {
 }
 
 JSONNode *
-JSONNodeNewNul() {
-    return JSONNodeNew(JSONNodeKind_Nul, (size_t)NULL);
+JSONNodeNewArr() {
+    return JSONNodeNew(JSONNodeKind_Arr, (size_t)NULL);
 }
 
 JSONNode *
-JSONNodeAppend(JSONNode * this, JSONNode * that) {
+JSONNodePush(JSONNode * this, JSONNode * that) {
     if (this->children == NULL) {
         this->children = that;
     }
@@ -144,6 +172,26 @@ JSONNodeAppend(JSONNode * this, JSONNode * that) {
     return that;
 }
 
+void
+JSONNodePop(JSONNode * this) {
+    if (this != NULL) {
+        JSONNode * ptr = this->children;
+
+        if (ptr == NULL) { // no children
+            JSONNodePop(this->parent);
+        }
+        else if (ptr->next == NULL) { // one child
+            this->children = NULL;
+            
+        }
+        else { // more than one child
+            while (ptr->next->next != NULL)
+                ptr = ptr->next;
+            ptr->next = NULL;
+        }
+    }
+}
+
 void
 Indent(int indent) {
     for (int i = 0; i < indent; i++)
@@ -164,6 +212,11 @@ JSONNodePrint(JSONNode * node) {
         printf("null");
         break;
     }
+    case JSONNodeKind_Int: {
+        int i = (int)node->data;
+        printf("%d", i);
+        break;
+    }
     case JSONNodeKind_Str: {
         char * str = (char *)node->data;
         printf("\"%s\"", str == NULL ? "" : str);
@@ -190,25 +243,79 @@ JSONNodePrint(JSONNode * node) {
         printf("}");
         break;
     }
+    case JSONNodeKind_Arr: {
+        printf("[ ");
+        JSONNode * ptr = node->children;
+        while (ptr != NULL) {
+            JSONNode * value = ptr;
+            JSONNodePrint(value);
+            ptr = ptr->next;
+            printf("%s", (ptr == NULL ? "" : ", "));
+        }
+        printf(" ]");
+        break;
+    }
     }
 }
 
 
 // Input
 
-JSONNode * g_Node;
+JSONNode * g_DrawNode = NULL;
+const char * g_DrawStr = "";
 
 void
-Draw(JSONNode * node, const char * str) {
+Draw(void) {
     vt100ClearScreen();
     vt100CursorHome();
     
-    printf("> %s\n\n", str);
+    if (g_DrawNode != NULL)
+        JSONNodePrint(g_DrawNode);
+
+    int v, h;
+    vt100GetScreenSize(&v, &h);
+    vt100CursorPos(v, 0);
+    printf("> %s", g_DrawStr);
+
+    vt100CursorPos(v, strlen(g_DrawStr) + 3);
+}
 
-    if (node != NULL)
-        JSONNodePrint(node);
+int
+GetChar() {
+    Draw();
+    int c = getch();
+    return c;
+}
+
+int
+PeekChar() {
+    int c = GetChar();
+    ungetch(c);
+    return c;
+}
 
-    vt100CursorPos(0, strlen(str) + 3);
+int
+GetInt() {
+    static char intStr[16];
+    int intStrLen = 0;
+    int result = 0;
+    int c;
+    g_DrawStr = intStr;
+    while ((c = GetChar()), (c != '\r') && (c != '\n')) {
+        if ((c == 8 || c == 127) && intStrLen > 0) {
+            intStrLen--;
+            intStr[intStrLen] = '\0';
+            result /= 10;
+        }
+        else if (intStrLen < 16 - 1 && (c >= '0' && c <= '9')) {
+            intStr[intStrLen++] = c;
+            intStr[intStrLen] = '\0';
+            result *= 10;
+            result += c - '0';
+        }
+    }
+    g_DrawStr = "";
+    return result;
 }
 
 char *
@@ -216,82 +323,81 @@ GetStr() {
     char * str = NEWARR(char, 16);
     int strLen = 0;
     int c;
-    while ((c = getch()), (c != '\r') && (c != '\n')) {
-        if (strLen < 16 - 1) {
+    g_DrawStr = str;
+    while ((c = GetChar()), (c != '\r') && (c != '\n')) {
+        if ((c == 8 || c == 127) && strLen > 0) {
+            strLen--;
+            str[strLen] = '\0';
+        }
+        else if (strLen < 16 - 1) {
             str[strLen++] = c;
             str[strLen] = '\0';
-            Draw(g_Node, str);
         }
     }
+    g_DrawStr = "";
     return str;
 }
 
 JSONNode *
 GetNode(JSONNode * parent) {
-    int c = getch();
+    int c = GetChar();
 
     JSONNode * result = JSONNodeNewNul();
     
     if (parent == NULL)
-        g_Node = result;
+        g_DrawNode = result;
 
     if (parent != NULL && result != NULL)
-        JSONNodeAppend(parent, result);
+        JSONNodePush(parent, result);
 
     switch (c) {
+    case 'i': {
+        result->kind = JSONNodeKind_Int;
+        result->data = (size_t)GetInt();
+        break;
+    }
     case 's': {
         result->kind = JSONNodeKind_Str;
-        Draw(g_Node, "");
         result->data = (size_t)GetStr();
-        Draw(g_Node, "");
         break;
     }
     case 'o': {
         result->kind = JSONNodeKind_Obj;
-        Draw(g_Node, "");
-        while ((c = peekch()), (c != '\r') && (c != '\n')) {
-            Draw(g_Node, "");
+        while ((c = PeekChar()), (c != '\r') && (c != '\n')) {
+            JSONNodePush(result, JSONNodeNewStr(GetStr()));
 
-            JSONNodeAppend(result, JSONNodeNewStr(GetStr()));
-            Draw(g_Node, "");
-
-            JSONNodeAppend(result, GetNode(result));
-            Draw(g_Node, "");
+            JSONNodePush(result, GetNode(result));
+        }
+        GetChar();
+        break;
+    }
+    case 'a': {
+        result->kind = JSONNodeKind_Arr;
+        while ((c = PeekChar()), (c != '\r') && (c != '\n')) {
+            JSONNodePush(result, GetNode(result));
         }
-        getch();
+        GetChar();
+        break;
     }
+    case 8:
+    case 127:
+        JSONNodePop(parent);
+        result = GetNode(parent);
+        break;
+    case 't':
+        result->kind = JSONNodeKind_Int;
+        result->data = (size_t)GetChar();
+        break;
     }
 
     return result;
 }
 
-JSONNode *
-TestNode() {
-    JSONNode * n = JSONNodeNewObj();
-    JSONNode * k1 = JSONNodeNewStr("key 1");
-    JSONNode * v1 = JSONNodeNewObj();
-    JSONNode * k11 = JSONNodeNewStr("key 11");
-    JSONNode * v11 = JSONNodeNewStr("val 11");
-    JSONNode * k12 = JSONNodeNewStr("key 12");
-    JSONNode * v12 = JSONNodeNewStr("val 12");
-    JSONNode * k2 = JSONNodeNewStr("key 2");
-    JSONNode * v2 = JSONNodeNewStr("val 2");
-
-    JSONNodeAppend(n, k1);
-    JSONNodeAppend(n, v1);
-    JSONNodeAppend(n, k2);
-    JSONNodeAppend(n, v2);
-
-    JSONNodeAppend(v1, k11);
-    JSONNodeAppend(v1, v11);
-    JSONNodeAppend(v1, k12);
-    JSONNodeAppend(v1, v12);
-
-    return n;
-}
+
+
 
 int main() {
-    Draw(NULL, "");
+    Draw();
 
     JSONNode * n = GetNode(NULL);
     //JSONNode * n = TestNode();
@@ -299,8 +405,9 @@ int main() {
     vt100ClearScreen();
     vt100CursorHome();
     JSONNodePrint(n);
+    printf("\n");
 
     // JSONFree(n);
 
     return 0;
-}
\ No newline at end of file
+}