aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/m4/lib/hard-locale.c
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-10-21 10:21:33 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-10-21 10:21:33 +0000
commit4eca37ecd81a80606e9c2afed5401f15d15e3671 (patch)
treeedb21b983f86981f8ed77704231cbe589bc19bdd /contrib/tools/m4/lib/hard-locale.c
parent7f4d37b99e25e931918580a353dba7eed11407ee (diff)
parentd3ed30f2deefe6a5ed0d07a3018c723749ca5d7b (diff)
downloadydb-4eca37ecd81a80606e9c2afed5401f15d15e3671.tar.gz
Merge branch 'rightlib' into mergelibs-241021-1020
Diffstat (limited to 'contrib/tools/m4/lib/hard-locale.c')
-rw-r--r--contrib/tools/m4/lib/hard-locale.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/contrib/tools/m4/lib/hard-locale.c b/contrib/tools/m4/lib/hard-locale.c
new file mode 100644
index 0000000000..c7d9da526f
--- /dev/null
+++ b/contrib/tools/m4/lib/hard-locale.c
@@ -0,0 +1,72 @@
+/* hard-locale.c -- Determine whether a locale is hard.
+
+ Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2016 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "hard-locale.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __GLIBC__
+# define GLIBC_VERSION __GLIBC__
+#elif defined __UCLIBC__
+# define GLIBC_VERSION 2
+#else
+# define GLIBC_VERSION 0
+#endif
+
+/* Return true if the current CATEGORY locale is hard, i.e. if you
+ can't get away with assuming traditional C or POSIX behavior. */
+bool
+hard_locale (int category)
+{
+ bool hard = true;
+ char const *p = setlocale (category, NULL);
+
+ if (p)
+ {
+ if (2 <= GLIBC_VERSION)
+ {
+ if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
+ hard = false;
+ }
+ else
+ {
+ char *locale = strdup (p);
+ if (locale)
+ {
+ /* Temporarily set the locale to the "C" and "POSIX" locales
+ to find their names, so that we can determine whether one
+ or the other is the caller's locale. */
+ if (((p = setlocale (category, "C"))
+ && strcmp (p, locale) == 0)
+ || ((p = setlocale (category, "POSIX"))
+ && strcmp (p, locale) == 0))
+ hard = false;
+
+ /* Restore the caller's locale. */
+ setlocale (category, locale);
+ free (locale);
+ }
+ }
+ }
+
+ return hard;
+}