|
|
@@ -10,6 +10,78 @@
|
|
|
#include <misc/debug.h>
|
|
|
#include <misc/expstring.h>
|
|
|
|
|
|
+/**
|
|
|
+ * Splits the given string by a character, and returns the result
|
|
|
+ * as a malloc'd array of char pointers, each malloc'd. The array
|
|
|
+ * is terminated by a NULL pointer.
|
|
|
+ *
|
|
|
+ * @param str string to split
|
|
|
+ * @param del delimiter character
|
|
|
+ * @return pointer to array of strings, or NULL on failure. On success,
|
|
|
+ * at least one string will always be returned.
|
|
|
+ */
|
|
|
+static char ** split_string (const char *str, char del);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Counts the number of strings in an array (same format as used by
|
|
|
+ * {@link split_string}).
|
|
|
+ *
|
|
|
+ * @param names pointer to array of strings; must not be NULL.
|
|
|
+ * @return number of strings
|
|
|
+ */
|
|
|
+static size_t count_strings (char **names);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Frees an array of strings (same format as used by
|
|
|
+ * {@link split_string}). This first frees the individual strings,
|
|
|
+ * then the whole array.
|
|
|
+ *
|
|
|
+ * @param names pointer to array of strings; must not be NULL.
|
|
|
+ */
|
|
|
+static void free_strings (char **names);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Concatenates the given strings, inserting a delimiter character
|
|
|
+ * in between. The result is returned as a newly malloc'd string.
|
|
|
+ * If there are no strings, an empty string is produced.
|
|
|
+ * If there is just one string, this string is copied.
|
|
|
+ *
|
|
|
+ * @param names pointer to array of strings; must not be NULL.
|
|
|
+ * Format is as returned by {@link split_string}.
|
|
|
+ * @param del delimiter to insert between strings
|
|
|
+ * @return resulting malloc'd string, or NULL on failure.
|
|
|
+ */
|
|
|
+static char * implode_strings (char **names, char del);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Splits the given string by a character in-place by replacing
|
|
|
+ * all delimiting characters with nulls, and returns the number
|
|
|
+ * of such replacements.
|
|
|
+ *
|
|
|
+ * @param str string to split in-place; must not be NULL.
|
|
|
+ * @param del delimiter character
|
|
|
+ * @return number of replaced characters, or equivalently, number
|
|
|
+ * of resulting strings minus one
|
|
|
+ */
|
|
|
+static size_t split_string_inplace2 (char *str, char del);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Concatenates the given strings, inserting a delimiter character
|
|
|
+ * in between. The result is returned as a newly malloc'd string.
|
|
|
+ * If there are no strings, an empty string is produced.
|
|
|
+ * If there is just one string, this string is copied.
|
|
|
+ *
|
|
|
+ * @param names pointer to a character array containing the
|
|
|
+ * null-terinated strings one after another, i.e.
|
|
|
+ * as produced by {@link split_string_inplace2}.
|
|
|
+ * Must not be NULL.
|
|
|
+ * @param num_names number of strings, e.g. the return value of
|
|
|
+ * {@link split_string_inplace2} plus one
|
|
|
+ * @param del delimiter to insert between strings
|
|
|
+ * @return resulting malloc'd string, or NULL on failure.
|
|
|
+ */
|
|
|
+static char * implode_compact_strings (const char *names, size_t num_names, char del);
|
|
|
+
|
|
|
static char ** split_string (const char *str, char del)
|
|
|
{
|
|
|
size_t len = strlen(str);
|
|
|
@@ -123,4 +195,52 @@ fail0:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static size_t split_string_inplace2 (char *str, char del)
|
|
|
+{
|
|
|
+ ASSERT(str)
|
|
|
+
|
|
|
+ size_t num_extra_parts = 0;
|
|
|
+
|
|
|
+ while (*str) {
|
|
|
+ if (*str == del) {
|
|
|
+ *str = '\0';
|
|
|
+ num_extra_parts++;
|
|
|
+ }
|
|
|
+ str++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return num_extra_parts;
|
|
|
+}
|
|
|
+
|
|
|
+static char * implode_compact_strings (const char *names, size_t num_names, char del)
|
|
|
+{
|
|
|
+ ASSERT(names)
|
|
|
+
|
|
|
+ ExpString str;
|
|
|
+ if (!ExpString_Init(&str)) {
|
|
|
+ goto fail0;
|
|
|
+ }
|
|
|
+
|
|
|
+ int is_first = 1;
|
|
|
+
|
|
|
+ while (num_names > 0) {
|
|
|
+ if (!is_first && !ExpString_AppendChar(&str, del)) {
|
|
|
+ goto fail1;
|
|
|
+ }
|
|
|
+ if (!ExpString_Append(&str, names)) {
|
|
|
+ goto fail1;
|
|
|
+ }
|
|
|
+ names += strlen(names) + 1;
|
|
|
+ num_names--;
|
|
|
+ is_first = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ExpString_Get(&str);
|
|
|
+
|
|
|
+fail1:
|
|
|
+ ExpString_Free(&str);
|
|
|
+fail0:
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
#endif
|