summaryrefslogtreecommitdiffstats
path: root/common/mapstrings.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2014-02-26 16:18:45 +0100
committerWerner Koch <wk@gnupg.org>2014-02-26 16:18:45 +0100
commitc72762f9acf3eef5c466ba76e895d7654df12ff7 (patch)
treebcb93136c589e406f69ae0d219402c5300d05654 /common/mapstrings.c
parentcommon: New function get_membuf_shrink. (diff)
downloadgnupg2-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.c167
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);
+}