Converted most of GTK launcher to use glib's string functions.
This commit is contained in:
committed by
Chris Forbes
parent
9739e7f51f
commit
0a1e6d16bd
@@ -22,11 +22,11 @@
|
||||
|
||||
int js_check_num_args(JSContextRef ctx, char const * func_name, int argc, int num_expected, JSValueRef * exception)
|
||||
{
|
||||
char buf[64];
|
||||
GString * buf = g_string_new(NULL);
|
||||
if (argc < num_expected)
|
||||
{
|
||||
sprintf(buf, "%s: Not enough args, expected %d got %d", func_name, num_expected, argc);
|
||||
*exception = JSValueMakeString(ctx, JS_STR(buf));
|
||||
g_string_printf(buf, "%s: Not enough args, expected %d got %d", func_name, num_expected, argc);
|
||||
*exception = JSValueMakeString(ctx, JS_STR(buf->str));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -101,8 +101,8 @@ JSValueRef js_exists_in_mod(JSContextRef ctx, JSObjectRef func,
|
||||
fclose(f);
|
||||
return_value = JSValueMakeNumber(ctx, 1);
|
||||
}
|
||||
|
||||
g_message("JS ExistsInMod: Not found");
|
||||
else
|
||||
g_message("JS ExistsInMod: Not found");
|
||||
|
||||
return return_value;
|
||||
}
|
||||
@@ -140,9 +140,8 @@ JSValueRef js_launch_mod(JSContextRef ctx, JSObjectRef func,
|
||||
|
||||
while (strlen(mod->requires) > 0)
|
||||
{
|
||||
char r[MOD_requires_MAX_LEN], * comma;
|
||||
strcpy(r, mod->requires);
|
||||
if (NULL != (comma = strchr(r, ',')))
|
||||
gchar * r = g_strdup(mod->requires), * comma;
|
||||
if (NULL != (comma = g_strstr_len(r, -1, ",")))
|
||||
{
|
||||
*comma = '\0';
|
||||
}
|
||||
@@ -160,10 +159,11 @@ JSValueRef js_launch_mod(JSContextRef ctx, JSObjectRef func,
|
||||
mod_list = (char *)realloc(mod_list, offset + strlen(r) + 1);
|
||||
sprintf(mod_list + offset, ",%s", r);
|
||||
offset += strlen(r) + 1;
|
||||
g_free(r);
|
||||
}
|
||||
|
||||
{
|
||||
char * launch_args[] = { "mono", "OpenRA.Game.exe", NULL, NULL };
|
||||
char * launch_args[] = { "mono", "OpenRA.Game.exe", NULL, "SupportDir=~/.openra", NULL };
|
||||
char * game_mods_arg;
|
||||
|
||||
game_mods_arg = (char *)malloc(strlen(mod_list) + strlen("Game.Mods=") + 1);
|
||||
|
||||
@@ -24,32 +24,43 @@ GtkTreeStore * tree_store;
|
||||
GtkTreeView * tree;
|
||||
GdkPixbuf * generic_mod_icon;
|
||||
|
||||
static mod_t mods[MAX_NUM_MODS];
|
||||
static int mod_count = 0;
|
||||
|
||||
void free_mod(mod_t * mod)
|
||||
{
|
||||
g_free(mod->key);
|
||||
g_free(mod->title);
|
||||
g_free(mod->version);
|
||||
g_free(mod->author);
|
||||
g_free(mod->description);
|
||||
g_free(mod->requires);
|
||||
}
|
||||
|
||||
gboolean window_delete(GtkWidget * widget, GdkEvent * event,
|
||||
gpointer user_data)
|
||||
{
|
||||
int i;
|
||||
server_teardown();
|
||||
for (i = 0; i < mod_count; i++)
|
||||
free_mod(mods + i);
|
||||
gtk_main_quit();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static mod_t mods[MAX_NUM_MODS];
|
||||
static int mod_count = 0;
|
||||
|
||||
typedef void ( * lines_callback ) (char const * line, gpointer data);
|
||||
typedef void ( * lines_callback ) (GString const * line, gpointer data);
|
||||
|
||||
//Splits console output into lines and passes each one to a callback
|
||||
void process_lines(char * const lines, int len, lines_callback cb, gpointer data)
|
||||
void process_lines(GString * lines, lines_callback cb, gpointer data)
|
||||
{
|
||||
int prev = 0, current = 0;
|
||||
while (current < len)
|
||||
while (current < lines->len)
|
||||
{
|
||||
if (lines[current] == '\n')
|
||||
if (lines->str[current] == '\n')
|
||||
{
|
||||
char * line = (char *)malloc(current - prev + 1);
|
||||
memcpy(line, lines + prev, current - prev);
|
||||
line[current - prev] = '\0';
|
||||
GString * line = g_string_new_len(lines->str + prev, current - prev);
|
||||
cb(line, data);
|
||||
free(line);
|
||||
g_string_free(line, TRUE);
|
||||
prev = current + 1;
|
||||
}
|
||||
current++;
|
||||
@@ -57,49 +68,46 @@ void process_lines(char * const lines, int len, lines_callback cb, gpointer data
|
||||
}
|
||||
|
||||
#define ASSIGN_TO_MOD(FIELD) \
|
||||
strncpy(mod->FIELD, val_start + 2, MOD_##FIELD##_MAX_LEN - 1); \
|
||||
mod->FIELD[MOD_##FIELD##_MAX_LEN - 1] = '\0'
|
||||
mod->FIELD = g_strdup(val_start)
|
||||
|
||||
#define min(X, Y) X < Y ? X : Y
|
||||
|
||||
void mod_metadata_line(char const * line, gpointer data)
|
||||
void mod_metadata_line(GString const * line, gpointer data)
|
||||
{
|
||||
mod_t * mod = (mod_t *)data;
|
||||
char * val_start = strchr(line, ':');
|
||||
if (memcmp(line, "Mod:", 4) == 0)
|
||||
gchar * val_start = g_strstr_len(line->str, -1, ":") + 2;
|
||||
if (g_str_has_prefix(line->str, "Mod:"))
|
||||
{
|
||||
ASSIGN_TO_MOD(key);
|
||||
}
|
||||
else if (memcmp(line, " Title:", min(strlen(line), 8)) == 0)
|
||||
else if (g_str_has_prefix(line->str, " Title:"))
|
||||
{
|
||||
ASSIGN_TO_MOD(title);
|
||||
}
|
||||
else if (memcmp(line, " Version:", min(strlen(line), 10)) == 0)
|
||||
else if (g_str_has_prefix(line->str, " Version:"))
|
||||
{
|
||||
ASSIGN_TO_MOD(version);
|
||||
}
|
||||
else if (memcmp(line, " Author:", min(strlen(line), 9)) == 0)
|
||||
else if (g_str_has_prefix(line->str, " Author:"))
|
||||
{
|
||||
ASSIGN_TO_MOD(author);
|
||||
}
|
||||
else if (memcmp(line, " Description:", min(strlen(line), 14)) == 0)
|
||||
else if (g_str_has_prefix(line->str, " Description:"))
|
||||
{
|
||||
ASSIGN_TO_MOD(description);
|
||||
}
|
||||
else if (memcmp(line, " Requires:", min(strlen(line), 11)) == 0)
|
||||
else if (g_str_has_prefix(line->str, " Requires:"))
|
||||
{
|
||||
ASSIGN_TO_MOD(requires);
|
||||
}
|
||||
else if (memcmp(line, " Standalone:", min(strlen(line), 13)) == 0)
|
||||
else if (g_str_has_prefix(line->str, " Standalone:"))
|
||||
{
|
||||
if (strcmp(val_start + 2, "True") == 0)
|
||||
if (strcmp(val_start, "True") == 0)
|
||||
mod->standalone = TRUE;
|
||||
else
|
||||
mod->standalone = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
mod_t * get_mod(char const * key)
|
||||
mod_t * get_mod(gchar const * key)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < mod_count; i++)
|
||||
@@ -141,20 +149,27 @@ gboolean append_to_mod(GtkTreeModel * model, GtkTreePath * path,
|
||||
|
||||
void mod_metadata_callback(GPid pid, gint status, gpointer data)
|
||||
{
|
||||
int out_len, * out_fd = (int *)data;
|
||||
char * msg = NULL;
|
||||
int * out_fd = (int *)data;
|
||||
GString * msg = NULL;
|
||||
mod_t * mod = mods + mod_count;
|
||||
GtkTreeIter iter, mod_iter;
|
||||
|
||||
mod_count = (mod_count + 1) % MAX_NUM_MODS;
|
||||
|
||||
free_mod(mod);
|
||||
memset(mod, 0, sizeof(mod_t));
|
||||
|
||||
msg = util_get_output(*out_fd, &out_len);
|
||||
msg = util_get_output(*out_fd);
|
||||
|
||||
process_lines(msg, out_len, mod_metadata_line, mod);
|
||||
close(*out_fd);
|
||||
free(out_fd);
|
||||
|
||||
free(msg);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
process_lines(msg, mod_metadata_line, mod);
|
||||
|
||||
g_string_free(msg, TRUE);
|
||||
|
||||
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(tree_store), &mod_iter);
|
||||
|
||||
@@ -185,14 +200,11 @@ void mod_metadata_callback(GPid pid, gint status, gpointer data)
|
||||
{
|
||||
gtk_tree_model_foreach(GTK_TREE_MODEL(tree_store), append_to_mod, mod);
|
||||
}
|
||||
|
||||
close(*out_fd);
|
||||
free(out_fd);
|
||||
}
|
||||
|
||||
typedef struct tree_node
|
||||
{
|
||||
char const * key;
|
||||
gchar const * key;
|
||||
gchar * node_path;
|
||||
} tree_node;
|
||||
|
||||
@@ -222,23 +234,32 @@ gboolean find_mod(GtkTreeModel * model, GtkTreePath * path,
|
||||
|
||||
void last_mod_callback(GPid pid, gint status, gpointer data)
|
||||
{
|
||||
int out_len, * out_fd = (int *)data;
|
||||
char * comma_pos = 0;
|
||||
char * msg = NULL;
|
||||
int * out_fd = (int *)data;
|
||||
gchar * comma_pos = 0, * newline_pos = 0;
|
||||
GString * msg = NULL;
|
||||
tree_node n;
|
||||
|
||||
memset(&n, 0, sizeof(tree_node));
|
||||
|
||||
msg = util_get_output(*out_fd, &out_len);
|
||||
msg = util_get_output(*out_fd);
|
||||
|
||||
if (0 == memcmp(msg, "Error:", 6))
|
||||
memcpy(msg, "ra", 3);
|
||||
else if (NULL != (comma_pos = strchr(msg, ',')))
|
||||
close(*out_fd);
|
||||
free(out_fd);
|
||||
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (0 == strcmp(msg->str, "Error:"))
|
||||
{
|
||||
*comma_pos = '\0';
|
||||
g_string_truncate(msg, 2);
|
||||
g_string_overwrite(msg, 0, "ra");
|
||||
}
|
||||
else if (NULL != (comma_pos = g_strstr_len(msg->str, -1, ",")))
|
||||
*comma_pos = '\0';
|
||||
else if (NULL != (newline_pos = g_strstr_len(msg->str, -1, "\n")))
|
||||
*newline_pos = '\0';
|
||||
|
||||
n.key = msg;
|
||||
n.key = msg->str;
|
||||
|
||||
gtk_tree_model_foreach(GTK_TREE_MODEL(tree_store), find_mod, &n);
|
||||
|
||||
@@ -254,31 +275,35 @@ void last_mod_callback(GPid pid, gint status, gpointer data)
|
||||
g_free(n.node_path);
|
||||
}
|
||||
|
||||
free(msg);
|
||||
g_string_free(msg, TRUE);
|
||||
}
|
||||
|
||||
void mod_list_line(char const * mod, gpointer user)
|
||||
void mod_list_line(GString const * mod, gpointer user)
|
||||
{
|
||||
util_get_mod_metadata(mod, mod_metadata_callback);
|
||||
util_get_mod_metadata(mod->str, mod_metadata_callback);
|
||||
}
|
||||
|
||||
void mod_list_callback(GPid pid, gint status, gpointer data)
|
||||
{
|
||||
int out_len, * out_fd = (int *)data;
|
||||
char * msg = NULL;
|
||||
int * out_fd = (int *)data;
|
||||
GString * msg = NULL;
|
||||
|
||||
msg = util_get_output(*out_fd, &out_len);
|
||||
|
||||
mod_count = 0;
|
||||
|
||||
process_lines(msg, out_len, mod_list_line, NULL);
|
||||
|
||||
util_get_setting("Game.Mods", last_mod_callback);
|
||||
|
||||
free(msg);
|
||||
msg = util_get_output(*out_fd);
|
||||
|
||||
close(*out_fd);
|
||||
free(out_fd);
|
||||
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
mod_count = 0;
|
||||
|
||||
process_lines(msg, mod_list_line, NULL);
|
||||
|
||||
util_get_setting("Game.Mods", last_mod_callback);
|
||||
|
||||
g_string_free(msg, TRUE);
|
||||
|
||||
g_spawn_close_pid(pid);
|
||||
}
|
||||
|
||||
@@ -287,7 +312,7 @@ void tree_view_selection_changed(GtkTreeView * tree_view, gpointer data)
|
||||
GtkTreePath * path;
|
||||
GtkTreeIter iter;
|
||||
gchar * key;
|
||||
char url[256];
|
||||
GString * url;
|
||||
|
||||
gtk_tree_view_get_cursor(tree_view, &path, NULL);
|
||||
|
||||
@@ -306,12 +331,15 @@ void tree_view_selection_changed(GtkTreeView * tree_view, gpointer data)
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(url, "http://localhost:%d/mods/%s/mod.html", WEBSERVER_PORT, key);
|
||||
url = g_string_new(NULL);
|
||||
|
||||
webkit_web_view_load_uri(browser, url);
|
||||
g_string_printf(url, "http://localhost:%d/mods/%s/mod.html", WEBSERVER_PORT, key);
|
||||
|
||||
webkit_web_view_load_uri(browser, url->str);
|
||||
|
||||
g_free(key);
|
||||
gtk_tree_path_free(path);
|
||||
g_string_free(url, TRUE);
|
||||
}
|
||||
|
||||
void make_tree_view(void)
|
||||
|
||||
@@ -16,26 +16,19 @@ enum
|
||||
N_COLUMNS
|
||||
};
|
||||
|
||||
#define MOD_key_MAX_LEN 16
|
||||
#define MOD_title_MAX_LEN 32
|
||||
#define MOD_version_MAX_LEN 16
|
||||
#define MOD_author_MAX_LEN 32
|
||||
#define MOD_description_MAX_LEN 128
|
||||
#define MOD_requires_MAX_LEN 32
|
||||
|
||||
#define MAX_NUM_MODS 64
|
||||
|
||||
typedef struct mod_t
|
||||
{
|
||||
char key[MOD_key_MAX_LEN];
|
||||
char title[MOD_title_MAX_LEN];
|
||||
char version[MOD_version_MAX_LEN];
|
||||
char author[MOD_author_MAX_LEN];
|
||||
char description[MOD_description_MAX_LEN];
|
||||
char requires[MOD_requires_MAX_LEN];
|
||||
gchar * key;
|
||||
gchar * title;
|
||||
gchar * version;
|
||||
gchar * author;
|
||||
gchar * description;
|
||||
gchar * requires;
|
||||
int standalone;
|
||||
} mod_t;
|
||||
|
||||
mod_t * get_mod(char const * key);
|
||||
mod_t * get_mod(gchar const * key);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
#include <glib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int util_do_command_async(char * command, GChildWatchFunc callback)
|
||||
gboolean util_do_command_async(gchar * command, GChildWatchFunc callback)
|
||||
{
|
||||
GPid child_pid;
|
||||
gint * out_fd = (gint *)malloc(sizeof(gint));
|
||||
char * spawn_args[] = { "mono", "OpenRA.Utility.exe", command, NULL };
|
||||
gchar * spawn_args[] = { "mono", "OpenRA.Utility.exe", command, NULL };
|
||||
gboolean result;
|
||||
|
||||
result = g_spawn_async_with_pipes(NULL, spawn_args, NULL,
|
||||
@@ -33,17 +33,17 @@ int util_do_command_async(char * command, GChildWatchFunc callback)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int util_get_mod_list (GChildWatchFunc callback)
|
||||
gboolean util_get_mod_list (GChildWatchFunc callback)
|
||||
{
|
||||
return util_do_command_async("-l", callback);
|
||||
}
|
||||
|
||||
int util_do_command_blocking(char * command, GChildWatchFunc callback)
|
||||
gboolean util_do_command_blocking(gchar * command, GChildWatchFunc callback)
|
||||
{
|
||||
GPid child_pid;
|
||||
int status;
|
||||
gint * out_fd = (gint *)malloc(sizeof(gint));
|
||||
char * spawn_args[] = { "mono", "OpenRA.Utility.exe", command, NULL };
|
||||
gint * out_fd = (gint *)g_malloc(sizeof(gint));
|
||||
gchar * spawn_args[] = { "mono", "OpenRA.Utility.exe", command, NULL };
|
||||
gboolean result;
|
||||
|
||||
result = g_spawn_async_with_pipes(NULL, spawn_args, NULL,
|
||||
@@ -55,7 +55,6 @@ int util_do_command_blocking(char * command, GChildWatchFunc callback)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//g_child_watch_add(child_pid, callback, out_fd);
|
||||
waitpid(child_pid, &status, 0);
|
||||
|
||||
callback(child_pid, status, out_fd);
|
||||
@@ -63,47 +62,44 @@ int util_do_command_blocking(char * command, GChildWatchFunc callback)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int util_get_mod_metadata(char const * mod, GChildWatchFunc callback)
|
||||
gboolean util_get_mod_metadata(gchar const * mod, GChildWatchFunc callback)
|
||||
{
|
||||
char * util_args;
|
||||
int return_val;
|
||||
GString * util_args = g_string_new(NULL);
|
||||
gboolean return_val;
|
||||
|
||||
util_args = (char *)malloc(strlen(mod) + strlen("-i=") + 1);
|
||||
sprintf(util_args, "-i=%s", mod);
|
||||
return_val = util_do_command_blocking(util_args, callback);
|
||||
free(util_args);
|
||||
g_string_printf(util_args, "-i=%s", mod);
|
||||
return_val = util_do_command_blocking(util_args->str, callback);
|
||||
g_string_free(util_args, TRUE);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
int util_get_setting(const char * setting, GChildWatchFunc callback)
|
||||
gboolean util_get_setting(gchar const * setting, GChildWatchFunc callback)
|
||||
{
|
||||
char * command;
|
||||
int return_val;
|
||||
GString * command = g_string_new(NULL);
|
||||
gboolean return_val;
|
||||
|
||||
command = (char *)malloc(strlen(setting) + strlen("--settings-value=~/.openra,") + 1);
|
||||
sprintf(command, "--settings-value=~/.openra,%s", setting);
|
||||
return_val = util_do_command_blocking(command, callback);
|
||||
free(command);
|
||||
g_string_printf(command, "--settings-value=~/.openra,%s", setting);
|
||||
return_val = util_do_command_blocking(command->str, callback);
|
||||
g_string_free(command, TRUE);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
int util_spawn_with_command(const char * command, const char * arg1, const char * arg2, GPid * pid)
|
||||
gint util_spawn_with_command(gchar const * command, gchar const * arg1, gchar const * arg2, GPid * pid)
|
||||
{
|
||||
char * complete_command;
|
||||
int out_fd;
|
||||
GString * complete_command = g_string_new(NULL);
|
||||
gint out_fd;
|
||||
gboolean result;
|
||||
|
||||
char * launch_args[] = { "mono", "OpenRA.Utility.exe", NULL, NULL };
|
||||
gchar * launch_args[] = { "mono", "OpenRA.Utility.exe", NULL, NULL };
|
||||
|
||||
complete_command = (char *)malloc(strlen(command) + strlen(arg1) + strlen(arg2) + 2);
|
||||
sprintf(complete_command, "%s%s,%s", command, arg1, arg2);
|
||||
g_string_printf(complete_command, "%s%s,%s", command, arg1, arg2);
|
||||
|
||||
launch_args[2] = complete_command;
|
||||
launch_args[2] = complete_command->str;
|
||||
|
||||
result = g_spawn_async_with_pipes(NULL, launch_args, NULL, G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, pid, NULL, &out_fd, NULL, NULL);
|
||||
|
||||
free(complete_command);
|
||||
g_string_free(complete_command, TRUE);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -113,39 +109,34 @@ int util_spawn_with_command(const char * command, const char * arg1, const char
|
||||
return out_fd;
|
||||
}
|
||||
|
||||
int util_do_download(const char * url, const char * dest, GPid * pid)
|
||||
gint util_do_download(gchar const * url, gchar const * dest, GPid * pid)
|
||||
{
|
||||
return util_spawn_with_command("--download-url=", url, dest, pid);
|
||||
}
|
||||
|
||||
int util_do_extract(const char * target, const char * dest, GPid * pid)
|
||||
gint util_do_extract(gchar const * target, gchar const * dest, GPid * pid)
|
||||
{
|
||||
return util_spawn_with_command("--extract-zip=", target, dest, pid);
|
||||
}
|
||||
|
||||
char * util_get_output(int fd, int * output_len)
|
||||
GString * util_get_output(int fd)
|
||||
{
|
||||
char buffer[1024], * msg = NULL;
|
||||
char buffer[1024];
|
||||
GString * msg = g_string_new(NULL);
|
||||
int read_bytes = 0;
|
||||
*output_len = 0;
|
||||
while (0 != (read_bytes = read(fd, buffer, 1024)))
|
||||
{
|
||||
if (-1 == read_bytes)
|
||||
{
|
||||
g_error("Error reading from command output");
|
||||
free(msg);
|
||||
*output_len = 0;
|
||||
g_string_free(msg, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*output_len += read_bytes;
|
||||
|
||||
msg = (char *)realloc(msg, *output_len + 1);
|
||||
|
||||
memcpy(msg + (*output_len - read_bytes), buffer, read_bytes);
|
||||
g_string_append_len(msg, buffer, read_bytes);
|
||||
}
|
||||
|
||||
msg[*output_len] = '\0';
|
||||
g_string_append_c(msg, '\0');
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
* see LICENSE.
|
||||
*/
|
||||
|
||||
int util_get_mod_list (GChildWatchFunc);
|
||||
int util_get_mod_metadata(char const *, GChildWatchFunc);
|
||||
int util_get_setting(const char *, GChildWatchFunc);
|
||||
int util_do_download(const char *, const char *, GPid *);
|
||||
int util_do_extract(const char *, const char *, GPid *);
|
||||
char * util_get_output(int, int *);
|
||||
gboolean util_get_mod_list (GChildWatchFunc);
|
||||
gboolean util_get_mod_metadata(gchar const *, GChildWatchFunc);
|
||||
gboolean util_get_setting(gchar const *, GChildWatchFunc);
|
||||
gint util_do_download(gchar const *, gchar const *, GPid *);
|
||||
gint util_do_extract(gchar const *, gchar const *, GPid *);
|
||||
GString * util_get_output(int);
|
||||
|
||||
Reference in New Issue
Block a user