4 static uint TokenizeList(char * string, const uint maxTokens, const char seperator, char * tokens[])
9 bool quoted = false; //bool escaped = false;
12 for(; *string && count < maxTokens; string++)
21 else if(*string == '\"')
23 else if(*string == '{' || *string == '[' || *string == '(' || *string == '<')
25 else if(*string == '}' || *string == ']' || *string == ')' || *string == '>')
27 else if(*string == seperator && !level)
29 tokens[count++] = start;
34 if(start && count < maxTokens)
36 tokens[count++] = start;
42 // String Unescape Copy
43 // TOFIX: THIS DOESN'T HANDLE NUMERIC ESCAPE CODES (OCTAL/HEXADECIMAL...)?
44 // Seems very similar to ReadString in pass15.ec (which also misses numeric escape codes :) )
45 static void struscpy(char * d, char * s)
97 static char * StripBrackets(char * string)
99 int length = strlen(string);
100 if(length > 1 && *string == '[' && string[length - 1] == ']')
103 string[length - 1] = '\0';
110 static char * StripCurlies(char * string)
112 int length = strlen(string);
113 if(length > 1 && *string == '{' && string[length - 1] == '}')
116 string[length - 1] = '\0';
123 class TempListItem : struct
129 static bool TokenizeListItem(char * string, TempListItem item)
131 char * equal = strstr(string, "=");
145 class Output : struct
158 class Command : struct
169 outputs.Free(Output::Free);
173 /*class TreeStackItem : struct
180 class TagButton : public Button
185 class GDBDialog : Window
187 text = $"GDB Command";
188 background = formColor;
189 borderStyle = sizable;
202 this, direction = horizontal, gap = 0;
203 isActiveClient = true;
204 background = darkGray;//formColor
205 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
212 bg, this, gap = 4, margin = 4 ;
213 isActiveClient = true;
214 background = darkGray;
216 anchor = { top = 0, bottom = 0 };
221 PaneSplitter splitter
223 this, leftPane = leftCol, rightPane = rightCol, split = 200;
228 bg, this, gap = 4, margin = 4;
229 isActiveClient = true;
230 background = darkGray;
232 anchor = { top = 0, bottom = 0 };
237 Label lhistory { leftCol, this, position = { 4, 4 }, labeledWindow = history };
240 leftCol, this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true;
241 // selectionColor = unfocusedSelectorColor;
242 fullRowSelect = true, alwaysHighLight = true;
245 anchor = { left = leftCol.margin, right = leftCol.margin };
246 text = $"Command History";
248 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
252 lastCommand = (Command)row.tag;
253 command.contents = lastCommand.command;
260 Label commandLabel { rightCol, this, position = { 4, 4 }, labeledWindow = command };
263 rightCol, this, text = $"Command:", size = { 328, 19 }, anchor = { left = rightCol.margin, right = rightCol.margin };
265 bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
267 if((SmartKey)key == up || (SmartKey)key == down)
271 bool previous = ((SmartKey)key == up);
274 lastCommand = previous ? commands.last : commands.first;
276 lastCommand = previous ? lastCommand.prev : lastCommand.next;
280 command.contents = lastCommand.command;
284 lastCommand = previous ? commands.first : commands.last;
287 else if((SmartKey)key == enter)
288 OnCommand(command.contents);
295 rightCol, this, direction = horizontal, gap = 4;
296 isActiveClient = true;
297 background = darkGray;
299 anchor = { left = rightCol.margin, right = rightCol.margin };
302 TagButton infoLibs { toolBar, this, text = "libs", tag = "info shared", NotifyClicked = QuickCommandNotifyClicked; };
303 TagButton infoPaths { toolBar, this, text = "paths", tag = "-environment-path", NotifyClicked = QuickCommandNotifyClicked; };
304 TagButton infoWorkDir { toolBar, this, text = "wd", tag = "-environment-pwd", NotifyClicked = QuickCommandNotifyClicked; };
305 TagButton infoDirs { toolBar, this, text = "pths", tag = "-environment-directory", NotifyClicked = QuickCommandNotifyClicked; };
306 TagButton infoTemp { toolBar, this, text = "pths", tag = "-environment-temp", NotifyClicked = QuickCommandNotifyClicked; };
308 bool QuickCommandNotifyClicked(Button button, int x, int y, Modifiers mods)
310 TagButton tagButton = (TagButton)button;
311 OnCommand(tagButton.tag);
315 Label outputLabel { rightCol, this, position = { 4, 4 }, labeledWindow = output };
318 rightCol, this, text = $"Output:", multiLine = true, hasVertScroll = true, hasHorzScroll = true;
320 anchor = { left = rightCol.margin, right = rightCol.margin };
321 font = { panelFont.faceName, panelFont.size };
324 Label treeLabel { rightCol, this, position = { 4, 4 }, labeledWindow = tree };
327 rightCol, this, text = $"Tree:";
328 multiSelect = false, fullRowSelect = false, hasVertScroll = true, hasHorzScroll = true;
329 borderStyle = deep, collapseControl = true, treeBranches = true;
330 anchor = { left = rightCol.margin, right = rightCol.margin };
331 font = { panelFont.faceName, panelFont.size };
338 for(out = lastCommand.outputs.first; out; out = out.next)
340 output.AddS(out.output);
348 if(lastCommand && lastCommand.outputs.first)
352 int i, j, outTksCount, subTksCount;
353 char * outTokens[3200], * subTokens[3200];
354 DataRow root, frame, row;
355 TempListItem item { };
359 root = tree.AddString("Output");
361 for(out = lastCommand.outputs.first; out; out = out.next)
363 if(out.output && out.output[0])
365 t = CopyString(out.output);
371 outTksCount = TokenizeList(s, sizeof(outTokens) / sizeof(char *), ',', outTokens);
372 row = root.AddString(outTokens[0]);
373 if(!strcmp(outTokens[0], "^done"))
375 for(i = 1; i < outTksCount; i++)
377 if(TokenizeListItem(outTokens[i], item))
379 if(!strcmp(item.name, "bkpt"))
381 row = root.AddString(item.name);
382 item.value = StripCurlies(item.value);
383 subTksCount = TokenizeList(item.value, sizeof(subTokens) / sizeof(char *), ',', subTokens);
384 for(j = 0; j < subTksCount; j++)
386 if(TokenizeListItem(subTokens[j], item))
387 UpdateTreeValue(item, row);
389 row.AddString("Bad");
392 else if(!strcmp(item.name, "stack"))
394 row = root.AddString(item.name);
395 item.value = StripBrackets(item.value);
396 subTksCount = TokenizeList(item.value, sizeof(subTokens) / sizeof(char *), ',', subTokens);
397 for(j = 0; j < subTksCount; j++)
399 if(TokenizeListItem(subTokens[j], item))
401 frame = row.AddString(item.name);
402 if(!strcmp(item.name, "frame"))
403 UpdateTreeFrame(item, frame);
405 UpdateTreeValue(item, row);
408 row.AddString("Bad");
411 else if(!strcmp(item.name, "path"))
413 StripQuotes(item.value, item.value);
414 subTksCount = TokenizeList(item.value, sizeof(subTokens) / sizeof(char *), ':', subTokens);
415 for(j = 0; j < subTksCount; j++)
417 row = root.AddString(subTokens[j]);
421 UpdateTreeValue(item, row);
424 row.AddString("Bad");
427 else if(!strcmp(outTokens[0], "^running"))
430 row.AddString(outTokens[1]);
432 else if(!strcmp(outTokens[0], "^exit"))
435 row.AddString(outTokens[1]);
437 else if(!strcmp(outTokens[0], "^error"))
440 row.AddString(outTokens[1]);
444 row = row.AddString("Unknown output");
446 row.AddString(outTokens[1]);
450 outTksCount = TokenizeList(s, sizeof(outTokens) / sizeof(char *), ',', outTokens);
451 row = root.AddString(outTokens[0]);
453 row = root.AddString("Unknown status-async-output");
458 outTksCount = TokenizeList(s, sizeof(outTokens) / sizeof(char *), ',', outTokens);
459 row = root.AddString(outTokens[0]);
460 //if(!strcmp(outTokens[0], "=thread-group-created")) //=thread-group-created,id="7611"
461 //else if(!strcmp(outTokens[0], "=thread-created")) //=thread-created,id="1",group-id="7611"
462 //else if(!strcmp(outTokens[0], "=library-loaded")) //=library-loaded,id="/lib/ld-linux.so.2",target-name="/lib/ld-linux.so.2",host-name="/lib/ld-linux.so.2",symbols-loaded="0"
463 if(!strcmp(outTokens[0], "=thread-group-created") || !strcmp(outTokens[0], "=thread-created") || !strcmp(outTokens[0], "=library-loaded"))
465 for(i = 1; i < outTksCount; i++)
466 row.AddString(outTokens[i]);
470 row = root.AddString("Unknown notify-async-output");
475 outTksCount = TokenizeList(s, sizeof(outTokens) / sizeof(char *), ',', outTokens);
476 row = root.AddString(outTokens[0]);
477 if(!strcmp(outTokens[0], "*stopped"))
479 for(i = 1; i < outTksCount; i++)
481 if(TokenizeListItem(outTokens[i], item))
483 if(!strcmp(item.name, "frame"))
485 frame = row.AddString(item.name);
486 UpdateTreeFrame(item, frame);
488 UpdateTreeValue(item, row);
491 row.AddString("Bad");
496 row = root.AddString("Unknown exec-async-output");
498 row.AddString(outTokens[1]);
502 if(!strcmpi(s, "(gdb) "))
508 row = root.AddString("Unknown prompt");
515 if(TrimEscapedNewLineChar(s))
517 s = StripBrackets(s);
518 if(!strncmp(s, "Executable and object file path: ", 33))
521 outTksCount = TokenizeList(s, sizeof(outTokens) / sizeof(char *), ':', outTokens);
522 for(i = 0; i < outTksCount; i++)
524 row = root.AddString(outTokens[i]);
534 if(TrimEscapedNewLineChar(s))
541 row = root.AddString("Unknown output");
552 void UpdateTreeValue(TempListItem item, DataRow row)
555 StripQuotes(item.value, item.value);
556 string = new char[strlen(item.name) + strlen(item.value) + 3];
557 sprintf(string, "%s: %s", item.name, item.value);
558 row.AddString(string);
562 void UpdateTreeFrame(TempListItem item, DataRow frame)
564 int k, l, m, frameTksCount, argsTksCount, mTksCount;
565 char * frameTokens[3200], * argsTokens[3200], * mTokens[3200];
567 item.value = StripCurlies(item.value);
568 frameTksCount = TokenizeList(item.value, sizeof(frameTokens) / sizeof(char *), ',', frameTokens);
569 for(k = 0; k < frameTksCount; k++)
571 if(TokenizeListItem(frameTokens[k], item))
573 if(!strcmp(item.name, "level"))
576 StripQuotes(item.value, item.value);
577 string = new char[strlen(item.value) + strlen(frame.string) + 7];
578 // WTH do I need to do in order to print with leading zeros
579 sprintf(string, "%d %s", atoi(item.value), frame.string);
580 frame.string = string;
583 else if(!strcmp(item.name, "addr"))
586 StripQuotes(item.value, item.value);
587 string = new char[strlen(item.value) + strlen(frame.string) + 4];
588 sprintf(string, "%s (%s)", frame.string, item.value);
589 frame.string = string;
592 else if(!strcmp(item.name, "args"))
595 args = frame.AddString("args");
596 item.value = StripBrackets(item.value);
597 argsTksCount = TokenizeList(item.value, sizeof(argsTokens) / sizeof(char *), ',', argsTokens);
598 for(l = 0; l < argsTksCount; l++)
600 arg = args.AddString("arg");
601 argsTokens[l] = StripCurlies(argsTokens[l]);
602 mTksCount = TokenizeList(argsTokens[l], sizeof(mTokens) / sizeof(char *), ',', mTokens);
603 for(m = 0; m < mTksCount; m++)
605 if(TokenizeListItem(mTokens[m], item))
607 if(!strcmp(item.name, "name"))
610 StripQuotes(item.value, item.value);
611 string = new char[strlen(arg.string) + strlen(item.value) + 2];
612 sprintf(string, "%s %s", arg.string, item.value);
616 else if(!strcmp(item.name, "value"))
619 StripQuotes(item.value, item.value);
620 string = new char[strlen(arg.string) + strlen(item.value) + 4];
621 sprintf(string, "%s = %s", arg.string, item.value);
626 UpdateTreeValue(item, args);
629 frame.AddString("Bad");
634 UpdateTreeValue(item, frame);
637 frame.AddString("Bad");
641 int TrimEscapedNewLineChar(char * s)
644 if(s[len - 1] == 'n' && s[len - 2] == '\\')
652 void AddCommand(char * string)
654 if(string && strlen(string))
656 Command cmd = Command { command = CopyString(string) };
658 history.AddString(string).tag = (uint64)cmd;
659 lastCommand = commands.last;
663 command.contents = string;
669 void AddOutput(char * string)
671 if(string && strlen(string))
673 Command last = commands.last;
676 last.outputs.Add(Output { output = CopyString(string) });
677 if(last == lastCommand)
683 virtual void OnCommand(char * string);
697 command.contents = lastCommand.command;
705 commands.Free(Command::Free);