This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: Portability fix for argp/argp.h.
- From: Simon Josefsson <jas at extundo dot com>
- To: Roland McGrath <roland at redhat dot com>
- Cc: Ulrich Drepper <drepper at redhat dot com>, libc-alpha at sources dot redhat dot com
- Date: Fri, 01 Aug 2003 13:07:15 +0200
- Subject: Re: Portability fix for argp/argp.h.
- References: <200308010830.h718UaA01346@magilla.sf.frob.com>
Roland McGrath <roland@redhat.com> writes:
>> Looking into this, I couldn't find the __attribute keyword described
>> anywhere,
>
> Look at the GCC manual. All the trailing __ are optional on the special
> keywords, in fact. But __attribute__ is the canonical form for that one
> and there's no reason not to just fix any __attribute occurrences to
> __attribute__ rather than requiring two macros for portability.
Right, OK.
>> >> +/* Used for extracting the program name from argv[0] */
>> >> +extern char *_argp_basename(char *name) __THROW;
>> >> +extern char *__argp_basename(char *name) __THROW;
>> >> +
>> >> +/* Getting the program name given an argp state */
>> >> +extern char *_argp_short_program_name(const struct argp_state *state) __THROW;
>> >> +extern char *__argp_short_program_name(const struct argp_state *state) __THROW;
>> >>
>> >
>> > The declarations for these functions definitely need not be in an
>> > installed header. I.e., they don't belong in <argp.h>.
>>
>> Definitely, removed.
>
> That doesn't mean repeat the decls so there is no proper checking.
> You can put these in a private header file like argp-namefrob.h.
OK. Revised patch below.
2003-08-01 Simon Josefsson <jas@extundo.com>
* argp/argp-xinl.c: Only include features.h if we are in libc, or
if we have HAVE_FEATURES_H.
* argp/argp-parse.c (argp_default_parser): Only use
program_invocation{_short,}_name if declared.
(argp_default_parser): Use {__argp_,}basename.
(parser_init): Use __argp_short_program_name.
* argp/argp-namefrob.h (__strchrnul, __mempcpy,
__strndup) [!_LIBC]: Remove __-prefix.
(clearerr_unlocked, feof_unlocked, ferror_unlocked)
(fflush_unlocked, fgets_unlocked, fputc_unlocked)
(fputs_unlocked, fread_unlocked, fwrite_unlocked, getc_unlocked)
(getchar_unlocked, putc_unlocked,
putchar_unlocked) [!HAVE_DECL_*]: Map to non-unlocked functions.
(__flockfile, __funlockfile) [HAVE_FLOCKFILE]: Remove __-prefix.
(__flockfile, __funlockfile) [!HAVE_FLOCKFILE]: Define to nothing.
[!_LIBC]: Declare __argp_short_program_name and __argp_basename.
* argp/argp-help.c: Don't include malloc.h, some platforms
complain and it doesn't appear to be used.
[!_LIBC && !HAVE_DECL_STRERROR]: Declare strerror.
[!_LIBC && !HAVE_DECL_STRERROR_R]: Declare strerror_r.
(__argp_basename, __argp_short_program_name): New. Taken from
LSH, by Niels Möller, modifed after comments from Ulrich Drepper.
(__argp_state_help, __argp_error, __argp_failure): Use it.
(__argp_failure): Use strerror() when necessary.
* argp/argp.h [!__attribute__]: Define to nothing.
* argp/argp-fmtstream.h: Ditto.
Index: argp-fmtstream.h
===================================================================
RCS file: /cvs/glibc/libc/argp/argp-fmtstream.h,v
retrieving revision 1.4
diff -u -p -r1.4 argp-fmtstream.h
--- argp-fmtstream.h 6 Jul 2001 04:54:44 -0000 1.4
+++ argp-fmtstream.h 1 Aug 2003 11:01:19 -0000
@@ -34,6 +34,19 @@
#include <string.h>
#include <unistd.h>
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
+# define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
+# define __format__ format
+# define __printf__ printf
+# endif
+#endif
+
#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
|| (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
/* line_wrap_stream is available, so use that. */
Index: argp-help.c
===================================================================
RCS file: /cvs/glibc/libc/argp/argp-help.c,v
retrieving revision 1.37
diff -u -p -r1.37 argp-help.c
--- argp-help.c 13 Jun 2003 20:38:13 -0000 1.37
+++ argp-help.c 1 Aug 2003 11:01:19 -0000
@@ -50,7 +50,6 @@ char *alloca ();
#include <string.h>
#include <assert.h>
#include <stdarg.h>
-#include <malloc.h>
#include <ctype.h>
#ifdef USE_IN_LIBIO
# include <wchar.h>
@@ -70,6 +69,16 @@ char *alloca ();
# endif
#endif
+#ifndef _LIBC
+# if !HAVE_DECL_STRERROR
+char *strerror (int errnum);
+# endif
+# if !HAVE_DECL_STRERROR_R
+char *strerror_r (int errnum, char *buf, size_t buflen);
+# endif
+# define __strerror_r strerror_r
+#endif
+
#include "argp.h"
#include "argp-fmtstream.h"
#include "argp-namefrob.h"
@@ -547,7 +556,7 @@ hol_entry_short_iterate (const struct ho
}
static inline int
-__attribute ((always_inline))
+__attribute__ ((always_inline))
hol_entry_long_iterate (const struct hol_entry *entry,
int (*func)(const struct argp_option *opt,
const struct argp_option *real,
@@ -1665,6 +1674,32 @@ void __argp_help (const struct argp *arg
weak_alias (__argp_help, argp_help)
#endif
+#ifndef _LIBC
+char *__argp_basename (char *name)
+{
+ char *short_name = strrchr (name, '/');
+ return short_name ? short_name + 1 : name;
+}
+#endif
+
+char *
+__argp_short_program_name (void)
+{
+#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME || defined _LIBC
+ return program_invocation_short_name;
+#elif HAVE_DECL_PROGRAM_INVOCATION_NAME
+ return __argp_basename (program_invocation_name);
+#else
+ /* FIXME: What now? Miles suggests that it is better to use NULL,
+ but currently the value is passed on directly to fputs_unlocked,
+ so that requires more changes. */
+#if __GNUC__
+# warning No reasonable value to return
+#endif /* __GNUC__ */
+ return "";
+#endif
+}
+
/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
from the set ARGP_HELP_*. */
void
@@ -1676,7 +1711,7 @@ __argp_state_help (const struct argp_sta
flags |= ARGP_HELP_LONG_ONLY;
_help (state ? state->root_argp : 0, state, stream, flags,
- state ? state->name : program_invocation_short_name);
+ state ? state->name : __argp_short_program_name ());
if (!state || ! (state->flags & ARGP_NO_EXIT))
{
@@ -1717,7 +1752,7 @@ __argp_error (const struct argp_state *s
__asprintf (&buf, fmt, ap);
__fwprintf (stream, L"%s: %s\n",
- state ? state->name : program_invocation_short_name,
+ state ? state->name : __argp_short_program_name (),
buf);
free (buf);
@@ -1726,7 +1761,7 @@ __argp_error (const struct argp_state *s
#endif
{
fputs_unlocked (state
- ? state->name : program_invocation_short_name,
+ ? state->name : __argp_short_program_name (),
stream);
putc_unlocked (':', stream);
putc_unlocked (' ', stream);
@@ -1771,11 +1806,11 @@ __argp_failure (const struct argp_state
#ifdef USE_IN_LIBIO
if (_IO_fwide (stream, 0) > 0)
__fwprintf (stream, L"%s",
- state ? state->name : program_invocation_short_name);
+ state ? state->name : __argp_short_program_name ());
else
#endif
fputs_unlocked (state
- ? state->name : program_invocation_short_name,
+ ? state->name : __argp_short_program_name (),
stream);
if (fmt)
@@ -1812,14 +1847,22 @@ __argp_failure (const struct argp_state
#ifdef USE_IN_LIBIO
if (_IO_fwide (stream, 0) > 0)
+#if defined _LIBC || defined HAVE_STRERROR_R
__fwprintf (stream, L": %s",
__strerror_r (errnum, buf, sizeof (buf)));
+#else
+ __fwprintf (stream, L": %s", strerror (errnum));
+#endif
else
#endif
{
putc_unlocked (':', stream);
putc_unlocked (' ', stream);
+#if defined _LIBC || defined HAVE_STRERROR_R
fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
+#else
+ fputs (strerror (errnum), stream);
+#endif
}
}
Index: argp-namefrob.h
===================================================================
RCS file: /cvs/glibc/libc/argp/argp-namefrob.h,v
retrieving revision 1.3
diff -u -p -r1.3 argp-namefrob.h
--- argp-namefrob.h 6 Jul 2001 04:54:44 -0000 1.3
+++ argp-namefrob.h 1 Aug 2003 11:01:19 -0000
@@ -84,6 +84,63 @@
#define __strcasecmp strcasecmp
#undef __vsnprintf
#define __vsnprintf vsnprintf
+#undef __strchrnul
+#define __strchrnul strchrnul
+#undef __mempcpy
+#define __mempcpy mempcpy
+#undef __strndup
+#define __strndup strndup
+
+#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
+# define clearerr_unlocked(x) clearerr (x)
+#endif
+#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
+# define feof_unlocked(x) feof (x)
+# endif
+#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
+# define ferror_unlocked(x) ferror (x)
+# endif
+#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
+# define fflush_unlocked(x) fflush (x)
+# endif
+#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
+# define fgets_unlocked(x,y,z) fgets (x,y,z)
+# endif
+#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
+# define fputc_unlocked(x,y) fputc (x,y)
+# endif
+#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
+# define fputs_unlocked(x,y) fputs (x,y)
+# endif
+#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
+# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
+# endif
+#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
+# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
+# endif
+#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
+# define getc_unlocked(x) getc (x)
+# endif
+#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
+# define getchar_unlocked() getchar ()
+# endif
+#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
+# define putc_unlocked(x,y) putc (x,y)
+# endif
+#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
+# define putchar_unlocked(x) putchar (x)
+# endif
+
+#ifdef HAVE_FLOCKFILE
+# define __flockfile flockfile
+# define __funlockfile funlockfile
+#else
+# define __flockfile
+# define __funlockfile
+#endif
+
+extern char *__argp_short_program_name (void);
+extern char *__argp_basename (char *name);
#endif /* !_LIBC */
Index: argp-parse.c
===================================================================
RCS file: /cvs/glibc/libc/argp/argp-parse.c,v
retrieving revision 1.17
diff -u -p -r1.17 argp-parse.c
--- argp-parse.c 8 Apr 2002 08:38:33 -0000 1.17
+++ argp-parse.c 1 Aug 2003 11:01:20 -0000
@@ -119,24 +119,29 @@ argp_default_parser (int key, char *arg,
break;
case OPT_PROGNAME: /* Set the program name. */
+#if HAVE_DECL_PROGRAM_INVOCATION_NAME
program_invocation_name = arg;
-
+#endif
/* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
__PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
to be that, so we have to be a bit careful here.] */
- arg = strrchr (arg, '/');
- if (arg)
- program_invocation_short_name = arg + 1;
- else
- program_invocation_short_name = program_invocation_name;
/* Update what we use for messages. */
- state->name = program_invocation_short_name;
+
+#ifdef __LIBC
+ state->name = basename (arg);
+#else
+ state->name = __argp_basename (arg);
+#endif
+
+#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+ program_invocation_short_name = state->name;
+#endif
if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
== ARGP_PARSE_ARGV0)
/* Update what getopt uses too. */
- state->argv[0] = program_invocation_name;
+ state->argv[0] = arg;
break;
@@ -599,7 +604,7 @@ parser_init (struct parser *parser, cons
parser->state.name = short_name ? short_name + 1 : argv[0];
}
else
- parser->state.name = program_invocation_short_name;
+ parser->state.name = __argp_short_program_name (NULL);
return 0;
}
Index: argp-xinl.c
===================================================================
RCS file: /cvs/glibc/libc/argp/argp-xinl.c,v
retrieving revision 1.3
diff -u -p -r1.3 argp-xinl.c
--- argp-xinl.c 6 Jul 2001 04:54:44 -0000 1.3
+++ argp-xinl.c 1 Aug 2003 11:01:20 -0000
@@ -22,7 +22,9 @@
#include <config.h>
#endif
-#include <features.h>
+#if defined HAVE_FEATURES_H || defined _LIBC
+# include <features.h>
+#endif
#ifndef __USE_EXTERN_INLINES
# define __USE_EXTERN_INLINES 1
Index: argp.h
===================================================================
RCS file: /cvs/glibc/libc/argp/argp.h,v
retrieving revision 1.25
diff -u -p -r1.25 argp.h
--- argp.h 12 Jun 2003 18:07:27 -0000 1.25
+++ argp.h 1 Aug 2003 11:01:20 -0000
@@ -36,6 +36,19 @@
# define __THROW
#endif
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
+# define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
+# define __format__ format
+# define __printf__ printf
+# endif
+#endif
+
#ifndef __error_t_defined
typedef int error_t;
# define __error_t_defined