-/* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2014 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
#include <unicase.h>
#include <unistr.h>
-#if (defined HAVE_NEWLOCALE) && (defined HAVE_STRCOLL_L)
+#if defined HAVE_NEWLOCALE && defined HAVE_STRCOLL_L && defined HAVE_USELOCALE
/* The GNU thread-aware locale API is documented in ``Thread-Aware Locale
Model, a Proposal'', by Ulrich Drepper:
#include "libguile/posix.h" /* for `scm_i_locale_mutex' */
-#ifdef HAVE_LANGINFO_H
-# include <langinfo.h>
-#endif
-#ifdef HAVE_NL_TYPES_H
-# include <nl_types.h>
-#endif
-#ifndef HAVE_NL_ITEM
-/* Cygwin has <langinfo.h> but lacks <nl_types.h> and `nl_item'. */
-typedef int nl_item;
-#endif
+/* Use Gnulib's header, which also provides `nl_item' & co. */
+#include <langinfo.h>
#ifndef HAVE_SETLOCALE
static inline char *
#define SCM_VALIDATE_OPTIONAL_LOCALE_COPY(_pos, _arg, _c_locale) \
do \
{ \
- if (!scm_is_eq ((_arg), SCM_UNDEFINED)) \
+ if (!SCM_UNBNDP (_arg)) \
SCM_VALIDATE_LOCALE_COPY (_pos, _arg, _c_locale); \
else \
(_c_locale) = NULL; \
scm_t_locale c_locale;
c_locale = (scm_t_locale) SCM_SMOB_DATA (locale);
- freelocale (c_locale);
+ if (c_locale)
+ freelocale (c_locale);
return 0;
}
}
}
+ /* silence gcc's unused variable warning */
+ (void) c_base_locale;
#endif
return locale;
Note: We don't use Gnulib's `nl_langinfo' module because it's currently not
as complete as the compatibility hacks in `i18n.scm'. */
+static char *
+copy_string_or_null (const char *s)
+{
+ if (s == NULL)
+ return NULL;
+ else
+ return strdup (s);
+}
SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
(SCM item, SCM locale),
"Reference Manual}).")
#define FUNC_NAME s_scm_nl_langinfo
{
-#ifdef HAVE_NL_LANGINFO
SCM result;
nl_item c_item;
char *c_result;
scm_t_locale c_locale;
-#ifdef HAVE_LANGINFO_CODESET
char *codeset;
-#endif
SCM_VALIDATE_INT_COPY (2, item, c_item);
SCM_VALIDATE_OPTIONAL_LOCALE_COPY (2, locale, c_locale);
if (c_locale != NULL)
{
#ifdef USE_GNU_LOCALE_API
- c_result = nl_langinfo_l (c_item, c_locale);
-#ifdef HAVE_LANGINFO_CODESET
- codeset = nl_langinfo_l (CODESET, c_locale);
-#endif /* HAVE_LANGINFO_CODESET */
+ c_result = copy_string_or_null (nl_langinfo_l (c_item, c_locale));
+ codeset = copy_string_or_null (nl_langinfo_l (CODESET, c_locale));
#else /* !USE_GNU_LOCALE_API */
/* We can't use `RUN_IN_LOCALE_SECTION ()' here because the locale
mutex is already taken. */
scm_locale_error (FUNC_NAME, lsec_err);
else
{
- c_result = nl_langinfo (c_item);
-#ifdef HAVE_LANGINFO_CODESET
- codeset = nl_langinfo (CODESET);
-#endif /* HAVE_LANGINFO_CODESET */
+ c_result = copy_string_or_null (nl_langinfo (c_item));
+ codeset = copy_string_or_null (nl_langinfo (CODESET));
restore_locale_settings (&lsec_prev_locale);
free_locale_settings (&lsec_prev_locale);
}
else
{
- c_result = nl_langinfo (c_item);
-#ifdef HAVE_LANGINFO_CODESET
- codeset = nl_langinfo (CODESET);
-#endif /* HAVE_LANGINFO_CODESET */
+ c_result = copy_string_or_null (nl_langinfo (c_item));
+ codeset = copy_string_or_null (nl_langinfo (CODESET));
}
- c_result = strdup (c_result);
unlock_locale_mutex ();
if (c_result == NULL)
}
#endif
-#if (defined FRAC_DIGITS) && (defined INT_FRAC_DIGITS)
+#if defined FRAC_DIGITS || defined INT_FRAC_DIGITS
+#ifdef FRAC_DIGITS
case FRAC_DIGITS:
+#endif
+#ifdef INT_FRAC_DIGITS
case INT_FRAC_DIGITS:
+#endif
/* This is to be interpreted as a single integer. */
if (*c_result == CHAR_MAX)
/* Unspecified. */
break;
#endif
-#if (defined P_CS_PRECEDES) && (defined INT_N_CS_PRECEDES)
+#if defined P_CS_PRECEDES || defined N_CS_PRECEDES || \
+ defined INT_P_CS_PRECEDES || defined INT_N_CS_PRECEDES || \
+ defined P_SEP_BY_SPACE || defined N_SEP_BY_SPACE
+#ifdef P_CS_PRECEDES
case P_CS_PRECEDES:
case N_CS_PRECEDES:
+#endif
+#ifdef INT_N_CS_PRECEDES
case INT_P_CS_PRECEDES:
case INT_N_CS_PRECEDES:
-#if (defined P_SEP_BY_SPACE) && (defined N_SEP_BY_SPACE)
+#endif
+#ifdef P_SEP_BY_SPACE
case P_SEP_BY_SPACE:
case N_SEP_BY_SPACE:
#endif
break;
#endif
-#if (defined P_SIGN_POSN) && (defined INT_N_SIGN_POSN)
+#if defined P_SIGN_POSN || defined N_SIGN_POSN || \
+ defined INT_P_SIGN_POSN || defined INT_N_SIGN_POSN
+#ifdef P_SIGN_POSN
case P_SIGN_POSN:
case N_SIGN_POSN:
+#endif
+#ifdef INT_P_SIGN_POSN
case INT_P_SIGN_POSN:
case INT_N_SIGN_POSN:
+#endif
/* See `(libc) Sign of Money Amount' for the interpretation of the
return value here. */
switch (*c_result)
#endif
default:
-#ifdef HAVE_LANGINFO_CODESET
result = scm_from_stringn (c_result, strlen (c_result),
codeset,
SCM_FAILED_CONVERSION_QUESTION_MARK);
-#else /* !HAVE_LANGINFO_CODESET */
- /* This may be incorrectly encoded if the locale differs
- from the c_locale. */
- result = scm_from_locale_string (c_result);
-#endif /* !HAVE_LANGINFO_CODESET */
free (c_result);
}
}
- return result;
-#else
- scm_syserror_msg (FUNC_NAME, "`nl-langinfo' not supported on your system",
- SCM_EOL, ENOSYS);
+ if (codeset != NULL)
+ free (codeset);
- return SCM_BOOL_F;
-#endif
+ return result;
}
#undef FUNC_NAME
static inline void
define_langinfo_items (void)
{
-#ifdef HAVE_LANGINFO_H
-
#define DEFINE_NLITEM_CONSTANT(_item) \
scm_c_define (# _item, scm_from_int (_item))
#endif
#undef DEFINE_NLITEM_CONSTANT
-
-#endif /* HAVE_NL_TYPES_H */
}
\f
{
SCM global_locale_smob;
-#ifdef HAVE_NL_LANGINFO
scm_add_feature ("nl-langinfo");
define_langinfo_items ();
-#endif
#include "libguile/i18n.x"