1 /* mapstrings.c - Static string mapping
2 * Copyright (C) 2014 Werner Koch
4 * This file is part of GnuPG.
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of either
9 * - the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
15 * - the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
19 * or both in parallel, as here.
21 * This file is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see <https://www.gnu.org/licenses/>.
35 #include "stringhelp.h"
43 #ifdef PACKAGE_BUGREPORT
44 { "EMAIL", PACKAGE_BUGREPORT },
46 { "EMAIL", "bug@example.org" },
48 { "GNUPG", GNUPG_NAME },
50 { "GPGSM", GPGSM_NAME },
51 { "GPG_AGENT", GPG_AGENT_NAME },
52 { "SCDAEMON", SCDAEMON_NAME },
53 { "DIRMNGR", DIRMNGR_NAME },
55 { "GPGCONF", GPGCONF_NAME },
56 { "GPGTAR", GPGTAR_NAME }
61 /* A list to remember already done mappings. */
64 struct mapping_s *next;
68 static struct mapping_s *mappings;
71 /* If STRING has already been mapped, return the mapped string. If
74 already_mapped (const char *string)
78 for (m=mappings; m; m = m->next)
79 if (m->key == string && !strcmp (m->key, string))
85 /* Store NEWSTRING under key STRING and return NEWSTRING. */
87 store_mapping (const char *string, char *newstring)
91 m = xmalloc (sizeof *m);
100 /* Find the first macro in STRING. Return a pointer to the
101 replacement value, set BEGPTR to the leading '@', and set ENDPTR to
102 the terminating '@'. If no macro is found return NULL. */
104 find_macro (const char *string, const char **begptr,
107 const char *s, *s2, *s3;
114 for (; (s2 = strchr (s, '@')); s = s2)
117 if (*s2 >= 'A' && *s2 <= 'Z' && (s3 = (strchr (s2, '@'))))
119 for (idx=0; idx < DIM (macros); idx++)
120 if (strlen (macros[idx].name) == (s3 - s2)
121 && !memcmp (macros[idx].name, s2, (s3 - s2)))
125 return macros[idx].value;
133 /* If STRING includes known @FOO@ macros, replace these macros and
134 return a new static string. Warning: STRING must have been
135 allocated statically. Note that this function allocates memory
136 which will not be released (similar to gettext). */
138 map_static_macro_string (const char *string)
140 const char *s, *s2, *s3, *value;
144 if ((s = already_mapped (string)))
147 value = find_macro (s, &s2, &s3);
149 return string; /* No macros at all. */
151 init_membuf (&mb, strlen (string) + 100);
154 put_membuf (&mb, s, s2 - s);
155 put_membuf_str (&mb, value);
158 while ((value = find_macro (s, &s2, &s3)));
159 put_membuf_str (&mb, s);
160 put_membuf (&mb, "", 1);
162 p = get_membuf_shrink (&mb, NULL);
164 log_fatal ("map_static_macro_string failed: %s\n", strerror (errno));
166 return store_mapping (string, p);