#ifndef STR_H #define STR_H #include #include "dynarr.h" typedef DYNARR(char) string; typedef struct { const char *s; size_t n; } strv_t; #define strv(s) (strv_t) { s, strlen(s) } #define strvs(s) (strv_t) { s, slen(s) } string snew(void); size_t slen(const string); void scats(string *, strv_t); void scatc(string *, char); void sfree(string); void sreplace(string *str, size_t i, size_t n, strv_t with); string sfmt(const char *fmt, ...); string sdup(const char *); #ifdef STR_IMPL #include string snew(void) { string s; DA_INIT(s); DA_PUSH(s, '\0'); return s; } size_t slen(const string s) { return DA_LEN(s) - 1; } void scatc(string *s, char c) { size_t n = DA_LEN(*s) + 1; DA_FIT(*s, n); (*s)[n-2] = c; (*s)[n-1] = '\0'; DA_LEN(*s) = n; } void scats(string *s, strv_t sv) { size_t n = DA_LEN(*s) + sv.n; DA_FIT(*s, n); memcpy(&(*s)[slen(*s)], sv.s, sv.n); (*s)[n-1] = '\0'; DA_LEN(*s) = n; } void sfree(string s) { DA_FREE(s); } string sfmt(const char *fmt, ...) { va_list count, print; string s; FILE *f = fopen("/dev/null", "w/o"); va_start(print, fmt); va_copy(count, print); size_t n = vfprintf(f, fmt, count) + 1; DA_INIT_SZ(s, n); vsprintf(s, fmt, print); va_end(print); fclose(f); return s; } string sdup(const char *s) { string d; size_t n = strlen(s) + 1; DA_INIT_SZ(d, n); memcpy(d, s, n); return d; } void sreplace(string *str, size_t i, size_t n, strv_t with) { string s = *str; size_t new_n = DA_LEN(s) + with.n - n; DA_FIT(s, new_n); memmove(&s[i + with.n], &s[i + n], slen(s) - (i + n)); memcpy(&s[i], with.s, with.n); s[new_n - 1] = 0; DA_LEN(s) = new_n; } #endif #endif