diff --git a/src/markup.c b/src/markup.c index dba630f..884fb24 100644 --- a/src/markup.c +++ b/src/markup.c @@ -12,9 +12,14 @@ #include "settings.h" #include "utils.h" +/** + * Convert all HTML special symbols to HTML entities. + * @param str (nullable) + */ static char *markup_quote(char *str) { - assert(str); + if (!str) + return NULL; str = string_replace_all("&", "&", str); str = string_replace_all("\"", """, str); @@ -25,9 +30,14 @@ static char *markup_quote(char *str) return str; } +/** + * Convert all HTML special entities to their actual char. + * @param str (nullable) + */ static char *markup_unquote(char *str) { - assert(str); + if (!str) + return NULL; str = string_replace_all(""", "\"", str); str = string_replace_all("'", "'", str); @@ -38,9 +48,14 @@ static char *markup_unquote(char *str) return str; } +/** + * Convert all HTML linebreak tags to a newline character + * @param str (nullable) + */ static char *markup_br2nl(char *str) { - assert(str); + if (!str) + return NULL; str = string_replace_all("
", "\n", str); str = string_replace_all("
", "\n", str); @@ -48,15 +63,10 @@ static char *markup_br2nl(char *str) return str; } -/* - * Remove HTML hyperlinks of a string. - * - * @str: The string to replace a tags - * @urls: (nullable): If any href-attributes found, an '\n' concatenated - * string of the URLs in format '[] ' - */ +/* see markup.h */ void markup_strip_a(char **str, char **urls) { + assert(*str); char *tag1 = NULL; if (urls) @@ -128,13 +138,7 @@ void markup_strip_a(char **str, char **urls) } } -/* - * Remove img-tags of a string. If alt attribute given, use this as replacement. - * - * @str: The string to replace img tags - * @urls: (nullable): If any src-attributes found, an '\n' concatenated string of - * the URLs in format '[] ' - */ +/* see markup.h */ void markup_strip_img(char **str, char **urls) { const char *start; @@ -217,18 +221,7 @@ void markup_strip_img(char **str, char **urls) } } -/* - * Strip any markup from text; turn it in to plain text. - * - * For well-formed markup, the following two commands should be - * roughly equivalent: - * - * out = markup_strip(in); - * pango_parse_markup(in, -1, 0, NULL, &out, NULL, NULL); - * - * However, `pango_parse_markup()` balks at invalid markup; - * `markup_strip()` shouldn't care if there is invalid markup. - */ +/* see markup.h */ char *markup_strip(char *str) { if (!str) @@ -317,10 +310,7 @@ static char *markup_escape_unsupported(char *str) return str; } -/* - * Transform the string in accordance with `markup_mode` and - * `settings.ignore_newline` - */ +/* see markup.h */ char *markup_transform(char *str, enum markup_mode markup_mode) { if (!str) diff --git a/src/markup.h b/src/markup.h index 9d5cda7..aea4f0f 100644 --- a/src/markup.h +++ b/src/markup.h @@ -4,11 +4,42 @@ #include "settings.h" +/** + * Strip any markup from text; turn it in to plain text. + * + * For well-formed markup, the following two commands should be + * roughly equivalent: + * + * out = markup_strip(in); + * pango_parse_markup(in, -1, 0, NULL, &out, NULL, NULL); + * + * However, `pango_parse_markup()` balks at invalid markup; + * `markup_strip()` shouldn't care if there is invalid markup. + */ char *markup_strip(char *str); +/** + * Remove HTML hyperlinks of a string. + * + * @param str The string to replace a tags + * @param urls (nullable) If any href-attributes found, an `\n` concatenated + * string of the URLs in format `[] ` + */ void markup_strip_a(char **str, char **urls); + +/** + * Remove img-tags of a string. If alt attribute given, use this as replacement. + * + * @param str The string to replace img tags + * @param urls (nullable) If any src-attributes found, an `\n` concatenated string of + * the URLs in format `[] ` + */ void markup_strip_img(char **str, char **urls); +/** + * Transform the string in accordance with `markup_mode` and + * `settings.ignore_newline` + */ char *markup_transform(char *str, enum markup_mode markup_mode); #endif diff --git a/src/utils.c b/src/utils.c index adfa14b..22a0c50 100644 --- a/src/utils.c +++ b/src/utils.c @@ -2,6 +2,7 @@ #include "utils.h" #include +#include #include #include #include @@ -10,16 +11,24 @@ #include "log.h" +/* see utils.h */ char *string_replace_char(char needle, char replacement, char *haystack) { + if (!haystack) + return NULL; + char *current = haystack; while ((current = strchr(current, needle))) *current++ = replacement; return haystack; } +/* see utils.h */ char *string_replace_at(char *buf, int pos, int len, const char *repl) { + assert(buf); + assert(repl); + char *tmp; int size, buf_len, repl_len; @@ -44,18 +53,14 @@ char *string_replace_at(char *buf, int pos, int len, const char *repl) return tmp; } -char *string_replace(const char *needle, const char *replacement, char *haystack) -{ - char *start; - start = strstr(haystack, needle); - if (!start) - return haystack; - - return string_replace_at(haystack, (start - haystack), strlen(needle), replacement); -} - +/* see utils.h */ char *string_replace_all(const char *needle, const char *replacement, char *haystack) { + if (!haystack) + return NULL; + assert(needle); + assert(replacement); + char *start; int needle_pos; int needle_len, repl_len; @@ -76,6 +81,7 @@ char *string_replace_all(const char *needle, const char *replacement, char *hays return haystack; } +/* see utils.h */ char *string_append(char *a, const char *b, const char *sep) { if (STR_EMPTY(a)) { @@ -93,7 +99,6 @@ char *string_append(char *a, const char *b, const char *sep) g_free(a); return new; - } /* see utils.h */ @@ -113,8 +118,11 @@ char *string_strip_quotes(const char *value) return s; } +/* see utils.h */ void string_strip_delimited(char *str, char a, char b) { + assert(str); + int iread=-1, iwrite=0, copen=0; while (str[++iread] != 0) { if (str[iread] == a) { @@ -128,13 +136,14 @@ void string_strip_delimited(char *str, char a, char b) str[iwrite] = 0; } +/* see utils.h */ char *string_to_path(char *string) { if (string && STRN_EQ(string, "~/", 2)) { char *home = g_strconcat(getenv("HOME"), "/", NULL); - string = string_replace("~/", home, string); + string = string_replace_at(string, 0, 2, home); g_free(home); } @@ -142,9 +151,9 @@ char *string_to_path(char *string) return string; } +/* see utils.h */ gint64 string_to_time(const char *string) { - assert(string); errno = 0; @@ -165,7 +174,7 @@ gint64 string_to_time(const char *string) } // endptr may point to a separating space - while (*endptr == ' ') + while (isspace(*endptr)) endptr++; if (STRN_EQ(endptr, "ms", 2)) diff --git a/src/utils.h b/src/utils.h index 6ea3b4e..b77fa28 100644 --- a/src/utils.h +++ b/src/utils.h @@ -16,23 +16,49 @@ //! Test if string a and b are the same case-insensitively #define STR_CASEQ(a, b) (strcasecmp(a, b) == 0) -/* replace all occurrences of the character needle with the character replacement in haystack */ +/** + * Replaces all occurrences of the char \p needle with the char \p replacement in \p haystack. + * + * Does not allocate a new string. + * + * @param needle The char to replace with replacement + * @param replacement The char which is the new one + * @param haystack (nullable) The string to replace + * + * @returns The exact value of the haystack paramater (to allow nesting) + */ char *string_replace_char(char needle, char replacement, char *haystack); -/* replace all occurrences of needle with replacement in haystack */ -char *string_replace_all(const char *needle, const char *replacement, char *haystack); - -/* replace characters with at position of the string */ +/** + * Replace a substring inside a string with another string. + * + * May reallocate memory. Free the result with `g_free`. + * + * @param buf The string to replace + * @param pos The position of the substring to replace + * @param len The length of the substring to replace + * @param repl The new contents of the substring. + */ char *string_replace_at(char *buf, int pos, int len, const char *repl); -/* replace needle with replacement in haystack */ -char *string_replace(const char *needle, const char *replacement, char *haystack); +/** + * Replace all occurences of a substring. + * + * @param needle The substring to search + * @param replacement The substring to replace + * @param haystack (nullable) The string to search the substring for + */ +char *string_replace_all(const char *needle, const char *replacement, char *haystack); +/** + * Append \p b to string \p a. And concatenate both strings with \p concat, if both are non-empty. + * + * @param a (nullable) The left side of the string + * @param b (nullable) The right side of the string + * @param sep (nullable) The concatenator to concatenate if a and b given + */ char *string_append(char *a, const char *b, const char *sep); -/* strip content between two delimiter characters (inplace) */ -void string_strip_delimited(char *str, char a, char b); - /** * Strip quotes from a string. Won't touch inner quotes. * @@ -41,10 +67,32 @@ void string_strip_delimited(char *str, char a, char b); */ char *string_strip_quotes(const char *value); -/* replace tilde and path-specific values with its equivalents */ +/** + * Strip content between two delimiter characters + * + * @param str The string to operate in place + * @param a Starting delimiter + * @param b Ending delimiter + */ +void string_strip_delimited(char *str, char a, char b); + +/** + * Replace tilde and path-specific values with its equivalents + * + * The string gets invalidated. The new valid representation is the return value. + * + * @param string (nullable) The string to convert to a path. + * @returns The tilde-replaced string. + */ char *string_to_path(char *string); -/* convert time units (ms, s, m) to internal gint64 microseconds */ +/** + * Convert time units (ms, s, m) to the internal `gint64` microseconds format + * + * If no unit is given, 's' (seconds) is assumed by default. + * + * @param string The string to parse the time format from. + */ gint64 string_to_time(const char *string); /** diff --git a/test/utils.c b/test/utils.c index b99af9e..91e99fb 100644 --- a/test/utils.c +++ b/test/utils.c @@ -5,7 +5,8 @@ TEST test_string_replace_char(void) { - char *text = malloc(128 * sizeof(char)); + char *text = g_malloc(128 * sizeof(char)); + strcpy(text, "a aa aaa"); ASSERT_STR_EQ("b bb bbb", string_replace_char('a', 'b', text)); @@ -14,8 +15,8 @@ TEST test_string_replace_char(void) strcpy(text, ""); ASSERT_STR_EQ("", string_replace_char('a', 'b', text)); - free(text); + g_free(text); PASS(); } @@ -27,8 +28,8 @@ TEST test_string_replace_char(void) TEST test_string_replace_all(void) { + char *text = g_malloc(128 * sizeof(char)); - char *text = malloc(128 * sizeof(char)); strcpy(text, "aaaaa"); ASSERT_STR_EQ("bbbbb", (text = string_replace_all("a", "b", text))); @@ -44,29 +45,7 @@ TEST test_string_replace_all(void) strcpy(text, "abcdabc"); ASSERT_STR_EQ("xyzabcdxyzabc", (text = string_replace_all("a", "xyza", text))); - free(text); - PASS(); -} - -TEST test_string_replace(void) -{ - char *text = malloc(128 * sizeof(char)); - strcpy(text, "aaaaa"); - ASSERT_STR_EQ("baaaa", (text = string_replace("a", "b", text)) ); - - strcpy(text, ""); - ASSERT_STR_EQ((text = string_replace("a", "b", text)), ""); - - strcpy(text, "Nothing to replace"); - ASSERT_STR_EQ((text = string_replace("z", "a", text)), "Nothing to replace"); - - strcpy(text, "Reverse this"); - ASSERT_STR_EQ("Reverse sith", (text = string_replace("this", "sith", text))); - - strcpy(text, "abcdabc"); - ASSERT_STR_EQ("xyzabcdabc", (text = string_replace("a", "xyza", text))); - - free(text); + g_free(text); PASS(); } @@ -132,7 +111,7 @@ TEST test_string_strip_quotes(void) TEST test_string_strip_delimited(void) { - char *text = malloc(128 * sizeof(char)); + char *text = g_malloc(128 * sizeof(char)); strcpy(text, "A string_strip_delimited test"); string_strip_delimited(text, '<', '>'); @@ -154,7 +133,7 @@ TEST test_string_strip_delimited(void) string_strip_delimited(text, '<', '>'); ASSERT_STR_EQ("Nothing is done if there are no delimiters in the string", text); - free(text); + g_free(text); PASS(); } @@ -202,7 +181,6 @@ SUITE(suite_utils) { RUN_TEST(test_string_replace_char); RUN_TEST(test_string_replace_all); - RUN_TEST(test_string_replace); RUN_TEST(test_string_append); RUN_TEST(test_string_strip_quotes); RUN_TEST(test_string_strip_delimited);