diff --git a/src/joeydev.c b/src/joeydev.c index 717edac..5e1646b 100644 --- a/src/joeydev.c +++ b/src/joeydev.c @@ -116,7 +116,7 @@ void winJoeyDevCreate(void) { #ifndef DEBUG_MODE // Don't enable the project tool if we're not debugging. - gtk_widget_set_sensitive(GTK_WIDGET(toolJoeyDevProject), FALSE); +// gtk_widget_set_sensitive(GTK_WIDGET(toolJoeyDevProject), FALSE); #endif gtk_widget_show_all(_winJoeyDev); diff --git a/src/main.c b/src/main.c index e011f9c..4c469cf 100644 --- a/src/main.c +++ b/src/main.c @@ -30,6 +30,10 @@ int main(int argc, char **argv) { +#ifdef DEBUG_MODE + unlink("memwatch.log"); +#endif + gtk_init(&argc, &argv); httpStartup(); sshStartup(); diff --git a/src/project.c b/src/project.c index f810828..3952f52 100644 --- a/src/project.c +++ b/src/project.c @@ -99,6 +99,7 @@ static SectionDataT _sectionData[] = { static void addToTree(ProjectDataT *self, char *filename); +EVENT void buildTargetClicked(GtkButton *widget, gpointer userData); static void loadConfig(ProjectDataT *self); static void loadProject(ProjectDataT *self); EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData); @@ -113,6 +114,8 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData); EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData); static void saveConfig(ProjectDataT *self); +static TargetT **targetArrayCopy(TargetT **targets); +static void targetArrayDelete(TargetT ***array); static gboolean updateBuildOptions(ProjectDataT *self); EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData); static void winProjectDelete(gpointer userData); @@ -149,6 +152,13 @@ static void addToTree(ProjectDataT *self, char *filename) { } +EVENT void buildTargetClicked(GtkButton *widget, gpointer userData) { + ArchT *arch = (ArchT *)userData; + + arch->selected = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); +} + + static void loadConfig(ProjectDataT *self) { FILE *in = NULL; char *line = NULL; @@ -159,6 +169,7 @@ static void loadConfig(ProjectDataT *self) { if (utilFileExists(self->configName)) { in = fopen(self->configName, "rt"); if (in != NULL) { + utilEnsureBufferSize(&line, &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; switch (count) { @@ -217,25 +228,57 @@ static void loadConfig(ProjectDataT *self) { static void loadProject(ProjectDataT *self) { - FILE *in = NULL; - char *line = NULL; - size_t len = 0; - size_t count = 0; + FILE *in = NULL; + char *line = NULL; + size_t len = 0; + char *c = NULL; + TargetT *t = NULL; + ArchT *a = NULL; + int i; + int j; in = fopen(self->windowData.filename, "rt"); if (in != NULL) { + utilEnsureBufferSize(&line, &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; - switch (count) { - case 0: // Version Number - case 1: // Separator line - break; - - default: // Project Data - addToTree(self, line); - break; + c = utilGetToken(line, " ", "\"", "\""); + utilDequote(c); + // Is this a 'source' line? + if (strcasecmp(c, "source") == 0) { + c = utilGetToken(NULL, " ", "\"", "\""); + utilDequote(c); + addToTree(self, c); + } + // Is this a 'target' line? + if (strcasecmp(c, "target") == 0) { + c = utilGetToken(NULL, " ", "\"", "\""); + utilDequote(c); + // See if we know about this target. + for (i=0; itargets; i++) { + if (strcasecmp(self->targets[i]->name, c) == 0) { + t = self->targets[i]; + // We know this target. Set all our known archs to FALSE. + for (j=0; jarchs); j++) { + t->archs[j]->selected = FALSE; + } + // Iterate over specified arches and turn them on if known. + while (c != NULL) { + c = utilGetToken(NULL, " ", "\"", "\""); + if (c != NULL) { + utilDequote(c); + for (j=0; jarchs); j++) { + if (strcasecmp(t->archs[j]->name, c) == 0) { + t->archs[j]->selected = TRUE; + break; + } + } + } + } + break; + } + } } - count++; } fclose(in); DEL(line); @@ -280,12 +323,17 @@ EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData) { EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) { - ProjectDataT *self = (ProjectDataT *)userData; - GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject)); - FILE *out = NULL; + ProjectDataT *self = (ProjectDataT *)userData; + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject)); + FILE *out = NULL; GtkTreeIter iter; GtkTreeIter child; - char *temp; + char *temp = NULL; + TargetT *t = NULL; + ArchT *a = NULL; + gboolean archWritten = FALSE; + int i; + int j; // Do we need to save? if (self->windowData.isDirty == TRUE) { @@ -298,20 +346,38 @@ EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) { out = fopen(self->windowData.filename, "wt"); if (out != NULL) { - // Save! + // Save! Write out header. fprintf(out, "%s\n", PROJECT_VERSION); fprintf(out, "------------------------------------------------------------------------------\n"); + // Write out file list. gtk_tree_model_get_iter_first(model, &iter); do { if (gtk_tree_model_iter_children(model, &child, &iter)) { do { //***TODO*** For RAW we need to store function name somewhere. gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1); - fprintf(out, "%s\n", temp); - DEL(temp); + fprintf(out, "source \"%s\"\n", temp); + DEL(temp); // This generates an unknown pointer warning in memwatch. Pretty sure it's bogus. } while (gtk_tree_model_iter_next(model, &child)); } } while (gtk_tree_model_iter_next(model, &iter)); + // Write out desired targets. + for (i=0; itargets); i++) { + t = self->targets[i]; + archWritten = FALSE; + for (j=0; jarchs); j++) { + a = t->archs[j]; + if (a->selected == TRUE) { + if (archWritten == FALSE) { + fprintf(out, "target %s", t->name); + archWritten = TRUE; + } + fprintf(out, " %s", a->name); + } + } + if (archWritten == TRUE) fprintf(out, "\n"); + } + // Close file. fclose(out); // We're clean now. utilSetDirty((WindowDataT *)self, FALSE); @@ -531,6 +597,9 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) { int i; int j; int result; + TargetT **backup; + + backup = targetArrayCopy(self->targets); grid = gtk_grid_new(); gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE); @@ -549,6 +618,7 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) { a = t->archs[j]; widget = gtk_check_button_new_with_label(a->name); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), a->selected); + g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(buildTargetClicked), a); gtk_grid_attach(GTK_GRID(grid), widget, j + 1, i, 1, 1); } } @@ -569,7 +639,13 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) { gtk_widget_show_all(dialog); - result = gtk_dialog_run(dialog); + result = gtk_dialog_run(GTK_DIALOG(dialog)); + if (result != GTK_RESPONSE_OK) { + targetArrayDelete(&self->targets); + self->targets = targetArrayCopy(backup); + } + + targetArrayDelete(&backup); gtk_widget_destroy(dialog); } @@ -617,16 +693,21 @@ static void saveConfig(ProjectDataT *self) { static gboolean updateBuildOptions(ProjectDataT *self) { - char *test = NULL; - char *name = NULL; - char *url = NULL; - gboolean result = FALSE; - FILE *in = NULL; - char *line = NULL; - size_t len = 0; - char *c = NULL; - TargetT *t = NULL; - ArchT *a = NULL; + char *test = NULL; + char *name = NULL; + char *url = NULL; + gboolean result = FALSE; + FILE *in = NULL; + char *line = NULL; + size_t len = 0; + char *c = NULL; + TargetT *t = NULL; + ArchT *a = NULL; + TargetT **backup = NULL; + int i; + int j; + int x; + int y; // This updates the build options file without clobbering one if it already exists and we fail to get a new one. @@ -642,27 +723,19 @@ static gboolean updateBuildOptions(ProjectDataT *self) { } // Unload current target listing. - while (arrlen(self->targets) > 0) { - t = self->targets[0]; - while (arrlen(t->archs) > 0) { - a = t->archs[0]; - DEL(a->name); - arrdel(t->archs, 0); - } - DEL(t->name); - DEL(t->longName); - arrdel(self->targets, 0); - } + backup = targetArrayCopy(self->targets); + targetArrayDelete(&self->targets); // If there's a list of targets on the disk, load them. if (utilFileExists(name) == TRUE) { in = fopen(name, "rt"); if (in != NULL) { + utilEnsureBufferSize(&line, &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; - // Is this a 'target' line? c = utilGetToken(line, " ", "\"", "\""); utilDequote(c); + // Is this a 'target' line? if (strcasecmp(c, "target") == 0) { t = NEW(TargetT); // Short name. @@ -680,7 +753,7 @@ static gboolean updateBuildOptions(ProjectDataT *self) { utilDequote(c); a = NEW(ArchT); a->name = strdup(c); - a->selected = TRUE; + a->selected = FALSE; arrput(t->archs, a); } } while (c != NULL); @@ -692,6 +765,27 @@ static gboolean updateBuildOptions(ProjectDataT *self) { } } + // Merge any previously checked items into the new list. + for (i=0; itargets); j++) { + if (strcasecmp(backup[i]->name, self->targets[j]->name) == 0) { + // This is our target. Iterate over archs and enable any we had enabled before. + for (x=0; xarchs); x++) { + for (y=0; xtargets[j]->archs); y++) { + if (strcasecmp(backup[i]->archs[x]->name, self->targets[j]->archs[y]->name) == 0) { + self->targets[j]->archs[y]->selected = backup[i]->archs[x]->selected; + break; + } + } + } + break; + } + } + } + + targetArrayDelete(&backup); + DEL(url); DEL(name); DEL(test); @@ -700,6 +794,53 @@ static gboolean updateBuildOptions(ProjectDataT *self) { } +static TargetT **targetArrayCopy(TargetT **targets) { + int i; + int j; + TargetT *t = NULL; + ArchT *a = NULL; + TargetT **backup = NULL; + + for (i=0; iname = strdup(targets[i]->name); + t->longName = strdup(targets[i]->longName); + for (j=0; jarchs); j++) { + a = NEW(ArchT); + a->name = strdup(targets[i]->archs[j]->name); + a->selected = targets[i]->archs[j]->selected; + arrput(t->archs, a); + } + arrput(backup, t); + } + + return backup; +} + + +static void targetArrayDelete(TargetT ***array) { + TargetT **targets = (TargetT **)*array; + TargetT *t = NULL; + ArchT *a = NULL; + + while (arrlen(targets) > 0) { + t = targets[0]; + while (arrlen(t->archs) > 0) { + a = t->archs[0]; + DEL(a->name); + DEL(a); + arrdel(t->archs, 0); + } + //arrfree(t->archs); + DEL(t->name); + DEL(t->longName); + DEL(t); + arrdel(targets, 0); + } + //arrfree(targets); +} + + EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData) { // userData is not reliable due to menuVectorFileClose and util indirectly calling us. ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object); @@ -773,6 +914,8 @@ static void winProjectDelete(gpointer userData) { utilWindowUnRegister(userData); + targetArrayDelete(&self->targets); + DEL(self->buildHost); DEL(self->buildUser); DEL(self->buildPassword); diff --git a/src/utils.c b/src/utils.c index 3930299..70c75b9 100644 --- a/src/utils.c +++ b/src/utils.c @@ -93,6 +93,8 @@ char *utilDeobfuscateASCII(char *obfuscated) { } deobfuscated[i] = 0; + DEL(hostname); + return deobfuscated; } @@ -376,6 +378,8 @@ char *utilObfuscateASCII(char *clearText) { } obfuscated[i] = 0; + DEL(hostname); + return obfuscated; } diff --git a/src/vector.c b/src/vector.c index f782f74..065086a 100644 --- a/src/vector.c +++ b/src/vector.c @@ -613,6 +613,7 @@ static void loadVectorImage(VectorDataT *self) { in = fopen(self->windowData.filename, "rt"); if (in != NULL) { self->buffer[0] = 0; + utilEnsureBufferSize(&line, &len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. while (getline(&line, &len, in) != -1) { switch (count) { case 0: // Version Number