[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/7] use gnulib to print --help and --version
From: |
Sami Kerola |
Subject: |
[PATCH 3/7] use gnulib to print --help and --version |
Date: |
Mon, 30 Dec 2013 11:58:21 +0000 |
* Makefile.am: update help2man invocation and add MAINTAINERCLEANFILES
* bootstrap.conf: include dirname, propername, and version-etc-fsf modules
* configure.ac: remove COPYRIGHT_YEAR from config.h
* doc/hello.texi: remove short options -h and -v
* po/POTFILES.in: add lib/version-etc.c to translations
* src/hello.c: remove print_version(), and rename print_help() to usage()
* src/system.h: add inline functions to print version and usage info
---
Makefile.am | 11 ++++-
bootstrap.conf | 3 ++
configure.ac | 4 --
doc/hello.texi | 4 --
po/POTFILES.in | 3 +-
src/hello.c | 128 ++++++++++++++++++++-------------------------------------
src/system.h | 90 ++++++++++++++++++++++++++++++++++++++++
7 files changed, 149 insertions(+), 94 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index aafb2b8..1487fdd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -48,7 +48,15 @@ EXTRA_DIST += $(man_MANS)
CLEANFILES = $(man_MANS)
hello.1: hello
- $(HELP2MAN) --include=$(top_srcdir)/man/hello.x $(top_builddir)/hello
-o $@
+ $(HELP2MAN) \
+ --source='$(PACKAGE_STRING)' \
+ --include=$(top_srcdir)/man/hello.x \
+ address@hidden \
+ $(top_builddir)/hello \
+ && sed \
+ -e '/For complete documentation/d' \
+ address@hidden > $@ \
+ && rm -f address@hidden
TESTS = \
tests/greeting-1 \
@@ -60,6 +68,7 @@ TESTS = \
EXTRA_DIST += $(TESTS)
noinst_LIBRARIES =
+MAINTAINERCLEANFILES =
MOSTLYCLEANFILES =
MOSTLYCLEANDIRS =
BUILT_SOURCES =
diff --git a/bootstrap.conf b/bootstrap.conf
index 21a1ecd..a1ca8b5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -22,6 +22,7 @@ gnulib_modules="
closeout
configmake
do-release-commit-and-tag
+ dirname
fdl
gendocs
getopt-gnu
@@ -33,7 +34,9 @@ gnulib_modules="
mbsrtowcs
non-recursive-gnulib-prefix-hack
progname
+ propername
readme-release
+ version-etc-fsf
wchar
"
diff --git a/configure.ac b/configure.ac
index 6b32fb5..6dedcc0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,10 +39,6 @@ dnl keep everything together.
gl_EARLY
gl_INIT
-dnl Copyright will apply as long as these sources are in use, e.g., are
-dnl being compiled, which is reasonable year to claim the copyright.
-AC_DEFINE([COPYRIGHT_YEAR], [m4_esyscmd([date +%Y])], [year in copyright
message])
-
dnl GNU help2man creates man pages from --help output; in many cases, this
dnl is sufficient, and obviates the need to maintain man pages separately.
dnl However, this means invoking executables, which we generally cannot do
diff --git a/doc/hello.texi b/doc/hello.texi
index 8743d29..92aa042 100644
--- a/doc/hello.texi
+++ b/doc/hello.texi
@@ -234,9 +234,7 @@ world!}.
Output @var{text} instead of the default greeting.
@item --help
address@hidden -h
@opindex --help
address@hidden -h
Print an informative help message on standard output and exit
successfully.
@@ -257,9 +255,7 @@ be mentioned (Hello doesn't have any).
Output the traditional greeting message @samp{hello, world}.
@item --version
address@hidden -v
@opindex --version
address@hidden -v
Print the version number and licensing information of Hello on
standard output and then exit successfully.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d33bd99..1b1ac82 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,8 +10,9 @@
src/hello.c
# Gnulib source files.
+lib/closeout.c
lib/error.c
lib/getopt.c
-lib/closeout.c
lib/quotearg.c
+lib/version-etc.c
lib/xalloc-die.c
diff --git a/src/hello.c b/src/hello.c
index fe85539..90b1c08 100644
--- a/src/hello.c
+++ b/src/hello.c
@@ -19,25 +19,32 @@
#include <config.h>
#include "system.h"
#include "progname.h"
+#include "progname.h"
+#include "propername.h"
#include "xalloc.h"
+/* The official name of this program (e.g., no `g' prefix). */
+#define PROGRAM_NAME "hello"
+
+#define AUTHORS \
+ proper_name ("The King"), \
+ proper_name ("others")
+
static const struct option longopts[] = {
{"greeting", required_argument, NULL, 'g'},
- {"help", no_argument, NULL, 'h'},
{"traditional", no_argument, NULL, 't'},
- {"version", no_argument, NULL, 'v'},
+ {GETOPT_HELP_OPTION_DECL},
+ {GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
/* Forward declarations. */
-static void print_help (void);
-static void print_version (void);
+static void usage (int status);
int
main (int argc, char *argv[])
{
int optc;
- int lose = 0;
const char *greeting_msg;
wchar_t *mb_greeting;
size_t len;
@@ -62,38 +69,28 @@ main (int argc, char *argv[])
This is implemented in the Gnulib module "closeout". */
atexit (close_stdout);
- while ((optc = getopt_long (argc, argv, "g:htv", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "g:t", longopts, NULL)) != -1)
switch (optc)
{
- /* --help and --version exit immediately, per GNU coding standards. */
- case 'v':
- print_version ();
- exit (EXIT_SUCCESS);
- break;
case 'g':
greeting_msg = optarg;
break;
- case 'h':
- print_help ();
- exit (EXIT_SUCCESS);
- break;
case 't':
greeting_msg = _("hello, world");
break;
+ /* --help and --version exit immediately, per GNU coding standards. */
+ case_GETOPT_HELP_CHAR;
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
- lose = 1;
- break;
+ usage (EXIT_FAILURE);
}
- if (lose || optind < argc)
+ if (optind < argc)
{
/* Print error message and exit. */
- if (optind < argc)
- fprintf (stderr, _("%s: extra operand: %s\n"), program_name,
- argv[optind]);
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
- exit (EXIT_FAILURE);
+ fprintf (stderr, _("%s: extra operand: %s\n"), program_name,
+ argv[optind]);
+ usage (EXIT_FAILURE);
}
len = mbsrtowcs(NULL, &greeting_msg, 0, NULL);
@@ -118,71 +115,34 @@ main (int argc, char *argv[])
blocks and identify the various pieces. */
static void
-print_help (void)
+usage (int status)
{
- /* TRANSLATORS: --help output 1 (synopsis)
- no-wrap */
- printf (_("\
-Usage: %s [OPTION]...\n"), program_name);
-
- /* TRANSLATORS: --help output 2 (brief description)
- no-wrap */
- fputs (_("\
+ if (status != EXIT_SUCCESS)
+ emit_try_help ();
+ else
+ {
+ /* TRANSLATORS: --help output 1 (synopsis)
+ no-wrap */
+ printf (_("\
+Usage: %s OPTION...\n"), program_name);
+
+ /* TRANSLATORS: --help output 2 (brief description)
+ no-wrap */
+ fputs (_("\
Print a friendly, customizable greeting.\n"), stdout);
- puts ("");
- /* TRANSLATORS: --help output 3: options 1/2
- no-wrap */
- fputs (_("\
- -h, --help display this help and exit\n\
- -v, --version display version information and exit\n"), stdout);
-
- puts ("");
- /* TRANSLATORS: --help output 4: options 2/2
- no-wrap */
- fputs (_("\
+ emit_mandatory_arg_note ();
+
+ /* TRANSLATORS: --help output 3: options 2/2
+ no-wrap */
+ fputs (_("\
-t, --traditional use traditional greeting\n\
-g, --greeting=TEXT use TEXT as the greeting message\n"), stdout);
- printf ("\n");
- /* TRANSLATORS: --help output 5+ (reports)
- TRANSLATORS: the placeholder indicates the bug-reporting address
- for this application. Please add _another line_ with the
- address for translation bugs.
- no-wrap */
- printf (_("\
-Report bugs to: %s\n"), PACKAGE_BUGREPORT);
-#ifdef PACKAGE_PACKAGER_BUG_REPORTS
- printf (_("Report %s bugs to: %s\n"), PACKAGE_PACKAGER,
- PACKAGE_PACKAGER_BUG_REPORTS);
-#endif
-#ifdef PACKAGE_URL
- printf (_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
-#else
- printf (_("%s home page: <http://www.gnu.org/software/%s/>\n"),
- PACKAGE_NAME, PACKAGE);
-#endif
- fputs (_("General help using GNU software: <http://www.gnu.org/gethelp/>\n"),
- stdout);
-}
-
-
+ fputs (HELP_OPTION_DESCRIPTION, stdout);
+ fputs (VERSION_OPTION_DESCRIPTION, stdout);
-/* Print version and copyright information. */
-
-static void
-print_version (void)
-{
- printf ("%s (%s) %s\n", PACKAGE, PACKAGE_NAME, VERSION);
- /* xgettext: no-wrap */
- puts ("");
-
- /* It is important to separate the year from the rest of the message,
- as done here, to avoid having to retranslate the message when a new
- year comes around. */
- printf (_("\
-Copyright (C) %d Free Software Foundation, Inc.\n\
-License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>\n\
-This is free software: you are free to change and redistribute it.\n\
-There is NO WARRANTY, to the extent permitted by law.\n"), COPYRIGHT_YEAR);
+ emit_ancillary_info ();
+ }
+ exit (status);
}
diff --git a/src/system.h b/src/system.h
index 3f94ad1..e2c59bf 100644
--- a/src/system.h
+++ b/src/system.h
@@ -33,6 +33,9 @@
#include <wchar.h>
#include <wctype.h>
+/* CHAR_MIN */
+#include <limits.h>
+
/* Internationalization. */
# include "gettext.h"
# define _(str) gettext (str)
@@ -41,4 +44,91 @@
/* Check for errors on write. */
# include "closeout.h"
+/* Usage and version priting. */
+# include "dirname.h"
+# include "progname.h"
+
+/* These enum values cannot possibly conflict with the option values
+ ordinarily used by commands, including CHAR_MAX + 1, etc. Avoid
+ CHAR_MIN - 1, as it may equal -1, the getopt end-of-options value. */
+enum
+{
+ GETOPT_HELP_CHAR = (CHAR_MIN - 2),
+ GETOPT_VERSION_CHAR = (CHAR_MIN - 3)
+};
+
+#define GETOPT_HELP_OPTION_DECL \
+ "help", no_argument, NULL, GETOPT_HELP_CHAR
+#define GETOPT_VERSION_OPTION_DECL \
+ "version", no_argument, NULL, GETOPT_VERSION_CHAR
+
+#define case_GETOPT_HELP_CHAR \
+ case GETOPT_HELP_CHAR: \
+ usage (EXIT_SUCCESS); \
+ break;
+
+#define emit_bug_reporting_address unused__emit_bug_reporting_address
+#include "version-etc.h"
+#undef emit_bug_reporting_address
+
+#include "propername.h"
+/* Define away proper_name (leaving proper_name_utf8, which affects far
+ fewer programs), since it's not worth the cost of adding ~17KB to
+ the x86_64 text size of every single program. This avoids a 40%
+ (almost ~2MB) increase in the on-disk space utilization for the set
+ of the 100 binaries. */
+#define proper_name(x) (x)
+
+#define case_GETOPT_VERSION_CHAR(Program_name, Authors) \
+ case GETOPT_VERSION_CHAR: \
+ version_etc (stdout, Program_name, PACKAGE_NAME, VERSION, Authors, \
+ (char *) NULL); \
+ exit (EXIT_SUCCESS); \
+ break;
+
+#define HELP_OPTION_DESCRIPTION \
+ _(" --help display this help and exit\n")
+#define VERSION_OPTION_DESCRIPTION \
+ _(" --version output version information and exit\n")
+
+static inline void
+emit_mandatory_arg_note (void)
+{
+ fputs (_("\n\
+Mandatory arguments to long options are mandatory for short options too.\n\
+"), stdout);
+}
+
+/* Just like strncmp, but the second argument must be a literal string
+ and you don't specify the length; that comes from the literal. */
+#define STRNCMP_LIT(s, literal) \
+ strncmp (s, "" literal "", sizeof (literal) - 1)
+
+static inline void
+emit_ancillary_info (void)
+{
+ printf (_("\n%s online help: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
+ /* Don't output this redundant message for English locales.
+ Note we still output for 'C' so that it gets included in the man page. */
+ const char *lc_messages = setlocale (LC_MESSAGES, NULL);
+ if (lc_messages && STRNCMP_LIT (lc_messages, "en_"))
+ {
+ /* TRANSLATORS: Replace LANG_CODE in this URL with your language code
+ <http://translationproject.org/team/LANG_CODE.html> to form one of
+ the URLs at http://translationproject.org/team/. Otherwise, replace
+ the entire URL with your translation team's email address. */
+ printf (_("Report %s translation bugs to "
+ "<http://translationproject.org/team/>\n"),
+ last_component (program_name));
+ }
+ printf (_("For complete documentation, run: "
+ "info %s '%s invocation'\n"), PACKAGE, last_component
(program_name));
+}
+
+static inline void
+emit_try_help (void)
+{
+ fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name);
+}
+
#endif /* HELLO_SYSTEM_H */
--
1.8.5.2
[PATCH 5/7] demonstrate how to add information to a manual page, Sami Kerola, 2013/12/30
[PATCH 4/7] use standard error printing facilities, Sami Kerola, 2013/12/30