diff options
author | Werner Koch <wk@gnupg.org> | 2014-02-26 16:18:45 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2014-02-26 16:18:45 +0100 |
commit | c72762f9acf3eef5c466ba76e895d7654df12ff7 (patch) | |
tree | bcb93136c589e406f69ae0d219402c5300d05654 /common/mapstrings.c | |
parent | common: New function get_membuf_shrink. (diff) | |
download | gnupg2-c72762f9acf3eef5c466ba76e895d7654df12ff7.tar.xz gnupg2-c72762f9acf3eef5c466ba76e895d7654df12ff7.zip |
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.
Diffstat (limited to 'common/mapstrings.c')
-rw-r--r-- | common/mapstrings.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/common/mapstrings.c b/common/mapstrings.c new file mode 100644 index 000000000..91795d572 --- /dev/null +++ b/common/mapstrings.c @@ -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); +} |