diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/version-etc.c | 104 |
1 files changed, 92 insertions, 12 deletions
diff --git a/lib/version-etc.c b/lib/version-etc.c index 663aa8dcf..031c2e921 100644 --- a/lib/version-etc.c +++ b/lib/version-etc.c @@ -21,9 +21,13 @@ # include <config.h> #endif +#include <stdarg.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "unlocked-io.h" #include "version-etc.h" +#include "xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -35,26 +39,77 @@ char* version_etc_copyright = "Copyright (C) 2003 Free Software Foundation, Inc."; -/* Display the --version information the standard way. +/* Like version_etc, below, but with the NULL-terminated author list + provided via a variable of type va_list. */ +void +version_etc_va (FILE *stream, + char const *command_name, char const *package, + char const *version, va_list authors) +{ + unsigned int n_authors; + va_list saved_authors; - If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of - the program. The formats are therefore: +#ifdef __va_copy + __va_copy (saved_authors, authors); +#else + saved_authors = authors; +#endif - PACKAGE VERSION + for (n_authors = 0; va_arg (authors, char const *); ++n_authors) + { + /* empty */ + } + va_end (authors); - or + if (n_authors == 0) + abort (); - COMMAND_NAME (PACKAGE) VERSION. */ -void -version_etc (FILE *stream, - const char *command_name, const char *package, - const char *version, const char *authors) -{ if (command_name) fprintf (stream, "%s (%s) %s\n", command_name, package, version); else fprintf (stream, "%s %s\n", package, version); - fprintf (stream, _("Written by %s.\n"), authors); + + switch (n_authors) + { + case 1: + vfprintf (stream, _("Written by %s.\n"), saved_authors); + break; + case 2: + vfprintf (stream, _("Written by %s and %s.\n"), saved_authors); + break; + case 3: + vfprintf (stream, _("Written by %s, %s, and %s.\n"), saved_authors); + break; + case 4: + vfprintf (stream, _("Written by %s, %s, %s, and %s.\n"), saved_authors); + break; + default: + { + + /* Note that the following must have one `%s' and one `%%s'. */ +#define FMT_TEMPLATE _("Written by %sand %%s.\n") + + /* for the string "%s, %s, ..., %s, " */ + size_t s_len = (n_authors - 1) * strlen ("%s, "); + char *s_fmt = xmalloc (s_len + 1); + + /* This could be a few bytes tighter, but don't bother because + that'd just make it a little more fragile. */ + char *full_fmt = xmalloc (strlen (FMT_TEMPLATE) + s_len + 1); + + unsigned int i; + char *s = s_fmt; + for (i = 0; i < n_authors - 1; i++) + s = stpcpy (s, "%s, "); + sprintf (full_fmt, FMT_TEMPLATE, s_fmt); + free (s_fmt); + + vfprintf (stream, full_fmt, saved_authors); + free (full_fmt); + } + break; + } + va_end (saved_authors); putc ('\n', stream); fputs (version_etc_copyright, stream); @@ -65,3 +120,28 @@ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"), stream); } + + +/* Display the --version information the standard way. + + If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of + the program. The formats are therefore: + + PACKAGE VERSION + + or + + COMMAND_NAME (PACKAGE) VERSION. + + There must be one or more author names (each as a separate string) + after the VERSION argument, and the final argument must be `NULL'. */ +void +version_etc (FILE *stream, + char const *command_name, char const *package, + char const *version, ...) +{ + va_list authors; + + va_start (authors, version); + version_etc_va (stream, command_name, package, version, authors); +} |