X-Git-Url: https://gitweb.ps.run/iftint/blobdiff_plain/7915eed596265bb03d9fc01eec6dd39015b01188..9622a59a303d6862ad5f2c141941c2986366ca9a:/main2.c diff --git a/main2.c b/main2.c index 96aba10..657fd0e 100644 --- a/main2.c +++ b/main2.c @@ -14,6 +14,22 @@ #define NEWARR(TYPE, NUM) ((TYPE *)calloc(NUM, sizeof(TYPE))) +// Util + +bool +charInString(char c, const char * str) { + for (int i = 0; i < strlen(str); i++) + if (c == str[i]) + return true; + return false; +} + +bool +isNewline(char c) { + return c == '\n' || c == '\r'; +} + + // getch #ifdef _WIN32 @@ -78,6 +94,16 @@ void vt100CursorHome() { vt100Escape("[H"); } void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); } void vt100SaveCursor() { vt100Escape("7"); } void vt100RestoreCursor() { vt100Escape("8"); } +// void vt100GetCursor(int * v, int * h) { +// *v = *h = 0; +// printf("\033[6n"); +// getch(); getch(); +// int c; +// while ((c = getch()) != ';') +// *v = (10*(*v)+(c-'0')); +// while ((c = getch()) != 'R') +// *h = (10*(*h)+(c-'0')); +// } void vt100GetScreenSize(int * v, int * h) { #ifdef _WIN32 CONSOLE_SCREEN_BUFFER_INFO csbi; @@ -91,6 +117,8 @@ void vt100GetScreenSize(int * v, int * h) { *v = w.ws_col; #endif } +void vt100EnableAlternateBuffer() { vt100Escape("[?1049h"); } +void vt100DisableAlternateBuffer() { vt100Escape("[?1049l"); } // JSON @@ -101,6 +129,7 @@ typedef enum { JSONNodeKind_Str, JSONNodeKind_Obj, JSONNodeKind_Arr, + JSONNodeKind_COUNT } JSONNodeKind; struct JSONNode; @@ -108,80 +137,37 @@ typedef struct JSONNode { JSONNodeKind kind; size_t data; struct JSONNode * parent; - struct JSONNode * children; + struct JSONNode * firstChild; + int childCount; + struct JSONNode * prev; struct JSONNode * next; } JSONNode; JSONNode * -JSONNodeNew(JSONNodeKind kind, size_t data) { +JSONNodeNew(JSONNodeKind kind) { JSONNode * result = NEW(JSONNode); result->kind = kind; - result->data = 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); -} - -JSONNode * -JSONNodeNewObj() { - return JSONNodeNew(JSONNodeKind_Obj, (size_t)NULL); -} - -JSONNode * -JSONNodeNewArr() { - return JSONNodeNew(JSONNodeKind_Arr, (size_t)NULL); -} - JSONNode * JSONNodePush(JSONNode * this, JSONNode * that) { - if (this->children == NULL) { - this->children = that; + if (this->firstChild == NULL) { + this->firstChild = that; } else { - JSONNode * lastNode = this->children; + JSONNode * lastNode = this->firstChild; while (lastNode->next != NULL) lastNode = lastNode->next; lastNode->next = that; + that->prev = lastNode; } + this->childCount++; that->parent = this; - that->next = NULL; 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++) @@ -189,22 +175,26 @@ Indent(int indent) { } void -JSONNodePrint(JSONNode * node) { +JSONNodePrint(JSONNode * node, JSONNode * currNode) { if (node == NULL) return; static int indent; if (node->parent == NULL) indent = 0; - + + if (currNode == node) { + vt100SaveCursor(); + } + switch (node->kind) { case JSONNodeKind_Nul: { printf("null"); break; } case JSONNodeKind_Int: { - int i = (int)node->data; - printf("%d", i); + char * str = (char *)node->data; + printf("%s", (str == NULL || strlen(str) == 0) ? "0" : str); break; } case JSONNodeKind_Str: { @@ -214,19 +204,21 @@ JSONNodePrint(JSONNode * node) { } case JSONNodeKind_Obj: { printf("{\n"); - JSONNode * ptr = node->children; + JSONNode * ptr = node->firstChild; indent++; while (ptr != NULL) { - char * key = (char *)ptr->data; - JSONNode * value = ptr->next; Indent(indent); - printf("\"%s\": ", key); - JSONNodePrint(value); - if (ptr->next != NULL) - ptr = ptr->next->next; - else - ptr = NULL; - printf("%s\n", (ptr == NULL ? "" : ",")); + JSONNodePrint(ptr, currNode); + ptr = ptr->next; + + if (ptr != NULL) { + printf(": "); + JSONNodePrint(ptr, currNode); + if (ptr->next != NULL) + printf(","); + ptr = ptr->next; + } + printf("\n"); } indent--; Indent(indent); @@ -234,15 +226,20 @@ JSONNodePrint(JSONNode * node) { break; } case JSONNodeKind_Arr: { - printf("[ "); - JSONNode * ptr = node->children; + printf("[\n"); + JSONNode * ptr = node->firstChild; + indent++; while (ptr != NULL) { - JSONNode * value = ptr; - JSONNodePrint(value); + Indent(indent); + JSONNodePrint(ptr, currNode); + if (ptr->next != NULL) + printf(","); + printf("\n"); ptr = ptr->next; - printf("%s", (ptr == NULL ? "" : ", ")); } - printf(" ]"); + indent--; + Indent(indent); + printf("]"); break; } } @@ -252,22 +249,17 @@ JSONNodePrint(JSONNode * node) { // Input JSONNode * g_DrawNode = NULL; -const char * g_DrawStr = ""; +JSONNode * g_CurrNode = NULL; void Draw(void) { vt100ClearScreen(); vt100CursorHome(); - 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 (g_DrawNode != NULL) { + JSONNodePrint(g_DrawNode, g_CurrNode); + vt100RestoreCursor(); + } } int @@ -284,131 +276,120 @@ PeekChar() { return c; } -void -GetInt(JSONNode * node) { - char intStr[16] = ""; - int intStrLen = 0; - - size_t * i = &node->data; - - int c; - g_DrawStr = intStr; - while ((c = GetChar()), (c != '\r') && (c != '\n')) { - if ((c == 8 || c == 127) && intStrLen > 0) { - intStrLen--; - intStr[intStrLen] = '\0'; - *i /= 10; - } - else if (intStrLen < 16 - 1 && (c >= '0' && c <= '9')) { - intStr[intStrLen++] = c; - intStr[intStrLen] = '\0'; - *i *= 10; - *i += c - '0'; - } - } - g_DrawStr = ""; -} +typedef bool(*CharPredicateFunc)(char, int); + +bool predStr(char c, int i) { return c >= 'a' && c <= 'z'; } +bool predInt(char c, int i) { return c >= '0' && c <= '9'; } void -GetStr(JSONNode * node) { +GetStr(JSONNode * node, CharPredicateFunc charPredicate) { node->data = (size_t)NEWARR(char, 16); int strLen = 0; char * str = (char *)node->data; int c; - g_DrawStr = str; - while ((c = GetChar()), (c != '\r') && (c != '\n')) { + while ((c = PeekChar()), ! isNewline(c)) { + getch(); if ((c == 8 || c == 127) && strLen > 0) { strLen--; str[strLen] = '\0'; } - else if (strLen < 16 - 1) { - str[strLen++] = c; + else if (strLen < 16 - 1 && charPredicate(c, strLen)) { + str[strLen] = c; + strLen++; str[strLen] = '\0'; } } - g_DrawStr = ""; } -void -GetNode(JSONNode * parent, JSONNode * node) { - int c = GetChar(); +JSONNode * +GetNode() { + JSONNode * result = NULL; - JSONNode * result = node; + JSONNode * node = NULL; - if (parent == NULL) - g_DrawNode = result; + while (true) { + if (isNewline(PeekChar())) { + getch(); - if (parent != NULL && result != NULL) - JSONNodePush(parent, result); + if (node == NULL || node->parent == NULL) + break; + + node = node->parent; + g_CurrNode = node; - switch (c) { - case 'i': { - result->kind = JSONNodeKind_Int; - GetInt(result); - break; - } - case 's': { - result->kind = JSONNodeKind_Str; - GetStr(result); - break; - } - case 'o': { - result->kind = JSONNodeKind_Obj; - while ((c = PeekChar()), (c != '\r') && (c != '\n')) { - JSONNode * newNode; - - newNode = JSONNodeNewStr(""); - JSONNodePush(result, newNode); - GetStr(newNode); - - newNode = JSONNodeNewNul(); - JSONNodePush(result, newNode); - GetNode(result, newNode); + continue; } - GetChar(); - break; - } - case 'a': { - result->kind = JSONNodeKind_Arr; - while ((c = PeekChar()), (c != '\r') && (c != '\n')) { - JSONNode * newNode = JSONNodeNewNul(); - JSONNodePush(result, newNode); - GetNode(result, newNode); + + // object key + if (node != NULL && node->kind == JSONNodeKind_Obj && node->childCount % 2 == 0) { + JSONNode * newNode = JSONNodeNew(JSONNodeKind_Str); + JSONNodePush(node, newNode); + + node = newNode; + g_CurrNode = node; + + GetStr(newNode, predStr); + + continue; + } + + int c = GetChar(); + + if (! charInString(c, "isoa")) + continue; + + JSONNode * newNode = JSONNodeNew(JSONNodeKind_Nul); + + if (result == NULL) + g_DrawNode = result = newNode; + + if (node != NULL) + JSONNodePush(node, newNode); + + node = newNode; + g_CurrNode = node; + + switch (c) { + case 'i': { + node->kind = JSONNodeKind_Int; + GetStr(node, predInt); + break; + } + case 's': { + node->kind = JSONNodeKind_Str; + GetStr(node, predStr); + break; + } + case 'o': { + node->kind = JSONNodeKind_Obj; + break; + } + case 'a': { + node->kind = JSONNodeKind_Arr; + break; + } + case 8: + case 127: + break; } - GetChar(); - break; - } - /* - case 8: - case 127: - JSONNodePop(parent); - JSONNode * newNode = JSONNodeNewNul(); - GetNode(parent, newNode); - break; - */ - case 't': - result->kind = JSONNodeKind_Int; - result->data = (size_t)GetChar(); - break; } + + return result; } int main() { - Draw(); + vt100EnableAlternateBuffer(); - JSONNode * n = JSONNodeNewNul(); - GetNode(NULL, n); - //JSONNode * n = TestNode(); + JSONNode * n = GetNode(); + + vt100DisableAlternateBuffer(); - vt100ClearScreen(); - vt100CursorHome(); - JSONNodePrint(n); - printf("\n"); + JSONNodePrint(n, NULL); // JSONFree(n);