Use double pointers for haystack

This commit is contained in:
Benedikt Heine 2017-09-06 21:41:26 +02:00
parent 4b7f656f6e
commit e16117ca30
3 changed files with 53 additions and 54 deletions

View File

@ -207,28 +207,24 @@ void notification_free(notification *n)
* to point to the first char, which occurs after replacement. * to point to the first char, which occurs after replacement.
* *
*/ */
char *notification_replace_single_field(char *haystack, char **needle, void notification_replace_single_field(char **haystack, char **needle,
const char *replacement, enum markup_mode markup_mode) { const char *replacement, enum markup_mode markup_mode) {
assert(*needle[0] == '%'); assert(*needle[0] == '%');
// needle has to point into haystack (but not on the last char) // needle has to point into haystack (but not on the last char)
assert(*needle >= haystack); assert(*needle >= *haystack);
assert(*needle - haystack < strlen(haystack) - 1); assert(*needle - *haystack < strlen(*haystack) - 1);
char *ret; int pos = *needle - *haystack;
int pos = *needle - haystack;
char *input = markup_transform(g_strdup(replacement), markup_mode); char *input = markup_transform(g_strdup(replacement), markup_mode);
ret = string_replace_at(haystack, pos, 2, input); *haystack = string_replace_at(*haystack, pos, 2, input);
// point the needle to the next char // point the needle to the next char
// which was originally in haystack // which was originally in haystack
*needle = ret + (*needle - haystack) + strlen(input); *needle = *haystack + pos + strlen(input);
g_free(input); g_free(input);
return ret;
} }
char *notification_extract_markup_urls(char **str_ptr) { char *notification_extract_markup_urls(char **str_ptr) {
@ -333,66 +329,66 @@ int notification_init(notification *n, int id)
switch(substr[1]){ switch(substr[1]){
case 'a': case 'a':
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->appname, n->appname,
MARKUP_NO); MARKUP_NO);
break; break;
case 's': case 's':
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->summary, n->summary,
n->markup); n->markup);
break; break;
case 'b': case 'b':
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->body, n->body,
n->markup); n->markup);
break; break;
case 'I': case 'I':
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->icon ? basename(n->icon) : "", n->icon ? basename(n->icon) : "",
MARKUP_NO); MARKUP_NO);
break; break;
case 'i': case 'i':
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->icon ? n->icon : "", n->icon ? n->icon : "",
MARKUP_NO); MARKUP_NO);
break; break;
case 'p': case 'p':
if (n->progress) if (n->progress)
sprintf(pg, "[%3d%%]", n->progress - 1); sprintf(pg, "[%3d%%]", n->progress - 1);
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->progress ? pg : "", n->progress ? pg : "",
MARKUP_NO); MARKUP_NO);
break; break;
case 'n': case 'n':
if (n->progress) if (n->progress)
sprintf(pg, "%d", n->progress - 1); sprintf(pg, "%d", n->progress - 1);
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
n->progress ? pg : "", n->progress ? pg : "",
MARKUP_NO); MARKUP_NO);
break; break;
case '%': case '%':
n->msg = notification_replace_single_field( notification_replace_single_field(
n->msg, &n->msg,
&substr, &substr,
"%", "%",
MARKUP_NO); MARKUP_NO);
break; break;
case '\0': case '\0':
fprintf(stderr, "WARNING: format_string has trailing %% character." fprintf(stderr, "WARNING: format_string has trailing %% character."

View File

@ -73,7 +73,7 @@ int notification_is_duplicate(const notification *a, const notification *b);
void notification_run_script(notification *n); void notification_run_script(notification *n);
int notification_close(notification *n, int reason); int notification_close(notification *n, int reason);
void notification_print(notification *n); void notification_print(notification *n);
char *notification_replace_single_field(char *haystack, char **needle, const char *replacement, enum markup_mode markup_mode); void notification_replace_single_field(char **haystack, char **needle, const char *replacement, enum markup_mode markup_mode);
void notification_update_text_to_render(notification *n); void notification_update_text_to_render(notification *n);
int notification_get_ttl(notification *n); int notification_get_ttl(notification *n);
int notification_get_age(notification *n); int notification_get_age(notification *n);

View File

@ -77,17 +77,20 @@ TEST test_notification_replace_single_field(void)
strcpy(str, "Markup %a preserved"); strcpy(str, "Markup %a preserved");
substr = strchr(str, '%'); substr = strchr(str, '%');
ASSERT_STR_EQ("Markup and &amp; <i>is</i> preserved", (str = notification_replace_single_field(str, &substr, "and &amp; <i>is</i>", MARKUP_FULL))); notification_replace_single_field(&str, &substr, "and &amp; <i>is</i>", MARKUP_FULL);
ASSERT_STR_EQ("Markup and &amp; <i>is</i> preserved", str);
ASSERT_EQ(26, substr - str); ASSERT_EQ(26, substr - str);
strcpy(str, "Markup %a escaped"); strcpy(str, "Markup %a escaped");
substr = strchr(str, '%'); substr = strchr(str, '%');
ASSERT_STR_EQ("Markup and &amp; &lt;i&gt;is&lt;/i&gt; escaped", (str = notification_replace_single_field(str, &substr, "and & <i>is</i>", MARKUP_NO))); notification_replace_single_field(&str, &substr, "and & <i>is</i>", MARKUP_NO);
ASSERT_STR_EQ("Markup and &amp; &lt;i&gt;is&lt;/i&gt; escaped", str);
ASSERT_EQ(38, substr - str); ASSERT_EQ(38, substr - str);
strcpy(str, "Markup %a"); strcpy(str, "Markup %a");
substr = strchr(str, '%'); substr = strchr(str, '%');
ASSERT_STR_EQ("Markup is removed and &amp; escaped", (str = notification_replace_single_field(str, &substr, "<i>is removed</i> and & escaped", MARKUP_STRIP))); notification_replace_single_field(&str, &substr, "<i>is removed</i> and & escaped", MARKUP_STRIP);
ASSERT_STR_EQ("Markup is removed and &amp; escaped", str);
ASSERT_EQ(35, substr - str); ASSERT_EQ(35, substr - str);
g_free(str); g_free(str);