bug-hello
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]