Target selections now saved in projects and not clobbered when new settings are loaded from the build VM.

This commit is contained in:
Scott Duensing 2023-01-25 19:44:55 -06:00
parent 2469ec2ca2
commit 65d83bd038
5 changed files with 197 additions and 45 deletions

View file

@ -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);

View file

@ -30,6 +30,10 @@
int main(int argc, char **argv) {
#ifdef DEBUG_MODE
unlink("memwatch.log");
#endif
gtk_init(&argc, &argv);
httpStartup();
sshStartup();

View file

@ -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; i<self->targets; 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; j<arrlen(t->archs); 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; j<arrlen(t->archs); 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; i<arrlen(self->targets); i++) {
t = self->targets[i];
archWritten = FALSE;
for (j=0; j<arrlen(t->archs); 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; i<arrlen(backup); i++) {
// Is this target in the new list?
for (j=0; j<arrlen(self->targets); 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; x<arrlen(backup[i]->archs); x++) {
for (y=0; x<arrlen(self->targets[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; i<arrlen(targets); i++) {
t = NEW(TargetT);
t->name = strdup(targets[i]->name);
t->longName = strdup(targets[i]->longName);
for (j=0; j<arrlen(targets[i]->archs); 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);

View file

@ -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;
}

View file

@ -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