From 75a9d5aa986332f7a0385970c5501b67a6da8c24 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 23 May 2023 19:22:26 -0500 Subject: [PATCH] Start of warning and error parsing. --- embedded/gitignore | 4 ++ include/utils.h | 3 +- src/editor.c | 4 +- src/messages.c | 2 +- src/project.c | 23 ++++--- src/results.c | 135 +++++++++++++++++++++++++++++++----------- src/utils.c | 58 +++++++++++++++++- src/vector.c | 2 +- ui/BuildResults.glade | 46 +++++++++++--- ui/Project.glade | 22 +++++-- 10 files changed, 232 insertions(+), 67 deletions(-) diff --git a/embedded/gitignore b/embedded/gitignore index 4453e16..815df51 100644 --- a/embedded/gitignore +++ b/embedded/gitignore @@ -2,5 +2,9 @@ # GitIgnore for JoeyDev Projects # +# No build results. +results/ +build.tar.bz2 + # No baked data. *.dat diff --git a/include/utils.h b/include/utils.h index 9d23bd4..6c913e3 100644 --- a/include/utils.h +++ b/include/utils.h @@ -64,7 +64,7 @@ typedef struct ArchiveS { extern char __utilFilenameBuffer[FILENAME_MAX]; -void utilAddTextToListBox(GtkListBox *list, char *text); +void utilAddTextToListBox(GtkListBox *list, char *text, gboolean markup); void utilClearContainer(GtkContainer *container); char *utilCreateString(char *format, ...); char *utilCreateStringVArgs(char *format, va_list args); @@ -77,6 +77,7 @@ void utilExtractResource(char *path); char *utilFileBasename(char *path); gboolean utilFileCopy(char *from, char *to); gboolean utilFileExists(char *filename); +ssize_t utilGetLine(char **lineptr, size_t *n, FILE *stream); gboolean utilFileOpen(WindowDataT *self, char *extension, char *what); char *utilFilePath(char *filename); char *utilFileRemoveExtension(char *filename); diff --git a/src/editor.c b/src/editor.c index 1762a2e..a93626f 100644 --- a/src/editor.c +++ b/src/editor.c @@ -182,7 +182,7 @@ static void loadEditor(EditorDataT *self) { in = fopen(self->windowData.filename, "rt"); if (in != NULL) { utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { + while (utilGetLine(&line, &len, in) != -1) { SSM(SCI_ADDTEXT, strlen(line), (sptr_t)line); } fclose(in); @@ -218,7 +218,7 @@ static void loadEditorConfig(char *lexer, EditorDataT *self) { if (in) { // Load config. utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 4096); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { + while (utilGetLine(&line, &len, in) != -1) { if (strlen(line) > 0) line[strlen(line) - 1] = 0; c = utilGetToken(line, " ", "\"", "\""); utilDequote(c); diff --git a/src/messages.c b/src/messages.c index 75b40d2..42a458c 100644 --- a/src/messages.c +++ b/src/messages.c @@ -163,7 +163,7 @@ static gboolean messagesUpdate(gpointer userData) { gtk_widget_show_all(_self->window); } - utilAddTextToListBox(GTK_LIST_BOX(_lstMessages), string); + utilAddTextToListBox(GTK_LIST_BOX(_lstMessages), string, TRUE); utilForceUpdate(); // Scroll to show new row. diff --git a/src/project.c b/src/project.c index f56d440..645bb98 100644 --- a/src/project.c +++ b/src/project.c @@ -31,6 +31,7 @@ #include "utils.h" #include "http.h" #include "ssh.h" + #include "messages.h" #include "compiler.h" #include "editor.h" @@ -111,6 +112,7 @@ EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userDat EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData); EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData); EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData); +EVENT void menuProjectBuildLastResults(GtkWidget *object, gpointer userData); EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData); EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData); EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData); @@ -267,12 +269,6 @@ static void cookFinished(CompilerContextT **context) { static void decompressBuild(ArchiveT *archive) { ProjectDataT *self = (ProjectDataT *)archive->userData; - char *temp; - - // Delete archive. - temp = utilCreateString("%s%s", self->windowData.path, LOCAL_BUILD_RESULTS); - unlink(temp); - DEL(temp); message(MSG_INFO, "Processing build results"); winBuildResultsCreate(self); @@ -374,7 +370,7 @@ static void loadConfig(ProjectDataT *self) { in = fopen(self->configName, "rt"); if (in != NULL) { utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { + while (utilGetLine(&line, &len, in) != -1) { if (strlen(line) > 0) line[strlen(line) - 1] = 0; switch (count) { case 0: // Version Number @@ -451,7 +447,7 @@ static void loadProject(ProjectDataT *self) { } // Load project. utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { + while (utilGetLine(&line, &len, in) != -1) { if (strlen(line) > 0) line[strlen(line) - 1] = 0; c = utilGetToken(line, " ", "\"", "\""); utilDequote(c); @@ -835,6 +831,15 @@ EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData) { } +EVENT void menuProjectBuildLastResults(GtkWidget *object, gpointer userData) { + ProjectDataT *self = (ProjectDataT *)userData; + + (void)object; + + winBuildResultsCreate(self); +} + + EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) { ProjectDataT *self = (ProjectDataT *)userData; GtkWidget *dialog; @@ -1313,7 +1318,7 @@ static gboolean updateBuildOptions(ProjectDataT *self) { in = fopen(name, "rt"); if (in != NULL) { utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { + while (utilGetLine(&line, &len, in) != -1) { if (strlen(line) > 0) line[strlen(line) - 1] = 0; c = utilGetToken(line, " ", "\"", "\""); utilDequote(c); diff --git a/src/results.c b/src/results.c index c99c21a..89203e3 100644 --- a/src/results.c +++ b/src/results.c @@ -20,6 +20,10 @@ */ +#pragma clang diagnostic push +#pragma ide diagnostic ignored "cert-err34-c" // atoi warnings + + #include "common.h" #include "results.h" #include "utils.h" @@ -32,8 +36,8 @@ typedef struct ResultsDataS { GtkWidget *notebookResults; GtkWidget *lstDebug; GtkWidget *lstRelease; - GtkWidget *lstRaw; - int lastSelected; + GtkWidget *lstRawDebug; + GtkWidget *lstRawRelease; } ResultsDataT; @@ -41,7 +45,8 @@ static ResultsDataT **_resultWindows = NULL; EVENT void resultClicked(GtkButton *widget, gpointer userData); -static void resultShow(gboolean release, int target, int arch, ResultsDataT *self); +static void resultLoadRaw(gboolean release, int target, int arch, ResultsDataT *self); +static void resultParseRaw(gboolean release, char *line, ResultsDataT *self); static void resultsUpdate(ResultsDataT *self); EVENT gboolean winBuildResultsClose(GtkWidget *object, gpointer userData); static void winBuildResultsDelete(gpointer userData); @@ -53,56 +58,99 @@ EVENT void resultClicked(GtkButton *widget, gpointer userData) { int a; gboolean r; + // ***TODO*** Highlight the button somehow so we know what we're viewing. + // Extract button info from widget name. r = (name[0] == 'r'); t = atoi(&name[1]); a = atoi(strstr(name, "a") + 1); - resultShow(r, t, a, userData); + resultLoadRaw(r, t, a, userData); } -static void resultShow(gboolean release, int target, int arch, ResultsDataT *self) { +static void resultLoadRaw(gboolean release, int target, int arch, ResultsDataT *self) { FILE *in; char *temp; char *line = NULL; size_t len = 0; TargetT *t; - // Do we need to load new results? - if (target != self->lastSelected) { + // Clear existing contents. + utilClearContainer(GTK_CONTAINER(release ? self->lstRelease : self->lstDebug)); + utilClearContainer(GTK_CONTAINER(release ? self->lstRawRelease : self->lstRawDebug)); - self->lastSelected = target; - - // Clear existing contents. - utilClearContainer(GTK_CONTAINER(self->lstDebug)); - utilClearContainer(GTK_CONTAINER(self->lstRelease)); - utilClearContainer(GTK_CONTAINER(self->lstRaw)); - - // Load raw results. - t = self->project->targets[target]; - temp = utilCreateString("%sresults%cbuild.%s.%s.%s", self->project->windowData.path, UTIL_PATH_CHAR, t->name, t->archs[arch]->name, release ? "release" : "debug"); - in = fopen(temp, "rt"); - if (in) { - while (!feof(in)) { - utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { - if (strlen(line) > 0) line[strlen(line) - 1] = 0; - utilAddTextToListBox(GTK_LIST_BOX(self->lstRaw), line); - //***TODO*** Parse these for the other tabs. And, oops, we need two RAW tabs! - } + // Load raw output results. + t = self->project->targets[target]; + temp = utilCreateString("%sresults%cbuild.%s.%s.%s", self->project->windowData.path, UTIL_PATH_CHAR, t->name, t->archs[arch]->name, release ? "release" : "debug"); + in = fopen(temp, "rt"); + if (in) { + while (!feof(in)) { + utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. + while (utilGetLine(&line, &len, in) != -1) { + if (strlen(line) > 0) line[strlen(line) - 1] = 0; + utilAddTextToListBox(GTK_LIST_BOX(release ? self->lstRawRelease : self->lstRawDebug), line, FALSE); + resultParseRaw(release, line, self); } - fclose(in); - DEL(line); } - DEL(temp); + fclose(in); + DEL(line); } + DEL(temp); // Display appropriate tab. gtk_notebook_set_current_page(GTK_NOTEBOOK(self->notebookResults), release ? 1 : 0); } +static void resultParseRaw(gboolean release, char *line, ResultsDataT *self) { + GtkWidget *messages; + GtkWidget *row; + GtkWidget *box; + GtkWidget *label; + GtkWidget *button; + char *temp; + char *text = NULL; + gboolean isWarning = FALSE; + + messages = release ? self->lstRelease : self->lstDebug; + + // ***TODO*** This is going to need to be a lot more complicated. + // We need the line number and filename from multiple compilers. + if (strstr(line, " warning: ") != NULL) { + text = line; + isWarning = TRUE; + } + if (strstr(line, " error: ") != NULL) { + text = line; + } + + if (text) { + // New listbox row. + row = gtk_list_box_row_new(); + box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); + gtk_widget_set_hexpand(box, TRUE); + + // Icon button. + button = gtk_button_new_from_icon_name(isWarning ? "dialog-warning" : "dialog-error", GTK_ICON_SIZE_BUTTON); + temp = utilCreateString("%c", isWarning ? 'w' : 'e'); // We store data about this button in its name. + gtk_widget_set_name(button, temp); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); + DEL(temp); + + // Message. + label = gtk_label_new(text); + gtk_label_set_use_markup(GTK_LABEL(label), FALSE); + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + + // Add to list. + gtk_container_add(GTK_CONTAINER(row), box); + gtk_list_box_insert(GTK_LIST_BOX(messages), row, -1); + gtk_widget_show_all(GTK_WIDGET(messages)); + } +} + + static void resultsUpdate(ResultsDataT *self) { int i; int j; @@ -119,6 +167,9 @@ static void resultsUpdate(ResultsDataT *self) { utilClearContainer(GTK_CONTAINER(self->gridResults)); + //***TODO*** This should probably iterate over what files exist not what we expect. + // We also need to figure out why the system list is empty some times and display an error/message. + // Iterate over target data and load results. for (i=0; iproject->targets); i++) { t = self->project->targets[i]; @@ -132,13 +183,13 @@ static void resultsUpdate(ResultsDataT *self) { // Add to grid. Name. w = gtk_label_new(t->longName); gtk_label_set_line_wrap(GTK_LABEL(w), FALSE); - gtk_label_set_xalign(GTK_LABEL(w), 1.0); + gtk_label_set_xalign(GTK_LABEL(w), 1.0f); gtk_grid_attach(GTK_GRID(self->gridResults), w, 0, gridLine, 1, 1); // Add to grid. Arch. w = gtk_label_new(t->archs[j]->name); gtk_label_set_line_wrap(GTK_LABEL(w), FALSE); - gtk_label_set_xalign(GTK_LABEL(w), 1.0); + gtk_label_set_xalign(GTK_LABEL(w), 1.0f); gtk_grid_attach(GTK_GRID(self->gridResults), w, 1, gridLine, 1, 1); // See if we got binaries for debug and release. @@ -190,7 +241,8 @@ static void resultsUpdate(ResultsDataT *self) { // Did we load anything? if (gridLine > 0) { - resultShow(FALSE, firstSystem, 0, self); + resultLoadRaw(FALSE, firstSystem, 0, self); + resultLoadRaw(TRUE, firstSystem, 0, self); } } @@ -214,7 +266,8 @@ void winBuildResultsCreate(ProjectDataT *project) { "gridBuildResults", "lstBuildMessagesDebug", "lstBuildMessagesRelease", - "lstBuildMessagesRaw", + "lstBuildOutputDebug", + "lstBuildOutputRelease", "notebookResults", NULL };static @@ -224,8 +277,10 @@ void winBuildResultsCreate(ProjectDataT *project) { NULL, NULL, NULL, + NULL, NULL }; + char *temp; // Is there already a results window open for this project? for (i=0; iwindowData.closeWindow = winBuildResultsClose; self->project = project; - self->lastSelected = -1; project->buildResults = self; // Load widgets from XML. @@ -249,13 +303,19 @@ void winBuildResultsCreate(ProjectDataT *project) { widgets[1] = &self->gridResults; widgets[2] = &self->lstDebug; widgets[3] = &self->lstRelease; - widgets[4] = &self->lstRaw; - widgets[5] = &self->notebookResults; + widgets[4] = &self->lstRawDebug; + widgets[5] = &self->lstRawRelease; + widgets[6] = &self->notebookResults; utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/BuildResults.glade", widgetNames, widgets, self); // Register window. utilWindowRegister(self); + // Adjust title. + temp = utilCreateString("%s - %s", self->windowData.title, self->project->projectName); + gtk_window_set_title(GTK_WINDOW(self->windowData.window), temp); + DEL(temp); + // Draw contents. resultsUpdate(self); @@ -283,3 +343,6 @@ static void winBuildResultsDelete(gpointer userData) { DEL(userData); } + + +#pragma clang diagnostic pop diff --git a/src/utils.c b/src/utils.c index 897f8db..aa848a6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -50,7 +50,7 @@ char __utilFilenameBuffer[FILENAME_MAX]; gboolean utilDecompressUpdate(gpointer userData); // Not static -void utilAddTextToListBox(GtkListBox *list, char *text) { +void utilAddTextToListBox(GtkListBox *list, char *text, gboolean markup) { GtkWidget *row; GtkWidget *box; GtkWidget *label; @@ -59,13 +59,13 @@ void utilAddTextToListBox(GtkListBox *list, char *text) { box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_widget_set_hexpand(box, TRUE); label = gtk_label_new(text); - gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_label_set_use_markup(GTK_LABEL(label), markup); // Add new row to the message box. gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(row), box); gtk_list_box_insert(GTK_LIST_BOX(list), row, -1); - gtk_widget_show_all(list); + gtk_widget_show_all(GTK_WIDGET(list)); } @@ -462,6 +462,58 @@ gboolean utilFileExists(char *filename) { } +ssize_t utilGetLine(char **lineptr, size_t *n, FILE *stream) { + size_t pos; + int c; + + /* The original code is public domain -- Will Hartung 4/9/09 */ + /* Modifications, public domain as well, by Antti Haapala, 11/10/17 + - Switched to getc on 5/23/19 */ + + if (lineptr == NULL || stream == NULL || n == NULL) { + errno = EINVAL; + return -1; + } + + c = getc(stream); + if (c == EOF) { + return -1; + } + + if (*lineptr == NULL) { + *lineptr = malloc(128); + if (*lineptr == NULL) { + return -1; + } + *n = 128; + } + + pos = 0; + while(c != EOF) { + if (pos + 1 >= *n) { + size_t new_size = *n + (*n >> 2); + if (new_size < 128) { + new_size = 128; + } + char *new_ptr = realloc(*lineptr, new_size); + if (new_ptr == NULL) { + return -1; + } + *n = new_size; + *lineptr = new_ptr; + } + + ((unsigned char *)(*lineptr))[pos ++] = c; + if (c == '\n') { + break; + } + c = getc(stream); + } + + (*lineptr)[pos] = '\0'; + return (ssize_t)pos; +} + gboolean utilFileOpen(WindowDataT *self, char *extension, char *what) { GtkWidget *dialog; GtkFileFilter *filter; diff --git a/src/vector.c b/src/vector.c index f841926..1cbd322 100644 --- a/src/vector.c +++ b/src/vector.c @@ -640,7 +640,7 @@ static void loadVectorImage(VectorDataT *self) { if (in != NULL) { self->buffer[0] = 0; utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. - while (getline(&line, &len, in) != -1) { + while (utilGetLine(&line, &len, in) != -1) { switch (count) { case 0: // Version Number break; diff --git a/ui/BuildResults.glade b/ui/BuildResults.glade index daca580..eb2bda1 100644 --- a/ui/BuildResults.glade +++ b/ui/BuildResults.glade @@ -4,12 +4,9 @@ False - 10 - 10 - 10 - 10 Build Results 800 + 400 task-due @@ -102,7 +99,7 @@ True False - Debug + Debug Messages False @@ -134,7 +131,7 @@ True False - Release + Release Messages 1 @@ -151,7 +148,7 @@ True False - + True False @@ -167,13 +164,46 @@ True False - Raw + Debug Output 2 False + + + True + True + in + + + True + False + + + True + False + + + + + + + 3 + + + + + True + False + Release Output + + + 3 + False + + True diff --git a/ui/Project.glade b/ui/Project.glade index b9fff1c..de35642 100644 --- a/ui/Project.glade +++ b/ui/Project.glade @@ -170,6 +170,22 @@ False + + + True + False + Last Build Results... + True + + + + + + + True + False + + True @@ -180,12 +196,6 @@ - - - True - False - - True