/* [ʞ] compose.c * ~ lexi hale * © affero general public license v3 * $ cc -c compose.c * # include * * compose.c contains some useful string utilities * that libc lacks. TODO add macro to use homebrew strlen instead of dragging in */ #ifdef k_header // only emit the declarations # define fn(x) #else # define fn(x) x #endif #include typedef struct pstr { size_t len; union { const char* ptr; char* mutptr; }; } pstr; #define _p(str) { sizeof str - 1, str } typedef struct safestr { union { const char* ptr; char* mutptr; }; // im sorry okay bool heap; size_t len; } safestr; void delstr(safestr s) fn ({ if (s.heap) { free(s.mutptr); } }); void clrstr(safestr* s) fn ({ delstr(*s); s->heap = false; s->ptr = NULL; s->len = 0; }) char* compose(pstr* lst,size_t ct, size_t* strsz) fn({ size_t len = 0; for (size_t i = 0; i < ct; ++i) { if (lst[i].len == 0) { if (lst[i].ptr == NULL) continue; lst[i].len = strlen(lst[i].ptr); } len += lst[i].len; } if (strsz != NULL) *strsz = len; if (len == 0) return NULL; char* str = malloc(len + 1); char* ptr = str; for (size_t i = 0; i < ct; ++i) { if (lst[i].len == 0) continue; strncpy(ptr,lst[i].ptr,lst[i].len); ptr += lst[i].len; } *ptr = 0; return str; });