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
|
#ifndef DEBUG_MODE
|
||||||
// Don't enable the project tool if we're not debugging.
|
// 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
|
#endif
|
||||||
|
|
||||||
gtk_widget_show_all(_winJoeyDev);
|
gtk_widget_show_all(_winJoeyDev);
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
unlink("memwatch.log");
|
||||||
|
#endif
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
httpStartup();
|
httpStartup();
|
||||||
sshStartup();
|
sshStartup();
|
||||||
|
|
197
src/project.c
197
src/project.c
|
@ -99,6 +99,7 @@ static SectionDataT _sectionData[] = {
|
||||||
|
|
||||||
|
|
||||||
static void addToTree(ProjectDataT *self, char *filename);
|
static void addToTree(ProjectDataT *self, char *filename);
|
||||||
|
EVENT void buildTargetClicked(GtkButton *widget, gpointer userData);
|
||||||
static void loadConfig(ProjectDataT *self);
|
static void loadConfig(ProjectDataT *self);
|
||||||
static void loadProject(ProjectDataT *self);
|
static void loadProject(ProjectDataT *self);
|
||||||
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
|
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 menuProjectBuildBuild(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
|
||||||
static void saveConfig(ProjectDataT *self);
|
static void saveConfig(ProjectDataT *self);
|
||||||
|
static TargetT **targetArrayCopy(TargetT **targets);
|
||||||
|
static void targetArrayDelete(TargetT ***array);
|
||||||
static gboolean updateBuildOptions(ProjectDataT *self);
|
static gboolean updateBuildOptions(ProjectDataT *self);
|
||||||
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
|
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
|
||||||
static void winProjectDelete(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) {
|
static void loadConfig(ProjectDataT *self) {
|
||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
|
@ -159,6 +169,7 @@ static void loadConfig(ProjectDataT *self) {
|
||||||
if (utilFileExists(self->configName)) {
|
if (utilFileExists(self->configName)) {
|
||||||
in = fopen(self->configName, "rt");
|
in = fopen(self->configName, "rt");
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
|
utilEnsureBufferSize(&line, &len, 1024); // Not technically needed, but fixes a pointer warning from memmaker.
|
||||||
while (getline(&line, &len, in) != -1) {
|
while (getline(&line, &len, in) != -1) {
|
||||||
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
||||||
switch (count) {
|
switch (count) {
|
||||||
|
@ -220,22 +231,54 @@ static void loadProject(ProjectDataT *self) {
|
||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
size_t count = 0;
|
char *c = NULL;
|
||||||
|
TargetT *t = NULL;
|
||||||
|
ArchT *a = NULL;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
in = fopen(self->windowData.filename, "rt");
|
in = fopen(self->windowData.filename, "rt");
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
|
utilEnsureBufferSize(&line, &len, 1024); // Not technically needed, but fixes a pointer warning from memmaker.
|
||||||
while (getline(&line, &len, in) != -1) {
|
while (getline(&line, &len, in) != -1) {
|
||||||
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
||||||
switch (count) {
|
c = utilGetToken(line, " ", "\"", "\"");
|
||||||
case 0: // Version Number
|
utilDequote(c);
|
||||||
case 1: // Separator line
|
// Is this a 'source' line?
|
||||||
break;
|
if (strcasecmp(c, "source") == 0) {
|
||||||
|
c = utilGetToken(NULL, " ", "\"", "\"");
|
||||||
default: // Project Data
|
utilDequote(c);
|
||||||
addToTree(self, line);
|
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++;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(in);
|
fclose(in);
|
||||||
DEL(line);
|
DEL(line);
|
||||||
|
@ -285,7 +328,12 @@ EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) {
|
||||||
FILE *out = NULL;
|
FILE *out = NULL;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkTreeIter child;
|
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?
|
// Do we need to save?
|
||||||
if (self->windowData.isDirty == TRUE) {
|
if (self->windowData.isDirty == TRUE) {
|
||||||
|
@ -298,20 +346,38 @@ EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) {
|
||||||
|
|
||||||
out = fopen(self->windowData.filename, "wt");
|
out = fopen(self->windowData.filename, "wt");
|
||||||
if (out != NULL) {
|
if (out != NULL) {
|
||||||
// Save!
|
// Save! Write out header.
|
||||||
fprintf(out, "%s\n", PROJECT_VERSION);
|
fprintf(out, "%s\n", PROJECT_VERSION);
|
||||||
fprintf(out, "------------------------------------------------------------------------------\n");
|
fprintf(out, "------------------------------------------------------------------------------\n");
|
||||||
|
// Write out file list.
|
||||||
gtk_tree_model_get_iter_first(model, &iter);
|
gtk_tree_model_get_iter_first(model, &iter);
|
||||||
do {
|
do {
|
||||||
if (gtk_tree_model_iter_children(model, &child, &iter)) {
|
if (gtk_tree_model_iter_children(model, &child, &iter)) {
|
||||||
do {
|
do {
|
||||||
//***TODO*** For RAW we need to store function name somewhere.
|
//***TODO*** For RAW we need to store function name somewhere.
|
||||||
gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1);
|
gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1);
|
||||||
fprintf(out, "%s\n", temp);
|
fprintf(out, "source \"%s\"\n", temp);
|
||||||
DEL(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, &child));
|
||||||
}
|
}
|
||||||
} while (gtk_tree_model_iter_next(model, &iter));
|
} 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);
|
fclose(out);
|
||||||
// We're clean now.
|
// We're clean now.
|
||||||
utilSetDirty((WindowDataT *)self, FALSE);
|
utilSetDirty((WindowDataT *)self, FALSE);
|
||||||
|
@ -531,6 +597,9 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) {
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
int result;
|
int result;
|
||||||
|
TargetT **backup;
|
||||||
|
|
||||||
|
backup = targetArrayCopy(self->targets);
|
||||||
|
|
||||||
grid = gtk_grid_new();
|
grid = gtk_grid_new();
|
||||||
gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE);
|
gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE);
|
||||||
|
@ -549,6 +618,7 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) {
|
||||||
a = t->archs[j];
|
a = t->archs[j];
|
||||||
widget = gtk_check_button_new_with_label(a->name);
|
widget = gtk_check_button_new_with_label(a->name);
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), a->selected);
|
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);
|
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);
|
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);
|
gtk_widget_destroy(dialog);
|
||||||
}
|
}
|
||||||
|
@ -627,6 +703,11 @@ static gboolean updateBuildOptions(ProjectDataT *self) {
|
||||||
char *c = NULL;
|
char *c = NULL;
|
||||||
TargetT *t = NULL;
|
TargetT *t = NULL;
|
||||||
ArchT *a = 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.
|
// 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.
|
// Unload current target listing.
|
||||||
while (arrlen(self->targets) > 0) {
|
backup = targetArrayCopy(self->targets);
|
||||||
t = self->targets[0];
|
targetArrayDelete(&self->targets);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there's a list of targets on the disk, load them.
|
// If there's a list of targets on the disk, load them.
|
||||||
if (utilFileExists(name) == TRUE) {
|
if (utilFileExists(name) == TRUE) {
|
||||||
in = fopen(name, "rt");
|
in = fopen(name, "rt");
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
|
utilEnsureBufferSize(&line, &len, 1024); // Not technically needed, but fixes a pointer warning from memmaker.
|
||||||
while (getline(&line, &len, in) != -1) {
|
while (getline(&line, &len, in) != -1) {
|
||||||
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
||||||
// Is this a 'target' line?
|
|
||||||
c = utilGetToken(line, " ", "\"", "\"");
|
c = utilGetToken(line, " ", "\"", "\"");
|
||||||
utilDequote(c);
|
utilDequote(c);
|
||||||
|
// Is this a 'target' line?
|
||||||
if (strcasecmp(c, "target") == 0) {
|
if (strcasecmp(c, "target") == 0) {
|
||||||
t = NEW(TargetT);
|
t = NEW(TargetT);
|
||||||
// Short name.
|
// Short name.
|
||||||
|
@ -680,7 +753,7 @@ static gboolean updateBuildOptions(ProjectDataT *self) {
|
||||||
utilDequote(c);
|
utilDequote(c);
|
||||||
a = NEW(ArchT);
|
a = NEW(ArchT);
|
||||||
a->name = strdup(c);
|
a->name = strdup(c);
|
||||||
a->selected = TRUE;
|
a->selected = FALSE;
|
||||||
arrput(t->archs, a);
|
arrput(t->archs, a);
|
||||||
}
|
}
|
||||||
} while (c != NULL);
|
} 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(url);
|
||||||
DEL(name);
|
DEL(name);
|
||||||
DEL(test);
|
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) {
|
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData) {
|
||||||
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
|
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
|
||||||
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
|
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
|
||||||
|
@ -773,6 +914,8 @@ static void winProjectDelete(gpointer userData) {
|
||||||
|
|
||||||
utilWindowUnRegister(userData);
|
utilWindowUnRegister(userData);
|
||||||
|
|
||||||
|
targetArrayDelete(&self->targets);
|
||||||
|
|
||||||
DEL(self->buildHost);
|
DEL(self->buildHost);
|
||||||
DEL(self->buildUser);
|
DEL(self->buildUser);
|
||||||
DEL(self->buildPassword);
|
DEL(self->buildPassword);
|
||||||
|
|
|
@ -93,6 +93,8 @@ char *utilDeobfuscateASCII(char *obfuscated) {
|
||||||
}
|
}
|
||||||
deobfuscated[i] = 0;
|
deobfuscated[i] = 0;
|
||||||
|
|
||||||
|
DEL(hostname);
|
||||||
|
|
||||||
return deobfuscated;
|
return deobfuscated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +378,8 @@ char *utilObfuscateASCII(char *clearText) {
|
||||||
}
|
}
|
||||||
obfuscated[i] = 0;
|
obfuscated[i] = 0;
|
||||||
|
|
||||||
|
DEL(hostname);
|
||||||
|
|
||||||
return obfuscated;
|
return obfuscated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -613,6 +613,7 @@ static void loadVectorImage(VectorDataT *self) {
|
||||||
in = fopen(self->windowData.filename, "rt");
|
in = fopen(self->windowData.filename, "rt");
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
self->buffer[0] = 0;
|
self->buffer[0] = 0;
|
||||||
|
utilEnsureBufferSize(&line, &len, 1024); // Not technically needed, but fixes a pointer warning from memmaker.
|
||||||
while (getline(&line, &len, in) != -1) {
|
while (getline(&line, &len, in) != -1) {
|
||||||
switch (count) {
|
switch (count) {
|
||||||
case 0: // Version Number
|
case 0: // Version Number
|
||||||
|
|
Loading…
Add table
Reference in a new issue