[03/14] Add internal implementations for argp.h, err.h, and error.h functions

Message ID 20180621021023.17036-4-gabriel@inconstante.eti.br
State New
Headers show
Series
  • Functions with format string for IEEE128 on powercpc64le
Related show

Commit Message

Gabriel F. T. Gomes June 21, 2018, 2:10 a.m.
Since the introduction of explicit flags in the internal implementation
of the printf family of functions, the 'mode' parameter can be used to
select which format long double parameters have (with the mode flag:
PRINTF_LDBL_IS_DBL).  This patch uses this feature in the implementation
of some functions in argp.h, err.h, and error.h (only those that take a
format string and positional parameters).  Future patches will add
support for 'nldbl' and 'ieee128' versions of these functions.

Tested for powerpc64le.

	* argp/argp-help.c (__argp_error_internal): New function,
	renamed from __argp_error, but that takes a 'mode_flags'
	parameter to control the format of long double parameters.
	(__argp_error): Converted into a call __argp_error_internal.
	(__argp_failure_internal): New function, renamed from
	__argp_failure, but that takes a 'mode_flags' parameter.
	(__argp_failure): Converted into a call __argp_failure_internal.
	* misc/err.c: [defined _LIBC] Include libioP.h for the
	definitions of __vfprintf_internal and __vfwprintf_internal.
	(convert_and_print): Add 'mode_flags' parameter.  Call
	__vfwprintf_internal, instead of __vfwprintf.
	(__vwarnx_internal): New function, renamed from vwarnx, but that
	takes a 'mode_flags' parameter.
	(vwarnx): Converted into a call to __vwarnx_internal.
	(__vwarn_internal): New function, renamed from vwarn, but that
	takes a 'mode_flags' parameter.
	(vwarn): Converted into a call to __vwarn_internal.
	* misc/error.c: Include libioP.h for the definitions of
	__vfprintf_internal and __vfwprintf_internal.
	(error_tail): Add 'mode_flags' parameter. Call
	__vfprintf_internal and __vfwprintf_internal.
	(__error_internal): New function, renamed from error, but that
	takes a 'mode_flags' parameter.
	(error): Converted into a call to __error_internal.
	(__error_at_line_internal): New function, renamed from
	error_at_line, but that takes a 'mode_flags' parameter.
	(error_at_line): Converted into a call to
	__error_at_line_internal.
---
 argp/argp-help.c | 44 ++++++++++++++++++++++++++------------------
 misc/err.c       | 36 +++++++++++++++++++++++++++---------
 misc/error.c     | 46 ++++++++++++++++++++++++++++++++--------------
 3 files changed, 85 insertions(+), 41 deletions(-)

-- 
2.14.4

Comments

Joseph Myers June 21, 2018, 9:36 p.m. | #1
On Wed, 20 Jun 2018, Gabriel F. T. Gomes wrote:

> Since the introduction of explicit flags in the internal implementation

> of the printf family of functions, the 'mode' parameter can be used to

> select which format long double parameters have (with the mode flag:

> PRINTF_LDBL_IS_DBL).  This patch uses this feature in the implementation

> of some functions in argp.h, err.h, and error.h (only those that take a

> format string and positional parameters).  Future patches will add

> support for 'nldbl' and 'ieee128' versions of these functions.


It's probably best to work with Paul on review of this patch, in case 
there are any issues where doing things one way rather than another is 
helpful to keeping the glibc and gnulib sources of the argp and error 
interfaces in sync as much as possible.

-- 
Joseph S. Myers
joseph@codesourcery.com

Patch

diff --git a/argp/argp-help.c b/argp/argp-help.c
index 9f25338ca0..6113cb2412 100644
--- a/argp/argp-help.c
+++ b/argp/argp-help.c
@@ -1750,7 +1750,8 @@  weak_alias (__argp_state_help, argp_state_help)
    by the program name and `:', to stderr, and followed by a `Try ... --help'
    message, then exit (1).  */
 void
