str.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #ifndef STR_H
  2. #define STR_H
  3. /* STR RETURN CODE */
  4. #define STR_RC_TYPE unsigned char
  5. extern __thread STR_RC_TYPE str_errno;
  6. #define STR_RC_OK ((STR_RC_TYPE) 0L) /* No Error */
  7. #define STR_RC_EFM ((STR_RC_TYPE) 1L) /* Failed to malloc */
  8. #define STR_RC_EVN ((STR_RC_TYPE) 2L) /* Value is Null */
  9. #define STR_RC_EFMC ((STR_RC_TYPE) 3L) /* Failed to memcpy */
  10. #include <stddef.h>
  11. #if defined(STR_TYPEDEF) || defined(TYPEDEFS)
  12. typedef struct str str_st;
  13. #endif /* STR_TYPEDEF || TYPEDEFS */
  14. struct str {
  15. char *data;
  16. char *_c_data;
  17. size_t size;
  18. size_t _c_size;
  19. };
  20. struct str*
  21. str_create(const char *cstring, size_t cstring_size);
  22. struct str*
  23. str_create_ns(const char *cstring);
  24. STR_RC_TYPE
  25. str_destroy(struct str *str);
  26. STR_RC_TYPE
  27. str_to_lowercase(struct str *str);
  28. STR_RC_TYPE
  29. str_to_uppercase(struct str *str);
  30. STR_RC_TYPE
  31. str_to_titlecase(struct str *str);
  32. _Bool
  33. str_starts_with(struct str *str, struct str* start);
  34. _Bool
  35. str_starts_with_char(struct str *str, char chr);
  36. _Bool
  37. str_starts_with_cstring(struct str *str, char *cstring, size_t cstring_size);
  38. _Bool
  39. str_starts_with_cstring_ns(struct str *str, char *cstring);
  40. _Bool
  41. str_ends_with(struct str *str, struct str* end);
  42. _Bool
  43. str_ends_with_char(struct str *str, char chr);
  44. _Bool
  45. str_ends_with_cstring(struct str *str, char *cstring, size_t cstring_size);
  46. _Bool
  47. str_ends_with_cstring_ns(struct str *str, char *cstring);
  48. _Bool
  49. str_is_empty(struct str *str);
  50. size_t
  51. str_count_str(struct str *str, struct str *str2);
  52. size_t
  53. str_count_char(struct str *str, char chr);
  54. size_t
  55. str_count_cstring(struct str *str, char *cstring, size_t cstring_size);
  56. size_t
  57. str_count_cstring_ns(struct str *str, char *cstring);
  58. // reverse
  59. // append
  60. // prepend
  61. // trim_left
  62. // trim_right
  63. // trim
  64. // split
  65. // split_limit
  66. // equal
  67. // iequal
  68. // cmp
  69. // icmp
  70. // in_array
  71. // in_list
  72. // contains
  73. // to_cstring
  74. // to_char
  75. // to_short
  76. // to_int
  77. // to_long
  78. // to_float
  79. // to_double
  80. // formatted
  81. // join
  82. #if defined(STR_IMP) || defined(IMPLEMENTATIONS)
  83. #include <string.h>
  84. #include <stdlib.h>
  85. #if defined(STR_LOG) || defined(LOGS)
  86. #define __LOG(OUT, PFX, TXT) fprintf(OUT, PFX" %s: %s", __func__, TXT)
  87. #define LOG_ERROR(TXT) __LOG(stderr, "[ERROR]", TXT)
  88. #define LOG_INFO(TXT) __LOG(stdout, "[INFO]", TXT)
  89. #else
  90. #define LOG_ERROR(TXT) ;
  91. #define LOG_INFO(TXT) ;
  92. #endif /* STR_LOG */
  93. #define true ((unsigned char) 1L)
  94. #define false ((unsigned char) 0L)
  95. #define TEST_FOR_NULL(POINTER) \
  96. if ( POINTER == NULL ) { \
  97. LOG_ERROR("Null Pointer Not Expected"); \
  98. str_errno = STR_RC_EVN; \
  99. return str_errno; \
  100. }
  101. #define TEST_FOR_NULL_SR(POINTER, STR_RC) \
  102. if ( POINTER == NULL ) { \
  103. LOG_ERROR("Null Pointer Not Expected"); \
  104. str_errno = STR_RC_EVN; \
  105. return STR_RC; \
  106. }
  107. #define CHECK_MALLOC(POINTER, STR_RC) \
  108. if ( POINTER == NULL ) { \
  109. LOG_ERROR("Failed to malloc"); \
  110. str_errno = STR_RC_EFM; \
  111. return STR_RC; \
  112. }
  113. #define CHECK_MALLOC_FREE(POINTER, STR_RC, FREE) \
  114. if ( POINTER == NULL ) { \
  115. free(FREE); \
  116. LOG_ERROR("Failed to malloc"); \
  117. str_errno = STR_RC_EFM; \
  118. return STR_RC; \
  119. }
  120. struct str*
  121. str_create(const char *cstring, size_t cstring_size)
  122. {
  123. str_errno = STR_RC_OK;
  124. struct str *ret = malloc(sizeof(struct str));
  125. CHECK_MALLOC(ret, NULL);
  126. ret->_c_size = cstring_size;
  127. ret->size = ret->_c_size;
  128. ret->data = malloc(ret->_c_size);
  129. CHECK_MALLOC_FREE(ret, NULL, ret);
  130. *ret->data = -1;
  131. ret->_c_data = ret->data;
  132. memcpy(ret->data, cstring, ret->_c_size);
  133. if ( *ret->data == -1 ) {
  134. str_destroy(ret);
  135. str_errno = STR_RC_EFMC;
  136. return NULL;
  137. }
  138. return ret;
  139. }
  140. struct str*
  141. str_create_ns(const char *cstring)
  142. {
  143. str_errno = STR_RC_OK;
  144. #ifdef CSTRING_H
  145. return str_create(cstring, cstring_len(cstring));
  146. #else
  147. return str_create(cstring, strlen(cstring));
  148. #endif /* CSTRING_H */
  149. }
  150. STR_RC_TYPE
  151. str_destroy(struct str *str)
  152. {
  153. TEST_FOR_NULL(str);
  154. str_errno = STR_RC_OK;
  155. free(str->data);
  156. free(str);
  157. return STR_RC_OK;
  158. }
  159. STR_RC_TYPE
  160. str_to_lowercase(struct str *str)
  161. {
  162. TEST_FOR_NULL(str);
  163. TEST_FOR_NULL(str->_c_data);
  164. str_errno = STR_RC_OK;
  165. for ( size_t z = 0; z < str->_c_size; ++z ) {
  166. char c = str->_c_data[z];
  167. str->_c_data[z] += (char) ((c >= 'A' && c <= 'Z') * 32);
  168. }
  169. return STR_RC_OK;
  170. }
  171. STR_RC_TYPE
  172. str_to_uppercase(struct str *str)
  173. {
  174. TEST_FOR_NULL(str);
  175. TEST_FOR_NULL(str->_c_data);
  176. str_errno = STR_RC_OK;
  177. for ( size_t z = 0; z < str->_c_size; ++z ) {
  178. char c = str->_c_data[z];
  179. str->_c_data[z] -= (char)((c >= 'a' && c <= 'z') * 32);
  180. }
  181. return STR_RC_OK;
  182. }
  183. STR_RC_TYPE
  184. str_to_titlecase(struct str *str)
  185. {
  186. TEST_FOR_NULL(str);
  187. TEST_FOR_NULL(str->_c_data);
  188. str_errno = STR_RC_OK;
  189. size_t limit = str->_c_size - 1;
  190. char pc = ' ';
  191. for ( size_t z = 1; z < limit; ++z ) {
  192. char c = str->_c_data[z];
  193. char nc = str->_c_data[z+1];
  194. str->_c_data[z] = (char) (
  195. ((c >= 'a' && c <= 'z')
  196. && (nc != ' ' && pc == ' ')) * (c - 32)
  197. + ((c >= 'A' && c <= 'Z')
  198. && (pc != ' ' || nc == ' ')) * (c + 32));
  199. pc = c;
  200. }
  201. return STR_RC_OK;
  202. }
  203. _Bool
  204. str_starts_with(struct str *str, struct str* start)
  205. {
  206. TEST_FOR_NULL_SR(str, false);
  207. TEST_FOR_NULL_SR(str->_c_data, false);
  208. TEST_FOR_NULL_SR(start, false);
  209. TEST_FOR_NULL_SR(start->_c_data, false);
  210. str_errno = STR_RC_OK;
  211. _Bool ret = false;
  212. return ret;
  213. }
  214. _Bool
  215. str_starts_with_char(struct str *str, char chr)
  216. {
  217. TEST_FOR_NULL_SR(str, false);
  218. TEST_FOR_NULL_SR(str->_c_data, false);
  219. str_errno = STR_RC_OK;
  220. return (*str->data == chr);
  221. }
  222. _Bool
  223. str_starts_with_cstring(struct str *str, char *cstring, size_t cstring_size);
  224. _Bool
  225. str_starts_with_cstring_ns(struct str *str, char *cstring);
  226. _Bool
  227. str_ends_with(struct str *str, struct str* end);
  228. _Bool
  229. str_ends_with_char(struct str *str, char chr);
  230. _Bool
  231. str_ends_with_cstring(struct str *str, char *cstring, size_t cstring_size);
  232. _Bool
  233. str_ends_with_cstring_ns(struct str *str, char *cstring);
  234. _Bool
  235. str_is_empty(struct str *str);
  236. size_t
  237. str_count_str(struct str *str, struct str *str2);
  238. size_t
  239. str_count_char(struct str *str, char chr);
  240. size_t
  241. str_count_cstring(struct str *str, char *cstring, size_t cstring_size);
  242. size_t
  243. str_count_cstring_ns(struct str *str, char *cstring);
  244. #undef true
  245. #undef false
  246. #undef TEST_FOR_NULL
  247. #undef TEST_FOR_NULL_SR
  248. #undef CHECK_MALLOC
  249. #undef CHECK_MALLOC_FREE
  250. #undef LOG_ERROR
  251. #undef LOG_INFO
  252. #endif /* STR_IMP || IMPLEMENTATIONS */
  253. #endif /* STR_H */