summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/wee-string.c87
-rw-r--r--src/core/wee-string.h4
2 files changed, 86 insertions, 5 deletions
diff --git a/src/core/wee-string.c b/src/core/wee-string.c
index bc93f7ce7..9b12d79a2 100644
--- a/src/core/wee-string.c
+++ b/src/core/wee-string.c
@@ -1055,6 +1055,9 @@ string_has_highlight_regex (const char *string, const char *regex)
/*
* Splits a string according to separators.
*
+ * This function must not be called directly (call string_split or
+ * string_split_shared instead).
+ *
* Examples:
* string_split ("abc de fghi", " ", 0, 0, NULL)
* ==> array[0] = "abc"
@@ -1069,12 +1072,13 @@ string_has_highlight_regex (const char *string, const char *regex)
*/
char **
-string_split (const char *string, const char *separators, int keep_eol,
- int num_items_max, int *num_items)
+string_split_internal (const char *string, const char *separators, int keep_eol,
+ int num_items_max, int *num_items, int shared)
{
int i, j, n_items;
char *string2, **array;
char *ptr, *ptr1, *ptr2;
+ const char *str_shared;
if (num_items != NULL)
*num_items = 0;
@@ -1144,13 +1148,18 @@ string_split (const char *string, const char *separators, int keep_eol,
{
if (keep_eol)
{
- array[i] = strdup (ptr1);
+ array[i] = (shared) ? (char *)string_shared_get (ptr1) : strdup (ptr1);
if (!array[i])
{
for (j = 0; j < n_items; j++)
{
if (array[j])
- free (array[j]);
+ {
+ if (shared)
+ string_shared_free (array[j]);
+ else
+ free (array[j]);
+ }
}
free (array);
free (string2);
@@ -1165,7 +1174,12 @@ string_split (const char *string, const char *separators, int keep_eol,
for (j = 0; j < n_items; j++)
{
if (array[j])
- free (array[j]);
+ {
+ if (shared)
+ string_shared_free (array[j]);
+ else
+ free (array[j]);
+ }
}
free (array);
free (string2);
@@ -1173,6 +1187,23 @@ string_split (const char *string, const char *separators, int keep_eol,
}
strncpy (array[i], ptr1, ptr2 - ptr1);
array[i][ptr2 - ptr1] = '\0';
+ if (shared)
+ {
+ str_shared = string_shared_get (array[i]);
+ if (!str_shared)
+ {
+ for (j = 0; j < n_items; j++)
+ {
+ if (array[j])
+ string_shared_free (array[j]);
+ }
+ free (array);
+ free (string2);
+ return NULL;
+ }
+ free (array[i]);
+ array[i] = (char *)str_shared;
+ }
}
ptr1 = ++ptr2;
}
@@ -1193,6 +1224,35 @@ string_split (const char *string, const char *separators, int keep_eol,
}
/*
+ * Splits a string according to separators.
+ *
+ * For full description, see function string_split_internal.
+ */
+
+char **
+string_split (const char *string, const char *separators, int keep_eol,
+ int num_items_max, int *num_items)
+{
+ return string_split_internal (string, separators, keep_eol,
+ num_items_max, num_items, 0);
+}
+
+/*
+ * Splits a string according to separators, and use shared strings for the
+ * strings in the array returned.
+ *
+ * For full description, see function string_split_internal.
+ */
+
+char **
+string_split_shared (const char *string, const char *separators, int keep_eol,
+ int num_items_max, int *num_items)
+{
+ return string_split_internal (string, separators, keep_eol,
+ num_items_max, num_items, 1);
+}
+
+/*
* Splits a string like the shell does for a command with arguments.
*
* This function is a C conversion of python class "shlex"
@@ -1402,6 +1462,23 @@ string_free_split (char **split_string)
}
/*
+ * Frees a split string (using shared strings).
+ */
+
+void
+string_free_split_shared (char **split_string)
+{
+ int i;
+
+ if (split_string)
+ {
+ for (i = 0; split_string[i]; i++)
+ string_shared_free (split_string[i]);
+ free (split_string);
+ }
+}
+
+/*
* Builds a string with a split string.
*
* Note: result must be free after use.
diff --git a/src/core/wee-string.h b/src/core/wee-string.h
index c3cf06ca7..d79ae8fac 100644
--- a/src/core/wee-string.h
+++ b/src/core/wee-string.h
@@ -59,8 +59,12 @@ extern int string_has_highlight_regex_compiled (const char *string,
extern int string_has_highlight_regex (const char *string, const char *regex);
extern char **string_split (const char *string, const char *separators,
int keep_eol, int num_items_max, int *num_items);
+extern char **string_split_shared (const char *string, const char *separators,
+ int keep_eol, int num_items_max,
+ int *num_items);
extern char **string_split_shell (const char *string);
extern void string_free_split (char **split_string);
+extern void string_free_split_shared (char **split_string);
extern char *string_build_with_split_string (const char **split_string,
const char *separator);
extern char **string_split_command (const char *command, char separator);