Imported Upstream version 2.8.4
[platform/upstream/man-db.git] / patches / argp-domain.patch
1 commit 6cd59e232112243bca08c588185ce3d397e89fd3
2 Author: Colin Watson <cjwatson@debian.org>
3 Date:   Mon May 28 17:41:05 2018 +0100
4
5     Fix domain handling in argp
6     
7     man-db sets its default text domain to "man-db", and keeps all Gnulib's
8     strings in a separate "man-db-gnulib" domain, using 'gnulib-tool
9     --po-domain=man-db' which results in
10     -DDEFAULT_TEXT_DOMAIN=\"man-db-gnulib\". (I checked this general
11     approach with Bruno a while back and he said it was fine.)
12     
13     However, Gnulib's argp implementation has three bugs which cause this
14     not to work properly:
15     
16       * It hardcodes "libc" as a domain in two places. This is obviously
17         wrong in Gnulib.
18     
19       * It uses argp_domain as both the domain used to translate its own
20         strings (i.e. string literals in lib/argp-*.c) and the domain used
21         to translate strings provided by the user, which normally have to
22         use gettext_noop so that they can be used as 'struct argp_option'
23         initialisers. This is dreadfully inconvenient because you have to
24         copy strings about all over the place and keep your POT file up to
25         date as the argp implementation changes. If argp is in libc then
26         this is obviously impossible.
27     
28         Instead, argp should use DEFAULT_TEXT_DOMAIN to translate its own
29         string literals (falling back to the default program domain if that
30         is not set), and should reserve argp_domain for translating strings
31         that appear in that argp structure.
32     
33       * In a number of places, argp uses the domain of the root argp
34         structure when translating text from a child argp structure. This is
35         the direct cause of Robert's bug, because the standard --help and
36         --version options are implemented as a child argp structure with its
37         own domain.
38     
39         My patch changes this to use argp_domain from the child instead.
40         However, on reflection, I'm not certain that this is correct;
41         arguably it needs to walk up the tree until it finds a domain to
42         use. This depends on whether you think that argp_domain == NULL
43         means "use default program domain" or "use same domain as parent
44         argp structure".
45     
46     https://lists.gnu.org/r/bug-gnulib/2008-03/msg00144.html
47
48 diff --git a/gl/lib/argp-help.c b/gl/lib/argp-help.c
49 index de98f2143..09a716e69 100644
50 --- a/gl/lib/argp-help.c
51 +++ b/gl/lib/argp-help.c
52 @@ -48,6 +48,16 @@
53  # include "gettext.h"
54  #endif
55  
56 +#ifdef _LIBC
57 +# define ARGP_TEXT_DOMAIN "libc"
58 +#else
59 +# ifdef DEFAULT_TEXT_DOMAIN
60 +#  define ARGP_TEXT_DOMAIN DEFAULT_TEXT_DOMAIN
61 +# else
62 +#  define ARGP_TEXT_DOMAIN NULL
63 +# endif
64 +#endif
65 +
66  #include "argp.h"
67  #include "argp-fmtstream.h"
68  #include "argp-namefrob.h"
69 @@ -144,7 +154,7 @@ validate_uparams (const struct argp_state *state, struct uparams *upptr)
70        if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
71          {
72            __argp_failure (state, 0, 0,
73 -                          dgettext (state->root_argp->argp_domain,
74 +                          dgettext (ARGP_TEXT_DOMAIN,
75                                      "\
76  ARGP_HELP_FMT: %s value is less than or equal to %s"),
77                            "rmargin", up->name);
78 @@ -220,7 +230,7 @@ fill_in_uparams (const struct argp_state *state)
79                      if (unspec && !un->is_bool)
80                        __argp_failure (state, 0, 0,
81                                        dgettext (state == NULL ? NULL
82 -                                                : state->root_argp->argp_domain,
83 +                                                : ARGP_TEXT_DOMAIN,
84                                                  "\
85  %.*s: ARGP_HELP_FMT parameter requires a value"),
86                                        (int) var_len, var);
87 @@ -231,7 +241,7 @@ fill_in_uparams (const struct argp_state *state)
88                if (un == uparam_names + nuparam_names)
89                  __argp_failure (state, 0, 0,
90                                  dgettext (state == NULL ? NULL
91 -                                          : state->root_argp->argp_domain, "\
92 +                                          : ARGP_TEXT_DOMAIN, "\
93  %.*s: Unknown ARGP_HELP_FMT parameter"),
94                                  (int) var_len, var);
95  
96 @@ -243,7 +253,7 @@ fill_in_uparams (const struct argp_state *state)
97              {
98                __argp_failure (state, 0, 0,
99                                dgettext (state == NULL ? NULL
100 -                                        : state->root_argp->argp_domain,
101 +                                        : ARGP_TEXT_DOMAIN,
102                                          "Garbage in ARGP_HELP_FMT: %s"), var);
103                break;
104              }
105 @@ -1120,7 +1130,7 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
106              __argp_fmtstream_putc (stream, *so);
107              if (!have_long_opt || uparams.dup_args)
108                arg (real, " %s", "[%s]",
109 -                   state == NULL ? NULL : state->root_argp->argp_domain,
110 +                   state == NULL ? NULL : entry->argp->argp_domain,
111                     stream);
112              else if (real->arg)
113                hhstate->suppressed_dup_arg = 1;
114 @@ -1142,7 +1152,7 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
115                 should be pretty rare anyway...  */
116              __argp_fmtstream_puts (stream,
117                                     dgettext (state == NULL ? NULL
118 -                                             : state->root_argp->argp_domain,
119 +                                             : entry->argp->argp_domain,
120                                               opt->name));
121            }
122      }
123 @@ -1156,7 +1166,7 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
124              comma (uparams.long_opt_col, &pest);
125              __argp_fmtstream_printf (stream, "--%s", opt->name);
126              arg (real, "=%s", "[=%s]",
127 -                 state == NULL ? NULL : state->root_argp->argp_domain, stream);
128 +                 state == NULL ? NULL : entry->argp->argp_domain, stream);
129            }
130      }
131  
132 @@ -1176,7 +1186,7 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
133    else
134      {
135        const char *tstr = real->doc ? dgettext (state == NULL ? NULL
136 -                                               : state->root_argp->argp_domain,
137 +                                               : entry->argp->argp_domain,
138                                                 real->doc) : 0;
139        const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
140        if (fstr && *fstr)
141 @@ -1225,7 +1235,7 @@ hol_help (struct hol *hol, const struct argp_state *state,
142    if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
143      {
144        const char *tstr = dgettext (state == NULL ? NULL
145 -                                   : state->root_argp->argp_domain, "\
146 +                                   : ARGP_TEXT_DOMAIN, "\
147  Mandatory or optional arguments to long options are also mandatory or \
148  optional for any corresponding short options.");
149        const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
150 @@ -1612,11 +1622,11 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
151  
152            if (first_pattern)
153              __argp_fmtstream_printf (fs, "%s %s",
154 -                                     dgettext (argp->argp_domain, "Usage:"),
155 +                                     dgettext (ARGP_TEXT_DOMAIN, "Usage:"),
156                                       name);
157            else
158              __argp_fmtstream_printf (fs, "%s %s",
159 -                                     dgettext (argp->argp_domain, "  or: "),
160 +                                     dgettext (ARGP_TEXT_DOMAIN, "  or: "),
161                                       name);
162  
163            /* We set the lmargin as well as the wmargin, because hol_usage
164 @@ -1627,7 +1637,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
165              /* Just show where the options go.  */
166              {
167                if (hol->num_entries > 0)
168 -                __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
169 +                __argp_fmtstream_puts (fs, dgettext (ARGP_TEXT_DOMAIN,
170                                                       " [OPTION...]"));
171              }
172            else
173 @@ -1655,7 +1665,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
174  
175    if (flags & ARGP_HELP_SEE)
176      {
177 -      __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
178 +      __argp_fmtstream_printf (fs, dgettext (ARGP_TEXT_DOMAIN, "\
179  Try '%s --help' or '%s --usage' for more information.\n"),
180                                 name, name);
181        anything = 1;
182 @@ -1682,7 +1692,7 @@ Try '%s --help' or '%s --usage' for more information.\n"),
183      {
184        if (anything)
185          __argp_fmtstream_putc (fs, '\n');
186 -      __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
187 +      __argp_fmtstream_printf (fs, dgettext (ARGP_TEXT_DOMAIN,
188                                               "Report bugs to %s.\n"),
189                                 argp_program_bug_address);
190        anything = 1;
191 @@ -1883,8 +1893,7 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
192  #  endif
193  # endif
194                if (! s && ! (s = strerror (errnum)))
195 -                s = dgettext (state->root_argp->argp_domain,
196 -                              "Unknown system error");
197 +                s = dgettext (ARGP_TEXT_DOMAIN, "Unknown system error");
198                fputs_unlocked (s, stream);
199  #endif
200              }
201 diff --git a/gl/lib/argp-parse.c b/gl/lib/argp-parse.c
202 index ae55e9e19..3f8b0ba69 100644
203 --- a/gl/lib/argp-parse.c
204 +++ b/gl/lib/argp-parse.c
205 @@ -40,6 +40,16 @@
206  #endif
207  #define N_(msgid) msgid
208  
209 +#ifdef _LIBC
210 +# define ARGP_TEXT_DOMAIN "libc"
211 +#else
212 +# ifdef DEFAULT_TEXT_DOMAIN
213 +#  define ARGP_TEXT_DOMAIN DEFAULT_TEXT_DOMAIN
214 +# else
215 +#  define ARGP_TEXT_DOMAIN NULL
216 +# endif
217 +#endif
218 +
219  #include "argp.h"
220  #include "argp-namefrob.h"
221  
222 @@ -135,7 +145,8 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
223  }
224  
225  static const struct argp argp_default_argp =
226 -  {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
227 +  {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL,
228 +   ARGP_TEXT_DOMAIN};
229  
230  \f
231  static const struct argp_option argp_version_options[] =
232 @@ -156,7 +167,7 @@ argp_version_parser (int key, char *arg, struct argp_state *state)
233          fprintf (state->out_stream, "%s\n", argp_program_version);
234        else
235          __argp_error (state, "%s",
236 -                      dgettext (state->root_argp->argp_domain,
237 +                      dgettext (ARGP_TEXT_DOMAIN,
238                                  "(PROGRAM ERROR) No version known!?"));
239        if (! (state->flags & ARGP_NO_EXIT))
240          exit (0);
241 @@ -168,7 +179,8 @@ argp_version_parser (int key, char *arg, struct argp_state *state)
242  }
243  
244  static const struct argp argp_version_argp =
245 -  {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
246 +  {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL,
247 +   ARGP_TEXT_DOMAIN};
248  \f
249  /* Returns the offset into the getopt long options array LONG_OPTIONS of a
250     long option with called NAME, or -1 if none is found.  Passing NULL as
251 @@ -609,8 +621,7 @@ parser_finalize (struct parser *parser,
252            if (!(parser->state.flags & ARGP_NO_ERRS)
253                && parser->state.err_stream)
254              fprintf (parser->state.err_stream,
255 -                     dgettext (parser->argp->argp_domain,
256 -                               "%s: Too many arguments\n"),
257 +                     dgettext (ARGP_TEXT_DOMAIN, "%s: Too many arguments\n"),
258                       parser->state.name);
259            err = EBADKEY;
260          }
261 @@ -759,7 +770,7 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
262          N_("(PROGRAM ERROR) Option should have been recognized!?");
263        if (group_key == 0)
264          __argp_error (&parser->state, "-%c: %s", opt,
265 -                      dgettext (parser->argp->argp_domain, bad_key_err));
266 +                      dgettext (ARGP_TEXT_DOMAIN, bad_key_err));
267        else
268          {
269            struct option *long_opt = parser->long_opts;
270 @@ -767,7 +778,7 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
271              long_opt++;
272            __argp_error (&parser->state, "--%s: %s",
273                          long_opt->name ? long_opt->name : "???",
274 -                        dgettext (parser->argp->argp_domain, bad_key_err));
275 +                        dgettext (ARGP_TEXT_DOMAIN, bad_key_err));
276          }
277      }
278