string.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #ifndef __sti__string_h__
  2. #define __sti__string_h__
  3. // Public Domain.
  4. #ifndef STI_REPLACE_STD_STRING
  5. #include <string.h>
  6. #endif
  7. #include "macros.h"
  8. /*
  9. Naming Convention
  10. Mostly derived from string.h
  11. str n? r? case? {operation} _inplace?
  12. str: consistent prefix
  13. n: limited by bytes
  14. r: reverse; starts at the end of the string
  15. case: case-insensitive
  16. operation: see below
  17. _inplace: modifies the source buffer
  18. Operations:
  19. cat: append onto existing string; strcat
  20. chr: search for a character; strchr
  21. cmp: compare; strcmp
  22. colwsp: collapse whitespace. All sequences of whitespace are converted into a single copy of the provided character
  23. cpy: copy; strcpy
  24. cspn: return length of inverse prefix substring (postfix for 'r' version)
  25. dup: duplicate into newly allocated memory; strdup
  26. dupa: duplicate onto the stack using alloca
  27. len: calculate length; strlen
  28. pbrk: search for the first of any of a set of characters
  29. rev: reverse the string
  30. spn: return length of prefix substring (postfix for 'r' version)
  31. skip: search for the first character not in a set of characters (strspn, but returns a pointer)
  32. str: search for a substring; strstr
  33. tolower: convert the string to lowercase
  34. toupper: convert the string to uppercase
  35. ltrim: remove a prefix of characters in a set from the beginning of the string
  36. rtrim: remove a suffix of characters in a set from the end of the string
  37. trim: remove a sequence characters in a set from the beginning and end of the string
  38. Arguments:
  39. int c; a single ascii character
  40. size_t len; operation limit, in bytes
  41. */
  42. // regular ascii functions:
  43. // spn functions return the number of characters spanned
  44. // returns a pointer to the found char, or NULL
  45. char* strnchr(const char* s, int c, size_t n);
  46. // returns s
  47. char* strrev(char* s);
  48. char* strnrev(const char* s, size_t n);
  49. // returns a pointer to the first match character
  50. char* strnpbrk(const char* s, const char* accept, size_t n);
  51. char* strrpbrk(const char* s, const char* accept);
  52. char* strnrpbrk(const char* s, const char* accept, size_t n);
  53. // The length of the initial part of "s" not containing any of the characters that are part of "reject".
  54. size_t strncspn(const char* s, const char* reject, size_t n);
  55. size_t strrcspn(const char* s, const char* reject);
  56. size_t strnrcspn(const char* s, const char* reject, size_t n);
  57. //return the number of characters spanned
  58. size_t strnrspn(const char* s, const char* accept, size_t n);
  59. // moves chars to left, returns s
  60. char* strnltrim(char* s, const char* charset, size_t n);
  61. // does not trim, returns s
  62. char* strcolwsp(char* s, int c);
  63. char* strncolwsp(char* s, int c, size_t n);
  64. // also trims, returns s
  65. char* strcolwsptrim(char* s, int c);
  66. // capitalize the first letter following whitespace, and the beginning of the string, returns s
  67. char* strcapwords(char* s);
  68. char* strncapwords(char* s, size_t n);
  69. // capitalize the first letter following terminal punctuation, and the beginning of the string, returns s
  70. char* strcapsentences(char* s);
  71. char* strncapsentences(char* s, size_t n);
  72. // limited strspn
  73. size_t strnspn(const char* s, size_t count, const char* accept);
  74. // reverse strspn
  75. size_t strrspn(const char* s, const char* accept);
  76. // reverse strstr
  77. const char* strrstr(const char* haystack, const char* needle);
  78. // length of the line, or length of the string if no \n found
  79. size_t strlnlen(const char* s);
  80. // strdup a line
  81. char* strlndup(const char* s);
  82. // use alloca
  83. //char* strdupa(const char* s);
  84. // TODO: string-reverse
  85. // line count;
  86. size_t strlinecnt(const char* s);
  87. // allocates a new buffer and calls sprintf with it
  88. char* sprintfdup(char* fmt, ...);
  89. // concatenate all argument strings together in a new buffer
  90. #define strcatdup(...) strcatdup_(PP_NARG(__VA_ARGS__), __VA_ARGS__)
  91. char* strcatdup_(size_t nargs, ...);
  92. // concatenate all argument strings together in a new buffer,
  93. // with the given joining string between them
  94. #define strjoin(j, ...) strjoin_(j, PP_NARG(__VA_ARGS__), __VA_ARGS__)
  95. char* strjoin_(char* joiner, size_t nargs, ...);
  96. // returns a null-terminated list of pointers to each line.
  97. // mutates the source (replaces newlines with nulls)
  98. char** strsplit_inplace(char* src, char delim, size_t* outLen);
  99. // allocates individual memory chunks for each split pointer
  100. char** strsplit(char* src, char delim, size_t* outLen);
  101. // trim left
  102. size_t strtriml(char* s, const char* trim);
  103. // trim right
  104. size_t strtrimr(char* s, const char* trim);
  105. // both left and right
  106. size_t strtrim(char* s, const char* trim);
  107. // handy shortcut
  108. static inline char* strskip(char* s, char* skip) {
  109. return s + strspn(s, skip);
  110. }
  111. // decodes strings according to the string literal rules in C
  112. // *s is advanced to the next char
  113. // gleefully advances the pointer through nulls like any other character
  114. // returns 1 if the character was escaped
  115. // returns an error code on invalid escape sequences
  116. int decode_c_string_char(char** s, int* c_out);
  117. typedef struct number_parse_info {
  118. union {
  119. long double f;
  120. unsigned long long int n;
  121. };
  122. char type; // 'f', 'i'
  123. char base;
  124. // suffixes
  125. char longs; // 0 for unspecified
  126. char not_signed; // 0 for unspecified
  127. } number_parse_info;
  128. int read_c_number(char** s, number_parse_info* info);
  129. // format in arbitrary base/charset
  130. int sprintlongb(char* buf, int base, int64_t n, char* charset);
  131. // returns the numerical value of a single hex digit
  132. unsigned int decodeHexDigit(char c);
  133. // returns rgba, with r in most significant bits and a in the least
  134. uint32_t decodeHexColor(char* s);
  135. // returns rgba, with r in out[0] and a in out[3], normalized to 0xFF = 1.0
  136. void decodeHexColorNorm(char* s, float* out);
  137. // snprintf, with a void*[] arg list
  138. int isnprintfv(char* out, ptrdiff_t out_sz, char* fmt, void** args);
  139. // TODO:
  140. // collapse whitespace
  141. // collapse ws to a single ' '
  142. // compare functions for natural interpretations of strings (version sort)
  143. #ifdef STI_REPLACE_STD_STRING
  144. // void* memccpy(void *restrict, const void *restrict, int, size_t);
  145. #define memccpy __builtin_memccpy
  146. // void* memchr(const void *, int, size_t);
  147. #define memchr __builtin_memchr
  148. // int memcmp(const void *, const void *, size_t);
  149. #define memcmp __builtin_memcmp
  150. #if !__has_builtin(__builtin_memcpy)
  151. void* memcpy(void* restrict dest, const void *restrict src, size_t n);
  152. #else
  153. #define memcpy __builtin_memcpy
  154. #endif
  155. // void* memmove(void*, const void *, size_t);
  156. #define memmove __builtin_memmove
  157. #if !__has_builtin(__builtin_memset)
  158. void* memset(void* s, int c, size_t n);
  159. #else
  160. #define memset __builtin_memset
  161. #endif
  162. // char* stpcpy(char *restrict, const char *restrict);
  163. #define stpcpy __builtin_stpcpy
  164. // char* stpncpy(char *restrict, const char *restrict, size_t);
  165. #define stpncpy __builtin_stpncpy
  166. // char* strcat(char *restrict, const char *restrict);
  167. #define strcat __builtin_strcat
  168. // char* strchr(const char *, int);
  169. #define strchr __builtin_strchr
  170. // int strcmp(const char *, const char *);
  171. #define strcmp __builtin_strcmp
  172. // int strcoll(const char *, const char *);
  173. #define strcoll __builtin_strcoll
  174. // int strcoll_l(const char *, const char *, locale_t);
  175. #define strcoll_l __builtin_strcoll_l
  176. // char* strcpy(char *restrict, const char *restrict);
  177. #define strcpy __builtin_strcpy
  178. // size_t strcspn(const char *, const char *);
  179. #define strcspn __builtin_strcspn
  180. // char* strdup(const char *);
  181. #define strdup __builtin_strdup
  182. // char* strerror(int);
  183. #define strerror __builtin_strerror
  184. // char* strerror_l(int, locale_t);
  185. #define strerror_l __builtin_strerror_l
  186. // int strerror_r(int, char *, size_t);
  187. #define strerror_r __builtin_strerror_r
  188. // size_t strlen(const char *);
  189. #define strlen __builtin_strlen
  190. // char* strncat(char *restrict, const char *restrict, size_t);
  191. #define strncat __builtin_strncat
  192. // int strncmp(const char *, const char *, size_t);
  193. #define strncmp __builtin_strncmp
  194. // char* strncpy(char *restrict, const char *restrict, size_t);
  195. #define strncpy __builtin_strncpy
  196. // char* strndup(const char *, size_t);
  197. #define strndup __builtin_strndup
  198. // size_t strnlen(const char *, size_t);
  199. #define strnlen __builtin_strnlen
  200. // char* strpbrk(const char *, const char *);
  201. #define strpbrk __builtin_strpbrk
  202. // char* strrchr(const char *, int);
  203. #define strrchr __builtin_strrchr
  204. // char* strsignal(int);
  205. #define strsignal __builtin_strsignal
  206. // size_t strspn(const char *, const char *);
  207. #define strspn __builtin_strspn
  208. // char* strstr(const char *, const char *);
  209. #define strstr __builtin_strstr
  210. // char* strtok(char *restrict, const char *restrict);
  211. #define strtok __builtin_strtok
  212. // char* strtok_r(char *restrict, const char *restrict, char **restrict);
  213. #define strtok_r __builtin_strtok_r
  214. // size_t strxfrm(char *restrict, const char *restrict, size_t);
  215. #define strxfrm __builtin_strxfrm
  216. // size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_t);
  217. #define strxfrm_l __builtin_strxfrm_l
  218. #endif
  219. #endif // __sti__string_h__