-/* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 "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 *
int category_mask;
} *scm_t_locale;
-
-/* Free the resources used by LOCALE. */
-static inline void
-scm_i_locale_free (scm_t_locale locale)
-{
- free (locale->locale_name);
- locale->locale_name = NULL;
-}
-
#else /* USE_GNU_LOCALE_API */
/* Alias for glibc's locale type. */
typedef locale_t scm_t_locale;
-#define scm_i_locale_free freelocale
-
#endif /* USE_GNU_LOCALE_API */
#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_SMOB (scm_tc16_locale_smob_type, "locale", 0);
+#ifdef USE_GNU_LOCALE_API
+
SCM_SMOB_FREE (scm_tc16_locale_smob_type, smob_locale_free, locale)
{
scm_t_locale c_locale;
c_locale = (scm_t_locale) SCM_SMOB_DATA (locale);
- scm_i_locale_free (c_locale);
+ if (c_locale)
+ freelocale (c_locale);
return 0;
}
+#endif /* USE_GNU_LOCALE_API */
+
static void inline scm_locale_error (const char *, int) SCM_NORETURN;
c_locale = scm_gc_malloc (sizeof (* c_locale), "locale");
-
lock_locale_mutex ();
c_locale->category_mask = LC_ALL_MASK;
current_locale = setlocale (LC_ALL, NULL);
if (current_locale != NULL)
- {
- c_locale->locale_name = strdup (current_locale);
- if (c_locale->locale_name == NULL)
- err = ENOMEM;
- }
+ c_locale->locale_name = scm_gc_strdup (current_locale, "locale");
else
err = EINVAL;
unlock_locale_mutex ();
- if (err)
- scm_gc_free (c_locale, sizeof (* c_locale), "locale");
- else
+ if (err == 0)
SCM_NEWSMOB (*result, scm_tc16_locale_smob_type, c_locale);
+ else
+ *result = SCM_BOOL_F;
return err;
}
c_locale = newlocale (c_category_mask, c_locale_name, c_base_locale);
free (c_locale_name);
+ c_locale_name = NULL;
if (c_locale == (locale_t) 0)
{
c_locale = scm_gc_malloc (sizeof (* c_locale), "locale");
c_locale->category_mask = c_category_mask;
- c_locale->locale_name = c_locale_name;
+ c_locale->locale_name = scm_gc_strdup (c_locale_name, "locale");
+ free (c_locale_name);
+ c_locale_name = NULL;
if (scm_is_eq (base_locale, SCM_VARIABLE_REF (scm_global_locale)))
{
}
}
+ /* silence gcc's unused variable warning */
+ (void) c_base_locale;
#endif
return 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);
{
#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 */
#else /* !USE_GNU_LOCALE_API */
/* We can't use `RUN_IN_LOCALE_SECTION ()' here because the locale
mutex is already taken. */
else
{
c_result = nl_langinfo (c_item);
-#ifdef HAVE_LANGINFO_CODESET
codeset = nl_langinfo (CODESET);
-#endif /* HAVE_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 = strdup (c_result);
+ if (c_result != NULL)
+ c_result = strdup (c_result);
+
unlock_locale_mutex ();
if (c_result == NULL)
default:
result = scm_from_latin1_symbol ("unspecified");
}
+ free (c_result);
break;
#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);
-
- return SCM_BOOL_F;
-#endif
}
#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))
DEFINE_NLITEM_CONSTANT (T_FMT); /* Time format for strftime. */
DEFINE_NLITEM_CONSTANT (T_FMT_AMPM);/* 12-hour time format for strftime. */
+#ifdef ERA
DEFINE_NLITEM_CONSTANT (ERA); /* Alternate era. */
+#endif
+#ifdef ERA_D_FMT
DEFINE_NLITEM_CONSTANT (ERA_D_FMT); /* Date in alternate era format. */
+#endif
+#ifdef ERA_D_T_FMT
DEFINE_NLITEM_CONSTANT (ERA_D_T_FMT); /* Date and time in alternate era
format. */
+#endif
+#ifdef ERA_T_FMT
DEFINE_NLITEM_CONSTANT (ERA_T_FMT); /* Time in alternate era format. */
+#endif
+#ifdef ALT_DIGITS
DEFINE_NLITEM_CONSTANT (ALT_DIGITS); /* Alternate symbols for digits. */
+#endif
DEFINE_NLITEM_CONSTANT (RADIXCHAR);
DEFINE_NLITEM_CONSTANT (THOUSEP);
#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"