[PATCH v3 0/6] Support translated long option names in getopt and argp
Vivien Kraus
vivien@planete-kraus.eu
Sat May 31 21:14:43 GMT 2025
Dear glibc developers,
Thank you for your interest in this feature.
Le vendredi 30 mai 2025 à 17:00 +0200, Florian Weimer a écrit :
> for (p = longopts, n_options = 0; p->name; p++, n_options++)
> if (!strncmp (p->name, d->__nextchar, namelen)
> - && namelen == strlen (p->name))
> + && namelen == strlen (p->name))
>
> Spurious whitespace-only change?
Sorry this is a mistake, I added code here and reverted later.
> > {
> > /* Exact match found. */
> > pfound = p;
> > @@ -221,7 +234,23 @@ process_long_option (int argc, char **argv,
> const char *optstring,
> >
> > if (pfound == NULL)
> > {
> > - /* Didn't find an exact match, so look for abbreviations.
> */
> > + /* Didn't find an exact match, try with translated option
> > + names. */
> > + for (p = longopts, option_index = 0; p->name; p++,
> option_index++)
> > + if (match_translated_option_name (d->__nextchar, namelen,
> p->name))
> > + {
> > + /* Exact match found with translation. */
> > + pfound = p;
> > + option_index = option_index;
> > + break;
> > + }
> > + }
>
> Matching translated abbreviations doesn't seem like a good idea to
> me.
> This increases the likelihood of conflicts between localized and
> default
> option names.
I fully agree, which is why the translation fallback happens before
the abbreviation fallback. The way git represents this change is not
clear, but the abbreviation check is actually pushed down in the code.
> > +
> "\x61\x69\x6e\x3b\x20\x63\x68\x61\x72\x73\x65\x74\x3d\x41\x53\x43"
> > +
> "\x49\x49\x0a\x43\x6f\x6e\x74\x65\x6e\x74\x2d\x54\x72\x61\x6e\x73"
> > +
> "\x66\x65\x72\x2d\x45\x6e\x63\x6f\x64\x69\x6e\x67\x3a\x20\x38\x62"
> > +
> "\x69\x74\x0a\x50\x6c\x75\x72\x61\x6c\x2d\x46\x6f\x72\x6d\x73\x3a"
> > +
> "\x20\x6e\x70\x6c\x75\x72\x61\x6c\x73\x3d\x32\x3b\x20\x70\x6c\x75"
> > +
> "\x72\x61\x6c\x3d\x28\x6e\x20\x21\x3d\x20\x31\x29\x3b\x0a\x00\x63"
> > + "\x6f\x6c\x6f\x75\x72\x00\x72\x65\x71\x75\x69\x72\x65\x64\x00";
> > +static const size_t mo_file_size = 479;
>
> This really should not be necessary. We can compile PO files as part
> of
> tests, see codeset_mo in libintl/Makefile.
Thank you, this will help.
Le vendredi 30 mai 2025 à 16:05 +0000, Joseph Myers a écrit :
> I think if would be best if translated option names were only supported
> when a context is specified, to avoid translations of a word also used
> (and marked for translation) other than as an option name quietly
> changing
> how a program behaves.
For getopt, I believe developers can enforce this rule by setting opttextdomain.
For argp, a specific context is required.
Le vendredi 30 mai 2025 à 18:55 +0200, Andreas Schwab a écrit :
> Why are option names not looked up with the leading dashes? That would
> obviate the need for a context.
It makes it difficult to manage PO files. In typical getopt usage, you
would mark the long option names for translation with the traditional
N_ macro (or a variant with context), and then xgettext could pick
them up. Since the long option names in the struct option field don’t
have dashes, then xgettext would also not add them. So you would need
to add another step after xgettext invocation, to add the dashes in
the PO template file.
I added tests to argp and reworked the code a bit, so that both
--usage and --help are handled. Both of them display the translated
name first, and mention the untranslated name too. Now, typical usage
of a program defining --color and translating as --colour in en_GB
will look like:
Usage: tst-argpusage-localized [-c?V] [--colour (--color)] [--help] [--usage]
[--version]
And typical help:
Usage: tst-argphelp-localized [OPTION...]
-c, --colour (--color) Rainbow!
-?, --help Give this help list
--usage Give a short usage message
-V, --version Print program version
The goal is if someone sees a script using --color, they can deduce it
means --colour.
The remaining problems are:
1. (new) For getopt_long invocation, all option names must have the
same context and translations must be in the same textdomain. Argp
lets us configure a domain per parser, but after combining different
parsers, it will call getopt_long (the reentrant version) with all the
options. Which textdomain should we then use to translate option
names in getopt_long? I think we should use the current default one,
whatever domain is configured in any parser component. Another
solution would be to configure getopt_long to use different domains
for different options, but it would mean to change the struct option
type to indicate the domain for each option.
2. Argp does not seem to care for contexts in one-word elements, such
as the argument placeholder (in --input=FILE, I am talking about
“FILE” here, which is translated without a context). Should we still
care for contexts in long option names? I believe so, because the
argument documentation is in all-caps, so it is quite specific
already.
3. Is my merge-context-^D-and-msgid-before-calling-gettext plagiarism
of the pgettext_expr macro?
4. Is it OK to use malloc?
5. Did I introduce a cancelation point (I can’t test them)?
6. I think I have to assign copyright.
Best regards,
Vivien
Vivien Kraus (6):
posix: allow getopt_long to match translated option names
argp: document translated names in --help and --usage
posix: Introduce a convenience function to translate the option name
posix: let the getopt caller set the translation context
argp: use "command-line option" context for option name translation
posix: let the getopt caller choose the textdomain for translation
argp/Makefile | 14 ++++
argp/argp-help.c | 63 ++++++++++++++---
argp/argp-parse.c | 1 +
argp/tst-argphelp-localized.c | 102 +++++++++++++++++++++++++++
argp/tst-argphelp-localized.po | 18 +++++
argp/tst-argpusage-localized.c | 82 ++++++++++++++++++++++
manual/argp.texi | 25 +++++--
manual/getopt.texi | 35 ++++++++--
posix/Makefile | 13 ++++
posix/Versions | 2 +-
posix/bits/getopt_core.h | 11 +++
posix/getopt.c | 122 ++++++++++++++++++++++++++++++---
posix/getopt_int.h | 2 +
posix/tstgetoptl.c | 120 ++++++++++++++++++++++++++++++++
posix/tstgetoptl.po | 27 ++++++++
15 files changed, 607 insertions(+), 30 deletions(-)
create mode 100644 argp/tst-argphelp-localized.c
create mode 100644 argp/tst-argphelp-localized.po
create mode 100644 argp/tst-argpusage-localized.c
create mode 100644 posix/tstgetoptl.c
create mode 100644 posix/tstgetoptl.po
base-commit: af90dc572ad232d05b667c4ce218d499f066b7bc
--
2.49.0
More information about the Libc-alpha
mailing list