#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; }