int pakfire_string_startswith(const char* s, const char* prefix);
int pakfire_string_partition(const char* s, const char* delim, char** s1, char** s2);
+char* pakfire_string_replace(const char* s, const char* pattern, const char* repl);
char* pakfire_format_size(double size);
char* pakfire_format_date(time_t t);
return 0;
}
+PAKFIRE_EXPORT char* pakfire_string_replace(
+ const char* s, const char* pattern, const char* repl) {
+ char* result = NULL;
+ const char** cache = NULL;
+ unsigned int count = 0;
+
+ const size_t pattern_length = strlen(pattern);
+
+ // Working pointer
+ const char* p = s;
+
+ // Find all occurrences of pattern and store their location
+ while (1) {
+ const char* needle = strstr(p, pattern);
+ if (!needle)
+ break;
+
+ // Make space in the cache
+ cache = reallocarray(cache, sizeof(*cache), count + 1);
+ cache[count++] = needle;
+
+ // Move p forward
+ p = needle + pattern_length;
+ }
+
+ // Copy the string if no occurence was found
+ if (count == 0) {
+ result = strdup(s);
+ goto ERROR;
+ }
+
+ // Store the end pointer
+ cache = reallocarray(cache, sizeof(*cache), count + 1);
+ cache[count] = s + strlen(s);
+
+ const size_t repl_length = strlen(repl);
+
+ // Determine the length of the final string
+ const size_t length = strlen(s) + ((repl_length - pattern_length) * count);
+
+ // Allocate enough memory for the result
+ result = malloc(length + 1);
+ if (!result)
+ goto ERROR;
+
+ // Reset p
+ p = s;
+
+ // Working pointer for the result
+ char* r = result;
+
+ // Copy everything up to the first match
+ ssize_t l = cache[0] - s;
+ memcpy(r, p, l);
+ r += l;
+ p += l;
+
+ for (unsigned int i = 0; i < count; i++) {
+ // Put replacement here
+ memcpy(r, repl, repl_length);
+ r += repl_length;
+ p += pattern_length;
+
+ // Determine the length between two matches
+ l = cache[i+1] - (cache[i] + pattern_length);
+
+ memcpy(r, p, l);
+ r += l;
+ p += l;
+ }
+
+ // Terminate the string
+ result[length] = '\0';
+
+ERROR:
+ if (cache)
+ free(cache);
+
+ return result;
+}
+
char* pakfire_lstrip(const char* s) {
while (*s && isspace(*s))
s++;
return EXIT_SUCCESS;
}
+static int test_string_replace(const struct test* t) {
+ const char* result = pakfire_string_replace(
+ "ABCABCABCABC", "AB", "CC"
+ );
+ ASSERT_STRING_EQUALS(result, "CCCCCCCCCCCC");
+
+ return EXIT_SUCCESS;
+}
+
int main(int argc, char** argv) {
testsuite_add_test(test_basename);
testsuite_add_test(test_dirname);
testsuite_add_test(test_string_startswith);
testsuite_add_test(test_string_partition);
+ testsuite_add_test(test_string_replace);
return testsuite_run();
}