[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: argmatch: accept perfect matches in documented arglists
From: |
Akim Demaille |
Subject: |
Re: argmatch: accept perfect matches in documented arglists |
Date: |
Thu, 2 May 2019 12:55:39 +0200 |
Hi Bruno,
> Le 27 avr. 2019 à 19:56, Bruno Haible <address@hidden> a écrit :
>
> Hi Akim,
>
>> Because that's not what argmatch provides. You seem to be referring to
>> a fully blown feature, and support for internationalization I guess.
>
> And support for help2man should not be forgotten either.
Sure.
>> I'm just exploiting the unique prefix feature to shoehorn the
>> documentation in there.
>
> I would find it better to go with a more featureful facility, then
> (among getopt, argmatch, argp, AutoOpts [1], etc.) - or invent a new one.
Is this what you have in mind? It's in the test because it's
simpler to prototype there. I should probably make the argmatch_group
private and provide pseudo constructors to be more robust to adding
new members if needed in the future. Of course the construction
would be runtime, but I suppose it will not be costly enough to be a
problem.
Most existing functions should probably be rewritten on top of
argmatch_group, with backward compatibility of course.
I'd be happy to check the output of argmatch_usage, but I don't think
we have the equivalent of string streams in gnulib, do we?
I did not try to depend on $COLUMNS, because it is not used so far in
gnulib.
commit 7fc2a29e4d82c7bf7882421e65af6224bfc30188
Author: Akim Demaille <address@hidden>
Date: Tue Apr 30 08:01:14 2019 +0200
WIP: argmatch: provide support for documentation
diff --git a/tests/test-argmatch.c b/tests/test-argmatch.c
index 9335adf55..99666a12c 100644
--- a/tests/test-argmatch.c
+++ b/tests/test-argmatch.c
@@ -21,10 +21,16 @@
#include "argmatch.h"
+#include <gettext.h>
+#include <stdbool.h>
#include <stdlib.h>
+#include <string.h> /* memcmp */
#include "macros.h"
+#define _(Msgid) gettext (Msgid)
+#define N_(Msgid) (Msgid)
+
/* Some packages define ARGMATCH_DIE and ARGMATCH_DIE_DECL in <config.h>, and
thus must link with a definition of that function. Provide it here. */
#ifdef ARGMATCH_DIE_DECL
@@ -59,6 +65,105 @@ static const enum backup_type backup_vals[] =
numbered_backups, numbered_backups, numbered_backups
};
+static const char *const backup_docs[] =
+{
+ N_("never make backups (even if --backup is given)"),
+ N_("make numbered backups"),
+ N_("numbered if numbered backups exist, simple otherwise"),
+ N_("always make simple backups"),
+ NULL
+};
+
+static const enum backup_type backup_doc_vals[] =
+{
+ no_backups,
+ simple_backups,
+ numbered_existing_backups,
+ numbered_backups
+};
+
+typedef struct argmatch_group
+{
+ /* Printed before the usage message. */
+ const char *doc_pre;
+ /* Printed after the usage message. */
+ const char *doc_post;
+ /* Size of the values (in bytes). */
+ size_t val_size;
+
+ /* The documentation of each documented value.
+ This dictates the order in which values are documented.
+ docs[i] documents doc_vals[i]. */
+ const char *const *docs;
+ /* Values that we document. */
+ const void *doc_vals;
+
+ /* Arguments denoting a value. */
+ const char *const *args;
+ /* vals[i] is the value for args[i]. */
+ const void *vals;
+} argmatch_group;
+
+argmatch_group backup_group =
+{
+ N_("\
+The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
+The version control method may be selected via the --backup option or
through\n\
+the VERSION_CONTROL environment variable. Here are the values:\n"),
+ NULL,
+ sizeof *backup_vals,
+ backup_docs,
+ backup_doc_vals,
+ backup_args,
+ backup_vals
+};
+
+void
+argmatch_usage (FILE *out, const argmatch_group *g)
+{
+ /* Width of the screen. Help2man does not seem to support arguments
+ on several lines, so in that case pretend a very large width. */
+ const int screen_width = getenv ("HELP2MAN") ? INT_MAX : 80;
+ if (g->doc_pre)
+ fprintf (out, "%s\n", _(g->doc_pre));
+ for (int i = 0; g->docs[i]; ++i)
+ {
+ int col = 0;
+ bool first = true;
+ for (int j = 0; g->args[j]; ++j)
+ if (! memcmp ((const char *)g->doc_vals + i * g->val_size,
+ (const char *)g->vals + j * g->val_size,
+ g->val_size))
+ {
+ if (!first
+ && screen_width < col + 2 + strlen (g->args[j]))
+ {
+ fprintf (out, ",\n");
+ col = 0;
+ first = true;
+ }
+ if (first)
+ {
+ col += fprintf (out, " ");
+ first = false;
+ }
+ else
+ col += fprintf (out, ",");
+ col += fprintf (out, " %s", g->args[j]);
+ }
+ /* The doc. Must be on column 20 separated by at least two
+ spaces. */
+ if (20 < col + 2)
+ {
+ fprintf (out, "\n");
+ col = 0;
+ }
+ fprintf (out, "%*s%s\n", 20 - col, "", _(g->docs[i]));
+ }
+ if (g->doc_post)
+ fprintf (out, "%s\n", _(g->doc_post));
+}
+
int
main (int argc, char *argv[])
{
@@ -90,9 +195,11 @@ main (int argc, char *argv[])
/* Ambiguous abbreviated. */
ASSERT (ARGMATCH ("ne", backup_args, backup_vals) == -2);
- /* Ambiguous abbreviated, but same value. */
+ /* Ambiguous abbreviated, but same value ("single" and "simple"). */
ASSERT (ARGMATCH ("si", backup_args, backup_vals) == 3);
ASSERT (ARGMATCH ("s", backup_args, backup_vals) == 3);
+ argmatch_usage (stdout, &backup_group);
+
return 0;
}
- Re: argmatch: accept perfect matches in documented arglists,
Akim Demaille <=
- Re: argmatch: accept perfect matches in documented arglists, Bruno Haible, 2019/05/05
- Re: argmatch: accept perfect matches in documented arglists, Akim Demaille, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Bruno Haible, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Akim Demaille, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Bruno Haible, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Akim Demaille, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Akim Demaille, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Bruno Haible, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Paul Eggert, 2019/05/19
- Re: argmatch: accept perfect matches in documented arglists, Akim Demaille, 2019/05/19