#ifndef _SK_UTIL_STRING_H #define _SK_UTIL_STRING_H #include "array.h" #include /** * stringize: * Convert value of preprocessor macro to C string literal. * * @param x: the name of the macro */ #define stringize(x) quote(x) /** * quote: * Quote literally whatever is passed into this macro as a C string. * * @param x: the value to quote * */ #ifdef HAVE_STRINGIZE #define quote(x) #x #else #error "No CPP stringize operator available?" #endif /** * boolstr: * Make string out of bool. * * @param b: the boolean variable * @returns "true" or "false" */ #define boolstr(b) (b ? "true" : "false") /** * strdup: * like strdup(3p). */ char *strdup(const char *s); /** * strajoin: * Joins a C string array using a separator character. * * The returned string should be free()d. * * @param sep: a char to insert between each element of the array * @param a: the array to join (NULL terminated) * @return a newly-allocated C string containing all of the elements joined */ #define strajoin(sep, a) stranjoin(sep, a, anullidx((void *)a)) /** * strajoin_r: * Joins a C string array using a separator character into a caller allocated * buffer. * * NOTE: the return value of this function is the length of the result if the * buffer would’ve been large enough. Use this to check for truncation. * If the destination buffer wasn’t large enough, the resulting string won’t be * NUL terminated. * * @param buf: the destination buffer (nothing will be written to it if NULL) * @param buflen: the length of @buf * @param sep: a char to insert between eaach element of the array * @param a: the array to join (NULL terminated) * @return the length of the full result string */ #define strajoin_r(buf, buflen, sep, a, nmemb) \ stranjoin_r(buf, buflen, sep, a, anullidx((void *)a)) /** * stranjoin: * Joins a C string array using a separator character. * * The returned string should be free()d. * * @param sep: a char to insert between each element of the array * @param a: the array to join * @param nmemb: the number of elements of @a * @return a newly-allocated C string containing all of the elements joined */ char *stranjoin(char sep, const char *a[], size_t nmemb); /** * stranjoin_r: * Joins a C string array using a separator character into a caller allocated * buffer. * * NOTE: the return value of this function is the length of the result if the * buffer would’ve been large enough. Use this to check for truncation. * If the destination buffer wasn’t large enough, the resulting string won’t be * NUL terminated. * * @param buf: the destination buffer (nothing will be written to it if NULL) * @param buflen: the length of @buf * @param sep: a char to insert between each element of @a * @param a: the array to join (NULL terminated) * @param nmemb: the number of elements of @a * @return the length of the untruncated joined string */ size_t stranjoin_r( char *restrict buf, size_t buflen, char sep, const char *restrict a[], size_t nmemb); char *_strjoin( /* internal */ char sep, /* const char * */...); size_t _strjoin_r( /* internal */ char *restrict buf, size_t buflen, char sep, /* const char * */...); /** * strjoin: * Joins a number of strings together to form one long string, with the * @separator inserted between each of them. The returned string * should be free()d. * * @param sep: a char to insert between each of the strings * @param ...: a list of strings to join * @return a newly-allocated string containing all of the strings joined */ #define strjoin(sep, ...) _strjoin(sep, __VA_ARGS__, NULL) /** * strjoin_r: * Joins a number of strings together to form one long string stored in a * caller-allocated buffer with the @separator inserted betwween each of them. * * @param buf: the destination buffer (nothing will be written to it if NULL) * @param buflen: the length of @buf * @param sep: a char to insert between each of the strings * @param ...: a list of strings to join * @return the length of the untruncated joined string */ #define strjoin_r(sep, ...) _strjoin_r(sep, __VA_ARGS__, NULL) /** * pathjoin: * Joins a number of path components together to form one single path. * The returned string should be free()d. * * @param ...: a list of path components to join * @return a newly-allocated string containing all of the path components joined */ #define pathjoin(...) strjoin(stringize(DIRSEP)[0], __VA_ARGS__) /** * pathjoin_r: * Joins a number of path components together to form one single path. * The result is stored in a caller-allocated buffer. * * @param buf: the destination buffer (nothing will be weitten to it if NULL) * @param buflen: the length of @buf * @param ...: a list of path components to join * @return the length of the untruncated joined string */ #define pathjoin_r(buf, buflen, ...) \ strjoin_r(buf, buflen, stringize(DIRSEP)[0], __VA_ARGS__) /** * strsplit: * Splits a string into a NULL-terminated array by a given separator. * * Call this function with a NULL buffer to determine the size of the resulting * array. * * @param str: the input string (null-terminated) * @param sep: a string containing one or more separator characters * @param buf: a buffer to put the array into * @returns the number of bytes written into buf */ size_t strsplit(const char *restrict in, const char *restrict sep, void *buf); #endif