[Top][All Lists]
[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
- Re: typo in error module,
Eric Blake <=