bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: typo in error module


From: Eric Blake
Subject: Re: typo in error module
Date: Tue, 1 Aug 2006 18:10:29 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Paul Eggert <eggert <at> CS.UCLA.EDU> writes:

> > Man, I wish there were an error() variant that took a va_list.
> 
> That'd be a nice thing to add -- could you propose it?
...
> Initially I suppose this stuff should be written so that the new
> interface is exported only in gnulib mode.
> 

I checked with glibc, and our error.c is already pretty far removed from 
theirs, so it wasn't worth my time trying to sync them.  Here's my proposal for 
a va_list variant of error.  OK to check in?  Note that it does affect the 
semantics of anyone using the error_print_progname callback - previously, error 
would not supply a space and now it does.  But that is the only way I could 
make error_at_line consistent with GNU Coding Standards.

>  While you're
> at it, perhaps you could make the new interface reentrant, so that it
> doesn't use the global variables.  (As long as we're wishing....)
> 

For now, I'd rather get verror approved.  But reentrency should just be a 
matter of defining something like:
verror_r (int status, int errnum, void (*print_progname) (void),
          unsigned int *count, char const *format, va_list args);
then doing:
verror(...)
{
  verror_r (status, errnum, error_print_prognam, &error_message_count,
            format, args);
}

I also wonder whether we should add:
[v]error_at_col (int status, int errnum, char const *file, size_t line,
                 size_t col, char const *format, ...);

where if col is nonzero, we output "program:file:line:col: message".  Note that 
I would use size_t (or should it be off_t?), and not the int used by 
error_at_line, since with large file offsets, int is insufficient for line and 
column numbers on worst-case input files.


2006-08-01  Eric Blake  <address@hidden>

        * error.c (error_print_progname): In order to comply with GNU
        Coding Standards as used by both error and error_at_line, this
        must end with a colon, not space.
        (error): Add space after calling error_print_progname.
        (error_at_line): Call exit even when no message is printed.
        Ensure spacing is consistent whether file/line pair is printed or
        not.  Avoid calling strcmp on NULL parameter.
        (verror, verror_at_line): New functions.
        * error.h (verror, verror_at_line): Add prototypes.

Index: lib/error.c
===================================================================
RCS file: /sources/gnulib/gnulib/lib/error.c,v
retrieving revision 1.43
diff -u -r1.43 error.c
--- lib/error.c 14 May 2005 06:03:58 -0000      1.43
+++ lib/error.c 1 Aug 2006 18:07:02 -0000
@@ -1,5 +1,5 @@
 /* Error handler for noninteractive utilities
-   Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1990-1998, 2000-2003, 2004, 2006 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
@@ -46,9 +46,10 @@
 # define _(String) String
 #endif
 
-/* If NULL, error will flush stdout, then print on stderr the program
-   name, a colon and a space.  Otherwise, error will call this
-   function without parameters instead.  */
+/* If NULL, print the contents of program_name and a colon as the program
+   name portion of error and error_at_line.  Otherwise, error will flush
+   stdout then call this function without parameters.  If this
+   callback prints to stderr, it should end output with a colon.  */
 void (*error_print_progname) (void);
 
 /* This variable is incremented each time `error' is called.  */
@@ -68,7 +69,7 @@
 extern void __error_at_line (int status, int errnum, const char *file_name,
                             unsigned int line_number, const char *message,
                             ...)
-     __attribute__ ((__format__ (__printf__, 5, 6)));;
+     __attribute__ ((__format__ (__printf__, 5, 6)));
 # define error __error
 # define error_at_line __error_at_line
 
@@ -181,15 +182,26 @@
 }
 
 
-/* Print the program name and error message MESSAGE, which is a printf-style
-   format string with optional args.
-   If ERRNUM is nonzero, print its corresponding system error message.
-   Exit with status STATUS if it is nonzero.  */
+/* Flush stdout, then print the program name as controlled by
+   error_print_progname, then a space, and the message with
+   `fprintf (stderr, FORMAT, ...)'.
+   GNU Coding Standards suggest that FORMAT start with lower case, and end
+   without a period.  FORMAT should not end with a newline.
+   If ERRNUM is nonzero, follow the message with ": " and strerror (ERRNUM).
+   If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */
 void
 error (int status, int errnum, const char *message, ...)
 {
   va_list args;
 
+  va_start (args, message);
+  verror (status, errnum, message, args);
+}
+
+/* Like error, but take a va_list ARGS instead.  */
+void
+verror (int status, int errnum, const char *message, va_list args)
+{
 #if defined _LIBC && defined __libc_ptf_call
   /* We do not want this call to be cut short by a thread
      cancellation.  Therefore disable cancellation for now.  */
@@ -203,7 +215,15 @@
   _IO_flockfile (stderr);
 #endif
   if (error_print_progname)
-    (*error_print_progname) ();
+    {
+      (*error_print_progname) ();
+#if _LIBC
+      if (_IO_fwide (stderr, 0) > 0)
+       putwc (L' ', stderr);
+      else
+#endif
+       putc (' ', stderr);
+    }
   else
     {
 #if _LIBC
@@ -214,7 +234,6 @@
        fprintf (stderr, "%s: ", program_name);
     }
 
-  va_start (args, message);
   error_tail (status, errnum, message, args);
 
 #ifdef _LIBC
@@ -226,25 +245,43 @@
 }
 
 /* Sometimes we want to have at most one error per line.  This
-   variable controls whether this mode is selected or not.  */
+   variable controls whether this mode is selected or not.  If non-zero,
+   error_at_line will be silent for a repeat location, but will still
+   exit if status is non-zero.  */
 int error_one_per_line;
 
