Recipe cooking is working!
This commit is contained in:
parent
f513dc3893
commit
4b32b111cf
19 changed files with 677 additions and 157 deletions
|
@ -37,23 +37,25 @@ option(DEBUG_MODE "Enable debugging output and memory tracing?" ON)
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
thirdparty-installed/memwatch/memwatch.c
|
thirdparty-installed/memwatch/memwatch.c
|
||||||
thirdparty-installed/cwalk-master/src/cwalk.c
|
thirdparty-installed/cwalk-master/src/cwalk.c
|
||||||
ui/generated/resources.c
|
ui/generated/resources.c
|
||||||
src/main.c
|
src/main.c
|
||||||
src/utils.c
|
src/utils.c
|
||||||
src/joeydev.c
|
src/joeydev.c
|
||||||
src/vector.c
|
src/vector.c
|
||||||
src/array.c
|
src/array.c
|
||||||
src/draw.c
|
src/draw.c
|
||||||
src/image.c
|
src/image.c
|
||||||
src/vecparse.c
|
src/vecparse.c
|
||||||
src/color.c
|
src/color.c
|
||||||
src/palette.c
|
src/palette.c
|
||||||
src/project.c
|
src/project.c
|
||||||
src/ssh.c
|
src/ssh.c
|
||||||
src/http.c
|
src/http.c
|
||||||
src/editor.c
|
src/editor.c
|
||||||
|
src/compiler.c
|
||||||
|
src/messages.c
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(include/config.h.in config.h)
|
configure_file(include/config.h.in config.h)
|
||||||
|
@ -72,6 +74,8 @@ add_custom_target(GENERATE_UI_HEADERS
|
||||||
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libgcrypt.a
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libgcrypt.a
|
||||||
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libssh2.a
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libssh2.a
|
||||||
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libz.a
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libz.a
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libtcc.a
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/tcc/libtcc1.a
|
||||||
)
|
)
|
||||||
add_dependencies(${CMAKE_PROJECT_NAME} GENERATE_UI_HEADERS)
|
add_dependencies(${CMAKE_PROJECT_NAME} GENERATE_UI_HEADERS)
|
||||||
|
|
||||||
|
@ -116,6 +120,8 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libgpg-error.a
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libgpg-error.a
|
||||||
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libcurl.a
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libcurl.a
|
||||||
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libz.a
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libz.a
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libtcc.a
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/tcc/libtcc1.a
|
||||||
${GTK3_LIBRARIES}
|
${GTK3_LIBRARIES}
|
||||||
-ldl
|
-ldl
|
||||||
-pthread
|
-pthread
|
||||||
|
|
36
embedded/recipe.h
Normal file
36
embedded/recipe.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECIPE_H
|
||||||
|
#define RECIPE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <tcclib.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern char **___recipeTargets;
|
||||||
|
|
||||||
|
|
||||||
|
extern void recipeAddTarget(char *target);
|
||||||
|
extern void recipeMessage(char *format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // RECIPE_H
|
|
@ -56,4 +56,7 @@ typedef struct WindowDataS {
|
||||||
} WindowDataT;
|
} WindowDataT;
|
||||||
|
|
||||||
|
|
||||||
|
extern char *__resourcePath;
|
||||||
|
|
||||||
|
|
||||||
#endif // COMMON_H
|
#endif // COMMON_H
|
||||||
|
|
30
include/compiler.h
Normal file
30
include/compiler.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef COMPILER_H
|
||||||
|
#define COMPILER_H
|
||||||
|
|
||||||
|
|
||||||
|
int compilerRunRecipe(char *recipe, char *input, char *outputPath, void *context);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // COMPILER_H
|
40
include/messages.h
Normal file
40
include/messages.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MESSAGES_H
|
||||||
|
#define MESSAGES_H
|
||||||
|
|
||||||
|
|
||||||
|
enum MessageTypesE {
|
||||||
|
MSG_INFO = 0,
|
||||||
|
MSG_WARN,
|
||||||
|
MSG_ERROR,
|
||||||
|
MSG_SEVERE, // This means something failed in JoeyDev itself.
|
||||||
|
MSG_COUNT
|
||||||
|
};
|
||||||
|
typedef enum MessageTypesE MessageTypesT;
|
||||||
|
|
||||||
|
|
||||||
|
void message(MessageTypesT level, char *format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MESSAGES_H
|
|
@ -24,7 +24,11 @@
|
||||||
#define PROJECT_H
|
#define PROJECT_H
|
||||||
|
|
||||||
|
|
||||||
void winProjectCreate(void);
|
struct ProjectDataS;
|
||||||
|
|
||||||
|
|
||||||
|
gboolean projectAddToTree(struct ProjectDataS *self, char *filename);
|
||||||
|
void winProjectCreate(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // PROJECT_H
|
#endif // PROJECT_H
|
||||||
|
|
|
@ -42,6 +42,7 @@ char *utilCreateStringVArgs(char *format, va_list args);
|
||||||
char *utilDeobfuscateASCII(char *obfuscated);
|
char *utilDeobfuscateASCII(char *obfuscated);
|
||||||
void utilDequote(char *string);
|
void utilDequote(char *string);
|
||||||
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
||||||
|
void utilExtractResource(char *path);
|
||||||
char *utilFileBasename(char *path);
|
char *utilFileBasename(char *path);
|
||||||
gboolean utilFileExists(char *filename);
|
gboolean utilFileExists(char *filename);
|
||||||
gboolean utilFileOpen(WindowDataT *self, char *extension, char *what);
|
gboolean utilFileOpen(WindowDataT *self, char *extension, char *what);
|
||||||
|
|
125
src/compiler.c
Normal file
125
src/compiler.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
#include "libtcc.h"
|
||||||
|
#include "project.h"
|
||||||
|
#include "messages.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "array.h"
|
||||||
|
|
||||||
|
|
||||||
|
char **___recipeTargets = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static void compilerErrorHandler(void *opaque, const char *msg);
|
||||||
|
void recipeAddTarget(char *target);
|
||||||
|
void recipeMessage(char *format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
static void compilerErrorHandler(void *opaque, const char *msg) {
|
||||||
|
char *isWarning = strstr(msg, " warning: ");
|
||||||
|
|
||||||
|
(void)opaque;
|
||||||
|
|
||||||
|
message(isWarning == NULL ? MSG_ERROR : MSG_WARN, "%s", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// All the paths passed in here are expected to be complete and absolute.
|
||||||
|
int compilerRunRecipe(char *recipe, char *input, char *outputPath, void *context) {
|
||||||
|
TCCState *s;
|
||||||
|
int result;
|
||||||
|
int (*entry)(char *, char *);
|
||||||
|
|
||||||
|
___recipeTargets = NULL;
|
||||||
|
|
||||||
|
s = tcc_new();
|
||||||
|
if (!s) {
|
||||||
|
// Something bad happened.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcc_set_options(s, "-Wall -Wno-write-strings");
|
||||||
|
tcc_set_lib_path(s, __resourcePath);
|
||||||
|
tcc_add_sysinclude_path(s, __resourcePath);
|
||||||
|
tcc_set_error_func(s, stdout, compilerErrorHandler);
|
||||||
|
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
|
||||||
|
|
||||||
|
if (tcc_add_file(s, recipe) < 0) {
|
||||||
|
// Errors in code.
|
||||||
|
tcc_delete(s);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcc_add_symbol(s, "___recipeTargets", ___recipeTargets);
|
||||||
|
tcc_add_symbol(s, "recipeAddTarget", recipeAddTarget);
|
||||||
|
tcc_add_symbol(s, "recipeMessage", recipeMessage);
|
||||||
|
|
||||||
|
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) {
|
||||||
|
// Something bad happened.
|
||||||
|
tcc_delete(s);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = tcc_get_symbol(s, "recipe");
|
||||||
|
if (!entry) {
|
||||||
|
// Something bad happened.
|
||||||
|
tcc_delete(s);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = entry(input, outputPath);
|
||||||
|
|
||||||
|
while (arrlen(___recipeTargets) > 0) {
|
||||||
|
if (projectAddToTree(context, ___recipeTargets[0])) {
|
||||||
|
utilSetDirty((WindowDataT *)context, TRUE);
|
||||||
|
}
|
||||||
|
DEL(___recipeTargets[0]);
|
||||||
|
arrdel(___recipeTargets, 0);
|
||||||
|
}
|
||||||
|
ARRFREE(___recipeTargets);
|
||||||
|
|
||||||
|
tcc_delete(s);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void recipeAddTarget(char *target) {
|
||||||
|
arrput(___recipeTargets, strdup(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void recipeMessage(char *format, ...) {
|
||||||
|
va_list args;
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
string = utilCreateStringVArgs(format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
message(MSG_INFO, "%s", string);
|
||||||
|
|
||||||
|
DEL(string);
|
||||||
|
}
|
27
src/main.c
27
src/main.c
|
@ -26,6 +26,10 @@
|
||||||
#include "joeydev.h"
|
#include "joeydev.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
char *__resourcePath = NULL;
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
@ -35,9 +39,30 @@ int main(int argc, char **argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
|
|
||||||
|
// Make sure we have a config & resources folder.
|
||||||
|
__resourcePath = utilCreateString("%s%cjoeydev%cresources%c", g_get_user_config_dir(), UTIL_PATH_CHAR, UTIL_PATH_CHAR, UTIL_PATH_CHAR);
|
||||||
|
utilMkDirP(__resourcePath, 0777);
|
||||||
|
|
||||||
httpStartup();
|
httpStartup();
|
||||||
sshStartup();
|
sshStartup();
|
||||||
|
|
||||||
|
// Extract files we need later.
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/libtcc.a");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/libtcc1.a");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/float.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/stdalign.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/stdarg.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/stdatomic.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/stdbool.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/stddef.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/stdnoreturn.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/tccdefs.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/tcclib.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/tgmath.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/varargs.h");
|
||||||
|
utilExtractResource("/com/kangaroopunch/joeydev/resources/recipe.h");
|
||||||
|
|
||||||
winJoeyDevCreate();
|
winJoeyDevCreate();
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
|
||||||
|
@ -45,5 +70,7 @@ int main(int argc, char **argv) {
|
||||||
sshShutdown();
|
sshShutdown();
|
||||||
httpShutdown();
|
httpShutdown();
|
||||||
|
|
||||||
|
DEL(__resourcePath);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
113
src/messages.c
Normal file
113
src/messages.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* JoeyDev
|
||||||
|
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "messages.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
static GtkWidget *_lstMessages = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
EVENT gboolean winMessagesClose(GtkWidget *object, gpointer userData);
|
||||||
|
static void winMessagesDelete(gpointer userData);
|
||||||
|
|
||||||
|
|
||||||
|
void message(MessageTypesT level, char *format, ...) {
|
||||||
|
WindowDataT *self = NULL;
|
||||||
|
char *widgetNames[] = {
|
||||||
|
"winMessages",
|
||||||
|
"lstMessages",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
GtkWidget **widgets[] = {
|
||||||
|
NULL,
|
||||||
|
&_lstMessages
|
||||||
|
};
|
||||||
|
GtkWidget *row;
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *label;
|
||||||
|
va_list args;
|
||||||
|
char *string;
|
||||||
|
char *temp;
|
||||||
|
char *labels[MSG_COUNT] = {
|
||||||
|
"<span foreground=\"gray\"> Info:</span>",
|
||||||
|
"<span foreground=\"yellow\">Warning:</span>",
|
||||||
|
"<span foreground=\"red\"> Error:</span>",
|
||||||
|
"<span foreground=\"red\"><b> Severe:</b></span>"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Do we need to open this window?
|
||||||
|
if (!_lstMessages) {
|
||||||
|
// Set up instance data. We only need WindowDataT since this is a "singleton" window.
|
||||||
|
self = NEW(WindowDataT);
|
||||||
|
self->closeWindow = winMessagesClose;
|
||||||
|
|
||||||
|
widgets[0] = &self->window;
|
||||||
|
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Messages.glade", widgetNames, widgets, self);
|
||||||
|
|
||||||
|
// Register window.
|
||||||
|
utilWindowRegister(self);
|
||||||
|
|
||||||
|
// Show window.
|
||||||
|
gtk_widget_show_all(self->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display message.
|
||||||
|
va_start(args, format);
|
||||||
|
temp = utilCreateStringVArgs(format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
string = utilCreateString("<tt>%s %s</tt>", labels[level], temp);
|
||||||
|
|
||||||
|
row = gtk_list_box_row_new();
|
||||||
|
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,6);
|
||||||
|
gtk_widget_set_hexpand(box, TRUE);
|
||||||
|
label = gtk_label_new(string);
|
||||||
|
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
|
||||||
|
|
||||||
|
DEL(string);
|
||||||
|
|
||||||
|
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(_lstMessages), row, -1);
|
||||||
|
|
||||||
|
gtk_widget_show_all(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EVENT gboolean winMessagesClose(GtkWidget *object, gpointer userData) {
|
||||||
|
// userData is not reliable due to util indirectly calling us.
|
||||||
|
WindowDataT *self = (WindowDataT *)utilGetWindowData(object);
|
||||||
|
|
||||||
|
(void)userData;
|
||||||
|
|
||||||
|
winMessagesDelete(self);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void winMessagesDelete(gpointer userData) {
|
||||||
|
utilWindowUnRegister(userData);
|
||||||
|
_lstMessages = NULL;
|
||||||
|
DEL(userData);
|
||||||
|
}
|
233
src/project.c
233
src/project.c
|
@ -31,6 +31,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
|
#include "messages.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
|
||||||
enum ProjectColumnsE {
|
enum ProjectColumnsE {
|
||||||
|
@ -88,24 +90,25 @@ typedef struct SectionDataS {
|
||||||
|
|
||||||
// These have to match ProjectSectionTypeT above.
|
// These have to match ProjectSectionTypeT above.
|
||||||
static SectionDataT _sectionData[] = {
|
static SectionDataT _sectionData[] = {
|
||||||
{ "Header", "*.h" },
|
{ "Header", "*.h" },
|
||||||
{ "Code", "*.c" },
|
{ "Code", "*.c" },
|
||||||
{ "Bitmap", "*.img" },
|
{ "Bitmap", "*.img" },
|
||||||
{ "Stencil", "*.stn" },
|
{ "Stencil", "*.stn" },
|
||||||
{ "Vector", "*.vic" },
|
{ "Vector", "*.vic" },
|
||||||
{ "Sound", "*.snd" },
|
{ "Sound", "*.snd" },
|
||||||
{ "Music", "*.mod" },
|
{ "Music", "*.mod" },
|
||||||
{ "Raw Data", NULL },
|
{ "Raw Data", NULL },
|
||||||
{ "Cooked Data", "*.dat" },
|
{ "Cooked Data", "*.dat" },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ProjectDataT *_cookingProjectData = NULL;
|
||||||
|
|
||||||
|
|
||||||
#define BUILD_SETTINGS_RESPONSE_TEST 1
|
#define BUILD_SETTINGS_RESPONSE_TEST 1
|
||||||
|
|
||||||
|
|
||||||
static void addToRecipeData(ProjectDataT *self, char *key, char *value);
|
static void addToRecipeData(ProjectDataT *self, char *key, char *value);
|
||||||
static void addToTree(ProjectDataT *self, char *filename);
|
|
||||||
EVENT void buildTargetClicked(GtkButton *widget, gpointer userData);
|
EVENT void buildTargetClicked(GtkButton *widget, gpointer userData);
|
||||||
EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData);
|
EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData);
|
||||||
EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData);
|
EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData);
|
||||||
|
@ -123,6 +126,7 @@ EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData);
|
||||||
|
EVENT void menuProjectBuildCookRecipes(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);
|
||||||
|
@ -148,59 +152,6 @@ static void addToRecipeData(ProjectDataT *self, char *key, char *value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void addToTree(ProjectDataT *self, char *filename) {
|
|
||||||
ProjectSectionTypeT section;
|
|
||||||
char *temp = NULL;
|
|
||||||
GtkTreeIter iter;
|
|
||||||
GtkTreeIter child;
|
|
||||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject));
|
|
||||||
ProjectSectionTypeT foundAt = SECTION_RAW_DATA; // If it isn't a file we know, put it in "Raw Data".
|
|
||||||
int fileLen;
|
|
||||||
int extLen;
|
|
||||||
|
|
||||||
// Is it long enough?
|
|
||||||
if (strlen(filename) > 2) {
|
|
||||||
// Is this already in the tree? This is a pretty brain-dead test.
|
|
||||||
gtk_tree_model_get_iter_first(model, &iter);
|
|
||||||
do {
|
|
||||||
if (gtk_tree_model_iter_children(model, &child, &iter)) {
|
|
||||||
do {
|
|
||||||
gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1);
|
|
||||||
if (strcmp(temp, filename) == 0) {
|
|
||||||
DEL(temp); // This generates an unknown pointer warning in memwatch. Pretty sure it's bogus.
|
|
||||||
return; // Silently fail to add on name collision.
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
|
|
||||||
// Find proper section.
|
|
||||||
for (section = 0; section < SECTION_COUNT; section++) {
|
|
||||||
if (_sectionData[section].extension != NULL) {
|
|
||||||
// Compare last two bytes of filename with extension - it's enough to differentiate them and allows for ".c" and ".h".
|
|
||||||
fileLen = strlen(filename) - 1;
|
|
||||||
extLen = strlen(_sectionData[section].extension) - 1;
|
|
||||||
if (filename[fileLen - 1] == _sectionData[section].extension[extLen - 1] && filename[fileLen] == _sectionData[section].extension[extLen]) {
|
|
||||||
foundAt = section;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEL(temp);
|
|
||||||
fileLen = 0;
|
|
||||||
utilEnsureBufferSize((unsigned char **)&temp, &fileLen, 4); // fileLen is just a throwaway here.
|
|
||||||
snprintf(temp, 4, "%d", foundAt);
|
|
||||||
gtk_tree_model_get_iter_from_string(model, &iter, temp);
|
|
||||||
gtk_tree_store_append(GTK_TREE_STORE(model), &child, &iter);
|
|
||||||
gtk_tree_store_set(GTK_TREE_STORE(model), &child, COL_FILENAME, filename, -1);
|
|
||||||
DEL(temp);
|
|
||||||
|
|
||||||
gtk_tree_view_expand_all(GTK_TREE_VIEW(self->treeProject));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EVENT void buildTargetClicked(GtkButton *widget, gpointer userData) {
|
EVENT void buildTargetClicked(GtkButton *widget, gpointer userData) {
|
||||||
ArchT *arch = (ArchT *)userData;
|
ArchT *arch = (ArchT *)userData;
|
||||||
|
|
||||||
|
@ -232,14 +183,18 @@ EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData) {
|
||||||
if (utilFileSaveOtherAs((WindowDataT *)userData, "*.c", "Recipe", &newFile)) {
|
if (utilFileSaveOtherAs((WindowDataT *)userData, "*.c", "Recipe", &newFile)) {
|
||||||
out = fopen(newFile, "wt");
|
out = fopen(newFile, "wt");
|
||||||
fprintf(out, ""
|
fprintf(out, ""
|
||||||
"//\n"
|
"//\n"
|
||||||
"// JoeyBuild Recipe Program\n"
|
"// JoeyBuild Recipe Program\n"
|
||||||
"//\n"
|
"//\n"
|
||||||
"\n"
|
"\n"
|
||||||
"int recipe(char *fileIn, char *fileOut) {\n"
|
"\n"
|
||||||
"\n"
|
"#include <recipe.h>\n"
|
||||||
"\treturn 0; // Return a non-zero value on failure.\n"
|
"\n"
|
||||||
"}\n"
|
"\n"
|
||||||
|
"int recipe(char *fileIn, char *outputPath) {\n"
|
||||||
|
"\n"
|
||||||
|
"\treturn 0; // Return a positive non-zero value on failure.\n"
|
||||||
|
"}\n"
|
||||||
);
|
);
|
||||||
fclose(out);
|
fclose(out);
|
||||||
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->tempWidget), newFile);
|
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->tempWidget), newFile);
|
||||||
|
@ -263,14 +218,12 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
|
||||||
GtkWidget *lblRaw;
|
GtkWidget *lblRaw;
|
||||||
GtkWidget *fileRecipe;
|
GtkWidget *fileRecipe;
|
||||||
GtkWidget *btnNewRecipe;
|
GtkWidget *btnNewRecipe;
|
||||||
GtkWidget *lblCooked;
|
|
||||||
GtkWidget *btnCancel;
|
GtkWidget *btnCancel;
|
||||||
GtkWidget *btnOkay;
|
GtkWidget *btnOkay;
|
||||||
int original;
|
int original;
|
||||||
int result;
|
int result;
|
||||||
int i;
|
int i;
|
||||||
char *raw = NULL;
|
char *raw = NULL;
|
||||||
char *cooked = NULL;
|
|
||||||
char *temp = NULL;
|
char *temp = NULL;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
char *widgetNames[] = {
|
char *widgetNames[] = {
|
||||||
|
@ -278,7 +231,6 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
|
||||||
"lblRaw",
|
"lblRaw",
|
||||||
"fileRecipe",
|
"fileRecipe",
|
||||||
"btnNewRecipe",
|
"btnNewRecipe",
|
||||||
"lblCooked",
|
|
||||||
"btnCancel",
|
"btnCancel",
|
||||||
"btnOkay",
|
"btnOkay",
|
||||||
NULL
|
NULL
|
||||||
|
@ -288,7 +240,6 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
|
||||||
&lblRaw,
|
&lblRaw,
|
||||||
&fileRecipe,
|
&fileRecipe,
|
||||||
&btnNewRecipe,
|
&btnNewRecipe,
|
||||||
&lblCooked,
|
|
||||||
&btnCancel,
|
&btnCancel,
|
||||||
&btnOkay
|
&btnOkay
|
||||||
};
|
};
|
||||||
|
@ -297,9 +248,6 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
|
||||||
|
|
||||||
raw = utilFileBasename(filename);
|
raw = utilFileBasename(filename);
|
||||||
gtk_label_set_text(GTK_LABEL(lblRaw), raw);
|
gtk_label_set_text(GTK_LABEL(lblRaw), raw);
|
||||||
cooked = utilFileRemoveExtension(raw);
|
|
||||||
strcat(cooked, ".dat");
|
|
||||||
gtk_label_set_text(GTK_LABEL(lblCooked), cooked);
|
|
||||||
|
|
||||||
self->tempWidget = fileRecipe;
|
self->tempWidget = fileRecipe;
|
||||||
|
|
||||||
|
@ -326,7 +274,6 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
|
||||||
}
|
}
|
||||||
// Did the recipe change?
|
// Did the recipe change?
|
||||||
if (!((original >= 0) && (strcmp(self->recipes[original]->value, temp) == 0))) {
|
if (!((original >= 0) && (strcmp(self->recipes[original]->value, temp) == 0))) {
|
||||||
addToTree(self, cooked);
|
|
||||||
addToRecipeData(self, raw, temp);
|
addToRecipeData(self, raw, temp);
|
||||||
utilSetDirty((WindowDataT *)self, TRUE);
|
utilSetDirty((WindowDataT *)self, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -335,7 +282,6 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DEL(path);
|
DEL(path);
|
||||||
DEL(cooked);
|
|
||||||
DEL(raw);
|
DEL(raw);
|
||||||
self->tempWidget = NULL;
|
self->tempWidget = NULL;
|
||||||
|
|
||||||
|
@ -436,7 +382,6 @@ static void loadProject(ProjectDataT *self) {
|
||||||
int j;
|
int j;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
char *raw = NULL;
|
char *raw = NULL;
|
||||||
char *cooked = NULL;
|
|
||||||
|
|
||||||
in = fopen(self->windowData.filename, "rt");
|
in = fopen(self->windowData.filename, "rt");
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
|
@ -463,9 +408,9 @@ static void loadProject(ProjectDataT *self) {
|
||||||
utilDequote(c);
|
utilDequote(c);
|
||||||
cwk_path_get_relative(path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
|
cwk_path_get_relative(path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
|
||||||
if (__utilFilenameBuffer[0] == 0) {
|
if (__utilFilenameBuffer[0] == 0) {
|
||||||
addToTree(self, c);
|
projectAddToTree(self, c);
|
||||||
} else {
|
} else {
|
||||||
addToTree(self, __utilFilenameBuffer);
|
projectAddToTree(self, __utilFilenameBuffer);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -502,20 +447,14 @@ static void loadProject(ProjectDataT *self) {
|
||||||
c = utilGetToken(NULL, " ", "\"", "\"");
|
c = utilGetToken(NULL, " ", "\"", "\"");
|
||||||
utilDequote(c);
|
utilDequote(c);
|
||||||
raw = strdup(c);
|
raw = strdup(c);
|
||||||
cooked = utilFileRemoveExtension(raw);
|
|
||||||
strcat(cooked, ".dat");
|
|
||||||
addToTree(self, cooked);
|
|
||||||
c = utilGetToken(NULL, " ", "\"", "\"");
|
c = utilGetToken(NULL, " ", "\"", "\"");
|
||||||
utilDequote(c);
|
utilDequote(c);
|
||||||
cwk_path_get_relative(path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
|
cwk_path_get_relative(path, c, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
|
||||||
if (__utilFilenameBuffer[0] == 0) {
|
if (__utilFilenameBuffer[0] == 0) {
|
||||||
addToRecipeData(self, raw, c);
|
addToRecipeData(self, raw, c);
|
||||||
debug("Writing Recipe [%s] = [%s]\n", raw, c);
|
|
||||||
} else {
|
} else {
|
||||||
addToRecipeData(self, raw, __utilFilenameBuffer);
|
addToRecipeData(self, raw, __utilFilenameBuffer);
|
||||||
debug("Writing Recipe [%s] = [%s]\n", raw, __utilFilenameBuffer);
|
|
||||||
}
|
}
|
||||||
DEL(cooked);
|
|
||||||
DEL(raw);
|
DEL(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,7 +654,7 @@ EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData) {
|
||||||
DEL(temp);
|
DEL(temp);
|
||||||
temp = strdup(__utilFilenameBuffer);
|
temp = strdup(__utilFilenameBuffer);
|
||||||
}
|
}
|
||||||
addToTree(self, temp);
|
projectAddToTree(self, temp);
|
||||||
utilSetDirty((WindowDataT *)self, TRUE);
|
utilSetDirty((WindowDataT *)self, TRUE);
|
||||||
DEL(temp);
|
DEL(temp);
|
||||||
}
|
}
|
||||||
|
@ -731,6 +670,8 @@ EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData) {
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
char *name = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
(void)object;
|
(void)object;
|
||||||
|
|
||||||
|
@ -743,6 +684,12 @@ EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
|
// Delete cook recipe if it exists.
|
||||||
|
gtk_tree_model_get(model, &iter, COL_FILENAME, &name, -1);
|
||||||
|
i = findRecipeData(self, name);
|
||||||
|
if (i >= 0) arrdel(self->recipes, i);
|
||||||
|
DEL(name);
|
||||||
|
// Remove item from tree.
|
||||||
gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
|
gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
|
||||||
utilSetDirty((WindowDataT *)self, TRUE);
|
utilSetDirty((WindowDataT *)self, TRUE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -947,8 +894,51 @@ EVENT void menuProjectBuildTargets(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) {
|
EVENT void menuProjectBuildCookRecipes(GtkWidget *object, gpointer userData) {
|
||||||
|
ProjectDataT *self = (ProjectDataT *)userData;
|
||||||
|
int i;
|
||||||
|
char *raw;
|
||||||
|
char *recipe;
|
||||||
|
char *path;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
// Only one cook at a time. Should not be able to happen.
|
||||||
|
if (_cookingProjectData) {
|
||||||
|
message(MSG_ERROR, "Cook currently running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember who started the cook.
|
||||||
|
_cookingProjectData = self;
|
||||||
|
|
||||||
|
// Find path of project file.
|
||||||
|
path = strdup(self->windowData.filename);
|
||||||
|
cwk_path_get_dirname(path, (size_t *)&i);
|
||||||
|
if (i > 0) path[i] = 0;
|
||||||
|
|
||||||
|
for (i=0; i<arrlen(self->recipes); i++) {
|
||||||
|
// Build pathnames.
|
||||||
|
cwk_path_change_basename(self->windowData.filename, self->recipes[i]->key, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
|
||||||
|
raw = strdup(__utilFilenameBuffer);
|
||||||
|
cwk_path_change_basename(self->windowData.filename, self->recipes[i]->value, __utilFilenameBuffer, sizeof(__utilFilenameBuffer));
|
||||||
|
recipe = strdup(__utilFilenameBuffer);
|
||||||
|
|
||||||
|
// Run it!
|
||||||
|
message(MSG_INFO, "Cooking %s", self->recipes[i]->key);
|
||||||
|
result = compilerRunRecipe(recipe, raw, path, self);
|
||||||
|
if (result != 0) {
|
||||||
|
//***TODO*** Not all negative returns are severe.
|
||||||
|
message(result > 0 ? MSG_ERROR : MSG_SEVERE, "Recipe %s returned %d", self->recipes[i]->value, result);
|
||||||
|
}
|
||||||
|
message(MSG_INFO, "Finished Cooking");
|
||||||
|
}
|
||||||
|
|
||||||
|
DEL(path);
|
||||||
|
_cookingProjectData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -960,15 +950,65 @@ EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean projectAddToTree(ProjectDataT *self, char *filename) {
|
||||||
|
ProjectSectionTypeT section;
|
||||||
|
char *temp = NULL;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreeIter child;
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject));
|
||||||
|
ProjectSectionTypeT foundAt = SECTION_RAW_DATA; // If it isn't a file we know, put it in "Raw Data".
|
||||||
|
int fileLen;
|
||||||
|
int extLen;
|
||||||
|
|
||||||
|
// Is it long enough?
|
||||||
|
if (strlen(filename) > 2) {
|
||||||
|
// Is this already in the tree? This is a pretty brain-dead test.
|
||||||
|
gtk_tree_model_get_iter_first(model, &iter);
|
||||||
|
do {
|
||||||
|
if (gtk_tree_model_iter_children(model, &child, &iter)) {
|
||||||
|
do {
|
||||||
|
gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1);
|
||||||
|
if (strcmp(temp, filename) == 0) {
|
||||||
|
DEL(temp); // This generates an unknown pointer warning in memwatch. Pretty sure it's bogus.
|
||||||
|
return FALSE; // Item exists and was not added.
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
|
||||||
|
// Find proper section.
|
||||||
|
for (section = 0; section < SECTION_COUNT; section++) {
|
||||||
|
if (_sectionData[section].extension != NULL) {
|
||||||
|
// Compare last two bytes of filename with extension - it's enough to differentiate them and allows for ".c" and ".h".
|
||||||
|
fileLen = strlen(filename) - 1;
|
||||||
|
extLen = strlen(_sectionData[section].extension) - 1;
|
||||||
|
if (filename[fileLen - 1] == _sectionData[section].extension[extLen - 1] && filename[fileLen] == _sectionData[section].extension[extLen]) {
|
||||||
|
foundAt = section;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEL(temp);
|
||||||
|
fileLen = 0;
|
||||||
|
utilEnsureBufferSize((unsigned char **)&temp, &fileLen, 4); // fileLen is just a throwaway here.
|
||||||
|
snprintf(temp, 4, "%d", foundAt);
|
||||||
|
gtk_tree_model_get_iter_from_string(model, &iter, temp);
|
||||||
|
gtk_tree_store_append(GTK_TREE_STORE(model), &child, &iter);
|
||||||
|
gtk_tree_store_set(GTK_TREE_STORE(model), &child, COL_FILENAME, filename, -1);
|
||||||
|
DEL(temp);
|
||||||
|
|
||||||
|
gtk_tree_view_expand_all(GTK_TREE_VIEW(self->treeProject));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE; // Item was added.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void saveConfig(ProjectDataT *self) {
|
static void saveConfig(ProjectDataT *self) {
|
||||||
char *temp;
|
char *temp;
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
|
||||||
// Make sure we have a config folder.
|
|
||||||
temp = utilCreateString("%s%cjoeydev", g_get_user_config_dir(), UTIL_PATH_CHAR);
|
|
||||||
utilMkDirP(temp, 0777);
|
|
||||||
DEL(temp);
|
|
||||||
|
|
||||||
// Save config.
|
// Save config.
|
||||||
out = fopen(self->configName, "wt");
|
out = fopen(self->configName, "wt");
|
||||||
if (out != NULL) {
|
if (out != NULL) {
|
||||||
|
@ -1058,7 +1098,7 @@ static gboolean updateBuildOptions(ProjectDataT *self) {
|
||||||
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.
|
utilEnsureBufferSize((unsigned char **)&line, (int *)&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;
|
||||||
c = utilGetToken(line, " ", "\"", "\"");
|
c = utilGetToken(line, " ", "\"", "\"");
|
||||||
|
@ -1236,9 +1276,6 @@ void winProjectCreate(void) {
|
||||||
//***DEBUG***
|
//***DEBUG***
|
||||||
self->windowData.filename = strdup("/home/scott/joeyapps/warehouse/Warehouse.joe");
|
self->windowData.filename = strdup("/home/scott/joeyapps/warehouse/Warehouse.joe");
|
||||||
loadProject(self);
|
loadProject(self);
|
||||||
for (int i=0; i<arrlen(self->recipes); i++) {
|
|
||||||
debug("Reading Recipe %d [%s] = [%s]\n", i, self->recipes[i]->key, self->recipes[i]->value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
49
src/utils.c
49
src/utils.c
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "cwalk.h"
|
#include "cwalk.h"
|
||||||
|
|
||||||
|
@ -130,6 +131,46 @@ void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void utilExtractResource(char *path) {
|
||||||
|
GInputStream *in;
|
||||||
|
gssize read;
|
||||||
|
gssize bytes = 0;
|
||||||
|
FILE *out = NULL;
|
||||||
|
unsigned char *buffer = NULL;
|
||||||
|
int name = (int)strlen(path) - 1;
|
||||||
|
char *target = NULL;
|
||||||
|
|
||||||
|
while (name >= 0 && path[name] != '/') name--;
|
||||||
|
target = utilCreateString("%s%s", __resourcePath, &path[name + 1]);
|
||||||
|
|
||||||
|
if (!utilFileExists(target)) {
|
||||||
|
utilEnsureBufferSize(&buffer, (int *)&bytes, 8192);
|
||||||
|
|
||||||
|
in = g_resources_open_stream(path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
|
||||||
|
if (in) {
|
||||||
|
out = fopen(target, "wb");
|
||||||
|
if (out) {
|
||||||
|
do {
|
||||||
|
read = g_input_stream_read(in, buffer, bytes, NULL, NULL);
|
||||||
|
fwrite(buffer, read, 1, out);
|
||||||
|
} while (read > 0);
|
||||||
|
fclose(out);
|
||||||
|
} else {
|
||||||
|
debug("Unable to write resource %s!\n", target);
|
||||||
|
}
|
||||||
|
g_input_stream_close(in, NULL, NULL);
|
||||||
|
g_object_unref(in);
|
||||||
|
} else {
|
||||||
|
debug("Resource %s not found!\n", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEL(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEL(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *utilFileBasename(char *path) {
|
char *utilFileBasename(char *path) {
|
||||||
const char *basename;
|
const char *basename;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
@ -231,6 +272,8 @@ gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) {
|
||||||
char *files = utilCreateString("%s Files", what);
|
char *files = utilCreateString("%s Files", what);
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
//***TODO*** Make this use utilFileSaveOtherAS
|
||||||
|
|
||||||
dialog = gtk_file_chooser_dialog_new("Save As",
|
dialog = gtk_file_chooser_dialog_new("Save As",
|
||||||
GTK_WINDOW(self->window),
|
GTK_WINDOW(self->window),
|
||||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
|
@ -240,7 +283,7 @@ gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) {
|
||||||
|
|
||||||
if (self->filename != NULL) {
|
if (self->filename != NULL) {
|
||||||
memcpy(__utilFilenameBuffer, self->filename, strlen(self->filename) + 1);
|
memcpy(__utilFilenameBuffer, self->filename, strlen(self->filename) + 1);
|
||||||
cwk_path_get_dirname(__utilFilenameBuffer, &x);
|
cwk_path_get_dirname(__utilFilenameBuffer, (size_t *)&x);
|
||||||
if (x > 0) __utilFilenameBuffer[x] = 0;
|
if (x > 0) __utilFilenameBuffer[x] = 0;
|
||||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),__utilFilenameBuffer);
|
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),__utilFilenameBuffer);
|
||||||
}
|
}
|
||||||
|
@ -283,7 +326,7 @@ gboolean utilFileSaveOtherAs(WindowDataT *self, char *extension, char *what, cha
|
||||||
|
|
||||||
if (*filename != NULL) {
|
if (*filename != NULL) {
|
||||||
memcpy(__utilFilenameBuffer, *filename, strlen(*filename) + 1);
|
memcpy(__utilFilenameBuffer, *filename, strlen(*filename) + 1);
|
||||||
cwk_path_get_dirname(__utilFilenameBuffer, &x);
|
cwk_path_get_dirname(__utilFilenameBuffer, (size_t *)&x);
|
||||||
if (x > 0) __utilFilenameBuffer[x] = 0;
|
if (x > 0) __utilFilenameBuffer[x] = 0;
|
||||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),__utilFilenameBuffer);
|
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),__utilFilenameBuffer);
|
||||||
}
|
}
|
||||||
|
@ -519,7 +562,7 @@ void utilWindowRegister(gpointer windowData) {
|
||||||
w->title = strdup(gtk_window_get_title(GTK_WINDOW(w->window)));
|
w->title = strdup(gtk_window_get_title(GTK_WINDOW(w->window)));
|
||||||
|
|
||||||
hmput(_windowList, w->window, windowData);
|
hmput(_windowList, w->window, windowData);
|
||||||
debug("Window Registered: %d\n", hmlen(_windowList));
|
debug("Window Registered: %ld\n", hmlen(_windowList));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -611,7 +611,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.
|
utilEnsureBufferSize((unsigned char **)&line, (int *)&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
|
||||||
|
|
BIN
thirdparty/tinycc-0.9.27.tar.bz2
(Stored with Git LFS)
vendored
Normal file
BIN
thirdparty/tinycc-0.9.27.tar.bz2
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
|
@ -152,6 +152,19 @@ pushd "${ROOT}" || exit &> /dev/null
|
||||||
popd || true &> /dev/null
|
popd || true &> /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f ${INSTALLED}/lib/libtcc.a ]]; then
|
||||||
|
echo Building Dependency: TinyCC...
|
||||||
|
tar xzf ${THIRDPARTY}/tinycc-0.9.27.tar.bz2
|
||||||
|
pushd tinycc-0.9.27 || exit &> /dev/null
|
||||||
|
./configure \
|
||||||
|
--prefix=${INSTALLED} \
|
||||||
|
--enable-static \
|
||||||
|
--with-libgcc
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
popd || true &> /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
popd || true &> /dev/null
|
popd || true &> /dev/null
|
||||||
|
|
||||||
echo Generating UI Embedded Code...
|
echo Generating UI Embedded Code...
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
<!-- Generated with glade 3.40.0 -->
|
<!-- Generated with glade 3.40.0 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.24"/>
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkFileFilter" id="filefilterRecipe">
|
||||||
|
<patterns>
|
||||||
|
<pattern>*.c</pattern>
|
||||||
|
</patterns>
|
||||||
|
</object>
|
||||||
<object class="GtkDialog" id="dialogCookSettings">
|
<object class="GtkDialog" id="dialogCookSettings">
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="title" translatable="yes">Cook Data</property>
|
<property name="title" translatable="yes">Cook Data</property>
|
||||||
|
@ -56,7 +61,7 @@
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<!-- n-columns=4 n-rows=3 -->
|
<!-- n-columns=4 n-rows=2 -->
|
||||||
<object class="GtkGrid">
|
<object class="GtkGrid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
|
@ -127,31 +132,6 @@
|
||||||
<property name="width">3</property>
|
<property name="width">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">end</property>
|
|
||||||
<property name="label" translatable="yes">Cooked:</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="lblCooked">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
|
||||||
<property name="label" translatable="yes">lblCooked</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
<property name="width">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="btnEdit">
|
<object class="GtkButton" id="btnEdit">
|
||||||
<property name="label" translatable="yes">Edit</property>
|
<property name="label" translatable="yes">Edit</property>
|
||||||
|
@ -187,9 +167,4 @@
|
||||||
<action-widget response="-5">btnOkay</action-widget>
|
<action-widget response="-5">btnOkay</action-widget>
|
||||||
</action-widgets>
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkFileFilter" id="filefilterRecipe">
|
|
||||||
<patterns>
|
|
||||||
<pattern>*.c</pattern>
|
|
||||||
</patterns>
|
|
||||||
</object>
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|
31
ui/Messages.glade
Normal file
31
ui/Messages.glade
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.40.0 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.24"/>
|
||||||
|
<object class="GtkWindow" id="winMessages">
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Messages</property>
|
||||||
|
<property name="default-width">440</property>
|
||||||
|
<property name="default-height">250</property>
|
||||||
|
<signal name="delete-event" handler="winMessagesClose" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="shadow-type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="lstMessages">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
|
@ -155,6 +155,22 @@
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="menuProjectBuildCookRecipes">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Cook Recipes</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<signal name="activate" handler="menuProjectBuildCookRecipes" swapped="no"/>
|
||||||
|
<accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuItem" id="menuProjectBuildBuild">
|
<object class="GtkMenuItem" id="menuProjectBuildBuild">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<gresources>
|
<gresources>
|
||||||
<gresource prefix="/com/kangaroopunch/joeydev">
|
<gresource prefix="/com/kangaroopunch/joeydev">
|
||||||
<file preprocess="xml-stripblanks">JoeyDev.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">JoeyDev.glade</file>
|
||||||
<file preprocess="xml-stripblanks">Project.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Project.glade</file>
|
||||||
<file preprocess="xml-stripblanks">BuildServer.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">BuildServer.glade</file>
|
||||||
<file preprocess="xml-stripblanks">Cook.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Cook.glade</file>
|
||||||
<file preprocess="xml-stripblanks">Editor.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Editor.glade</file>
|
||||||
<file preprocess="xml-stripblanks">Vector.glade</file>
|
<file compressed="true" preprocess="xml-stripblanks">Vector.glade</file>
|
||||||
|
<file compressed="true" preprocess="xml-stripblanks">Messages.glade</file>
|
||||||
<file>Logo.png</file>
|
<file>Logo.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/com/kangaroopunch/joeydev/icons/32x32/actions">
|
<gresource prefix="/com/kangaroopunch/joeydev/icons/32x32/actions">
|
||||||
|
@ -20,4 +21,20 @@
|
||||||
<file>action-color.png</file>
|
<file>action-color.png</file>
|
||||||
<file>action-palette.png</file>
|
<file>action-palette.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
|
<gresource prefix="/com/kangaroopunch/joeydev/resources">
|
||||||
|
<file compressed="true" alias="libtcc.a">../thirdparty-installed/lib/libtcc.a</file>
|
||||||
|
<file compressed="true" alias="libtcc1.a">../thirdparty-installed/lib/tcc/libtcc1.a</file>
|
||||||
|
<file compressed="true" alias="float.h">../thirdparty-installed/lib/tcc/include/float.h</file>
|
||||||
|
<file compressed="true" alias="stdalign.h">../thirdparty-installed/lib/tcc/include/stdalign.h</file>
|
||||||
|
<file compressed="true" alias="stdarg.h">../thirdparty-installed/lib/tcc/include/stdarg.h</file>
|
||||||
|
<file compressed="true" alias="stdatomic.h">../thirdparty-installed/lib/tcc/include/stdatomic.h</file>
|
||||||
|
<file compressed="true" alias="stdbool.h">../thirdparty-installed/lib/tcc/include/stdbool.h</file>
|
||||||
|
<file compressed="true" alias="stddef.h">../thirdparty-installed/lib/tcc/include/stddef.h</file>
|
||||||
|
<file compressed="true" alias="stdnoreturn.h">../thirdparty-installed/lib/tcc/include/stdnoreturn.h</file>
|
||||||
|
<file compressed="true" alias="tccdefs.h">../thirdparty-installed/lib/tcc/include/tccdefs.h</file>
|
||||||
|
<file compressed="true" alias="tcclib.h">../thirdparty-installed/lib/tcc/include/tcclib.h</file>
|
||||||
|
<file compressed="true" alias="tgmath.h">../thirdparty-installed/lib/tcc/include/tgmath.h</file>
|
||||||
|
<file compressed="true" alias="varargs.h">../thirdparty-installed/lib/tcc/include/varargs.h</file>
|
||||||
|
<file compressed="true" alias="recipe.h">../embedded/recipe.h</file>
|
||||||
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|
Loading…
Add table
Reference in a new issue