about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--iconv/Makefile3
-rw-r--r--iconv/iconv_prog.c3
-rw-r--r--iconv/iconv_prog.h6
-rw-r--r--locale/Makefile3
-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
-rw-r--r--localedata/Makefile12
-rw-r--r--localedata/gen-locale.sh24
14 files changed, 384 insertions, 242 deletions
diff --git a/ChangeLog b/ChangeLog
index 9ae9618aa9..fe715d9348 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
 2017-10-25  Carlos O'Donell  <carlos@redhat.com>
 
+	* locale/programs/record-status.h: Define globals, and function
+	prototypes. Move function bodies...
+	* locale/programs/record-status.c: ... to here. New file.
+	* iconv/Makefile (iconv_prog-modules): Add record-status.
+	* locale/Makefile (lib-modules): Likewise.
+	* iconv/iconv_prog.c: Remove verbose.
+	* iconv/iconv_prog.h: Include record-status.h (defines verbose).
+	* locale/programs/charmap.c (charmap_read): If warn_ascii is true then
+	record a warning about ASCII compatibility.
+	* locale/programs/ld-monetary.c (monetary_finish): If
+	warn_int_curr_symbol is true then record a warning about the symbol
+	not being in our ISO 4217 list.
+	* locale/programs/locale.c: Include record-status.h. Remove verbose.
+	* locale/programs/localedef.c: Include ctype.h. Remove delcaration of
+	verbose, recorded_warning_count, recorded_error_count, and be_quiet.
+	(OPT_NO_WARN): Define.
+	(OPT_WARN): Define.
+	(options): Add entry for --no-warnings, and --warnings.
+	(set_warnings): New function to enable/disable warnings.
+	(parse_opt): Call set_warnings for OPT_NO_WARN and OPT_WARN.
+	* locale/programs/localedef.h: Remove warn_int_curr_symbol.
+	* localedata/gen-locale.sh: Default flags to `--quiet -c'.
+	Add `--no-warnings=ascii' to locales using SHIFT_JIS or SHIFT_JIXX0213.
+	Pass flags to generate_locale.
+	(generate_locale): Accept new flag argument and pass it to localedef
+	invocation.
+	* localedata/Makefile (INSTALL-SUPPORTED-LOCALES): Use
+	--no-warnings=ascii for SHIFT_JIS and SHIFT_JISX0213 charmaps.
+
 	* localedata/Makefile (test-input-data): Use full file name.
 	* localedata/da_DK.in: Rename to...
 	* localedata/da_DK.ISO-8859-1.in: ...this.
diff --git a/iconv/Makefile b/iconv/Makefile
index fd3575178e..d3405651d6 100644
--- a/iconv/Makefile
+++ b/iconv/Makefile
@@ -31,7 +31,8 @@ routines	+= gconv_dl
 vpath %.c ../locale/programs ../intl
 
 iconv_prog-modules = iconv_charmap charmap charmap-dir linereader \
-		     dummy-repertoire simple-hash xstrdup xmalloc
+		     dummy-repertoire simple-hash xstrdup xmalloc \
+		     record-status
 iconvconfig-modules = strtab xmalloc hash-string
 extra-objs	   = $(iconv_prog-modules:=.o) $(iconvconfig-modules:=.o)
 CFLAGS-iconv_prog.c = -I../locale/programs
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
index 35d6eb3646..52b9c78afe 100644
--- a/iconv/iconv_prog.c
+++ b/iconv/iconv_prog.c
@@ -97,9 +97,6 @@ static const char *to_code = "";
 /* File to write output to.  If NULL write to stdout.  */
 static const char *output_file;
 
-/* Nonzero if verbose ouput is wanted.  */
-int verbose;
-
 /* Nonzero if list of all coded character sets is wanted.  */
 static int list;
 
diff --git a/iconv/iconv_prog.h b/iconv/iconv_prog.h
index 1571fc9181..cc2a6774a9 100644
--- a/iconv/iconv_prog.h
+++ b/iconv/iconv_prog.h
@@ -20,11 +20,9 @@
 #define _ICONV_PROG_H	1
 
 #include <stdio.h>
-#include <charmap.h>
-
 
-/* Nonzero if verbose ouput is wanted.  */
-extern int verbose;
+#include <charmap.h>
+#include <record-status.h>
 
 /* If nonzero omit invalid character from output.  */
 extern int omit_invalid;
diff --git a/locale/Makefile b/locale/Makefile
index 98ee76272d..ddbaad7452 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -53,7 +53,8 @@ localedef-modules	:= localedef $(categories:%=ld-%) \
 			   repertoire locarchive
 localedef-aux		:= md5
 locale-modules		:= locale locale-spec
