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 vt100GetScreenSize(int * v, int * h) {
83 CONSOLE_SCREEN_BUFFER_INFO csbi;
84 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
85 *h = csbi.srWindow.Right - csbi.srWindow.Left + 1;
86 *v = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
89 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
107 typedef struct JSONNode {
110 struct JSONNode * parent;
111 struct JSONNode * children;
112 struct JSONNode * next;
116 JSONNodeNew(JSONNodeKind kind, size_t data) {
117 JSONNode * result = NEW(JSONNode);
125 return JSONNodeNew(JSONNodeKind_Nul, (size_t)NULL);
129 JSONNodeNewInt(int i) {
130 return JSONNodeNew(JSONNodeKind_Int, (size_t)i);
134 JSONNodeNewStr(const char * str) {
135 return JSONNodeNew(JSONNodeKind_Str, (size_t)str);
140 return JSONNodeNew(JSONNodeKind_Obj, (size_t)NULL);
145 return JSONNodeNew(JSONNodeKind_Arr, (size_t)NULL);
149 JSONNodePush(JSONNode * this, JSONNode * that) {
150 if (this->children == NULL) {
151 this->children = that;
154 JSONNode * lastNode = this->children;
155 while (lastNode->next != NULL)
156 lastNode = lastNode->next;
157 lastNode->next = that;
166 JSONNodePop(JSONNode * this) {
168 JSONNode * ptr = this->children;
170 if (ptr == NULL) { // no children
171 JSONNodePop(this->parent);
173 else if (ptr->next == NULL) { // one child
174 this->children = NULL;
177 else { // more than one child
178 while (ptr->next->next != NULL)
187 for (int i = 0; i < indent; i++)
192 JSONNodePrint(JSONNode * node) {
197 if (node->parent == NULL)
200 switch (node->kind) {
201 case JSONNodeKind_Nul: {
205 case JSONNodeKind_Int: {
206 int i = (int)node->data;
210 case JSONNodeKind_Str: {
211 char * str = (char *)node->data;
212 printf("\"%s\"", str == NULL ? "" : str);
215 case JSONNodeKind_Obj: {
217 JSONNode * ptr = node->children;
219 while (ptr != NULL) {
220 char * key = (char *)ptr->data;
221 JSONNode * value = ptr->next;
223 printf("\"%s\": ", key);
224 JSONNodePrint(value);
225 if (ptr->next != NULL)
226 ptr = ptr->next->next;
229 printf("%s\n", (ptr == NULL ? "" : ","));
236 case JSONNodeKind_Arr: {
238 JSONNode * ptr = node->children;
239 while (ptr != NULL) {
240 JSONNode * value = ptr;
241 JSONNodePrint(value);
243 printf("%s", (ptr == NULL ? "" : ", "));
254 JSONNode * g_DrawNode = NULL;
255 const char * g_DrawStr = "";
262 if (g_DrawNode != NULL)
263 JSONNodePrint(g_DrawNode);
266 vt100GetScreenSize(&v, &h);
267 vt100CursorPos(v, 0);
268 printf("> %s", g_DrawStr);
270 vt100CursorPos(v, strlen(g_DrawStr) + 3);
288 GetInt(JSONNode * node) {
289 char intStr[16] = "";
292 size_t * i = &node->data;
296 while ((c = GetChar()), (c != '\r') && (c != '\n')) {
297 if ((c == 8 || c == 127) && intStrLen > 0) {
299 intStr[intStrLen] = '\0';
302 else if (intStrLen < 16 - 1 && (c >= '0' && c <= '9')) {
303 intStr[intStrLen++] = c;
304 intStr[intStrLen] = '\0';
313 GetStr(JSONNode * node) {
314 node->data = (size_t)NEWARR(char, 16);
317 char * str = (char *)node->data;
321 while ((c = GetChar()), (c != '\r') && (c != '\n')) {
322 if ((c == 8 || c == 127) && strLen > 0) {
326 else if (strLen < 16 - 1) {
335 GetNode(JSONNode * parent, JSONNode * node) {
338 JSONNode * result = node;
343 if (parent != NULL && result != NULL)
344 JSONNodePush(parent, result);
348 result->kind = JSONNodeKind_Int;
353 result->kind = JSONNodeKind_Str;
358 result->kind = JSONNodeKind_Obj;
359 while ((c = PeekChar()), (c != '\r') && (c != '\n')) {
362 newNode = JSONNodeNewStr("");
363 JSONNodePush(result, newNode);
366 newNode = JSONNodeNewNul();
367 JSONNodePush(result, newNode);
368 GetNode(result, newNode);
374 result->kind = JSONNodeKind_Arr;
375 while ((c = PeekChar()), (c != '\r') && (c != '\n')) {
376 JSONNode * newNode = JSONNodeNewNul();
377 JSONNodePush(result, newNode);
378 GetNode(result, newNode);
387 JSONNode * newNode = JSONNodeNewNul();
388 GetNode(parent, newNode);
392 result->kind = JSONNodeKind_Int;
393 result->data = (size_t)GetChar();
404 JSONNode * n = JSONNodeNewNul();
406 //JSONNode * n = TestNode();