1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-06-12 18:11:03 +02:00

common: Improve helpfile.c to provide a generic template API.

* common/util.h (GET_TEMPLATE_CURRENT_LOCALE): New.
(GET_TEMPLATE_SUBST_ENVVARS): New.
(GET_TEMPLATE_CRLF): New.
* common/helpfile.c (findkey_fname): Add arg flags and terminate line
with CRLF if requested.
(findkey_locale): Replace arg only_current_locale by flags and add arg
domain.
(gnupg_get_help_string): Factor all code out to ...
(gnupg_get_template): new.  Add arg domain.  Handle SUBST flags.  Do
not trim tralins spaces with the CRLF flag.

* common/t-helpfile.c (main): Require domain name and add two options.
This commit is contained in:
Werner Koch 2025-05-28 15:19:19 +02:00
parent ef5fa47ee8
commit 8d837279bc
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 83 additions and 31 deletions

View File

@ -1,5 +1,6 @@
/* helpfile.c - GnuPG's helpfile feature
* Copyright (C) 2007 Free Software Foundation, Inc.
* Copyright (C) 2011,2012, 2025 g10 Code GmbH
*
* This file is part of GnuPG.
*
@ -25,6 +26,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
*/
#include <config.h>
@ -38,7 +40,7 @@
/* Try to find KEY in the file FNAME. */
static char *
findkey_fname (const char *key, const char *fname)
findkey_fname (const char *key, const char *fname, unsigned int flags)
{
gpg_error_t err = 0;
estream_t fp;
@ -126,7 +128,10 @@ findkey_fname (const char *key, const char *fname)
if (is_membuf_ready (&mb))
{
put_membuf_str (&mb, p);
put_membuf (&mb, "\n", 1);
if ((flags & GET_TEMPLATE_CRLF))
put_membuf (&mb, "\r\n", 2);
else
put_membuf (&mb, "\n", 1);
}
}
@ -159,22 +164,23 @@ findkey_fname (const char *key, const char *fname)
/* Try the help files depending on the locale. */
static char *
findkey_locale (const char *key, const char *locname,
int only_current_locale, const char *dirname)
findkey_locale (const char *domain, const char *key, const char *locname,
const char *dirname, unsigned int flags)
{
const char *s;
char *fname, *ext, *p;
char *result;
fname = xtrymalloc (strlen (dirname) + 6 + strlen (locname) + 4 + 1);
fname = xtrymalloc (strlen (dirname) + 2
+ strlen (domain) + strlen (locname) + 4 + 1);
if (!fname)
return NULL;
ext = stpcpy (stpcpy (fname, dirname), "/help.");
ext = stpcpy (stpcpy (stpcpy (stpcpy (fname, dirname), "/"), domain), ".");
/* Search with locale name and territory. ("help.LL_TT.txt") */
if (strchr (locname, '_'))
{
strcpy (stpcpy (ext, locname), ".txt");
result = findkey_fname (key, fname);
result = findkey_fname (key, fname, flags);
}
else
result = NULL; /* No territory. */
@ -187,17 +193,17 @@ findkey_locale (const char *key, const char *locname,
for (p=ext, s=locname; *s && *s != '_';)
*p++ = *s++;
strcpy (p, ".txt");
result = findkey_fname (key, fname);
result = findkey_fname (key, fname, flags);
}
else
result = NULL;
}
if (!result && (!only_current_locale || !*locname) )
if (!result && (!(flags & GET_TEMPLATE_CURRENT_LOCALE) || !*locname))
{
/* Last try: Search in file without any locale info. ("help.txt") */
strcpy (ext, "txt");
result = findkey_fname (key, fname);
result = findkey_fname (key, fname, flags);
}
xfree (fname);
@ -205,31 +211,32 @@ findkey_locale (const char *key, const char *locname,
}
/* Return a malloced help text as identified by KEY. The system takes
/* Return a malloced text as identified by KEY. The system takes
the string from an UTF-8 encoded file to be created by an
administrator or as distributed with GnuPG. On a GNU or Unix
system the entry is searched in these files:
/etc/gnupg/help.LL.txt
/etc/gnupg/help.txt
/usr/share/gnupg/help.LL.txt
/usr/share/gnupg/help.txt
/etc/gnupg/<domain>.<LL>.txt
/etc/gnupg/<domain>.txt
/usr/share/gnupg/<domain>.<LL>.txt
/usr/share/gnupg/<domain>.txt
Here LL denotes the two digit language code of the current locale.
If ONLY_CURRENT_LOCALE is set, the function won't fallback to the
english valiant ("help.txt") unless that locale has been requested.
The <domain> is either "help" or any other domain like "mail-tube".
Here <LL> denotes the two digit language code of the current
locale. If the flag bit GET_TEMPLATE_CURRENT_LOCALE is set, the
function won't fallback to the english valiant ("<domain>.txt")
unless that locale has been requested.
The help file needs to be encoded in UTF-8, lines with a '#' in the
The template file needs to be encoded in UTF-8, lines with a '#' in the
first column are comment lines and entirely ignored. Help keys are
identified by a key consisting of a single word with a single dot
as the first character. All key lines listed without any
intervening lines (except for comment lines) lead to the same help
text. Lines following the key lines make up the actual hep texts.
text. Lines following the key lines make up the actual template texts.
*/
char *
gnupg_get_help_string (const char *key, int only_current_locale)
gnupg_get_template (const char *domain, const char *key, unsigned int flags)
{
static const char *locname;
char *result;
@ -250,7 +257,7 @@ gnupg_get_help_string (const char *key, int only_current_locale)
else if (*p == '_')
{
if (count++)
*p = 0; /* Also cut at a underscore in the territory. */
*p = 0; /* Also cut at an underscore in the territory. */
}
locname = buffer;
}
@ -259,14 +266,32 @@ gnupg_get_help_string (const char *key, int only_current_locale)
if (!key || !*key)
return NULL;
result = findkey_locale (key, locname, only_current_locale,
gnupg_sysconfdir ());
result = findkey_locale (domain, key, locname,
gnupg_sysconfdir (), flags);
if (!result)
result = findkey_locale (key, locname, only_current_locale,
gnupg_datadir ());
result = findkey_locale (domain, key, locname,
gnupg_datadir (), flags);
if (result)
if (result && (flags & GET_TEMPLATE_SUBST_ENVVARS))
{
char *tmp = substitute_envvars (result);
if (tmp)
{
xfree (result);
result = tmp;
}
}
if (result && !(flags & GET_TEMPLATE_CRLF))
trim_trailing_spaces (result);
return result;
}
char *
gnupg_get_help_string (const char *key, int only_current)
{
return gnupg_get_template ("help", key,
only_current? GET_TEMPLATE_CURRENT_LOCALE : 0);
}