-lib-modules		:= charmap-dir simple-hash xmalloc xstrdup
+lib-modules		:= charmap-dir simple-hash xmalloc xstrdup \
+			   record-status
 
 
 GPERF = gperf
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
diff --git a/localedata/Makefile b/localedata/Makefile
index 75f71bb8b2..a5f3c92d58 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -200,17 +200,25 @@ install-locales: $(INSTALL-SUPPORTED-LOCALES)
 install-locales-dir:
 	$(..)./scripts/mkinstalldirs $(inst_complocaledir)
 
+# The SHIFT_JIS and SHIFT_JISX0213 character maps are not ASCII compatible,
+# therefore we have to use --no-warnings=ascii to disable the ASCII check.
+# See localedata/gen-locale.sh for the same logic.
 $(INSTALL-SUPPORTED-LOCALES): install-locales-dir
 	@locale=`echo $@ | sed -e 's/^install-//'`; \
 	charset=`echo $$locale | sed -e 's,.*/,,'`; \
 	locale=`echo $$locale | sed -e 's,/[^/]*,,'`; \
+	flags="--quiet -c"; \
+	if [ "$$charset" = 'SHIFT_JIS' ] \
+	   || [ "$$charset" = 'SHIFT_JISX0213' ]; then \
+	   flags="$$flags --no-warnings=ascii"; \
+	fi; \
 	echo -n `echo $$locale | sed 's/\([^.\@]*\).*/\1/'`; \
 	echo -n ".$$charset"; \
 	echo -n `echo $$locale | sed 's/\([^\@]*\)\(\@.*\)*/\2/'`; \
 	echo -n '...'; \
 	input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \
-	$(LOCALEDEF) --alias-file=../intl/locale.alias \
-		     -i locales/$$input -c -f charmaps/$$charset \
+	$(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \
+		     -i locales/$$input -f charmaps/$$charset \
 		     $(addprefix --prefix=,$(install_root)) $$locale \
 	&& echo ' done'; \
 
diff --git a/localedata/gen-locale.sh b/localedata/gen-locale.sh
index b4ec68c36e..757a0e9321 100644
--- a/localedata/gen-locale.sh
+++ b/localedata/gen-locale.sh
@@ -30,16 +30,12 @@ generate_locale ()
   charmap=$1
   input=$2
   out=$3
+  flags=$4
   ret=0
   ${localedef_before_env} ${run_program_env} I18NPATH=../localedata \
-	${localedef_after_env} --quiet -c -f $charmap -i $input \
+	${localedef_after_env} $flags -f $charmap -i $input \
 	${common_objpfx}localedata/$out || ret=$?
-  # All locales compile fine, except those with SHIFT_JIS charmap
-  # and those fail with exit code 1 because SHIFT_JIS issues a
-  # warning (it is not ASCII compatible).
-  if [ $ret -eq 0 ] \
-     || ( [ $ret -eq 1 ] \
-          && [ "$charmap" = "SHIFT_JIS" ] ); then
+  if [ $ret -eq 0 ]; then
     # The makefile checks the timestamp of the LC_CTYPE file,
     # but localedef won't have touched it if it was able to
     # hard-link it to an existing file.
@@ -57,6 +53,9 @@ charmap=`echo $locfile|sed 's|[^.]*[.]\(.*\)/LC_CTYPE|\1|'`
 
 echo "Generating locale $locale.$charmap: this might take a while..."
 
+# Run quietly and force output.
+flags="--quiet -c"
+
 # For SJIS the charmap is SHIFT_JIS. We just want the locale to have
 # a slightly nicer name instead of using "*.SHIFT_SJIS", but that
 # means we need a mapping here.
@@ -65,4 +64,13 @@ if [ "$charmap" = "SJIS" ]; then
   charmap_real="SHIFT_JIS"
 fi
 
-generate_locale $charmap_real $locale $locale.$charmap
+# In addition to this the SHIFT_JIS character maps are not ASCII
+# compatible so we must use `--no-warnings=ascii' to disable the
+# warning. See localedata/Makefile $(INSTALL-SUPPORTED-LOCALES)
+# for the same logic.
+if [ "$charmap_real" = 'SHIFT_JIS' ] \
+   || [ "$charmpa_real" = 'SHIFT_JISX0213' ]; then
+  flags="$flags --no-warnings=ascii"
+fi
+
+generate_locale $charmap_real $locale $locale.$charmap "$flags"