Converted most of GTK launcher to use glib's string functions.

This commit is contained in:
Matthew Bowra-Dean
2010-12-30 16:04:47 +13:00
committed by Chris Forbes
parent 9739e7f51f
commit 0a1e6d16bd
5 changed files with 144 additions and 132 deletions

View File

@@ -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,7 +101,7 @@ JSValueRef js_exists_in_mod(JSContextRef ctx, JSObjectRef func,
fclose(f);
return_value = JSValueMakeNumber(ctx, 1);
}
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);

View File

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

View File

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

View File

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

View File

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