+/* Like error, with the addition that if FNAME is not NULL, the file and
+   line number of the error are printed after the program name.  */
 void
 error_at_line (int status, int errnum, const char *file_name,
               unsigned int line_number, const char *message, ...)
 {
   va_list args;
 
-  if (error_one_per_line)
+  va_start (args, message);
+  verror_at_line (status, errnum, file_name, line_number, message, args);
+}
+
+/* Like error_at_line, but take a va_list ARGS instead.  */
+void
+verror_at_line (int status, int errnum, const char *file_name,
+               unsigned int line_number, const char *message, va_list args)
+{
+  if (error_one_per_line && file_name)
     {
       static const char *old_file_name;
       static unsigned int old_line_number;
 
       if (old_line_number == line_number
+         && old_file_name
          && (file_name == old_file_name
              || strcmp (old_file_name, file_name) == 0))
-       /* Simply return and print nothing.  */
-       return;
+       {
+         /* A message has already been printed for this line.  */
+         if (status)
+           exit (status);
+         return;
+       }
 
       old_file_name = file_name;
       old_line_number = line_number;
@@ -268,7 +305,7 @@
     {
 #if _LIBC
       if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s: ", program_name);
+       __fwprintf (stderr, L"%s:", program_name);
       else
 #endif
        fprintf (stderr, "%s:", program_name);
@@ -283,8 +320,16 @@
 #endif
        fprintf (stderr, "%s:%d: ", file_name, line_number);
     }
+  else
+    {
+#if _LIBC
+      if (_IO_fwide (stderr, 0) > 0)
+       putwc (L' ', stderr);
+      else
+#endif
+       putc (' ', stderr);
+    }
 
-  va_start (args, message);
   error_tail (status, errnum, message, args);
 
 #ifdef _LIBC
Index: lib/error.h
===================================================================
RCS file: /sources/gnulib/gnulib/lib/error.h,v
retrieving revision 1.20
diff -u -r1.20 error.h
--- lib/error.h 14 May 2005 06:03:58 -0000      1.20
+++ lib/error.h 1 Aug 2006 18:07:02 -0000
@@ -1,5 +1,5 @@
 /* Declaration for error-reporting function
-   Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 2003, 2006 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
@@ -32,31 +32,56 @@
 # endif
 #endif
 
+#include <stdarg.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* Print a message with `fprintf (stderr, FORMAT, ...)';
-   if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
+/* Flush stdout, then print the program name as controlled by
+   error_print_progname, then a space, and the message with
+   `fprintf (stderr, FORMAT, ...)'.
+   GNU Coding Standards suggest that FORMAT start with lower case, and end
+   without a period.  FORMAT should not end with a newline.
+   If ERRNUM is nonzero, follow the message with ": " and strerror (ERRNUM).
    If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */
 
 extern void error (int __status, int __errnum, const char *__format, ...)
      __attribute__ ((__format__ (__printf__, 3, 4)));
 
+/* Like error, but take a va_list ARGS instead.  */
+
+extern void verror (int __status, int __errnum, const char *__format,
+                    va_list __args)
+     __attribute__ ((__format__ (__printf__, 3, 0)));
+
+/* Like error, with the addition that if FNAME is not NULL, the file and
+   line number of the error are printed after the program name.  */
+
 extern void error_at_line (int __status, int __errnum, const char *__fname,
                           unsigned int __lineno, const char *__format, ...)
      __attribute__ ((__format__ (__printf__, 5, 6)));
 
-/* If NULL, error will flush stdout, then print on stderr the program
-   name, a colon and a space.  Otherwise, error will call this
-   function without parameters instead.  */
+/* Like error_at_line, but take a va_list ARGS instead.  */
+
+extern void verror_at_line (int __status, int __errnum, const char *__fname,
+                            unsigned int __lineno, const char *__format,
+                            va_list __args)
+     __attribute__ ((__format__ (__printf__, 5, 0)));
+
+/* If NULL, print the contents of program_name and a colon as the program
+   name portion of error and error_at_line.  Otherwise, error will flush
+   stdout then call this function without parameters.  If this
+   callback prints to stderr, it should end output with a colon.  */
 extern void (*error_print_progname) (void);
 
 /* This variable is incremented each time `error' is called.  */
 extern unsigned int error_message_count;
 
 /* Sometimes we want to have at most one error per line.  This
-   variable controls whether this mode is selected or not.  */
+   variable controls whether this mode is selected or not.  If non-zero,
+   error_at_line will be silent for a repeat location, but will still
+   exit if status is non-zero.  */
 extern int error_one_per_line;
 
 #ifdef __cplusplus







reply via email to

[Prev in Thread] Current Thread [Next in Thread]