-__argp_error (const struct argp_state *state, const char *fmt, ...)
+__argp_error_internal (const struct argp_state *state, const char *fmt,
+		       va_list ap, unsigned int mode_flags)
 {
   if (!state || !(state->flags & ARGP_NO_ERRS))
     {
@@ -1758,18 +1759,14 @@  __argp_error (const struct argp_state *state, const char *fmt, ...)
 
       if (stream)
 	{
-	  va_list ap;
-
 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
 	  __flockfile (stream);
 #endif
 
-	  va_start (ap, fmt);
-
 #ifdef _LIBC
 	  char *buf;
 
-	  if (__vasprintf (&buf, fmt, ap) < 0)
+	  if (__vasprintf_internal (&buf, fmt, ap, mode_flags) < 0)
 	    buf = NULL;
 
 	  __fxprintf (stream, "%s: %s\n",
@@ -1782,21 +1779,27 @@  __argp_error (const struct argp_state *state, const char *fmt, ...)
 	  putc_unlocked (':', stream);
 	  putc_unlocked (' ', stream);
 
-	  vfprintf (stream, fmt, ap);
+	  __vfprintf_internal (stream, fmt, ap, mode_flags);
 
 	  putc_unlocked ('\n', stream);
 #endif
 
 	  __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
 
-	  va_end (ap);
-
 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
 	  __funlockfile (stream);
 #endif
 	}
     }
 }
+void
+__argp_error (const struct argp_state *state, const char *fmt, ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  __argp_error_internal (state, fmt, ap, 0);
+  va_end (ap);
+}
 #ifdef weak_alias
 weak_alias (__argp_error, argp_error)
 #endif
@@ -1810,8 +1813,9 @@  weak_alias (__argp_error, argp_error)
    *parsing errors*, and the former is for other problems that occur during
    parsing but don't reflect a (syntactic) problem with the input.  */
 void
-__argp_failure (const struct argp_state *state, int status, int errnum,
-		const char *fmt, ...)
+__argp_failure_internal (const struct argp_state *state, int status,
+			 int errnum, const char *fmt, va_list ap,
+			 unsigned int mode_flags)
 {
   if (!state || !(state->flags & ARGP_NO_ERRS))
     {
@@ -1833,13 +1837,10 @@  __argp_failure (const struct argp_state *state, int status, int errnum,
 
 	  if (fmt)
 	    {
-	      va_list ap;
-
-	      va_start (ap, fmt);
 #ifdef _LIBC
 	      char *buf;
 
-	      if (__vasprintf (&buf, fmt, ap) < 0)
+	      if (__vasprintf_internal (&buf, fmt, ap, mode_flags) < 0)
 		buf = NULL;
 
 	      __fxprintf (stream, ": %s", buf);
@@ -1849,10 +1850,8 @@  __argp_failure (const struct argp_state *state, int status, int errnum,
 	      putc_unlocked (':', stream);
 	      putc_unlocked (' ', stream);
 
-	      vfprintf (stream, fmt, ap);
+	      __vfprintf_internal (stream, fmt, ap, mode_flags);
 #endif
-
-	      va_end (ap);
 	    }
 
 	  if (errnum)
@@ -1887,6 +1886,15 @@  __argp_failure (const struct argp_state *state, int status, int errnum,
 	}
     }
 }
+void
+__argp_failure (const struct argp_state *state, int status, int errnum,
+		const char *fmt, ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  __argp_failure_internal (state, status, errnum, fmt, ap, 0);
+  va_end (ap);
+}
 #ifdef weak_alias
 weak_alias (__argp_failure, argp_failure)
 #endif
diff --git a/misc/err.c b/misc/err.c
index 2b836e8358..e46bda3021 100644
--- a/misc/err.c
+++ b/misc/err.c
@@ -27,6 +27,10 @@ 
 #define flockfile(s) _IO_flockfile (s)
 #define funlockfile(s) _IO_funlockfile (s)
 
+#ifdef _LIBC
+# include <../libio/libioP.h>
+#endif
+
 extern char *__progname;
 
 #define VA(call)							      \
@@ -38,7 +42,8 @@  extern char *__progname;
 }
 
 static void
-convert_and_print (const char *format, __gnuc_va_list ap)
+convert_and_print (const char *format, __gnuc_va_list ap,
+		   unsigned int mode_flags)
 {
 #define ALLOCA_LIMIT	2000
   size_t len;
@@ -79,32 +84,33 @@  convert_and_print (const char *format, __gnuc_va_list ap)
     /* The string cannot be converted.  */
     wformat = (wchar_t *) L"???";
 
-  __vfwprintf (stderr, wformat, ap);
+  __vfwprintf_internal (stderr, wformat, ap, mode_flags);
 }
 
 void
-vwarnx (const char *format, __gnuc_va_list ap)
+__vwarnx_internal (const char *format, __gnuc_va_list ap,
+		   unsigned int mode_flags)
 {
   flockfile (stderr);
   if (_IO_fwide (stderr, 0) > 0)
     {
       __fwprintf (stderr, L"%s: ", __progname);
-      convert_and_print (format, ap);
+      convert_and_print (format, ap, mode_flags);
       putwc_unlocked (L'\n', stderr);
     }
   else
     {
       fprintf (stderr, "%s: ", __progname);
       if (format)
-	vfprintf (stderr, format, ap);
+	__vfprintf_internal (stderr, format, ap, mode_flags);
       putc_unlocked ('\n', stderr);
     }
   funlockfile (stderr);
 }
-libc_hidden_def (vwarnx)
 
 void
-vwarn (const char *format, __gnuc_va_list ap)
+__vwarn_internal (const char *format, __gnuc_va_list ap,
+		   unsigned int mode_flags)
 {
   int error = errno;
 
@@ -114,7 +120,7 @@  vwarn (const char *format, __gnuc_va_list ap)
       __fwprintf (stderr, L"%s: ", __progname);
       if (format)
 	{
-	  convert_and_print (format, ap);
+	  convert_and_print (format, ap, mode_flags);
 	  fputws_unlocked (L": ", stderr);
 	}
       __set_errno (error);
@@ -125,7 +131,7 @@  vwarn (const char *format, __gnuc_va_list ap)
       fprintf (stderr, "%s: ", __progname);
       if (format)
 	{
-	  vfprintf (stderr, format, ap);
+	  __vfprintf_internal (stderr, format, ap, mode_flags);
 	  fputs_unlocked (": ", stderr);
 	}
       __set_errno (error);
@@ -133,8 +139,20 @@  vwarn (const char *format, __gnuc_va_list ap)
     }
   funlockfile (stderr);
 }
+
+void
+vwarn (const char *format, __gnuc_va_list ap)
+{
+  __vwarn_internal (format, ap, 0);
+}
 libc_hidden_def (vwarn)
 
+void
+vwarnx (const char *format, __gnuc_va_list ap)
+{
+  __vwarnx_internal (format, ap, 0);
+}
+libc_hidden_def (vwarnx)
 
 void
 warn (const char *format, ...)
diff --git a/misc/error.c b/misc/error.c
index b4e8b6c938..9f8067eb9b 100644
--- a/misc/error.c
+++ b/misc/error.c
@@ -39,6 +39,7 @@ 
 # include <stdbool.h>
 # include <stdint.h>
 # include <wchar.h>
+# include <../libio/libioP.h>
 # define mbsrtowcs __mbsrtowcs
 # define USE_UNLOCKED_IO 0
 # define _GL_ATTRIBUTE_FORMAT_PRINTF(a, b)
@@ -200,7 +201,8 @@  print_errno_message (int errnum)
 }
 
 static void _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) _GL_ARG_NONNULL ((3))
