mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
common: New function map_static_macro_string.
* common/mapstrings.c: New. * common/t-mapstrings.c: New. * common/t-support.h (DIM, DIMof): Define if not defined. * common/Makefile.am: Add new files.
This commit is contained in:
parent
556562086a
commit
c72762f9ac
@ -42,7 +42,7 @@ include $(top_srcdir)/am/cmacros.am
|
||||
jnlib_sources = \
|
||||
libjnlib-config.h \
|
||||
types.h host2net.h dynload.h w32help.h \
|
||||
stringhelp.c stringhelp.h \
|
||||
mapstrings.c stringhelp.c stringhelp.h \
|
||||
strlist.c strlist.h \
|
||||
utf8conv.c utf8conv.h \
|
||||
argparse.c argparse.h \
|
||||
@ -165,7 +165,8 @@ if HAVE_W32_SYSTEM
|
||||
jnlib_tests += t-w32-reg
|
||||
endif
|
||||
module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil \
|
||||
t-session-env t-openpgp-oid t-ssh-utils t-dns-cert
|
||||
t-session-env t-openpgp-oid t-ssh-utils t-dns-cert \
|
||||
t-mapstrings
|
||||
if !HAVE_W32CE_SYSTEM
|
||||
module_tests += t-exechelp
|
||||
endif
|
||||
@ -200,3 +201,4 @@ t_session_env_LDADD = $(t_common_ldadd)
|
||||
t_openpgp_oid_LDADD = $(t_common_ldadd)
|
||||
t_ssh_utils_LDADD = $(t_common_ldadd)
|
||||
t_dns_cert_LDADD = $(t_common_ldadd) $(DNSLIBS)
|
||||
t_mapstrings_LDADD = $(t_common_ldadd)
|
||||
|
167
common/mapstrings.c
Normal file
167
common/mapstrings.c
Normal file
@ -0,0 +1,167 @@
|
||||
/* mapstrings.c - Static string mapping
|
||||
* Copyright (C) 2014 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of either
|
||||
*
|
||||
* - the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* or
|
||||
*
|
||||
* - the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* or both in parallel, as here.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "stringhelp.h"
|
||||
#include "membuf.h"
|
||||
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
const char *value;
|
||||
} macros[] = {
|
||||
#ifdef PACKAGE_BUGREPORT
|
||||
{ "EMAIL", PACKAGE_BUGREPORT },
|
||||
#else
|
||||
{ "EMAIL", "bug@example.org" },
|
||||
#endif
|
||||
{ "GNUPG", GNUPG_NAME },
|
||||
{ "GPG", GPG_NAME },
|
||||
{ "GPGSM", GPGSM_NAME },
|
||||
{ "GPG_AGENT", GPG_AGENT_NAME },
|
||||
{ "SCDAEMON", SCDAEMON_NAME },
|
||||
{ "DIRMNGR", DIRMNGR_NAME },
|
||||
{ "G13", G13_NAME },
|
||||
{ "GPGCONF", GPGCONF_NAME },
|
||||
{ "GPGTAR", GPGTAR_NAME }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* A list to remember already done mappings. */
|
||||
struct mapping_s
|
||||
{
|
||||
struct mapping_s *next;
|
||||
const char *key;
|
||||
const char *value;
|
||||
};
|
||||
static struct mapping_s *mappings;
|
||||
|
||||
|
||||
/* If STRING has already been mapped, return the mapped string. If
|
||||
not return NULL. */
|
||||
static const char *
|
||||
already_mapped (const char *string)
|
||||
{
|
||||
struct mapping_s *m;
|
||||
|
||||
for (m=mappings; m; m = m->next)
|
||||
if (m->key == string && !strcmp (m->key, string))
|
||||
return m->value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Store NEWSTRING under key STRING and return NEWSTRING. */
|
||||
static const char *
|
||||
store_mapping (const char *string, char *newstring)
|
||||
{
|
||||
struct mapping_s *m;
|
||||
|
||||
m = xmalloc (sizeof *m);
|
||||
m->key = string;
|
||||
m->value = newstring;
|
||||
m->next = mappings;
|
||||
mappings = m;
|
||||
return newstring;
|
||||
}
|
||||
|
||||
|
||||
/* Find the first macro in STRING. Return a pointer to the
|
||||
replacement value, set BEGPTR to the leading '@', and set ENDPTR to
|
||||
the terminating '@'. If no macro is found return NULL. */
|
||||
const char *
|
||||
find_macro (const char *string, const char **begptr,
|
||||
const char **endptr)
|
||||
{
|
||||
const char *s, *s2, *s3;
|
||||
int idx;
|
||||
|
||||
s = string;
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
for (; (s2 = strchr (s, '@')); s = s2)
|
||||
{
|
||||
s2++;
|
||||
if (*s2 >= 'A' && *s2 <= 'Z' && (s3 = (strchr (s2, '@'))))
|
||||
{
|
||||
for (idx=0; idx < DIM (macros); idx++)
|
||||
if (strlen (macros[idx].name) == (s3 - s2)
|
||||
&& !memcmp (macros[idx].name, s2, (s3 - s2)))
|
||||
{
|
||||
*begptr = s2 - 1;
|
||||
*endptr = s3;
|
||||
return macros[idx].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* If STRING includes known @FOO@ macros, replace these macros and
|
||||
return a new static string. Warning: STRING must have been
|
||||
allocated statically. Note that this function allocated memory
|
||||
which will not be released (similar to gettext). */
|
||||
const char *
|
||||
map_static_macro_string (const char *string)
|
||||
{
|
||||
const char *s, *s2, *s3, *value;
|
||||
membuf_t mb;
|
||||
char *p;
|
||||
|
||||
if ((s = already_mapped (string)))
|
||||
return s;
|
||||
s = string;
|
||||
value = find_macro (s, &s2, &s3);
|
||||
if (!value)
|
||||
return string; /* No macros at all. */
|
||||
|
||||
init_membuf (&mb, strlen (string) + 100);
|
||||
do
|
||||
{
|
||||
put_membuf (&mb, s, s2 - s);
|
||||
put_membuf_str (&mb, value);
|
||||
s = s3 + 1;
|
||||
}
|
||||
while ((value = find_macro (s, &s2, &s3)));
|
||||
put_membuf_str (&mb, s);
|
||||
put_membuf (&mb, "", 1);
|
||||
|
||||
p = get_membuf_shrink (&mb, NULL);
|
||||
if (!p)
|
||||
log_fatal ("map_static_macro_string failed: %s\n", strerror (errno));
|
||||
|
||||
return store_mapping (string, p);
|
||||
}
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*-- stringhelp.c --*/
|
||||
char *has_leading_keyword (const char *string, const char *keyword);
|
||||
|
||||
const char *memistr (const void *buf, size_t buflen, const char *sub);
|
||||
@ -145,5 +146,8 @@ char *strconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
|
||||
char *xstrconcat (const char *s1, ...) GNUPG_GCC_A_SENTINEL(0);
|
||||
|
||||
|
||||
/*-- mapstrings.c --*/
|
||||
const char *map_static_macro_string (const char *string);
|
||||
|
||||
|
||||
#endif /*LIBJNLIB_STRINGHELP_H*/
|
||||
|
101
common/t-mapstrings.c
Normal file
101
common/t-mapstrings.c
Normal file
@ -0,0 +1,101 @@
|
||||
/* t-mapstrings.c - Regression tests for mapstrings.c
|
||||
* Copyright (C) 2014 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of either
|
||||
*
|
||||
* - the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* or
|
||||
*
|
||||
* - the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* or both in parallel, as here.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stringhelp.h"
|
||||
|
||||
#include "t-support.h"
|
||||
|
||||
static void
|
||||
test_map_static_macro_string (void)
|
||||
{
|
||||
static struct {
|
||||
const char *string;
|
||||
const char *expected;
|
||||
const char *lastresult;
|
||||
} tests[] = {
|
||||
{ "@GPG@ (@GNUPG@)",
|
||||
GPG_NAME " (" GNUPG_NAME ")" },
|
||||
{ "@GPG@(@GNUPG@)",
|
||||
GPG_NAME "(" GNUPG_NAME ")" },
|
||||
{ "@GPG@@GNUPG@",
|
||||
GPG_NAME GNUPG_NAME },
|
||||
{ " @GPG@@GNUPG@",
|
||||
" " GPG_NAME GNUPG_NAME },
|
||||
{ " @GPG@@GNUPG@ ",
|
||||
" " GPG_NAME GNUPG_NAME " " },
|
||||
{ " @GPG@GNUPG@ ",
|
||||
" " GPG_NAME "GNUPG@ " },
|
||||
{ " @ GPG@GNUPG@ ",
|
||||
" @ GPG" GNUPG_NAME " " },
|
||||
{ "--@GPGTAR@",
|
||||
"--" GPGTAR_NAME }
|
||||
};
|
||||
int testno;
|
||||
const char *result;
|
||||
|
||||
for (testno=0; testno < DIM(tests); testno++)
|
||||
{
|
||||
result = map_static_macro_string (tests[testno].string);
|
||||
if (!result)
|
||||
fail (testno);
|
||||
if (strcmp (result, tests[testno].expected))
|
||||
fail (testno);
|
||||
if (!tests[testno].lastresult)
|
||||
tests[testno].lastresult = result;
|
||||
}
|
||||
|
||||
/* A second time to check that the same string is been returned. */
|
||||
for (testno=0; testno < DIM(tests); testno++)
|
||||
{
|
||||
result = map_static_macro_string (tests[testno].string);
|
||||
if (!result)
|
||||
fail (testno);
|
||||
if (strcmp (result, tests[testno].expected))
|
||||
fail (testno);
|
||||
if (result != tests[testno].lastresult)
|
||||
fail (testno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
test_map_static_macro_string ();
|
||||
|
||||
return 0;
|
||||
}
|
@ -44,6 +44,11 @@
|
||||
# define getenv(a) (NULL)
|
||||
#endif
|
||||
|
||||
#ifndef DIM
|
||||
# define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
||||
# define DIMof(type,member) DIM(((type *)0)->member)
|
||||
#endif
|
||||
|
||||
|
||||
/* Replacement prototypes. */
|
||||
void *gcry_xmalloc (size_t n);
|
||||
|
Loading…
x
Reference in New Issue
Block a user