mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
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.
This commit is contained in:
parent
c2c2b5a49b
commit
ed4c373966
7 changed files with 81 additions and 11 deletions
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
* as published by the Free Software Foundation; either version 3 of
|
* 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;
|
static SCM features_var;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -58,7 +60,7 @@ SCM_DEFINE (scm_program_arguments, "program-arguments", 0, 0, 0,
|
||||||
"options like @code{-e} and @code{-l}.")
|
"options like @code{-e} and @code{-l}.")
|
||||||
#define FUNC_NAME s_scm_program_arguments
|
#define FUNC_NAME s_scm_program_arguments
|
||||||
{
|
{
|
||||||
return scm_fluid_ref (progargs_fluid);
|
return scm_fluid_ref (scm_program_arguments_fluid);
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ scm_set_program_arguments (int argc, char **argv, char *first)
|
||||||
SCM args = scm_makfromstrs (argc, argv);
|
SCM args = scm_makfromstrs (argc, argv);
|
||||||
if (first)
|
if (first)
|
||||||
args = scm_cons (scm_from_locale_string (first), args);
|
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,
|
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.")
|
"strings within it are copied, so should not be modified later.")
|
||||||
#define FUNC_NAME s_scm_set_program_arguments_scm
|
#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
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ SCM_DEFINE (scm_set_program_arguments_scm, "set-program-arguments", 1, 0, 0,
|
||||||
void
|
void
|
||||||
scm_init_feature()
|
scm_init_feature()
|
||||||
{
|
{
|
||||||
progargs_fluid = scm_make_fluid ();
|
scm_program_arguments_fluid = scm_make_fluid ();
|
||||||
|
|
||||||
features_var = scm_c_define ("*features*", SCM_EOL);
|
features_var = scm_c_define ("*features*", SCM_EOL);
|
||||||
#ifndef _Windows
|
#ifndef _Windows
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
#ifndef SCM_FEATURE_H
|
#ifndef SCM_FEATURE_H
|
||||||
#define 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* 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 SCM scm_program_arguments (void);
|
||||||
SCM_API void scm_set_program_arguments (int argc, char **argv, char *first);
|
SCM_API void scm_set_program_arguments (int argc, char **argv, char *first);
|
||||||
SCM_API SCM scm_set_program_arguments_scm (SCM lst);
|
SCM_API SCM scm_set_program_arguments_scm (SCM lst);
|
||||||
|
|
||||||
|
SCM_INTERNAL SCM scm_program_arguments_fluid;
|
||||||
SCM_INTERNAL void scm_init_feature (void);
|
SCM_INTERNAL void scm_init_feature (void);
|
||||||
|
|
||||||
#endif /* SCM_FEATURE_H */
|
#endif /* SCM_FEATURE_H */
|
||||||
|
|
|
@ -332,7 +332,7 @@ invoke_main_func (void *body_data)
|
||||||
{
|
{
|
||||||
struct main_func_closure *closure = (struct main_func_closure *) 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);
|
(*closure->main_func) (closure->closure, closure->argc, closure->argv);
|
||||||
|
|
||||||
scm_restore_signals ();
|
scm_restore_signals ();
|
||||||
|
|
|
@ -22,10 +22,12 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <localcharset.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <uniconv.h>
|
||||||
|
|
||||||
#include "libguile/_scm.h"
|
#include "libguile/_scm.h"
|
||||||
#include "libguile/eval.h"
|
#include "libguile/eval.h"
|
||||||
|
@ -368,6 +370,41 @@ scm_shell_usage (int fatal, char *message)
|
||||||
: SCM_BOOL_F));
|
: 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
|
/* Given an array of command-line switches, return a Scheme expression
|
||||||
to carry out the actions specified by the switches.
|
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",
|
return scm_call_2 (scm_c_public_ref ("ice-9 command-line",
|
||||||
"compile-shell-switches"),
|
"compile-shell-switches"),
|
||||||
scm_makfromstrs (argc, argv),
|
locale_arguments_to_string_list (argc, argv),
|
||||||
(scm_usage_name
|
(scm_usage_name
|
||||||
? scm_from_locale_string (scm_usage_name)
|
? scm_from_locale_string (scm_usage_name)
|
||||||
: scm_from_latin1_string ("guile")));
|
: scm_from_latin1_string ("guile")));
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#ifndef SCM_SCRIPT_H
|
#ifndef SCM_SCRIPT_H
|
||||||
#define 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
* 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 SCM scm_compile_shell_switches (int argc, char **argv);
|
||||||
SCM_API void scm_shell (int argc, char **argv);
|
SCM_API void scm_shell (int argc, char **argv);
|
||||||
SCM_API char *scm_usage_name;
|
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);
|
SCM_INTERNAL void scm_init_script (void);
|
||||||
|
|
||||||
#endif /* SCM_SCRIPT_H */
|
#endif /* SCM_SCRIPT_H */
|
||||||
|
|
|
@ -82,6 +82,9 @@ TESTS += test-import-order
|
||||||
EXTRA_DIST += test-import-order-a.scm test-import-order-b.scm \
|
EXTRA_DIST += test-import-order-a.scm test-import-order-b.scm \
|
||||||
test-import-order-c.scm test-import-order-d.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
|
||||||
test_num2integral_SOURCES = test-num2integral.c
|
test_num2integral_SOURCES = test-num2integral.c
|
||||||
test_num2integral_CFLAGS = ${test_cflags}
|
test_num2integral_CFLAGS = ${test_cflags}
|
||||||
|
|
24
test-suite/standalone/test-command-line-encoding
Executable file
24
test-suite/standalone/test-command-line-encoding
Executable file
|
@ -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:
|
Loading…
Add table
Add a link
Reference in a new issue