8 - whitelist input on GetStr/GetInt
13 #define NEW(TYPE) ((TYPE *)calloc(1, sizeof(TYPE)))
14 #define NEWARR(TYPE, NUM) ((TYPE *)calloc(NUM, sizeof(TYPE)))
20 charInString(char c, const char * str) {
21 for (int i = 0; i < strlen(str); i++)
29 return c == '\n' || c == '\r';
33 return c == 8 || c == 127;
43 #include <sys/ioctl.h>
48 /* reads from keypress, doesn't echo */
51 struct termios oldattr, newattr;
53 tcgetattr( STDIN_FILENO, &oldattr );
55 newattr.c_lflag &= ~( ICANON | ECHO ); // no ECHO for echo(?)
56 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
58 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
65 struct termios oldattr, newattr;
66 tcgetattr( STDIN_FILENO, &oldattr );
68 newattr.c_lflag &= ~( ICANON | ECHO );
69 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
71 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
88 void vt100Escape(const char * str, ...) {
92 printf("%c", ASCII_ESC);
96 void vt100ClearScreen() { vt100Escape("[2J"); }
97 void vt100CursorHome() { vt100Escape("[H"); }
98 void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); }
99 void vt100SaveCursor() { vt100Escape("7"); }
100 void vt100RestoreCursor() { vt100Escape("8"); }
101 // void vt100GetCursor(int * v, int * h) {
103 // printf("\033[6n");
106 // while ((c = getch()) != ';')
107 // *v = (10*(*v)+(c-'0'));
108 // while ((c = getch()) != 'R')
109 // *h = (10*(*h)+(c-'0'));
111 void vt100GetScreenSize(int * v, int * h) {
113 CONSOLE_SCREEN_BUFFER_INFO csbi;
114 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
115 *h = csbi.srWindow.Right - csbi.srWindow.Left + 1;
116 *v = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
119 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
124 void vt100EnableAlternateBuffer() { vt100Escape("[?1049h"); }
125 void vt100DisableAlternateBuffer() { vt100Escape("[?1049l"); }
140 typedef struct JSONNode {
143 struct JSONNode * parent;
144 struct JSONNode * firstChild;
146 struct JSONNode * prev;
147 struct JSONNode * next;
151 JSONNodeNew(JSONNodeKind kind) {
152 JSONNode * result = NEW(JSONNode);
158 JSONNodePush(JSONNode * this, JSONNode * that) {
159 if (this->firstChild == NULL) {
160 this->firstChild = that;
163 JSONNode * lastNode = this->firstChild;
164 while (lastNode->next != NULL)
165 lastNode = lastNode->next;
166 lastNode->next = that;
167 that->prev = lastNode;
176 JSONNodeRemove(JSONNode * node) {
177 if (node->prev == NULL) { // first child
178 node->parent->firstChild = node->next;
179 if (node->next != NULL)
180 node->next->prev = NULL;
183 else { // second child
184 node->prev->next = node->next;
185 if (node->next != NULL)
186 node->next->prev = node->prev;
193 for (int i = 0; i < indent; i++)
198 JSONNodePrint(JSONNode * node, JSONNode * currNode) {
203 if (node->parent == NULL)
206 if (currNode == node) {
210 switch (node->kind) {
211 case JSONNodeKind_Nul: {
215 case JSONNodeKind_Int: {
216 char * str = (char *)node->data;
217 printf("%s", (str == NULL || strlen(str) == 0) ? "0" : str);
220 case JSONNodeKind_Str: {
221 char * str = (char *)node->data;
222 printf("\"%s\"", str == NULL ? "" : str);
225 case JSONNodeKind_Obj: {
227 JSONNode * ptr = node->firstChild;
229 while (ptr != NULL) {
231 JSONNodePrint(ptr, currNode);
236 JSONNodePrint(ptr, currNode);
237 if (ptr->next != NULL)
248 case JSONNodeKind_Arr: {
250 JSONNode * ptr = node->firstChild;
252 while (ptr != NULL) {
254 JSONNodePrint(ptr, currNode);
255 if (ptr->next != NULL)
271 JSONNode * g_DrawNode = NULL;
272 JSONNode * g_CurrNode = NULL;
279 if (g_DrawNode != NULL) {
280 JSONNodePrint(g_DrawNode, g_CurrNode);
281 vt100RestoreCursor();
299 typedef bool(*CharPredicateFunc)(char, int);
301 bool predStr(char c, int i) { return c >= 'a' && c <= 'z'; }
302 bool predInt(char c, int i) { return c >= '0' && c <= '9'; }
306 JSONNode * result = NULL;
307 JSONNode * node = NULL;
311 bool editingNode = false;
320 if (node == NULL || node->parent == NULL)
324 g_CurrNode = node = node->parent;
330 JSONNode * old = node;
332 /**/ if (c == 'i') { node = JSONNodeNew(JSONNodeKind_Int); editingNode = true; }
333 else if (c == 's') { node = JSONNodeNew(JSONNodeKind_Str); editingNode = true; }
334 else if (c == 'o') { node = JSONNodeNew(JSONNodeKind_Obj); }
335 else if (c == 'a') { node = JSONNodeNew(JSONNodeKind_Arr); }
336 else if (isBackspace(c) && node != NULL) {
337 g_CurrNode = node = JSONNodeRemove(node);
340 else if (c == 'h') { if (node->prev != NULL) g_CurrNode = node = node->prev; continue; }
341 else if (c == 'l') { if (node->next != NULL) g_CurrNode = node = node->next; continue; }
342 else if (c == 'k') { if (node->parent != NULL) g_CurrNode = node = node->parent; continue; }
343 else if (c == 'j') { if (node->firstChild != NULL) g_CurrNode = node = node->firstChild; continue; }
349 JSONNodePush(old, node);
351 g_DrawNode = result = node;
354 if (node->data == (size_t)NULL) {
355 node->data = (size_t)NEWARR(char, 16);
358 char * str = (char *)node->data;
360 if (isBackspace(c)) {
361 str[strLen-1] = '\0';
364 else if (strLen < 16 - 1) {
366 str[strLen+1] = '\0';
379 vt100EnableAlternateBuffer();
381 JSONNode * n = GetNode();
383 vt100DisableAlternateBuffer();
385 JSONNodePrint(n, NULL);