coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] create a convenient function to align/print option help text


From: Nguyễn Thái Ngọc Duy
Subject: [PATCH] create a convenient function to align/print option help text
Date: Sun, 2 Sep 2012 15:48:35 +0700

This is just a proof of concept. I'd like to know this approach may be
accepted.

It helps avoid manual aligning of help text, which is boring
(e.g. chmod's --no-preserve-root does it wrong) and impossible to do
right for shared options such as --verbose and --help.

It also helps avoid misalignment in translations because translators may
not notice that the number of spaces in such a translations has a special
meaning.

The convenient function may end up in gnulib, I don't know.

Signed-off-by: Nguyễn Thái Ngọc Duy <address@hidden>
---
 lib/Makefile.am |  2 +-
 lib/usage.c     | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/usage.h     |  4 ++++
 src/chmod.c     | 40 ++++++++++++++++++--------------
 4 files changed, 100 insertions(+), 18 deletions(-)
 create mode 100644 lib/usage.c
 create mode 100644 lib/usage.h

diff --git a/lib/Makefile.am b/lib/Makefile.am
index 885f9b2..d8851af 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -31,7 +31,7 @@ include gnulib.mk
 AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
 
 libcoreutils_a_SOURCES += \
-  buffer-lcm.c buffer-lcm.h
+  buffer-lcm.c buffer-lcm.h usage.c
 
 libcoreutils_a_LIBADD += $(LIBOBJS)
 libcoreutils_a_DEPENDENCIES += $(LIBOBJS)
diff --git a/lib/usage.c b/lib/usage.c
new file mode 100644
index 0000000..e2ecc00
--- /dev/null
+++ b/lib/usage.c
@@ -0,0 +1,72 @@
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <gettext.h>
+#include "xalloc.h"
+
+#define _(msgid) gettext (msgid)
+
+int print_usage(const char **help)
+{
+  int i;
+  int arg_len = 0;
+  char *buf;
+
+  for (i = 0; help[i]; i++)
+    {
+      const char *h = _(help[i]);
+      int len;
+      if (i % 2)
+        continue;
+      len =  h[0] == '-' && h[1] == '-' ? 4 : 0;
+      len += strlen (h);
+      if (len > arg_len)
+        arg_len = len;
+    }
+
+  arg_len += 4;                 /* two leading and trailing spaces */
+  buf = xmalloc (arg_len + 1);
+  memset (buf, ' ', arg_len);
+  buf[arg_len] = '\0';
+
+  for (i = 0; help[i]; i += 2)
+    {
+      const char *a = _(help[i]);
+      const char *h = _(help[i + 1]);
+      int p = 2;
+
+      if (!h)
+        {
+          free (buf);
+          return -1;
+        }
+
+      if (a[0] == '-' && a[1] == '-')
+        p += 4;
+      memcpy (buf + p, a, strlen (a));
+      fputs (buf, stdout);
+      memset (buf, ' ', arg_len);
+
+      while (*h)
+        {
+          const char *newline = strchr (h, '\n');
+          if (newline)
+            {
+              fwrite (h, newline + 1 - h, 1, stdout);
+              fputs (buf, stdout);
+              h = newline + 1;
+            }
+          else
+            {
+              fputs (h, stdout);
+              break;
+            }
+        }
+      fputs ("\n", stdout);
+    }
+
+  free (buf);
+
+  return 0;
+}
diff --git a/lib/usage.h b/lib/usage.h
new file mode 100644
index 0000000..64e3bc0
--- /dev/null
+++ b/lib/usage.h
@@ -0,0 +1,4 @@
+#ifndef __USAGE_H__
+#define __USAGE_H__
+extern int print_usage(const char **help);
+#endif
diff --git a/src/chmod.c b/src/chmod.c
index a54078c..5e790a3 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -31,6 +31,7 @@
 #include "quotearg.h"
 #include "root-dev-ino.h"
 #include "xfts.h"
+#include "usage.h"
 
 /* The official name of this program (e.g., no 'g' prefix).  */
 #define PROGRAM_NAME "chmod"
@@ -107,6 +108,27 @@ static struct option const long_options[] =
   {NULL, 0, NULL, 0}
 };
 
+static const char *option_help[] =
+{
+  N_("-c, --changes"),
+  N_("like --verbose but report only when a change is made"),
+  N_("-f, --silent, --quiet"),
+  N_("suppress most error messages"),
+  N_("-v, --verbose"),
+  N_("output a diagnostic for every file processed"),
+  N_("--no-preserve-root"),
+  N_("do not treat '/' specially (the default)"),
+  N_("--preserve-root"),
+  N_("fail to operate recursively on '/'"),
+  N_("--reference=RFILE"),
+  N_("use RFILE's mode instead of MODE values"),
+  N_("-R, --recursive"),
+  N_("change files and directories recursively"),
+  N_("--help"), N_("display this help and exit"),
+  N_("--version"), N_("output version information and exit"),
+  NULL
+};
+
 /* Return true if the chmodable permission bits of FILE changed.
    The old mode was OLD_MODE, but it was changed to NEW_MODE.  */
 
@@ -379,23 +401,7 @@ Change the mode of each FILE to MODE.\n\
 With --reference, change the mode of each FILE to that of RFILE.\n\
 \n\
 "), stdout);
-      fputs (_("\
-  -c, --changes          like verbose but report only when a change is made\n\
-  -f, --silent, --quiet  suppress most error messages\n\
-  -v, --verbose          output a diagnostic for every file processed\n\
-"), stdout);
-      fputs (_("\
-      --no-preserve-root  do not treat '/' specially (the default)\n\
-      --preserve-root    fail to operate recursively on '/'\n\
-"), stdout);
-      fputs (_("\
-      --reference=RFILE  use RFILE's mode instead of MODE values\n\
-"), stdout);
-      fputs (_("\
-  -R, --recursive        change files and directories recursively\n\
-"), stdout);
-      fputs (HELP_OPTION_DESCRIPTION, stdout);
-      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      print_usage (option_help);
       fputs (_("\
 \n\
 Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'.\n\
-- 
1.7.12.rc2.18.g61b472e




reply via email to

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