string.h 8.8 KB

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