Target selections now saved in projects and not clobbered when new settings are loaded from the build VM.
This commit is contained in:
parent
2469ec2ca2
commit
65d83bd038
5 changed files with 197 additions and 45 deletions
|
@ -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);
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
unlink("memwatch.log");
|
||||
#endif
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
httpStartup();
|
||||
sshStartup();
|
||||
|
|
231
src/project.c
231
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; 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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue