X-Git-Url: https://gitweb.ps.run/iftint/blobdiff_plain/9622a59a303d6862ad5f2c141941c2986366ca9a..HEAD:/main2.c diff --git a/main2.c b/main2.c index 657fd0e..3dcbf84 100644 --- a/main2.c +++ b/main2.c @@ -28,6 +28,17 @@ 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 @@ -168,6 +179,30 @@ JSONNodePush(JSONNode * this, JSONNode * that) { return that; } +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++) @@ -209,15 +244,11 @@ JSONNodePrint(JSONNode * node, JSONNode * currNode) { while (ptr != NULL) { Indent(indent); JSONNodePrint(ptr, currNode); + printf(": "); + JSONNodePrint(ptr->firstChild, currNode); + if (ptr->next != NULL) + printf(","); ptr = ptr->next; - - if (ptr != NULL) { - printf(": "); - JSONNodePrint(ptr, currNode); - if (ptr->next != NULL) - printf(","); - ptr = ptr->next; - } printf("\n"); } indent--; @@ -281,98 +312,93 @@ 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, CharPredicateFunc charPredicate) { - node->data = (size_t)NEWARR(char, 16); - int strLen = 0; - - char * str = (char *)node->data; - - int c; - while ((c = PeekChar()), ! isNewline(c)) { - getch(); - 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'; - } - } -} - JSONNode * GetNode() { JSONNode * result = NULL; - JSONNode * node = NULL; + int c; + int strLen = 0; + + typedef enum { + InputState_Initial, + InputState_Primitive, + InputState_Object, + InputState_KeyValue, + InputState_Array, + } InputState; + InputState inputState; + + bool editingNode = false; while (true) { - if (isNewline(PeekChar())) { - getch(); + c = GetChar(); + if (c == KEY_CTRL_C) + break; + + if (isNewline(c)) { if (node == NULL || node->parent == NULL) break; - - node = node->parent; - g_CurrNode = node; - - continue; - } - - // 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; + if (node->parent->kind == JSONNodeKind_Obj) // editing obj key + g_CurrNode = node = node->firstChild; + else if (node->parent->kind == JSONNodeKind_Str) // editing obj value + g_CurrNode = node = node->parent->parent; + else + g_CurrNode = node = node->parent; - GetStr(newNode, predStr); + editingNode = JSONNodeEditable(node); continue; } - - int c = GetChar(); - if (! charInString(c, "isoa")) - continue; + if (JSONNodeEditable(node) && editingNode) { + if (node->data == (size_t)NULL) { + node->data = (size_t)NEWARR(char, 16); + strLen = 0; + } + char * str = (char *)node->data; - 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; + if (isBackspace(c)) { + str[strLen-1] = '\0'; + strLen--; + } + else if (strLen < 16 - 1) { + str[strLen] = c; + str[strLen+1] = '\0'; + strLen++; + } } - case 8: - case 127: - break; + else { + JSONNode * old = node; + + /**/ 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); } + else if (c == 'a') { node = JSONNodeNew(JSONNodeKind_Arr); } + else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; continue; } + else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; continue; } + else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; continue; } + else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; continue; } + else if (c == ' ') { if (JSONNodeEditable(node)) editingNode = true; continue; } + else if (isBackspace(c) && node != NULL) { g_CurrNode = node = JSONNodeRemove(node); continue; } + else { continue; } + + if (old != NULL) { + // new node was added to an object + if (old->kind == JSONNodeKind_Obj) { + JSONNode * keyNode = JSONNodeNew(JSONNodeKind_Str); + JSONNodePush(keyNode, node); + node = keyNode; + editingNode = true; + } + JSONNodePush(old, node); + } + else { + g_DrawNode = result = node; + } + + g_CurrNode = node; } }