diff options
author | Ludovic Courtès <ludo@gnu.org> | 2011-12-15 01:23:23 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2011-12-15 01:31:23 +0100 |
commit | ed4c3739668b4b111b38555b8bc101cb74c87c1c (patch) | |
tree | bebdd170764e27c853187118cf36d79fec78697c | |
parent | c2c2b5a49b1ce37a42417037c3515864a808e53b (diff) |
Arrange to convert command-line arguments from the right encoding.
This is a temporary workaround for the 2.0 stable series. The next
stable series should have an implicit `setlocale (LC_ALL, "")' call,
which will make this unnecessary.
* libguile/feature.c (progargs_fluid): Rename to...
(scm_program_arguments_fluid): ... this. Update users.
* libguile/feature.h (scm_program_arguments_fluid): New internal
declaration.
* libguile/init.c (invoke_main_func): Call
`scm_i_set_boot_program_arguments' instead of
`scm_set_program_arguments'.
* libguile/script.c (locale_arguments_to_string_list,
scm_i_set_boot_program_arguments): New functions.
(scm_compile_shell_switches): Use `locale_arguments_to_string_list'.
* libguile/script.h (scm_i_set_boot_program_arguments): New internal
declaration.
* test-suite/standalone/Makefile.am (check_SCRIPTS, TESTS): Add
`test-command-line-encoding'.
* test-suite/standalone/test-command-line-encoding: New file.
-rw-r--r-- | libguile/feature.c | 16 | ||||
-rw-r--r-- | libguile/feature.h | 5 | ||||
-rw-r--r-- | libguile/init.c | 2 | ||||
-rw-r--r-- | libguile/script.c | 39 | ||||
-rw-r--r-- | libguile/script.h | 3 | ||||
-rw-r--r-- | test-suite/standalone/Makefile.am | 3 | ||||
-rwxr-xr-x | test-suite/standalone/test-command-line-encoding | 24 |
7 files changed, 81 insertions, 11 deletions
diff --git a/libguile/feature.c b/libguile/feature.c index 700740319..f3bddc788 100644 --- a/libguile/feature.c +++ b/libguile/feature.c @@ -1,5 +1,6 @@ -/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2004, 2006, 2007, 2009 Free Software Foundation, Inc. - * +/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + * 2006, 2007, 2009, 2011 Free Software Foundation, Inc. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 3 of @@ -36,7 +37,8 @@ -static SCM progargs_fluid; +SCM scm_program_arguments_fluid; + static SCM features_var; void @@ -58,7 +60,7 @@ SCM_DEFINE (scm_program_arguments, "program-arguments", 0, 0, 0, "options like @code{-e} and @code{-l}.") #define FUNC_NAME s_scm_program_arguments { - return scm_fluid_ref (progargs_fluid); + return scm_fluid_ref (scm_program_arguments_fluid); } #undef FUNC_NAME @@ -74,7 +76,7 @@ scm_set_program_arguments (int argc, char **argv, char *first) SCM args = scm_makfromstrs (argc, argv); if (first) args = scm_cons (scm_from_locale_string (first), args); - scm_fluid_set_x (progargs_fluid, args); + scm_fluid_set_x (scm_program_arguments_fluid, args); } SCM_DEFINE (scm_set_program_arguments_scm, "set-program-arguments", 1, 0, 0, @@ -89,7 +91,7 @@ SCM_DEFINE (scm_set_program_arguments_scm, "set-program-arguments", 1, 0, 0, "strings within it are copied, so should not be modified later.") #define FUNC_NAME s_scm_set_program_arguments_scm { - return scm_fluid_set_x (progargs_fluid, lst); + return scm_fluid_set_x (scm_program_arguments_fluid, lst); } #undef FUNC_NAME @@ -99,7 +101,7 @@ SCM_DEFINE (scm_set_program_arguments_scm, "set-program-arguments", 1, 0, 0, void scm_init_feature() { - progargs_fluid = scm_make_fluid (); + scm_program_arguments_fluid = scm_make_fluid (); features_var = scm_c_define ("*features*", SCM_EOL); #ifndef _Windows diff --git a/libguile/feature.h b/libguile/feature.h index d373bc773..467f9ed74 100644 --- a/libguile/feature.h +++ b/libguile/feature.h @@ -3,7 +3,8 @@ #ifndef SCM_FEATURE_H #define SCM_FEATURE_H -/* Copyright (C) 1995,1996,1999,2000,2001, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1999, 2000, 2001, 2006, 2007, 2008, + * 2011 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,6 +30,8 @@ SCM_API void scm_add_feature (const char* str); SCM_API SCM scm_program_arguments (void); SCM_API void scm_set_program_arguments (int argc, char **argv, char *first); SCM_API SCM scm_set_program_arguments_scm (SCM lst); + +SCM_INTERNAL SCM scm_program_arguments_fluid; SCM_INTERNAL void scm_init_feature (void); #endif /* SCM_FEATURE_H */ diff --git a/libguile/init.c b/libguile/init.c index 8e3888d3e..633f8c681 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -332,7 +332,7 @@ invoke_main_func (void *body_data) { struct main_func_closure *closure = (struct main_func_closure *) body_data; - scm_set_program_arguments (closure->argc, closure->argv, 0); + scm_i_set_boot_program_arguments (closure->argc, closure->argv); (*closure->main_func) (closure->closure, closure->argc, closure->argv); scm_restore_signals (); diff --git a/libguile/script.c b/libguile/script.c index 5e0685a56..83daf8ac1 100644 --- a/libguile/script.c +++ b/libguile/script.c @@ -22,10 +22,12 @@ # include <config.h> #endif +#include <localcharset.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <ctype.h> +#include <uniconv.h> #include "libguile/_scm.h" #include "libguile/eval.h" @@ -368,6 +370,41 @@ scm_shell_usage (int fatal, char *message) : SCM_BOOL_F)); } +/* Return a list of strings from ARGV, which contains ARGC strings + assumed to be encoded in the current locale. Use + `environ_locale_charset' instead of relying on + `scm_from_locale_string' because the user hasn't had a change to call + (setlocale LC_ALL "") yet. + + XXX: This hack is for 2.0 and will be removed in the next stable + series where the `setlocale' call will be implicit. See + <http://lists.gnu.org/archive/html/guile-devel/2011-11/msg00040.html> + for details. */ +static SCM +locale_arguments_to_string_list (int argc, char **const argv) +{ + int i; + SCM lst; + const char *encoding; + + encoding = environ_locale_charset (); + for (i = argc - 1, lst = SCM_EOL; + i >= 0; + i--) + lst = scm_cons (scm_from_stringn (argv[i], (size_t) -1, encoding, + SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE), + lst); + + return lst; +} + +/* Set the value returned by `program-arguments', given ARGC and ARGV. */ +void +scm_i_set_boot_program_arguments (int argc, char *argv[]) +{ + scm_fluid_set_x (scm_program_arguments_fluid, + locale_arguments_to_string_list (argc, argv)); +} /* Given an array of command-line switches, return a Scheme expression to carry out the actions specified by the switches. @@ -378,7 +415,7 @@ scm_compile_shell_switches (int argc, char **argv) { return scm_call_2 (scm_c_public_ref ("ice-9 command-line", "compile-shell-switches"), - scm_makfromstrs (argc, argv), + locale_arguments_to_string_list (argc, argv), (scm_usage_name ? scm_from_locale_string (scm_usage_name) : scm_from_latin1_string ("guile"))); diff --git a/libguile/script.h b/libguile/script.h index 7e3828aa3..cf0162a40 100644 --- a/libguile/script.h +++ b/libguile/script.h @@ -3,7 +3,7 @@ #ifndef SCM_SCRIPT_H #define SCM_SCRIPT_H -/* Copyright (C) 1997,1998,2000, 2006, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000, 2006, 2008, 2011 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -37,6 +37,7 @@ SCM_API void scm_shell_usage (int fatal, char *message); SCM_API SCM scm_compile_shell_switches (int argc, char **argv); SCM_API void scm_shell (int argc, char **argv); SCM_API char *scm_usage_name; +SCM_INTERNAL void scm_i_set_boot_program_arguments (int argc, char *argv[]); SCM_INTERNAL void scm_init_script (void); #endif /* SCM_SCRIPT_H */ diff --git a/test-suite/standalone/Makefile.am b/test-suite/standalone/Makefile.am index 55d2ea5f7..08d249c48 100644 --- a/test-suite/standalone/Makefile.am +++ b/test-suite/standalone/Makefile.am @@ -82,6 +82,9 @@ TESTS += test-import-order EXTRA_DIST += test-import-order-a.scm test-import-order-b.scm \ test-import-order-c.scm test-import-order-d.scm +check_SCRIPTS += test-command-line-encoding +TESTS += test-command-line-encoding + # test-num2integral test_num2integral_SOURCES = test-num2integral.c test_num2integral_CFLAGS = ${test_cflags} diff --git a/test-suite/standalone/test-command-line-encoding b/test-suite/standalone/test-command-line-encoding new file mode 100755 index 000000000..525c0aeed --- /dev/null +++ b/test-suite/standalone/test-command-line-encoding @@ -0,0 +1,24 @@ +#!/bin/sh + +# Choose a UTF-8 locale. The locale doesn't have to be available on the +# system since `environ_locale_charset' does not actually try to set it. +LC_ALL="en_US.UTF-8" +export LC_ALL +unset LANG +unset LC_CTYPE + +exec guile -q -s "$0" "λ" +!# + +;; Make sure our first argument is a lower-case lambda. +;; +;; Up to Guile 2.0.3 included, command-line arguments would not be converted +;; according to the locale settings; see +;; <http://lists.gnu.org/archive/html/guile-devel/2011-11/msg00026.html> for +;; details. +(exit (string=? (cadr (program-arguments)) "λ")) + +;; Local Variables: +;; mode: scheme +;; coding: utf-8 +;; End: |