diff options
| -rw-r--r-- | common/stringhelp.c | 33 | ||||
| -rw-r--r-- | common/stringhelp.h | 7 | ||||
| -rw-r--r-- | common/t-stringhelp.c | 112 |
3 files changed, 151 insertions, 1 deletions
diff --git a/common/stringhelp.c b/common/stringhelp.c index 9347c3551..8bbc68ab1 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -2,7 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, * 2008, 2009, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch - * Copyright (C) 2015, 2021 g10 Code GmbH + * Copyright (C) 2015, 2021, 2025 g10 Code GmbH * * This file is part of GnuPG. * @@ -1721,6 +1721,37 @@ format_text (const char *text_in, int target_cols, int max_cols) } +/* In STRING replace the first occurance of SUBSTR by the string + * REPLACE. Return a new malloced string or set ERRNO and set NULL on + * error. If SUBSTR is not found a verbatim copy of STRING is + * returned. */ +char * +replace_substr (const char *string, const char *substr, const char *replace) +{ + size_t stringlen, substrlen, replacelen, n; + const char *s; + char *buffer; + + stringlen = strlen (string); + substrlen = strlen (substr); + replacelen = strlen (replace); + + if (stringlen < substrlen || !(s = strstr (string, substr))) + return xtrystrdup (string); + + stringlen -= substrlen; /* Found thus sryinglen >= substrlen */ + buffer = xtrymalloc (stringlen + replacelen +1); + if (!buffer) + return NULL; + memcpy (buffer, string, n=(s-string)); + memcpy (buffer+n, replace, replacelen); + strcpy (buffer+n+replacelen, s+substrlen); + + + return buffer; +} + + /* Substitute variables in STRING and return a new string. GETVAL is * a function which maps NAME to its value; that value is a string * which may not change during the execution time of this function. diff --git a/common/stringhelp.h b/common/stringhelp.h index d93373ec5..037ee8139 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -170,6 +170,13 @@ int compare_version_strings (const char *my_version, const char *req_version); /* Format a string so that it fits within about TARGET_COLS columns. */ char *format_text (const char *text, int target_cols, int max_cols); + +/* Return a new malloced string with the first occurance of SUBSTR in + * STRING replaced by REPLACE. Returns NULL on memory error. */ +char *replace_substr (const char *string, + const char *substr, const char *replace); + + /* Substitute variables in STRING. */ char *substitute_vars (const char *string, const char *(*getval)(void *cookie, const char *name), diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c index b43bb7932..3bd9ba928 100644 --- a/common/t-stringhelp.c +++ b/common/t-stringhelp.c @@ -1202,6 +1202,117 @@ test_compare_version_strings (void) static void +test_replace_substr (void) +{ + struct { + const char *string; + const char *substr; + const char *replace; + const char *result; + } t[] = { + { "Look afar and see the end from the beginning.", + "see ", + "view ", + "Look afar and view the end from the beginning." + }, + { "Look afar and see the end from the beginning.", + "see ", + "xxx ", + "Look afar and xxx the end from the beginning." + }, + { "Look afar and see the end from the beginning.", + "see ", + "xx ", + "Look afar and xx the end from the beginning." + }, + { "Look afar and see the end from the beginning.", + "see ", + "x ", + "Look afar and x the end from the beginning." + }, + { "Look afar and see the end from the beginning.", + "see ", + " ", + "Look afar and the end from the beginning." + }, + { "Look afar and see the end from the beginning.", + "see ", + "", + "Look afar and the end from the beginning." + }, + { "Be different: conform.", + "", + "xxx", + "xxxBe different: conform." + }, + { "Be different: conform.", + "foo", + "bar", + "Be different: conform." + }, + { "Be different: conform.", + "different", + "unlike", + "Be unlike: conform." + }, + { "Be different: conform.", + "B", + "Bee", + "Beee different: conform." + }, + { "Be different: conform.", + ".", + "", + "Be different: conform" + }, + { "Be different: conform.", + ".", + "!", + "Be different: conform!" + }, + { "Be different: conform.", + ".", + "...", + "Be different: conform..." + }, + { "Be different: conform.", + ":", + " - this is a very long replacement string - ", + "Be different - this is a very long replacement string - conform." + }, + { "", + "", + "", + "" + } + }; + int idx; + char *res; + + for (idx=0; idx < DIM(t); idx++) + { + res = replace_substr (t[idx].string, t[idx].substr, t[idx].replace); + if (!res) + { + fprintf (stderr,"error replacing in '%s' (test %d): %s\n", + t[idx].string, idx, strerror (errno)); + exit (2); + } + if (strcmp (res, t[idx].result)) + { + fprintf (stderr, "string is '%s'\n", t[idx].string); + fprintf (stderr, " substr '%s'\n", t[idx].substr); + fprintf (stderr, " replace '%s'\n", t[idx].replace); + fprintf (stderr, " expected '%s'\n", t[idx].result); + fprintf (stderr, " got '%s'\n", res); + fail (idx); + } + xfree (res); + } +} + + +static void test_substitute_envvars (void) { struct { @@ -1317,6 +1428,7 @@ main (int argc, char **argv) test_split_fields_colon (); test_compare_version_strings (); test_format_text (); + test_replace_substr (); test_substitute_envvars (); xfree (home_buffer); |
