X-Git-Url: https://gitweb.ps.run/iftint/blobdiff_plain/4889cf922e51c34f714941498d25588ceb258e67..refs/heads/StateParsing:/main2.c diff --git a/main2.c b/main2.c index 86cc7b7..c8b9023 100644 --- a/main2.c +++ b/main2.c @@ -14,6 +14,33 @@ #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'; +} +bool +isBackspace(char c) { + return c == 8 || c == 127; +} + + +// Key defines + +#define KEY_CTRL_C 3 +#define KEY_BACKSPACE1 8 +#define KEY_BACKSPACE2 127 + + // getch #ifdef _WIN32 @@ -112,6 +139,7 @@ typedef enum { JSONNodeKind_Int, JSONNodeKind_Str, JSONNodeKind_Obj, + JSONNodeKind_Key, JSONNodeKind_Arr, JSONNodeKind_COUNT } JSONNodeKind; @@ -121,80 +149,61 @@ 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; - } +JSONNode * +JSONNodeRemove(JSONNode * node) { + if (node->prev == NULL) { // first child + node->parent->firstChild = node->next; + if (node->next != NULL) + node->next->prev = NULL; + return node->parent; + } + else { // second child + node->prev->next = node->next; + if (node->next != NULL) + node->next->prev = node->prev; + return node->prev; } } +bool +JSONNodeEditable(JSONNode * node) { + if (node == NULL) return false; + else if (node->kind == JSONNodeKind_Int) return true; + else if (node->kind == JSONNodeKind_Str) return true; + return false; +} + void Indent(int indent) { for (int i = 0; i < indent; i++) @@ -210,6 +219,10 @@ JSONNodePrint(JSONNode * node, JSONNode * currNode) { if (node->parent == NULL) indent = 0; + if (currNode == node) { + vt100SaveCursor(); + } + switch (node->kind) { case JSONNodeKind_Nul: { printf("null"); @@ -227,43 +240,45 @@ JSONNodePrint(JSONNode * node, JSONNode * currNode) { } case JSONNodeKind_Obj: { printf("{\n"); - JSONNode * ptr = node->children; + JSONNode * ptr = node->firstChild; indent++; while (ptr != NULL) { - JSONNode * key = ptr; - JSONNode * value = ptr->next; Indent(indent); - JSONNodePrint(key, currNode); - printf(": "); - JSONNodePrint(value, currNode); + JSONNodePrint(ptr, currNode); + JSONNodePrint(ptr->firstChild, currNode); if (ptr->next != NULL) - ptr = ptr->next->next; - else - ptr = NULL; - printf("%s\n", (ptr == NULL ? "" : ",")); + printf(","); + ptr = ptr->next; + printf("\n"); } indent--; Indent(indent); printf("}"); break; } + case JSONNodeKind_Key: { + char * str = (char *)node->data; + printf("\"%s\": ", str == NULL ? "" : str); + break; + } case JSONNodeKind_Arr: { - printf("[ "); - JSONNode * ptr = node->children; + printf("[\n"); + JSONNode * ptr = node->firstChild; + indent++; while (ptr != NULL) { - JSONNode * value = ptr; - JSONNodePrint(value, currNode); + 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; } } - - if (currNode == node) { - vt100SaveCursor(); - } } @@ -303,94 +318,143 @@ 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, CharPredicateFunc charPredicate) { - node->data = (size_t)NEWARR(char, 16); - int strLen = 0; - - char * str = (char *)node->data; +GetInput(JSONNode * node, char c) { + if (node->data == (size_t)NULL) { + node->data = (size_t)NEWARR(char, 16); + } - int c; - while ((c = GetChar()), (c != '\r') && (c != '\n')) { - if ((c == 8 || c == 127) && strLen > 0) { - strLen--; - str[strLen] = '\0'; - } - else if (strLen < 16 - 1 && charPredicate(c, strLen)) { - str[strLen] = c; - strLen++; - str[strLen] = '\0'; - } + char * str = (char *)node->data; + int strLen = strlen(str); + + if (isBackspace(c)) { + str[strLen-1] = '\0'; + } + else if (strLen < 16 - 1) { + str[strLen] = c; + str[strLen+1] = '\0'; } } -void -GetNode(JSONNode * parent, JSONNode * node) { - int c = GetChar(); +JSONNode * +GetNode() { + JSONNode * result = NULL; + JSONNode * node = NULL; + int c; - g_CurrNode = node; + bool editingNode = false; - if (parent == NULL) - g_DrawNode = node; + while (true) { + Draw(); + c = getch(); - if (parent != NULL && node != NULL) - JSONNodePush(parent, node); + if (c == KEY_CTRL_C) + break; - 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; - while ((c = PeekChar()), (c != '\r') && (c != '\n')) { - JSONNode * newNode; - - newNode = JSONNodeNewStr(""); - g_CurrNode = newNode; - JSONNodePush(node, newNode); - GetStr(newNode, predStr); - - newNode = JSONNodeNewNul(); - JSONNodePush(node, newNode); - GetNode(node, newNode); + if (node == NULL) { + /**/ if (c == 'i') { node = JSONNodeNew(JSONNodeKind_Int); editingNode = true; } + else if (c == 's') { node = JSONNodeNew(JSONNodeKind_Str); editingNode = true; } + else if (c == 'o') { node = JSONNodeNew(JSONNodeKind_Obj); editingNode = true; } + else if (c == 'a') { node = JSONNodeNew(JSONNodeKind_Arr); editingNode = true; } + g_DrawNode = g_CurrNode = result = node; } - g_CurrNode = node; - getch(); - break; - } - case 'a': { - node->kind = JSONNodeKind_Arr; - while ((c = PeekChar()), (c != '\r') && (c != '\n')) { - JSONNode * newNode; - - newNode = JSONNodeNewNul(); - //g_CurrNode = newNode; - JSONNodePush(node, newNode); - GetNode(node, newNode); + else if (node->kind ==JSONNodeKind_Int) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + + g_CurrNode = node; + } + } + else if (node->kind ==JSONNodeKind_Str) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + + g_CurrNode = node; + } + } + else if (node->kind ==JSONNodeKind_Obj) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + + g_CurrNode = node; + } + } + else if (node->kind ==JSONNodeKind_Key) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + + g_CurrNode = node; + } + } + else if (node->kind ==JSONNodeKind_Arr) { + if (editingNode) { + GetInput(node, c); + } + else { + /**/ if (c == 'i' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Int)); editingNode = true; } + else if (c == 's' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Str)); editingNode = true; } + else if (c == 'o' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Obj)); editingNode = true; } + else if (c == 'a' && node->parent != NULL) { node = JSONNodePush(node->parent, JSONNodeNew(JSONNodeKind_Arr)); editingNode = true; } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; } + else if (c == ' ') { editingNode = true; } + else if (isBackspace(c)) { g_CurrNode = node = JSONNodeRemove(node); } + + g_CurrNode = node; + } } - g_CurrNode = node; - getch(); - break; - } - /* - case 8: - case 127: - JSONNodePop(parent); - JSONNode * newNode = JSONNodeNewNul(); - GetNode(parent, newNode); - break; - */ - case 't': - node->kind = JSONNodeKind_Int; - node->data = (size_t)GetChar(); - break; } + + return result; } @@ -399,20 +463,13 @@ GetNode(JSONNode * parent, JSONNode * node) { int main() { vt100EnableAlternateBuffer(); - Draw(); - - JSONNode * n = JSONNodeNewNul(); - GetNode(NULL, n); - //JSONNode * n = TestNode(); + JSONNode * n = GetNode(); + + vt100DisableAlternateBuffer(); - vt100ClearScreen(); - vt100CursorHome(); JSONNodePrint(n, NULL); - printf("\n"); // JSONFree(n); - - vt100DisableAlternateBuffer(); return 0; }