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';
39 #include <sys/ioctl.h>
44 /* reads from keypress, doesn't echo */
47 struct termios oldattr, newattr;
49 tcgetattr( STDIN_FILENO, &oldattr );
51 newattr.c_lflag &= ~( ICANON | ECHO ); // no ECHO for echo(?)
52 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
54 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
61 struct termios oldattr, newattr;
62 tcgetattr( STDIN_FILENO, &oldattr );
64 newattr.c_lflag &= ~( ICANON | ECHO );
65 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
67 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
84 void vt100Escape(const char * str, ...) {
88 printf("%c", ASCII_ESC);
92 void vt100ClearScreen() { vt100Escape("[2J"); }
93 void vt100CursorHome() { vt100Escape("[H"); }
94 void vt100CursorPos(int v, int h) { vt100Escape("[%d;%dH", v, h); }
95 void vt100SaveCursor() { vt100Escape("7"); }
96 void vt100RestoreCursor() { vt100Escape("8"); }
97 // void vt100GetCursor(int * v, int * h) {
102 // while ((c = getch()) != ';')
103 // *v = (10*(*v)+(c-'0'));
104 // while ((c = getch()) != 'R')
105 // *h = (10*(*h)+(c-'0'));
107 void vt100GetScreenSize(int * v, int * h) {
109 CONSOLE_SCREEN_BUFFER_INFO csbi;
110 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
111 *h = csbi.srWindow.Right - csbi.srWindow.Left + 1;
112 *v = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
115 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
120 void vt100EnableAlternateBuffer() { vt100Escape("[?1049h"); }
121 void vt100DisableAlternateBuffer() { vt100Escape("[?1049l"); }
136 typedef struct JSONNode {
139 struct JSONNode * parent;
140 struct JSONNode * firstChild;
142 struct JSONNode * prev;
143 struct JSONNode * next;
147 JSONNodeNew(JSONNodeKind kind) {
148 JSONNode * result = NEW(JSONNode);
154 JSONNodePush(JSONNode * this, JSONNode * that) {
155 if (this->firstChild == NULL) {
156 this->firstChild = that;
159 JSONNode * lastNode = this->firstChild;
160 while (lastNode->next != NULL)
161 lastNode = lastNode->next;
162 lastNode->next = that;
163 that->prev = lastNode;
173 for (int i = 0; i < indent; i++)
178 JSONNodePrint(JSONNode * node, JSONNode * currNode) {
183 if (node->parent == NULL)
186 if (currNode == node) {
190 switch (node->kind) {
191 case JSONNodeKind_Nul: {
195 case JSONNodeKind_Int: {
196 char * str = (char *)node->data;
197 printf("%s", (str == NULL || strlen(str) == 0) ? "0" : str);
200 case JSONNodeKind_Str: {
201 char * str = (char *)node->data;
202 printf("\"%s\"", str == NULL ? "" : str);
205 case JSONNodeKind_Obj: {
207 JSONNode * ptr = node->firstChild;
209 while (ptr != NULL) {
211 JSONNodePrint(ptr, currNode);
216 JSONNodePrint(ptr, currNode);
217 if (ptr->next != NULL)
228 case JSONNodeKind_Arr: {
230 JSONNode * ptr = node->firstChild;
232 while (ptr != NULL) {
234 JSONNodePrint(ptr, currNode);
235 if (ptr->next != NULL)
251 JSONNode * g_DrawNode = NULL;
252 JSONNode * g_CurrNode = NULL;
259 if (g_DrawNode != NULL) {
260 JSONNodePrint(g_DrawNode, g_CurrNode);
261 vt100RestoreCursor();
279 typedef bool(*CharPredicateFunc)(char, int);
281 bool predStr(char c, int i) { return c >= 'a' && c <= 'z'; }
282 bool predInt(char c, int i) { return c >= '0' && c <= '9'; }
285 GetStr(JSONNode * node, CharPredicateFunc charPredicate) {
286 node->data = (size_t)NEWARR(char, 16);
289 char * str = (char *)node->data;
292 while ((c = PeekChar()), ! isNewline(c)) {
294 if ((c == 8 || c == 127) && strLen > 0) {
298 else if (strLen < 16 - 1 && charPredicate(c, strLen)) {
308 JSONNode * result = NULL;
310 JSONNode * node = NULL;
313 if (isNewline(PeekChar())) {
316 if (node == NULL || node->parent == NULL)
326 if (node != NULL && node->kind == JSONNodeKind_Obj && node->childCount % 2 == 0) {
327 JSONNode * newNode = JSONNodeNew(JSONNodeKind_Str);
328 JSONNodePush(node, newNode);
333 GetStr(newNode, predStr);
340 if (! charInString(c, "isoa"))
343 JSONNode * newNode = JSONNodeNew(JSONNodeKind_Nul);
346 g_DrawNode = result = newNode;
349 JSONNodePush(node, newNode);
356 node->kind = JSONNodeKind_Int;
357 GetStr(node, predInt);
361 node->kind = JSONNodeKind_Str;
362 GetStr(node, predStr);
366 node->kind = JSONNodeKind_Obj;
370 node->kind = JSONNodeKind_Arr;
386 vt100EnableAlternateBuffer();
388 JSONNode * n = GetNode();
390 vt100DisableAlternateBuffer();
392 JSONNodePrint(n, NULL);