View File

@ -39,6 +39,7 @@ int
main (int argc, char **argv)
{
char *result;
unsigned int flags = 0;
if (argc)
{ argc--; argv++; }
@ -48,17 +49,35 @@ main (int argc, char **argv)
verbose = 1;
argc--; argv++;
}
if (argc && !strcmp (argv[0], "--env"))
{
flags |= GET_TEMPLATE_SUBST_ENVVARS;
argc--; argv++;
}
if (argc && !strcmp (argv[0], "--crlf"))
{
flags |= GET_TEMPLATE_CRLF;
argc--; argv++;
}
if (argc != 2)
{
fprintf (stderr, "Usage: t-helpfile [--env] [--crlf] domain key\n");
exit (2);
}
result = gnupg_get_help_string (argc? argv[0]:NULL, 0);
result = gnupg_get_template (argv[0], argv[1], flags);
if (!result)
{
fprintf (stderr,
"Error: nothing found for '%s'\n", argc?argv[0]:"(null)");
"Error: nothing found for '%s' in domain '%s'\n",
argv[1], argv[0]);
errcount++;
}
else
{
printf ("key '%s' result='%s'\n", argc?argv[0]:"(null)", result);
printf ("domain '%s' key '%s' result='%s'\n",
argv[0], argv[1], result);
xfree (result);
}

View File

@ -296,6 +296,14 @@ void gnupg_set_builddir (const char *newdir);
void gnupg_rl_initialize (void);
/*-- helpfile.c --*/
/* Bit flags for gnupg_get_template. */
#define GET_TEMPLATE_CURRENT_LOCALE 1 /* Use only the current locale. */
#define GET_TEMPLATE_SUBST_ENVVARS 2 /* Substitute environment variables. */
#define GET_TEMPLATE_CRLF 4 /* Use CR+LF. */
char *gnupg_get_template (const char *domain, const char *key,
unsigned int flags);
char *gnupg_get_help_string (const char *key, int only_current_locale);
/*-- localename.c --*/