return ret;
}
+/**
+ * Escapes some special characters in the source string by inserting a '\'
+ * before them. Acts like g_strescape() but does not demage utf8 chars.
+ * Returns a newly allocated string.
+ */
+char *util_strescape(const char *source, const char *exceptions)
+{
+ GString *result = g_string_new(NULL);
+ while (TRUE) {
+ char c = *source++;
+ if ('\0' == c) {
+ goto done;
+ }
+ if (exceptions && !strchr(exceptions, c)) {
+ continue;
+ }
+ switch (c) {
+ case '\n':
+ g_string_append(result, "\\n");
+ break;
+ case '\"':
+ g_string_append(result, "\\\"");
+ break;
+ case '\\':
+ g_string_append(result, "\\\\");
+ break;
+ case '\b':
+ g_string_append(result, "\\b");
+ break;
+ case '\f':
+ g_string_append(result, "\\f");
+ break;
+ case '\r':
+ g_string_append(result, "\\r");
+ break;
+ case '\t':
+ g_string_append(result, "\\t");
+ break;
+ default:
+ g_string_append_c(result, c);
+ }
+ }
+done:
+ return g_string_free(result, FALSE);
+}
+
static void create_dir_if_not_exists(const char *dirpath)
{
if (!g_file_test(dirpath, G_FILE_TEST_IS_DIR)) {
char *util_sanitize_uri(const char *uri_str);
char *util_strcasestr(const char *haystack, const char *needle);
char *util_str_replace(const char* search, const char* replace, const char* string);
+char *util_strescape(const char *source, const char *exceptions);
gboolean util_wildmatch(const char *pattern, const char *subject);
#endif /* end of include guard: _UTIL_H */
g_assert_false(util_wildmatch("foo,?", "fo"));
}
+static void test_strescape(void)
+{
+ unsigned int i;
+ char *value;
+ struct {
+ char *in;
+ char *expected;
+ char *excludes;
+ } data[] = {
+ {"", "", NULL},
+ {"foo", "foo", NULL},
+ {"a\nb\nc", "a\\nb\\nc", NULL},
+ {"foo\"bar", "foo\\bar", NULL},
+ {"s\\t", "s\\\\t", NULL},
+ {"u\bv", "u\\bv", NULL},
+ {"w\fx", "w\\fx", NULL},
+ {"y\rz", "y\\rz", NULL},
+ {"tab\tdi\t", "tab\\tdi\\t", NULL},
+ {"❧äüö\n@foo\t\"bar\"", "❧äüö\\n@foo\\t\\\"bar\\\"", NULL},
+ {"❧äüö\n@foo\t\"bar\"", "❧äüö\\n@foo\\t\"bar\"", "\""},
+ {"❧äüö\n@foo\t\"bar\"", "❧äüö\n@foo\t\\\"bar\\\"", "\n\t"},
+ };
+ for (i = 0; i < LENGTH(data); i++) {
+ value = util_strescape(data->in, data->excludes);
+ g_assert_cmpstr(value, ==, data->expected);
+ g_free(value);
+ }
+}
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/test-util/wildmatch-curlybraces", test_wildmatch_curlybraces);
g_test_add_func("/test-util/wildmatch-complete", test_wildmatch_complete);
g_test_add_func("/test-util/wildmatch-multi", test_wildmatch_multi);
+ g_test_add_func("/test-util/strescape", test_strescape);
return g_test_run();
}