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)))
26 /* reads from keypress, doesn't echo */
29 struct termios oldattr, newattr;
31 tcgetattr( STDIN_FILENO, &oldattr );
33 newattr.c_lflag &= ~( ICANON | ECHO );
34 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
36 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
40 /* reads from keypress, echoes */
43 struct termios oldattr, newattr;
45 tcgetattr( STDIN_FILENO, &oldattr );
47 newattr.c_lflag &= ~( ICANON );
48 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
50 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
57 struct termios oldattr, newattr;
58 tcgetattr( STDIN_FILENO, &oldattr );
60 newattr.c_lflag &= ~( ICANON | ECHO );
61 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
63 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
80 void vt100Escape(const char * str, ...) {
84 printf("%c", ASCII_ESC);
88 void vt100ClearScreen() { vt100Escape("[2J"); }
89 void vt100CursorHome() { vt100Escape("[H"); }
90 void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); }
91 void vt100SaveCursor() { vt100Escape("7"); }
92 void vt100RestoreCursor() { vt100Escape("8"); }
106 typedef struct JSONNode {
109 struct JSONNode * parent;
110 struct JSONNode * children;
111 struct JSONNode * next;
115 JSONNodeNew(JSONNodeKind kind, size_t data) {
116 JSONNode * result = NEW(JSONNode);
124 return JSONNodeNew(JSONNodeKind_Nul, (size_t)NULL);
128 JSONNodeNewInt(int i) {
129 return JSONNodeNew(JSONNodeKind_Int, (size_t)i);
133 JSONNodeNewStr(const char * str) {
134 return JSONNodeNew(JSONNodeKind_Str, (size_t)str);
139 return JSONNodeNew(JSONNodeKind_Obj, (size_t)NULL);
144 return JSONNodeNew(JSONNodeKind_Arr, (size_t)NULL);
148 JSONNodePush(JSONNode * this, JSONNode * that) {
149 if (this->children == NULL) {
150 this->children = that;
153 JSONNode * lastNode = this->children;
154 while (lastNode->next != NULL)
155 lastNode = lastNode->next;
156 lastNode->next = that;
165 JSONNodePop(JSONNode * this) {
167 JSONNode * ptr = this->children;
169 if (ptr == NULL) { // no children
170 JSONNodePop(this->parent);
172 else if (ptr->next == NULL) { // one child
173 this->children = NULL;
176 else { // more than one child
177 while (ptr->next->next != NULL)
186 for (int i = 0; i < indent; i++)
191 JSONNodePrint(JSONNode * node) {
196 if (node->parent == NULL)
199 switch (node->kind) {
200 case JSONNodeKind_Nul: {
204 case JSONNodeKind_Int: {
205 int i = (int)node->data;
209 case JSONNodeKind_Str: {
210 char * str = (char *)node->data;
211 printf("\"%s\"", str == NULL ? "" : str);
214 case JSONNodeKind_Obj: {
216 JSONNode * ptr = node->children;
218 while (ptr != NULL) {
219 char * key = (char *)ptr->data;
220 JSONNode * value = ptr->next;
222 printf("\"%s\": ", key);
223 JSONNodePrint(value);
224 if (ptr->next != NULL)
225 ptr = ptr->next->next;
228 printf("%s\n", (ptr == NULL ? "" : ","));
235 case JSONNodeKind_Arr: {
237 JSONNode * ptr = node->children;
238 while (ptr != NULL) {
239 JSONNode * value = ptr;
240 JSONNodePrint(value);
242 printf("%s", (ptr == NULL ? "" : ", "));
256 Draw(JSONNode * node, const char * str) {
260 printf("> %s\n\n", str);
265 vt100CursorPos(0, strlen(str) + 3);
270 static char intStr[16];
274 while ((c = getch()), (c != '\r') && (c != '\n')) {
275 if ((c == 8 || c == 127) && intStrLen > 0) {
277 intStr[intStrLen] = '\0';
279 Draw(g_Node, intStr);
281 else if (intStrLen < 16 - 1 && (c >= '0' && c <= '9')) {
282 intStr[intStrLen++] = c;
283 intStr[intStrLen] = '\0';
286 Draw(g_Node, intStr);
294 char * str = NEWARR(char, 16);
297 while ((c = getch()), (c != '\r') && (c != '\n')) {
298 if ((c == 8 || c == 127) && strLen > 0) {
303 else if (strLen < 16 - 1) {
313 GetNode(JSONNode * parent) {
316 JSONNode * result = JSONNodeNewNul();
321 if (parent != NULL && result != NULL)
322 JSONNodePush(parent, result);
326 result->kind = JSONNodeKind_Int;
328 result->data = (size_t)GetInt();
333 result->kind = JSONNodeKind_Str;
335 result->data = (size_t)GetStr();
340 result->kind = JSONNodeKind_Obj;
342 while ((c = peekch()), (c != '\r') && (c != '\n')) {
345 JSONNodePush(result, JSONNodeNewStr(GetStr()));
348 JSONNodePush(result, GetNode(result));
355 result->kind = JSONNodeKind_Arr;
357 while ((c = peekch()), (c != '\r') && (c != '\n')) {
360 JSONNodePush(result, GetNode(result));
370 result = GetNode(parent);
373 result->kind = JSONNodeKind_Int;
374 result->data = (size_t)getch();
383 JSONNode * n = JSONNodeNewObj();
384 JSONNode * k1 = JSONNodeNewStr("key 1");
385 JSONNode * v1 = JSONNodeNewObj();
386 JSONNode * k11 = JSONNodeNewStr("key 11");
387 JSONNode * v11 = JSONNodeNewStr("val 11");
388 JSONNode * k12 = JSONNodeNewStr("key 12");
389 JSONNode * v12 = JSONNodeNewStr("val 12");
390 JSONNode * k2 = JSONNodeNewStr("key 2");
391 JSONNode * v2 = JSONNodeNewStr("val 2");
398 JSONNodePush(v1, k11);
399 JSONNodePush(v1, v11);
400 JSONNodePush(v1, k12);
401 JSONNodePush(v1, v12);
409 JSONNode * n = GetNode(NULL);
410 //JSONNode * n = TestNode();