+2006-10-31  Joel E. Denny  <jdenny@ces.clemson.edu>
+
+       Finish implementing --warnings=error, which should not be implied by
+       --warnings=all (or by its synonyms -W and --warnings without
+       subarguments).
+       * src/complain.c (set_warning_issued): New function to report that
+       warnings are being treated as errors and to record an error if so.
+       Invoke...
+       (warn_at, warn): ... here.
+       * src/getargs.c (warnings_args, warnings_types): Reorder so that
+       "error - warnings are errors" does not appear above "all - all of the
+       above".
+       (getargs): For -W and --warnings without subarguments, don't let
+       FLAGS_ARGMATCH set warnings_error in warnings_flag.
+       * src/getargs.h (enum warnings): Unset warnings_error in warnings_all.
+
 2006-10-31  Joel E. Denny  <jdenny@ces.clemson.edu>
 
        * src/getargs.c (flags_argmatch): Don't cause segmentation fault for
 
 
 #include "complain.h"
 #include "files.h"
+#include "getargs.h"
 
 /* The calling program should define program_name and set it to the
    name of the executing program.  */
 | Report a warning, and proceed.  |
 `--------------------------------*/
 
+static void
+set_warning_issued (void)
+{
+  static bool warning_issued = false;
+  if (!warning_issued && (warnings_flag & warnings_error))
+    {
+      fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
+      complaint_issued = true;
+    }
+  warning_issued = true;
+}
+
 void
 warn_at (location loc, const char *message, ...)
 {
+  set_warning_issued ();
   ERROR_MESSAGE (&loc, _("warning"), message);
 }
 
 void
 warn (const char *message, ...)
 {
+  set_warning_issued ();
   ERROR_MESSAGE (NULL, _("warning"), message);
 }
 
 
   /* In a series of synonyms, present the most meaningful first, so
      that argmatch_valid be more readable.  */
   "none       - no warnings",
-  "error      - warnings are errors",
   "yacc       - incompatibilities with POSIX YACC",
   "all        - all of the above",
+  "error      - warnings are errors",
   0
 };
 
 static const int warnings_types[] =
 {
   warnings_none,
-  warnings_error,
   warnings_yacc,
-  warnings_all
+  warnings_all,
+  warnings_error
 };
 
 ARGMATCH_VERIFY (warnings_args, warnings_types);
        break;
 
       case 'W':
-       FLAGS_ARGMATCH (warnings, optarg);
+       if (optarg)
+         FLAGS_ARGMATCH (warnings, optarg);
+       else
+         warnings_flag |= warnings_all;
        break;
 
       case LOCATIONS_OPTION:
 
     warnings_none             = 0,      /**< Issue no warnings.  */
     warnings_error            = 1 << 0, /**< Warnings are treated as errors.  */
     warnings_yacc             = 1 << 1, /**< POSIXME.  */
-    warnings_all              = ~0      /**< All of the above.  */
+    warnings_all              = ~warnings_error /**< All above warnings.  */
   };
 /** What warnings are issued.  */
 extern int warnings_flag;