From 7fcda040abed69893157e6114f5570c7476d0a10 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ji=C5=99=C3=AD=20Techet?= Date: Thu, 2 Jul 2015 18:14:56 +0200 Subject: [PATCH] Fix various utf8/locale problems in build and message window Non-ascii characters in file/directory names caused: 1. build commands didn't succeed 2. characters in the message window weren't shown in correct encoding 3. clicking on a row with error in the message window didn't open the file with error. This patch fixes these three issues. --- src/build.c | 32 +++++++++++++------------------- src/msgwindow.c | 35 ++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/build.c b/src/build.c index 86811d43b..bdbb05b2c 100644 --- a/src/build.c +++ b/src/build.c @@ -667,10 +667,8 @@ static void clear_all_errors(void) static gchar *build_replace_placeholder(const GeanyDocument *doc, const gchar *src) { GString *stack; - gchar *filename = NULL; gchar *replacement; gchar *executable = NULL; - gchar *ret_str; /* to be freed when not in use anymore */ gint line_num; g_return_val_if_fail(doc == NULL || doc->is_valid, NULL); @@ -678,20 +676,18 @@ static gchar *build_replace_placeholder(const GeanyDocument *doc, const gchar *s stack = g_string_new(src); if (doc != NULL && doc->file_name != NULL) { - filename = utils_get_utf8_from_locale(doc->file_name); - /* replace %f with the filename (including extension) */ - replacement = g_path_get_basename(filename); + replacement = g_path_get_basename(doc->file_name); utils_string_replace_all(stack, "%f", replacement); g_free(replacement); /* replace %d with the absolute path of the dir of the current file */ - replacement = g_path_get_dirname(filename); + replacement = g_path_get_dirname(doc->file_name); utils_string_replace_all(stack, "%d", replacement); g_free(replacement); /* replace %e with the filename (excluding extension) */ - executable = utils_remove_ext_from_filename(filename); + executable = utils_remove_ext_from_filename(doc->file_name); replacement = g_path_get_basename(executable); utils_string_replace_all(stack, "%e", replacement); g_free(replacement); @@ -712,19 +708,15 @@ static gchar *build_replace_placeholder(const GeanyDocument *doc, const gchar *s else if (strstr(stack->str, "%p")) { /* fall back to %d */ ui_set_statusbar(FALSE, _("failed to substitute %%p, no project active")); - if (doc != NULL && filename != NULL) - replacement = g_path_get_dirname(filename); + if (doc != NULL && doc->file_name != NULL) + replacement = g_path_get_dirname(doc->file_name); } utils_string_replace_all(stack, "%p", replacement); g_free(replacement); - - ret_str = utils_get_utf8_from_locale(stack->str); g_free(executable); - g_free(filename); - g_string_free(stack, TRUE); - return ret_str; /* don't forget to free src also if needed */ + return g_string_free(stack, FALSE); /* don't forget to free src also if needed */ } @@ -733,10 +725,10 @@ static gchar *build_replace_placeholder(const GeanyDocument *doc, const gchar *s static void build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *dir) { GError *error = NULL; - gchar *argv[] = { "/bin/sh", "-c", (gchar *) cmd, NULL }; + gchar *argv[] = { "/bin/sh", "-c", NULL, NULL }; gchar *working_dir; gchar *utf8_working_dir; - gchar *utf8_cmd_string; + gchar *cmd_string; g_return_if_fail(doc == NULL || doc->is_valid); @@ -750,15 +742,16 @@ static void build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *d clear_all_errors(); SETPTR(current_dir_entered, NULL); - utf8_cmd_string = utils_get_utf8_from_locale(cmd); utf8_working_dir = !EMPTY(dir) ? g_strdup(dir) : g_path_get_dirname(doc->file_name); working_dir = utils_get_locale_from_utf8(utf8_working_dir); gtk_list_store_clear(msgwindow.store_compiler); gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_COMPILER); - msgwin_compiler_add(COLOR_BLUE, _("%s (in directory: %s)"), utf8_cmd_string, utf8_working_dir); + msgwin_compiler_add(COLOR_BLUE, _("%s (in directory: %s)"), cmd, utf8_working_dir); g_free(utf8_working_dir); - g_free(utf8_cmd_string); + + cmd_string = utils_get_locale_from_utf8(cmd); + argv[2] = cmd_string; #ifdef G_OS_UNIX cmd = NULL; /* under Unix, use argv to start cmd via sh for compatibility */ @@ -782,6 +775,7 @@ static void build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *d } g_free(working_dir); + g_free(cmd_string); } diff --git a/src/msgwindow.c b/src/msgwindow.c index 4e580b8b3..86fc1ff54 100644 --- a/src/msgwindow.c +++ b/src/msgwindow.c @@ -651,11 +651,16 @@ find_prev_build_dir(GtkTreePath *cur, GtkTreeModel *model, gchar **prefix) } -static gboolean goto_compiler_file_line(const gchar *filename, gint line, gboolean focus_editor) +static gboolean goto_compiler_file_line(const gchar *fname, gint line, gboolean focus_editor) { - if (!filename || line <= -1) + gboolean ret = FALSE; + gchar *filename; + + if (!fname || line <= -1) return FALSE; + filename = utils_get_locale_from_utf8(fname); + /* If the path doesn't exist, try the current document. * This happens when we receive build messages in the wrong order - after the * 'Leaving directory' messages */ @@ -675,8 +680,8 @@ static gboolean goto_compiler_file_line(const gchar *filename, gint line, gboole if (g_file_test(name, G_FILE_TEST_EXISTS)) { ui_set_statusbar(FALSE, _("Could not find file '%s' - trying the current document path."), - filename); - filename = name; + fname); + SETPTR(filename, name); } else g_free(name); @@ -695,8 +700,6 @@ static gboolean goto_compiler_file_line(const gchar *filename, gint line, gboole if (doc != NULL) { - gboolean ret; - if (! doc->changed && editor_prefs.use_indicators) /* if modified, line may be wrong */ editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1); @@ -704,10 +707,13 @@ static gboolean goto_compiler_file_line(const gchar *filename, gint line, gboole if (ret && focus_editor) gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci)); - return ret; + ret = TRUE; } } - return FALSE; + + g_free(filename); + + return ret; } @@ -1009,7 +1015,7 @@ void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir, gchar **filename, gint *line) { GeanyFiletype *ft; - gchar *trimmed_string; + gchar *trimmed_string, *utf8_dir; *filename = NULL; *line = -1; @@ -1018,8 +1024,10 @@ void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir, return; if (dir == NULL) - dir = build_info.dir; - g_return_if_fail(dir != NULL); + utf8_dir = utils_get_utf8_from_locale(build_info.dir); + else + utf8_dir = g_strdup(dir); + g_return_if_fail(utf8_dir != NULL); trimmed_string = g_strdup(string); g_strchug(trimmed_string); /* remove possible leading whitespace */ @@ -1032,8 +1040,9 @@ void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir, /* fallback to default old-style parsing */ parse_compiler_error_line(trimmed_string, filename, line); } - make_absolute(filename, dir); + make_absolute(filename, utf8_dir); g_free(trimmed_string); + g_free(utf8_dir); } @@ -1052,7 +1061,7 @@ static void msgwin_parse_generic_line(const gchar *string, gchar **filename, gin /* extract the filename */ if (fields[0] != NULL) { - *filename = g_strdup(fields[0]); + *filename = utils_get_locale_from_utf8(fields[0]); if (msgwindow.messages_dir != NULL) make_absolute(filename, msgwindow.messages_dir); -- 2.11.4.GIT