From 1d8af5a018282dc6a93b9ed7c87d9d2f87287b14 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Mon, 13 Jul 2015 13:04:24 +0200 Subject: Copy the dependencies from sawmill project --- src/strutil.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/strutil.c (limited to 'src/strutil.c') diff --git a/src/strutil.c b/src/strutil.c new file mode 100644 index 0000000..7d436ec --- /dev/null +++ b/src/strutil.c @@ -0,0 +1,124 @@ +#include "common.h" + +#include "strutil.h" + +#include + +char* strdup_len(const char* src, size_t len) +{ + char* ret = malloc(len + 1); + if (ret) + { + memcpy(ret, src, len); + ret[len] = '\0'; + } + return ret; +} + +static inline bool escaped(char* start, char* cur) +{ + return cur > start && cur[-1] == '\\' && !escaped(start, cur - 1); +} + +void unescape(char* str) +{ + char* end = str + strlen(str); + char* s; + for (s = end - 1; s >= str; s--) + { + if (*s == '\\' && s < end - 1 && !escaped(str, s)) + { + end--; + memmove(s, s + 1, end - s); + } + } + *end = '\0'; +} + +char* escape(const char* str, const char* chars) +{ + dynstr_t* d = dynstr_new_str(str); + if (d) + { + if (dynstr_escape(d, chars)) + { + return dynstr_done(d); + } + dynstr_free(d); + } + return NULL; +} + +bool dynstr_escape(dynstr_t* str, const char* chars) +{ + char* s; + for (s = str->data + str->len - 1; s >= str->data; s--) + { + if (*s == '\\' || strchr(chars, *s)) + { + size_t pos = s - str->data; + if (!dynstr_appendc(str, '/')) + { + return false; + } + s = str->data + pos; + memmove(s + 1, s, str->len - (pos + 1)); + *s = '\\'; + } + } + return true; +} + +static void free_list(char** list, size_t count) +{ + char** l; + for (l = list; count-- > 0; l++) + { + free(*l); + } + free(list); +} + +char** split_len(const char* start, const char* end, char delim) +{ + char** ret; + size_t count = 0, size = 2; + assert(start && end); + assert(start <= end); + ret = malloc((size + 1) * sizeof(char*)); + if (ret) + { + const char* last = start; + for (;;) + { + const char* p; + for (p = last; p < end && *p != delim; p++); + if (count == size) + { + size_t ns = size * 2; + char** tmp = realloc(ret, (ns + 1) * sizeof(char*)); + if (!tmp) + { + free_list(ret, count); + return NULL; + } + size = ns; + ret = tmp; + } + ret[count] = strdup_len(last, p - last); + if (!ret[count]) + { + free_list(ret, count); + return NULL; + } + count++; + if (p == end) + { + break; + } + last = p + 1; + } + ret[count] = NULL; + } + return ret; +} -- cgit v1.2.3-70-g09d2