From: Florian Forster Date: Sat, 20 Dec 2008 15:54:32 +0000 (+0100) Subject: src/utils_subst.[ch]: Implement `subst_string'. X-Git-Tag: collectd-4.6.0~122 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=088d5c6d5a5ea3457cd6a4eafff40f5c780c3692;p=collectd.git src/utils_subst.[ch]: Implement `subst_string'. Works like `subst', but instead of specifying start and end offsets you specify `needle', the string that is to be replaced. If `needle' is found in `string' (using strstr(3)), the offset is calculated and `subst' is called with the determined parameters. --- diff --git a/src/utils_subst.c b/src/utils_subst.c index 05dc8441..3c9fe5a2 100644 --- a/src/utils_subst.c +++ b/src/utils_subst.c @@ -78,5 +78,66 @@ char *asubst (const char *string, int off1, int off2, const char *replacement) return ret; } /* asubst */ +char *subst_string (char *buf, size_t buflen, const char *string, + const char *needle, const char *replacement) +{ + char *temp; + size_t needle_len; + size_t i; + + if ((buf == NULL) || (string == NULL) + || (needle == NULL) || (replacement == NULL)) + return (NULL); + + temp = (char *) malloc (buflen); + if (temp == NULL) + { + ERROR ("subst_string: malloc failed."); + return (NULL); + } + + needle_len = strlen (needle); + strncpy (buf, string, buflen); + + /* Limit the loop to prevent endless loops. */ + for (i = 0; i < buflen; i++) + { + char *begin_ptr; + size_t begin; + + /* Find `needle' in `buf'. */ + begin_ptr = strstr (buf, needle); + if (begin_ptr == NULL) + break; + + /* Calculate the start offset. */ + begin = begin_ptr - buf; + + /* Substitute the region using `subst'. The result is stored in + * `temp'. */ + begin_ptr = subst (temp, buflen, buf, + begin, begin + needle_len, + replacement); + if (begin_ptr == NULL) + { + WARNING ("subst_string: subst failed."); + break; + } + + /* Copy the new string in `temp' to `buf' for the next round. */ + strncpy (buf, temp, buflen); + } + + if (i >= 100) + { + WARNING ("subst_string: Loop exited after %zu iterations: " + "string = %s; needle = %s; replacement = %s;", + i, string, needle, replacement); + } + + sfree (temp); + return (buf); +} /* char *subst_string */ + /* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/utils_subst.h b/src/utils_subst.h index bba33af4..4387b85d 100644 --- a/src/utils_subst.h +++ b/src/utils_subst.h @@ -75,6 +75,25 @@ char *subst (char *buf, size_t buflen, const char *string, int off1, int off2, */ char *asubst (const char *string, int off1, int off2, const char *replacement); +/* + * subst_string: + * + * Works like `subst', but instead of specifying start and end offsets you + * specify `needle', the string that is to be replaced. If `needle' is found + * in `string' (using strstr(3)), the offset is calculated and `subst' is + * called with the determined parameters. + * + * If the substring is not found, no error will be indicated and + * `subst_string' works mostly like `strncpy'. + * + * If the substring appears multiple times, all appearances will be replaced. + * If the substring has been found `buflen' times, an endless loop is assumed + * and the loop is broken. A warning is printed and the function returns + * success. + */ +char *subst_string (char *buf, size_t buflen, const char *string, + const char *needle, const char *replacement); + #endif /* UTILS_SUBST_H */ /* vim: set sw=4 ts=4 tw=78 noexpandtab : */