Janne Blomqvist
2018-12-01 21:16:15 UTC
This patch initializes the locale system when using a Fortran main
program. For non-Fortran main programs that link to libgfortran this
is not done, as such programs are expeced to handle locales
themselves. Following the approach used by python
(https://www.python.org/dev/peps/pep-0538/ ), if the user environment
uses the default C locale, it tries a few fallback options (C.UTF-8,
C.utf8, UTF-8) to set the LC_CTYPE to a UTF-8 locale.
This enables localized error messages for OS errors (strerror() etc.).
Currently this is done unconditionally when set_options() is called,
which is done by the Fortran main(). This should perhaps be handled
through the options array, in order to enable users to disable it,
e.g. for non-Fortran main programs that still want to properly
initialize libgfortran?
Regtested on x86_64-pc-linux-gnu, Ok for trunk?
libgfortran/ChangeLog:
2018-12-01 Janne Blomqvist <***@gcc.gnu.org>
* runtime/compile_options.c (set_options): Initialize locale.
---
libgfortran/runtime/compile_options.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c
index 1d37e7709df..02274c8251a 100644
--- a/libgfortran/runtime/compile_options.c
+++ b/libgfortran/runtime/compile_options.c
@@ -24,7 +24,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgfortran.h"
#include <signal.h>
-
+#include <locale.h>
+#include <string.h>
/* Useful compile-time options will be stored in here. */
compile_options_t compile_options;
@@ -161,6 +162,28 @@ set_options (int num, int options[])
compile_options.fpe_summary = options[6];
#ifndef LIBGFOR_MINIMAL
+
+ /* Set the locale. This is not selectable by a compile option, but
+ this should be setup only when using a Fortran main program, not
+ when loading libgfortran. */
+ setlocale (LC_ALL, "");
+ char *ctype_loc = setlocale (LC_CTYPE, NULL);
+ if (ctype_loc && strcmp (ctype_loc, "C") == 0)
+ {
+ /* Try to set the LC_CTYPE to a locale supporting UTF-8 even if
+ the environment specifies the default C locale. This is
+ similar to e.g. python (see PEP 538). */
+ setlocale (LC_CTYPE, "C.UTF-8");
+ ctype_loc = setlocale (LC_CTYPE, NULL);
+ if (ctype_loc && strcmp (ctype_loc, "C") == 0)
+ {
+ setlocale (LC_CTYPE, "C.utf8");
+ ctype_loc = setlocale (LC_CTYPE, NULL);
+ if (ctype_loc && strcmp (ctype_loc, "C") == 0)
+ setlocale (LC_CTYPE, "UTF-8");
+ }
+ }
+
/* If backtrace is required, we set signal handlers on the POSIX
2001 signals with core action. */
if (compile_options.backtrace)
program. For non-Fortran main programs that link to libgfortran this
is not done, as such programs are expeced to handle locales
themselves. Following the approach used by python
(https://www.python.org/dev/peps/pep-0538/ ), if the user environment
uses the default C locale, it tries a few fallback options (C.UTF-8,
C.utf8, UTF-8) to set the LC_CTYPE to a UTF-8 locale.
This enables localized error messages for OS errors (strerror() etc.).
Currently this is done unconditionally when set_options() is called,
which is done by the Fortran main(). This should perhaps be handled
through the options array, in order to enable users to disable it,
e.g. for non-Fortran main programs that still want to properly
initialize libgfortran?
Regtested on x86_64-pc-linux-gnu, Ok for trunk?
libgfortran/ChangeLog:
2018-12-01 Janne Blomqvist <***@gcc.gnu.org>
* runtime/compile_options.c (set_options): Initialize locale.
---
libgfortran/runtime/compile_options.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c
index 1d37e7709df..02274c8251a 100644
--- a/libgfortran/runtime/compile_options.c
+++ b/libgfortran/runtime/compile_options.c
@@ -24,7 +24,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgfortran.h"
#include <signal.h>
-
+#include <locale.h>
+#include <string.h>
/* Useful compile-time options will be stored in here. */
compile_options_t compile_options;
@@ -161,6 +162,28 @@ set_options (int num, int options[])
compile_options.fpe_summary = options[6];
#ifndef LIBGFOR_MINIMAL
+
+ /* Set the locale. This is not selectable by a compile option, but
+ this should be setup only when using a Fortran main program, not
+ when loading libgfortran. */
+ setlocale (LC_ALL, "");
+ char *ctype_loc = setlocale (LC_CTYPE, NULL);
+ if (ctype_loc && strcmp (ctype_loc, "C") == 0)
+ {
+ /* Try to set the LC_CTYPE to a locale supporting UTF-8 even if
+ the environment specifies the default C locale. This is
+ similar to e.g. python (see PEP 538). */
+ setlocale (LC_CTYPE, "C.UTF-8");
+ ctype_loc = setlocale (LC_CTYPE, NULL);
+ if (ctype_loc && strcmp (ctype_loc, "C") == 0)
+ {
+ setlocale (LC_CTYPE, "C.utf8");
+ ctype_loc = setlocale (LC_CTYPE, NULL);
+ if (ctype_loc && strcmp (ctype_loc, "C") == 0)
+ setlocale (LC_CTYPE, "UTF-8");
+ }
+ }
+
/* If backtrace is required, we set signal handlers on the POSIX
2001 signals with core action. */
if (compile_options.backtrace)
--
2.17.1
2.17.1