summaryrefslogtreecommitdiff
path: root/locale/programs
diff options
context:
space:
mode:
Diffstat (limited to 'locale/programs')
-rw-r--r--locale/programs/charmap.c12
-rw-r--r--locale/programs/ld-monetary.c9
-rw-r--r--locale/programs/locale.c8
-rw-r--r--locale/programs/localedef.c67
-rw-r--r--locale/programs/localedef.h1
-rw-r--r--locale/programs/record-status.c229
-rw-r--r--locale/programs/record-status.h220
7 files changed, 323 insertions, 223 deletions
diff --git a/locale/programs/charmap.c b/locale/programs/charmap.c
index a670db9532..964d932372 100644
--- a/locale/programs/charmap.c
+++ b/locale/programs/charmap.c
@@ -256,9 +256,15 @@ charmap_read (const char *filename, int verbose, int error_not_found,
if (failed)
{
- record_warning (_("\
-character map `%s' is not ASCII compatible, locale not ISO C compliant\n"),
- result->code_set_name);
+ /* A user may disable the ASCII compatibility warning check,
+ but we must remember that the encoding is not ASCII
+ compatible, since it may have other implications. Later
+ we will set _NL_CTYPE_MAP_TO_NONASCII from this value. */
+ if (warn_ascii)
+ record_warning (_(
+"character map `%s' is not ASCII compatible, locale not ISO C compliant "
+"[--no-warnings=ascii]"),
+ result->code_set_name);
enc_not_ascii_compatible = true;
}
}
diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c
index 9d94738041..13c9697ae1 100644
--- a/locale/programs/ld-monetary.c
+++ b/locale/programs/ld-monetary.c
@@ -234,12 +234,17 @@ No definition for %s category found"), "LC_MONETARY");
char symbol[4];
strncpy (symbol, monetary->int_curr_symbol, 3);
symbol[3] = '\0';
+ /* A user may disable this waning for testing purposes or
+ for building a locale with a 3 letter country code that
+ was not yet supported in our ISO 4217 list.
+ See the use of --no-warnings=intcurrsym. */
if (bsearch (symbol, valid_int_curr, NR_VALID_INT_CURR,
sizeof (const char *),
- (comparison_fn_t) curr_strcmp) == NULL)
+ (comparison_fn_t) curr_strcmp) == NULL
+ && warn_int_curr_symbol)
record_warning (_("\
%s: value of field `int_curr_symbol' does \
-not correspond to a valid name in ISO 4217"),
+not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
"LC_MONETARY");
}
}
diff --git a/locale/programs/locale.c b/locale/programs/locale.c
index a29a32bc1a..939214dbd0 100644
--- a/locale/programs/locale.c
+++ b/locale/programs/locale.c
@@ -40,6 +40,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
+#include "record-status.h"
#include "localeinfo.h"
#include "charmap-dir.h"
#include "../locarchive.h"
@@ -59,13 +60,6 @@ static int do_all;
/* Print names of all available character maps. */
static int do_charmaps = 0;
-/* Nonzero if verbose output is wanted. Note that this definition is
- file-local in scope, and does not extended to uses of verbose in
- record-status.h functions like record_verbose. This means that this
- verbose will not enable record_verbose messages for uses from locale,
- but it does for uses from localdef (where verbose is global). */
-static int verbose;
-
/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index 7d76154228..973bb55c1f 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -32,6 +32,7 @@
#include <error.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <ctype.h>
#include "localedef.h"
#include "charmap.h"
@@ -48,18 +49,6 @@ struct copy_def_list_t *copy_list;
/* If this is defined be POSIX conform. */
int posix_conformance;
-/* If not zero give a lot more messages. */
-int verbose;
-
-/* Warnings recorded by record_warnings (see localedef.h). */
-int recorded_warning_count;
-
-/* Errors recorded by record_error (see localedef.h). */
-int recorded_error_count;
-
-/* If not zero suppress warnings and information messages. */
-int be_quiet;
-
/* If not zero force output even if warning were issued. */
static int force_output;
@@ -114,6 +103,8 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
#define OPT_LIST_ARCHIVE 309
#define OPT_LITTLE_ENDIAN 400
#define OPT_BIG_ENDIAN 401
+#define OPT_NO_WARN 402
+#define OPT_WARN 403
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
@@ -134,6 +125,13 @@ static const struct argp_option options[] =
{ "quiet", OPT_QUIET, NULL, 0,
N_("Suppress warnings and information messages") },
{ "verbose", 'v', NULL, 0, N_("Print more messages") },
+ { "no-warnings", OPT_NO_WARN, N_("<warnings>"), 0,
+ N_("Comma-separated list of warnings to disable; "
+ "supported warnings are: ascii, intcurrsym") },
+ { "warnings", OPT_WARN, N_("<warnings>"), 0,
+ N_("Comma-separated list of warnings to enable; "
+ "supported warnings are: ascii, intcurrsym") },
+
{ NULL, 0, NULL, 0, N_("Archive control:") },
{ "no-archive", OPT_NO_ARCHIVE, NULL, 0,
N_("Don't add new data to archive") },
@@ -309,6 +307,43 @@ no output file produced because errors were issued"));
exit (recorded_warning_count != 0);
}
+/* Search warnings for matching warnings and if found enable those
+ warnings if ENABLED is true, otherwise disable the warnings. */
+static void
+set_warnings (char *warnings, bool enabled)
+{
+ char *tok = warnings;
+ char *copy = (char *) malloc (strlen (warnings) + 1);
+ char *save = copy;
+
+ /* As we make a copy of the warnings list we remove all spaces from
+ the warnings list to make the processing a more robust. We don't
+ support spaces in a warning name. */
+ do
+ {
+ while (isspace (*tok) != 0)
+ tok++;
+ }
+ while ((*save++ = *tok++) != '\0');
+
+ warnings = copy;
+
+ /* Tokenize the input list of warnings to set, compare them to
+ known warnings, and set the warning. We purposely ignore unknown
+ warnings, and are thus forward compatible, users can attempt to
+ disable whaterver new warnings they know about, but we will only
+ disable those *we* known about. */
+ while ((tok = strtok_r (warnings, ",", &save)) != NULL)
+ {
+ warnings = NULL;
+ if (strcmp (tok, "ascii") == 0)
+ warn_ascii = enabled;
+ else if (strcmp (tok, "intcurrsym") == 0)
+ warn_int_curr_symbol = enabled;
+ }
+
+ free (copy);
+}
/* Handle program arguments. */
static error_t
@@ -346,6 +381,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
case OPT_BIG_ENDIAN:
set_big_endian (true);
break;
+ case OPT_NO_WARN:
+ /* Disable the warnings. */
+ set_warnings (arg, false);
+ break;
+ case OPT_WARN:
+ /* Enable the warnings. */
+ set_warnings (arg, true);
+ break;
case 'c':
force_output = 1;
break;
diff --git a/locale/programs/localedef.h b/locale/programs/localedef.h
index 96aa6966a0..89b3ff08a7 100644
--- a/locale/programs/localedef.h
+++ b/locale/programs/localedef.h
@@ -114,7 +114,6 @@ struct localedef_t
/* Global variables of the localedef program. */
-extern int verbose;
extern const char *repertoire_global;
extern int max_locarchive_open_retry;
extern bool no_archive;
diff --git a/locale/programs/record-status.c b/locale/programs/record-status.c
new file mode 100644
index 0000000000..ab85d7611f
--- /dev/null
+++ b/locale/programs/record-status.c
@@ -0,0 +1,229 @@
+/* Functions for recorded errors, warnings, and verbose messages.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ 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; version 2 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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <error.h>
+#include <errno.h>
+#include <locale.h>
+
+#include "record-status.h"
+
+/* Warnings recorded by record_warnings. */
+int recorded_warning_count;
+
+/* Errors recorded by record_errors. */
+int recorded_error_count;
+
+/* If not zero suppress warnings and information messages. */
+int be_quiet;
+
+/* If not zero give a lot more messages. */
+int verbose;
+
+/* Warnings which can be disabled: */
+/* By default we check the character map for ASCII compatibility. */
+bool warn_ascii = true;
+/* By default we check that the international currency symbol matches a
+ known country code. */
+bool warn_int_curr_symbol = true;
+
+/* Alter the current locale to match the locale configured by the
+ user, and return the previous saved state. */
+struct locale_state
+push_locale (void)
+{
+ int saved_errno;
+ const char *orig;
+ char *copy = NULL;
+
+ saved_errno = errno;
+
+ orig = setlocale (LC_CTYPE, NULL);
+ if (orig == NULL)
+ error (0, 0, "failed to read locale!");
+
+ if (setlocale (LC_CTYPE, "") == NULL)
+ error (0, 0, "failed to set locale!");
+
+ errno = saved_errno;
+
+ if (orig != NULL)
+ copy = strdup (orig);
+
+ /* We will return either a valid locale or NULL if we failed
+ to save the locale. */
+ return (struct locale_state) { .cur_locale = copy };
+}
+
+/* Use the saved state to restore the locale. */
+void
+pop_locale (struct locale_state ls)
+{
+ const char *set = NULL;
+ /* We might have failed to save the locale, so only attempt to
+ restore a validly saved non-NULL locale. */
+ if (ls.cur_locale != NULL)
+ {
+ set = setlocale (LC_CTYPE, ls.cur_locale);
+ if (set == NULL)
+ error (0, 0, "failed to restore %s locale!", ls.cur_locale);
+
+ free (ls.cur_locale);
+ }
+}
+
+/* Wrapper to print verbose informative messages.
+ Verbose messages are only printed if --verbose
+ is in effect and --quiet is not. */
+void
+__attribute__ ((__format__ (__printf__, 2, 3), nonnull (1, 2), unused))
+record_verbose (FILE *stream, const char *format, ...)
+{
+ char *str;
+ va_list arg;
+
+ if (!verbose)
+ return;
+
+ if (!be_quiet)
+ {
+ struct locale_state ls;
+ int ret;
+
+ va_start (arg, format);
+ ls = push_locale ();
+
+ ret = vasprintf (&str, format, arg);
+ if (ret == -1)
+ abort ();
+
+ pop_locale (ls);
+ va_end (arg);
+
+ fprintf (stream, "[verbose] %s\n", str);
+
+ free (str);
+ }
+}
+
+/* Wrapper to print warning messages. We keep track of how
+ many were called because this effects our exit code.
+ Nothing is printed if --quiet is in effect, but warnings
+ are always counted. */
+void
+__attribute__ ((__format__ (__printf__, 1, 2), nonnull (1), unused))
+record_warning (const char *format, ...)
+{
+ char *str;
+ va_list arg;
+
+ recorded_warning_count++;
+
+ if (!be_quiet)
+ {
+ struct locale_state ls;
+ int ret;
+
+ va_start (arg, format);
+ ls = push_locale ();
+
+ ret = vasprintf (&str, format, arg);
+ if (ret == -1)
+ abort ();
+
+ pop_locale (ls);
+ va_end (arg);
+
+ fprintf (stderr, "[warning] %s\n", str);
+
+ free (str);
+ }
+}
+
+/* Wrapper to print error messages. We keep track of how
+ many were called because this effects our exit code.
+ Nothing is printed if --quiet is in effect, but errors
+ are always counted, and fatal errors always exit the
+ program. */
+void
+__attribute__ ((__format__ (__printf__, 3, 4), nonnull (3), unused))
+record_error (int status, int errnum, const char *format, ...)
+{
+ char *str;
+ va_list arg;
+
+ recorded_error_count++;
+
+ /* The existing behaviour is that even if you use --quiet, a fatal
+ error is always printed and terminates the process. */
+ if (!be_quiet || status != 0)
+ {
+ struct locale_state ls;
+ int ret;
+
+ va_start (arg, format);
+ ls = push_locale ();
+
+ ret = vasprintf (&str, format, arg);
+ if (ret == -1)
+ abort ();
+
+ pop_locale (ls);
+ va_end (arg);
+
+ error (status, errnum, "[error] %s", str);
+
+ free (str);
+ }
+}
+/* ... likewise for error_at_line. */
+void
+__attribute__ ((__format__ (__printf__, 5, 6), nonnull (3, 5), unused))
+record_error_at_line (int status, int errnum, const char *filename,
+ unsigned int linenum, const char *format, ...)
+{
+ char *str;
+ va_list arg;
+
+ recorded_error_count++;
+
+ /* The existing behaviour is that even if you use --quiet, a fatal
+ error is always printed and terminates the process. */
+ if (!be_quiet || status != 0)
+ {
+ struct locale_state ls;
+ int ret;
+
+ va_start (arg, format);
+ ls = push_locale ();
+
+ ret = vasprintf (&str, format, arg);
+ if (ret == -1)
+ abort ();
+
+ pop_locale (ls);
+ va_end (arg);
+
+ error_at_line (status, errnum, filename, linenum, "[error] %s", str);
+
+ free (str);
+ }
+}
diff --git a/locale/programs/record-status.h b/locale/programs/record-status.h
index b6bc58cddc..345f7f4b37 100644
--- a/locale/programs/record-status.h
+++ b/locale/programs/record-status.h
@@ -18,210 +18,34 @@
#ifndef _RECORD_STATUS_H
#define _RECORD_STATUS_H 1
-#include <stdlib.h>
-#include <stdarg.h>
-#include <error.h>
-#include <locale.h>
-#include <string.h>
-
-/* We tentatively define all of the global data we use:
- * recorded_warning_count: Number of warnings counted.
- * recorded_error_count: Number of errors counted.
- * be_quiet: Should all calls be silent?
- * verbose: Should verbose messages be printed? */
-int recorded_warning_count;
-int recorded_error_count;
-int be_quiet;
-int verbose;
-
-/* Saved locale state. */
+#include <stdio.h>
+#include <stdbool.h>
+
+/* Error, warning and verbose count and control. */
+extern int recorded_warning_count;
+extern int recorded_error_count;
+extern int be_quiet;
+extern int verbose;
+extern bool warn_ascii;
+extern bool warn_int_curr_symbol;
+
+/* Record verbose, warnings, or errors... */
+void record_verbose (FILE *stream, const char *format, ...);
+void record_warning (const char *format, ...);
+void record_error (int status, int errnum, const char *format, ...);
+void record_error_at_line (int status, int errnum,
+ const char *filename, unsigned int linenum,
+ const char *format, ...);
+
+/* Locale related functionality for custom error functions. */
struct locale_state
{
/* The current in-use locale. */
char *cur_locale;
};
-/* Alter the current locale to match the locale configured by the
- user, and return the previous saved state. */
-static struct locale_state
-push_locale (void)
-{
- int saved_errno;
- const char *orig;
- char *copy = NULL;
-
- saved_errno = errno;
-
- orig = setlocale (LC_CTYPE, NULL);
- if (orig == NULL)
- error (0, 0, "failed to read locale!");
-
- if (setlocale (LC_CTYPE, "") == NULL)
- error (0, 0, "failed to set locale!");
-
- errno = saved_errno;
-
- if (orig != NULL)
- copy = strdup (orig);
-
- /* We will return either a valid locale or NULL if we failed
- to save the locale. */
- return (struct locale_state) { .cur_locale = copy };
-}
-
-/* Use the saved state to restore the locale. */
-static void
-pop_locale (struct locale_state ls)
-{
- const char *set = NULL;
- /* We might have failed to save the locale, so only attempt to
- restore a validly saved non-NULL locale. */
- if (ls.cur_locale != NULL)
- {
- set = setlocale (LC_CTYPE, ls.cur_locale);
- if (set == NULL)
- error (0, 0, "failed to restore %s locale!", ls.cur_locale);
-
- free (ls.cur_locale);
- }
-}
-
-/* Wrapper to print verbose informative messages.
- Verbose messages are only printed if --verbose
- is in effect and --quiet is not. */
-static void
-__attribute__ ((__format__ (__printf__, 2, 3), nonnull (1, 2), unused))
-record_verbose (FILE *stream, const char *format, ...)
-{
- char *str;
- va_list arg;
-
- if (!verbose)
- return;
-
- if (!be_quiet)
- {
- struct locale_state ls;
- int ret;
-
- va_start (arg, format);
- ls = push_locale ();
-
- ret = vasprintf (&str, format, arg);
- if (ret == -1)
- abort ();
-
- pop_locale (ls);
- va_end (arg);
-
- fprintf (stream, "%s\n", str);
-
- free (str);
- }
-}
-
-/* Wrapper to print warning messages. We keep track of how
- many were called because this effects our exit code.
- Nothing is printed if --quiet is in effect, but warnings
- are always counted. */
-static void
-__attribute__ ((__format__ (__printf__, 1, 2), nonnull (1), unused))
-record_warning (const char *format, ...)
-{
- char *str;
- va_list arg;
-
- recorded_warning_count++;
-
- if (!be_quiet)
- {
- struct locale_state ls;
- int ret;
-
- va_start (arg, format);
- ls = push_locale ();
-
- ret = vasprintf (&str, format, arg);
- if (ret == -1)
- abort ();
-
- pop_locale (ls);
- va_end (arg);
-
- fprintf (stderr, "%s\n", str);
-
- free (str);
- }
-}
-
-/* Wrapper to print error messages. We keep track of how
- many were called because this effects our exit code.
- Nothing is printed if --quiet is in effect, but errors
- are always counted, and fatal errors always exit the
- program. */
-static void
-__attribute__ ((__format__ (__printf__, 3, 4), nonnull (3), unused))
-record_error (int status, int errnum, const char *format, ...)
-{
- char *str;
- va_list arg;
-
- recorded_error_count++;
-
- /* The existing behaviour is that even if you use --quiet, a fatal
- error is always printed and terminates the process. */
- if (!be_quiet || status != 0)
- {
- struct locale_state ls;
- int ret;
-
- va_start (arg, format);
- ls = push_locale ();
-
- ret = vasprintf (&str, format, arg);
- if (ret == -1)
- abort ();
-
- pop_locale (ls);
- va_end (arg);
-
- error (status, errnum, "%s", str);
-
- free (str);
- }
-}
-/* ... likewise for error_at_line. */
-static void
-__attribute__ ((__format__ (__printf__, 5, 6), nonnull (3, 5), unused))
-record_error_at_line (int status, int errnum, const char *filename,
- unsigned int linenum, const char *format, ...)
-{
- char *str;
- va_list arg;
-
- recorded_error_count++;
-
- /* The existing behaviour is that even if you use --quiet, a fatal
- error is always printed and terminates the process. */
- if (!be_quiet || status != 0)
- {
- struct locale_state ls;
- int ret;
-
- va_start (arg, format);
- ls = push_locale ();
-
- ret = vasprintf (&str, format, arg);
- if (ret == -1)
- abort ();
-
- pop_locale (ls);
- va_end (arg);
-
- error_at_line (status, errnum, filename, linenum, "%s", str);
+struct locale_state push_locale (void);
+void pop_locale (struct locale_state ls);
- free (str);
- }
-}
#endif