[geany/geany] 26adca: Windows: Convert generated batch script into system codepage
Enrico Tröger
git-noreply at geany.org
Sun Nov 13 13:55:40 UTC 2016
Branch: refs/heads/master
Author: Enrico Tröger <enrico.troeger at uvena.de>
Committer: Enrico Tröger <enrico.troeger at uvena.de>
Date: Sun, 13 Nov 2016 13:55:40 UTC
Commit: 26adcabd694014328f61b3ca5fe0d5be610849c0
https://github.com/geany/geany/commit/26adcabd694014328f61b3ca5fe0d5be610849c0
Log Message:
-----------
Windows: Convert generated batch script into system codepage
Instead of fiddling with the "chcp" command in the generated batch
script on Windows, convert the whole script content into the system
codepage before executing it.
Modified Paths:
--------------
src/build.c
src/spawn.c
src/win32.c
src/win32.h
Modified: src/build.c
15 lines changed, 8 insertions(+), 7 deletions(-)
===================================================================
@@ -1070,7 +1070,7 @@ static gchar *build_create_shellscript(const gchar *working_dir, const gchar *cm
gboolean success = TRUE;
#ifdef G_OS_WIN32
gchar *expanded_cmd;
- guint codepage;
+ gchar *utf8_script_content;
#else
gchar *escaped_dir;
#endif
@@ -1080,16 +1080,17 @@ static gchar *build_create_shellscript(const gchar *working_dir, const gchar *cm
close(fd);
#ifdef G_OS_WIN32
- /* We set the console codepage to UTF-8 (65001) before changing the working directory
- * because the working directory is in UTF-8 encoding.
- * Then we reset it again to the default value before executing the command. */
- codepage = win32_get_console_codepage();
/* Expand environment variables like %blah%. */
expanded_cmd = win32_expand_environment_variables(cmd);
str = g_strdup_printf(
- "chcp 65001 > nul\ncd \"%s\"\nchcp %u > nul\n\n%s\n\n%s\ndel \"%%0\"\n\npause\n",
- working_dir, codepage, expanded_cmd, (autoclose) ? "" : "pause");
+ "cd \"%s\"\n\n\n%s\n\n%s\ndel \"%%0\"\n\npause\n",
+ working_dir, expanded_cmd, (autoclose) ? "" : "pause");
g_free(expanded_cmd);
+ /* Convert script content into system codepage */
+ utf8_script_content = win32_convert_to_system_codepage(str, error);
+ if (utf8_script_content == NULL)
+ return NULL;
+ SETPTR(str, utf8_script_content);
#else
escaped_dir = g_shell_quote(working_dir);
str = g_strdup_printf(
Modified: src/spawn.c
129 lines changed, 80 insertions(+), 49 deletions(-)
===================================================================
@@ -522,10 +522,9 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch
#ifdef G_OS_WIN32
GString *command;
GArray *environment;
- GError *gerror = NULL;
- gchar *locale_working_directory;
- gchar *locale_command;
- gchar *failure;
+ gchar *locale_working_directory = NULL;
+ gchar *locale_command = NULL;
+ gboolean success = TRUE;
if (command_line)
{
@@ -565,67 +564,99 @@ static gboolean spawn_async_with_pipes(const gchar *working_directory, const gch
g_message("full spawn command line: %s", command->str);
#endif
- while (envp && *envp)
+ while (envp && *envp && success)
{
- g_array_append_vals(environment, *envp, strlen(*envp) + 1);
+ gsize locale_entry_len;
+ gchar *locale_entry;
+
+ if (g_utf8_validate(*envp, -1, NULL))
+ {
+ /* TODO: better error message */
+ locale_entry = g_locale_from_utf8(*envp, -1, NULL, &locale_entry_len, error);
+ }
+ else
+ {
+ locale_entry_len = strlen(*envp);
+ locale_entry = g_memdup(*envp, locale_entry_len + 1);
+ }
+
+ if (! locale_entry)
+ success = FALSE;
+ else
+ {
+ /* copy the entry, including NUL terminator */
+ g_array_append_vals(environment, locale_entry, locale_entry_len + 1);
+ g_free(locale_entry);
+ }
+
envp++;
}
- // convert working directory into locale encoding
- if (g_utf8_validate(working_directory, -1, NULL))
+ /* convert working directory into locale encoding */
+ if (success && working_directory)
{
- locale_working_directory = g_locale_from_utf8(working_directory, -1, NULL, NULL, &gerror);
- if (gerror) {
- /* TODO use the code below post-1.28 as it introduces a new string
- gchar *msg = g_strdup_printf(
- _("Failed to convert working directory into locale encoding: %s"), gerror->message);
- g_set_error_literal(error, gerror->domain, gerror->code, msg);
- */
- g_set_error_literal(error, gerror->domain, gerror->code, gerror->message);
- g_error_free(gerror);
- g_string_free(command, TRUE);
- g_array_free(environment, TRUE);
- g_free(locale_working_directory);
- /*g_free(msg);*/
- return FALSE;
+ if (g_utf8_validate(working_directory, -1, NULL))
+ {
+ GError *gerror = NULL;
+
+ locale_working_directory = g_locale_from_utf8(working_directory, -1, NULL, NULL, &gerror);
+ if (! locale_working_directory)
+ {
+ /* TODO use the code below post-1.28 as it introduces a new string
+ g_set_error(error, gerror->domain, gerror->code,
+ _("Failed to convert working directory into locale encoding: %s"), gerror->message);
+ */
+ g_propagate_error(error, gerror);
+ success = FALSE;
+ }
}
+ else
+ locale_working_directory = g_strdup(working_directory);
}
- // convert command into locale encoding
- if (g_utf8_validate(command->str, -1, NULL))
+ /* convert command into locale encoding */
+ if (success)
{
- locale_command = g_locale_from_utf8(command->str, -1, NULL, NULL, &gerror);
- if (gerror) {
- /* TODO use the code below post-1.28 as it introduces a new string
- gchar *msg = g_strdup_printf(
- _("Failed to convert command into locale encoding: %s"), gerror->message);
- g_set_error_literal(error, gerror->domain, gerror->code, msg);
- */
- g_set_error_literal(error, gerror->domain, gerror->code, gerror->message);
- g_error_free(gerror);
- g_string_free(command, TRUE);
- g_array_free(environment, TRUE);
- g_free(locale_working_directory);
- g_free(locale_command);
- /*g_free(msg);*/
- return FALSE;
+ if (g_utf8_validate(command->str, -1, NULL))
+ {
+ GError *gerror = NULL;
+
+ locale_command = g_locale_from_utf8(command->str, -1, NULL, NULL, &gerror);
+ if (! locale_command)
+ {
+ /* TODO use the code below post-1.28 as it introduces a new string
+ g_set_error(error, gerror->domain, gerror->code,
+ _("Failed to convert command into locale encoding: %s"), gerror->message);
+ */
+ g_propagate_error(error, gerror);
+ success = FALSE;
+ }
+ }
+ else
+ locale_command = g_strdup(command->str);
+ }
+
+ if (success)
+ {
+ gchar *failure;
+
+ failure = spawn_create_process_with_pipes(locale_command, locale_working_directory,
+ envp ? environment->data : NULL, child_pid, stdin_fd, stdout_fd, stderr_fd);
+
+ if (failure)
+ {
+ g_set_error_literal(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, failure);
+ g_free(failure);
}
+
+ success = failure == NULL;
}
- failure = spawn_create_process_with_pipes(locale_command, locale_working_directory,
- envp ? environment->data : NULL, child_pid, stdin_fd, stdout_fd, stderr_fd);
g_string_free(command, TRUE);
g_array_free(environment, TRUE);
g_free(locale_working_directory);
g_free(locale_command);
- if (failure)
- {
- g_set_error_literal(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, failure);
- g_free(failure);
- return FALSE;
- }
-
- return TRUE;
+ return success;
#else /* G_OS_WIN32 */
int cl_argc;
char **full_argv;
Modified: src/win32.c
22 lines changed, 20 insertions(+), 2 deletions(-)
===================================================================
@@ -1034,14 +1034,32 @@ gchar *win32_get_user_config_dir(void)
/* Retrieve the console codepage
- * In case GetConsoleOutputCP() returns 0 (i.e. the application doesn't have an own console window
+ * In case GetConsoleCP() returns 0 (i.e. the application doesn't have an own console window
* fallback to GetOEMCP(). */
guint win32_get_console_codepage(void)
{
- guint codepage = GetConsoleOutputCP();
+ guint codepage = GetConsoleCP();
if (codepage == 0)
codepage = GetOEMCP();
return codepage;
}
+
+/* Convert a string into the system's default codepage, this is different from the
+ * locale (e.g. default codepage is 850 but locale is CP1252).
+ * This assumes the input string is encoded as UTF-8, otherwise a copy of
+ * the input string is returned. */
+gchar *win32_convert_to_system_codepage(const gchar *str, GError **error)
+{
+ if (g_utf8_validate(str, -1, NULL))
+ {
+ guint codepage_code = win32_get_console_codepage();
+ gchar codepage[8] = { 0 };
+ g_snprintf(codepage, G_N_ELEMENTS(codepage), "%u", codepage_code);
+ return g_convert(str, -1, codepage, "utf-8", NULL, NULL, error);
+ }
+ else
+ return g_strdup(str);
+}
+
#endif
Modified: src/win32.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -70,6 +70,8 @@ gchar *win32_get_user_config_dir(void);
guint win32_get_console_codepage(void);
+gchar *win32_convert_to_system_codepage(const gchar *str, GError **error);
+
G_END_DECLS
#endif /* G_OS_WIN32 */
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list