mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
common: New function map_static_strings
* common/mapstrings.c (struct intmapping_s): New. (map_static_strings): New. * common/stringhelp.c (do_strconcat): Rename to ... (vstrconcat): this and make global. * common/t-mapstrings.c (test_map_static_strings): New test.
This commit is contained in:
parent
e081a601f7
commit
c145366549
@ -68,6 +68,18 @@ struct mapping_s
|
||||
static struct mapping_s *mappings;
|
||||
|
||||
|
||||
/* Similar to above but using two integers and a domain as key. */
|
||||
struct intmapping_s
|
||||
{
|
||||
struct intmapping_s *next;
|
||||
int key1;
|
||||
int key2;
|
||||
const char *string;
|
||||
char domain[1];
|
||||
};
|
||||
static struct intmapping_s *intmappings;
|
||||
|
||||
|
||||
/* If STRING has already been mapped, return the mapped string. If
|
||||
not return NULL. */
|
||||
static const char *
|
||||
@ -165,3 +177,40 @@ map_static_macro_string (const char *string)
|
||||
|
||||
return store_mapping (string, p);
|
||||
}
|
||||
|
||||
|
||||
/* If a list of strings has already been mapped to a the tuple
|
||||
* (DOMAIN,KEY1,KEY2) return that string. If not, create a mapping
|
||||
* made up of the concatenation of the given strings. */
|
||||
const char *
|
||||
map_static_strings (const char *domain, int key1, int key2,
|
||||
const char *string1, ...)
|
||||
{
|
||||
va_list arg_ptr;
|
||||
struct intmapping_s *m;
|
||||
|
||||
if (!string1 || !domain)
|
||||
return "";
|
||||
|
||||
for (m = intmappings; m; m = m->next)
|
||||
if (m->key1 == key1 && m->key2 == key2 && !strcmp (domain, m->domain))
|
||||
return m->string;
|
||||
|
||||
m = xmalloc (sizeof *m + strlen (domain));
|
||||
strcpy (m->domain, domain);
|
||||
m->key1 = key1;
|
||||
m->key2 = key2;
|
||||
|
||||
va_start (arg_ptr, string1);
|
||||
m->string = vstrconcat (string1, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
if (!m->string)
|
||||
log_fatal ("map_static_strings failed: %s\n", strerror (errno));
|
||||
|
||||
gpgrt_annotate_leaked_object (m->string);
|
||||
gpgrt_annotate_leaked_object (m);
|
||||
|
||||
m->next = intmappings;
|
||||
intmappings = m;
|
||||
return m->string;
|
||||
}
|
||||
|
@ -1167,9 +1167,10 @@ try_percent_escape (const char *str, const char *extra)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
do_strconcat (const char *s1, va_list arg_ptr)
|
||||
/* Same as strconcat but takes a va_list. Returns EINVAL if the list
|
||||
* is too long, all other errors are due to an ENOMEM condition. */
|
||||
char *
|
||||
vstrconcat (const char *s1, va_list arg_ptr)
|
||||
{
|
||||
const char *argv[48];
|
||||
size_t argc;
|
||||
@ -1214,7 +1215,7 @@ strconcat (const char *s1, ...)
|
||||
else
|
||||
{
|
||||
va_start (arg_ptr, s1);
|
||||
result = do_strconcat (s1, arg_ptr);
|
||||
result = vstrconcat (s1, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
}
|
||||
return result;
|
||||
@ -1233,7 +1234,7 @@ xstrconcat (const char *s1, ...)
|
||||
else
|
||||
{
|
||||
va_start (arg_ptr, s1);
|
||||
result = do_strconcat (s1, arg_ptr);
|
||||
result = vstrconcat (s1, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
}
|
||||
if (!result)
|
||||
|
@ -141,9 +141,12 @@ char *try_percent_escape (const char *str, const char *extra);
|
||||
NULL. Returns a malloced buffer with the new string or NULL on a
|
||||
malloc error or if too many arguments are given. */
|
||||
char *strconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0);
|
||||
/* Same but taking a va_list. */
|
||||
char *vstrconcat (const char *s1, va_list arg_ptr);
|
||||
/* Ditto, but die on error. */
|
||||
char *xstrconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0);
|
||||
|
||||
|
||||
char **strsplit (char *string, char delim, char replacement, int *count);
|
||||
|
||||
/* Tokenize STRING using the set of delimiters in DELIM. */
|
||||
@ -172,5 +175,7 @@ char *substitute_envvars (const char *string);
|
||||
|
||||
/*-- mapstrings.c --*/
|
||||
const char *map_static_macro_string (const char *string);
|
||||
const char *map_static_strings (const char *domain, int key1, int key2,
|
||||
const char *string1, ...);
|
||||
|
||||
#endif /*GNUPG_COMMON_STRINGHELP_H*/
|
||||
|
@ -88,6 +88,31 @@ test_map_static_macro_string (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_map_static_strings (void)
|
||||
{
|
||||
const char *s, *s1;
|
||||
|
||||
s1 = map_static_strings ("mydomain", 0, 42,
|
||||
"This", " ", "is", " ", "my"," ","string", NULL);
|
||||
if (strcmp (s1, "This is my string"))
|
||||
fail (1);
|
||||
s = map_static_strings ("mydomain", 0, 42,
|
||||
"This", " ", "is", " ", "my"," ","string", NULL);
|
||||
if (strcmp (s1, s))
|
||||
fail (2);
|
||||
s = map_static_strings ("mydomain", 0, 42, "foo", NULL);
|
||||
if (strcmp (s1, s))
|
||||
fail (3);
|
||||
s = map_static_strings ("mydomain", 1, 42, "foo 1.42", NULL);
|
||||
if (!strcmp (s1, s))
|
||||
fail (4);
|
||||
s = map_static_strings ("xdomain", 1, 42, "foo 1.42 other domain", NULL);
|
||||
if (!strcmp (s1, s))
|
||||
fail (5);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -95,6 +120,7 @@ main (int argc, char **argv)
|
||||
(void)argv;
|
||||
|
||||
test_map_static_macro_string ();
|
||||
test_map_static_strings ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user