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)))
23 #include <sys/ioctl.h>
28 /* reads from keypress, doesn't echo */
31 struct termios oldattr, newattr;
33 tcgetattr( STDIN_FILENO, &oldattr );
35 newattr.c_lflag &= ~( ICANON | ECHO ); // no ECHO for echo(?)
36 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
38 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
45 struct termios oldattr, newattr;
46 tcgetattr( STDIN_FILENO, &oldattr );
48 newattr.c_lflag &= ~( ICANON | ECHO );
49 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
51 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
68 void vt100Escape(const char * str, ...) {
72 printf("%c", ASCII_ESC);
76 void vt100ClearScreen() { vt100Escape("[2J"); }
77 void vt100CursorHome() { vt100Escape("[H"); }
78 void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); }
79 void vt100SaveCursor() { vt100Escape("7"); }
80 void vt100RestoreCursor() { vt100Escape("8"); }
81 void vt100GetCursor(int * v, int * h) {
86 while ((c = getch()) != ';')
87 *v = (10*(*v)+(c-'0'));
88 while ((c = getch()) != 'R')
89 *h = (10*(*h)+(c-'0'));
91 void vt100GetScreenSize(int * v, int * h) {
93 CONSOLE_SCREEN_BUFFER_INFO csbi;
94 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
95 *h = csbi.srWindow.Right - csbi.srWindow.Left + 1;
96 *v = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
99 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
104 void vt100EnableAlternateBuffer() { vt100Escape("[?1049h"); }
105 void vt100DisableAlternateBuffer() { vt100Escape("[?1049l"); }
120 typedef struct JSONNode {
123 struct JSONNode * parent;
124 struct JSONNode * children;
125 struct JSONNode * next;
129 JSONNodeNew(JSONNodeKind kind, size_t data) {
130 JSONNode * result = NEW(JSONNode);
138 return JSONNodeNew(JSONNodeKind_Nul, (size_t)NULL);
142 JSONNodeNewInt(int i) {
143 return JSONNodeNew(JSONNodeKind_Int, (size_t)i);
147 JSONNodeNewStr(const char * str) {
148 return JSONNodeNew(JSONNodeKind_Str, (size_t)str);
153 return JSONNodeNew(JSONNodeKind_Obj, (size_t)NULL);
158 return JSONNodeNew(JSONNodeKind_Arr, (size_t)NULL);
162 JSONNodePush(JSONNode * this, JSONNode * that) {
163 if (this->children == NULL) {
164 this->children = that;
167 JSONNode * lastNode = this->children;
168 while (lastNode->next != NULL)
169 lastNode = lastNode->next;
170 lastNode->next = that;
179 JSONNodePop(JSONNode * this) {
181 JSONNode * ptr = this->children;
183 if (ptr == NULL) { // no children
184 JSONNodePop(this->parent);
186 else if (ptr->next == NULL) { // one child
187 this->children = NULL;
190 else { // more than one child
191 while (ptr->next->next != NULL)
200 for (int i = 0; i < indent; i++)
204 static int currV = 0;
205 static int currH = 0;
208 JSONNodePrint(JSONNode * node, JSONNode * currNode) {
213 if (node->parent == NULL)
216 switch (node->kind) {
217 case JSONNodeKind_Nul: {
221 case JSONNodeKind_Int: {
222 int i = (int)node->data;
226 case JSONNodeKind_Str: {
227 char * str = (char *)node->data;
228 printf("\"%s\"", str == NULL ? "" : str);
231 case JSONNodeKind_Obj: {
233 JSONNode * ptr = node->children;
235 while (ptr != NULL) {
236 char * key = (char *)ptr->data;
237 JSONNode * value = ptr->next;
239 printf("\"%s\": ", key);
240 JSONNodePrint(value, currNode);
241 if (ptr->next != NULL)
242 ptr = ptr->next->next;
245 printf("%s\n", (ptr == NULL ? "" : ","));
252 case JSONNodeKind_Arr: {
254 JSONNode * ptr = node->children;
255 while (ptr != NULL) {
256 JSONNode * value = ptr;
257 JSONNodePrint(value, currNode);
259 printf("%s", (ptr == NULL ? "" : ", "));
266 if (currNode == node) {
267 int currOffsets[JSONNodeKind_COUNT];
268 currOffsets[JSONNodeKind_Nul] = 0;
269 currOffsets[JSONNodeKind_Int] = 0;
270 currOffsets[JSONNodeKind_Str] = 1;
271 currOffsets[JSONNodeKind_Obj] = 1;
272 currOffsets[JSONNodeKind_Arr] = 2;
273 vt100GetCursor(&currV, &currH);
274 currH -= currOffsets[node->kind];
281 JSONNode * g_DrawNode = NULL;
282 JSONNode * g_CurrNode = NULL;
289 if (g_DrawNode != NULL) {
290 JSONNodePrint(g_DrawNode, g_CurrNode);
291 vt100CursorPos(currV, currH);
310 GetInt(JSONNode * node) {
311 char intStr[16] = "";
314 size_t * i = &node->data;
317 while ((c = GetChar()), (c != '\r') && (c != '\n')) {
318 if ((c == 8 || c == 127) && intStrLen > 0) {
320 intStr[intStrLen] = '\0';
323 else if (intStrLen < 16 - 1 && (c >= '0' && c <= '9')) {
324 intStr[intStrLen++] = c;
325 intStr[intStrLen] = '\0';
333 GetStr(JSONNode * node) {
334 node->data = (size_t)NEWARR(char, 16);
337 char * str = (char *)node->data;
340 while ((c = GetChar()), (c != '\r') && (c != '\n')) {
341 if ((c == 8 || c == 127) && strLen > 0) {
345 else if (strLen < 16 - 1) {
354 GetNode(JSONNode * parent, JSONNode * node) {
357 JSONNode * result = node;
363 if (parent != NULL && result != NULL)
364 JSONNodePush(parent, result);
368 result->kind = JSONNodeKind_Int;
373 result->kind = JSONNodeKind_Str;
378 result->kind = JSONNodeKind_Obj;
379 while ((c = PeekChar()), (c != '\r') && (c != '\n')) {
382 newNode = JSONNodeNewStr("");
383 g_CurrNode = newNode;
384 JSONNodePush(result, newNode);
387 newNode = JSONNodeNewNul();
388 JSONNodePush(result, newNode);
389 GetNode(result, newNode);
396 result->kind = JSONNodeKind_Arr;
397 while ((c = PeekChar()), (c != '\r') && (c != '\n')) {
398 JSONNode * newNode = JSONNodeNewNul();
399 g_CurrNode = newNode;
400 JSONNodePush(result, newNode);
401 GetNode(result, newNode);
411 JSONNode * newNode = JSONNodeNewNul();
412 GetNode(parent, newNode);
416 result->kind = JSONNodeKind_Int;
417 result->data = (size_t)GetChar();
426 vt100EnableAlternateBuffer();
430 JSONNode * n = JSONNodeNewNul();
432 //JSONNode * n = TestNode();
436 JSONNodePrint(n, NULL);
441 vt100DisableAlternateBuffer();