-error_tail (int status, int errnum, const char *message, va_list args)
+error_tail (int status, int errnum, const char *message, va_list args,
+	    unsigned int mode_flags)
 {
 #if _LIBC
   if (_IO_fwide (stderr, 0) > 0)
@@ -261,14 +263,14 @@  error_tail (int status, int errnum, const char *message, va_list args)
 	  wmessage = (wchar_t *) L"???";
 	}
 
-      __vfwprintf (stderr, wmessage, args);
+      __vfwprintf_internal (stderr, wmessage, args, mode_flags);
 
       if (use_malloc)
 	free (wmessage);
     }
   else
 #endif
-    vfprintf (stderr, message, args);
+    __vfprintf_internal (stderr, message, args, mode_flags);
   va_end (args);
 
   ++error_message_count;
@@ -290,10 +292,9 @@  error_tail (int status, int errnum, const char *message, va_list args)
    If ERRNUM is nonzero, print its corresponding system error message.
    Exit with status STATUS if it is nonzero.  */
 void
-error (int status, int errnum, const char *message, ...)
+__error_internal (int status, int errnum, const char *message,
+		  va_list args, unsigned int mode_flags)
 {
-  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.  */
@@ -317,8 +318,7 @@  error (int status, int errnum, const char *message, ...)
 #endif
     }
 
-  va_start (args, message);
-  error_tail (status, errnum, message, args);
+  error_tail (status, errnum, message, args, mode_flags);
 
 #ifdef _LIBC
   _IO_funlockfile (stderr);
@@ -327,17 +327,25 @@  error (int status, int errnum, const char *message, ...)
 # endif
 #endif
 }
+
+void
+error (int status, int errnum, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  __error_internal (status, errnum, message, ap, 0);
+  va_end (ap);
+}
 
 /* Sometimes we want to have at most one error per line.  This
    variable controls whether this mode is selected or not.  */
 int error_one_per_line;
 
 void
-error_at_line (int status, int errnum, const char *file_name,
-	       unsigned int line_number, const char *message, ...)
+__error_at_line_internal (int status, int errnum, const char *file_name,
+			  unsigned int line_number, const char *message,
+			  va_list args, unsigned int mode_flags)
 {
-  va_list args;
-
   if (error_one_per_line)
     {
       static const char *old_file_name;
@@ -388,8 +396,7 @@  error_at_line (int status, int errnum, const char *file_name,
 	   file_name, line_number);
 #endif
 
-  va_start (args, message);
-  error_tail (status, errnum, message, args);
+  error_tail (status, errnum, message, args, mode_flags);
 
 #ifdef _LIBC
   _IO_funlockfile (stderr);
@@ -399,6 +406,17 @@  error_at_line (int status, int errnum, const char *file_name,
 #endif
 }
 
+void
+error_at_line (int status, int errnum, const char *file_name,
+	       unsigned int line_number, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  __error_at_line_internal (status, errnum, file_name, line_number,
+			    message, ap, 0);
+  va_end (ap);
+}
+
 #ifdef _LIBC
 /* Make the weak alias.  */
 # undef error