#include #include #include "libstring.h" struct string *string_create(char *s) { if (!s) { struct string *r = calloc(1, sizeof(struct string)); char *data = calloc((BASE_STRING_SIZE + 1), sizeof(char)); if (!r || !data) { fprintf(stderr, "string_create: calloc failed.\n"); return NULL; } r->data = data; r->capacity = BASE_STRING_SIZE; return r; } struct string *str = malloc(1 * sizeof(struct string)); if (!str) { fprintf(stderr, "string_create: malloc failed.\n"); return NULL; } // Align the capacity on the string base size size_t l = strlen(s); size_t m = (l + 1) % BASE_STRING_SIZE; str->length = l; str->capacity = (l + 1) + (BASE_STRING_SIZE - m); str->data = calloc(str->capacity, sizeof(char)); if (!str->data) { fprintf(stderr, "string_create: malloc failed.\n"); return NULL; } memcpy(str->data, s, l); return str; } void string_free(struct string *str) { if (str) { free(str->data); free(str); } } static bool _resize_string(struct string *str, int p) { char *new_data = realloc( str->data, ((p >= 0) ? str->capacity * 2 : str->capacity / 2) + 1); if (!new_data) { fprintf(stderr, "_resize_string: realloc failed.\n"); return false; } str->data = new_data; str->capacity = ((p >= 0) ? str->capacity * 2 : str->capacity / 2); return true; } bool string_pushc(struct string *str, char c) { if (str->length == str->capacity) { if (!_resize_string(str, 1)) { return false; } } str->data[str->length] = c; str->length++; str->data[str->length] = 0; return true; } bool string_pushstr(struct string *str, char *s) { if (!s || !s[0]) { return true; } size_t l = strlen(s); while (str->length + l >= str->capacity) { if (!_resize_string(str, 1)) { return false; } } memcpy(str->data + str->length, s, l); str->length += l; str->data[str->length] = 0; return true; } bool string_catenate(struct string *dst, struct string *src) { if (!src) { return true; } if (!dst || !string_pushstr(dst, src->data)) { return false; } string_free(src); return true; } struct string *string_deepcopy(struct string *str) { return string_create(str->data); }