| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- #ifndef STR_H
- #define STR_H
- /* STR RETURN CODE */
- #define STR_RC_TYPE unsigned char
- extern __thread STR_RC_TYPE str_errno;
- #define STR_RC_OK ((STR_RC_TYPE) 0L) /* No Error */
- #define STR_RC_EFM ((STR_RC_TYPE) 1L) /* Failed to malloc */
- #define STR_RC_EVN ((STR_RC_TYPE) 2L) /* Value is Null */
- #define STR_RC_EFMC ((STR_RC_TYPE) 3L) /* Failed to memcpy */
- #include <stddef.h>
- #if defined(STR_TYPEDEF) || defined(TYPEDEFS)
- typedef struct str str_st;
- #endif /* STR_TYPEDEF || TYPEDEFS */
- struct str {
- char *data;
- char *_c_data;
- size_t size;
- size_t _c_size;
- };
- struct str*
- str_create(const char *cstring, size_t cstring_size);
- struct str*
- str_create_ns(const char *cstring);
- STR_RC_TYPE
- str_destroy(struct str *str);
- STR_RC_TYPE
- str_to_lowercase(struct str *str);
- STR_RC_TYPE
- str_to_uppercase(struct str *str);
- STR_RC_TYPE
- str_to_titlecase(struct str *str);
- _Bool
- str_starts_with(struct str *str, struct str* start);
- _Bool
- str_starts_with_char(struct str *str, char chr);
- _Bool
- str_starts_with_cstring(struct str *str, char *cstring, size_t cstring_size);
- _Bool
- str_starts_with_cstring_ns(struct str *str, char *cstring);
- _Bool
- str_ends_with(struct str *str, struct str* end);
- _Bool
- str_ends_with_char(struct str *str, char chr);
- _Bool
- str_ends_with_cstring(struct str *str, char *cstring, size_t cstring_size);
- _Bool
- str_ends_with_cstring_ns(struct str *str, char *cstring);
- _Bool
- str_is_empty(struct str *str);
- size_t
- str_count_str(struct str *str, struct str *str2);
- size_t
- str_count_char(struct str *str, char chr);
- size_t
- str_count_cstring(struct str *str, char *cstring, size_t cstring_size);
- size_t
- str_count_cstring_ns(struct str *str, char *cstring);
- // reverse
- // append
- // prepend
- // trim_left
- // trim_right
- // trim
- // split
- // split_limit
- // equal
- // iequal
- // cmp
- // icmp
- // in_array
- // in_list
- // contains
- // to_cstring
- // to_char
- // to_short
- // to_int
- // to_long
- // to_float
- // to_double
- // formatted
- // join
- #if defined(STR_IMP) || defined(IMPLEMENTATIONS)
- #include <string.h>
- #include <stdlib.h>
- #if defined(STR_LOG) || defined(LOGS)
- #define __LOG(OUT, PFX, TXT) fprintf(OUT, PFX" %s: %s", __func__, TXT)
- #define LOG_ERROR(TXT) __LOG(stderr, "[ERROR]", TXT)
- #define LOG_INFO(TXT) __LOG(stdout, "[INFO]", TXT)
- #else
- #define LOG_ERROR(TXT) ;
- #define LOG_INFO(TXT) ;
- #endif /* STR_LOG */
- #define true ((unsigned char) 1L)
- #define false ((unsigned char) 0L)
- #define TEST_FOR_NULL(POINTER) \
- if ( POINTER == NULL ) { \
- LOG_ERROR("Null Pointer Not Expected"); \
- str_errno = STR_RC_EVN; \
- return str_errno; \
- }
- #define TEST_FOR_NULL_SR(POINTER, STR_RC) \
- if ( POINTER == NULL ) { \
- LOG_ERROR("Null Pointer Not Expected"); \
- str_errno = STR_RC_EVN; \
- return STR_RC; \
- }
- #define CHECK_MALLOC(POINTER, STR_RC) \
- if ( POINTER == NULL ) { \
- LOG_ERROR("Failed to malloc"); \
- str_errno = STR_RC_EFM; \
- return STR_RC; \
- }
- #define CHECK_MALLOC_FREE(POINTER, STR_RC, FREE) \
- if ( POINTER == NULL ) { \
- free(FREE); \
- LOG_ERROR("Failed to malloc"); \
- str_errno = STR_RC_EFM; \
- return STR_RC; \
- }
- struct str*
- str_create(const char *cstring, size_t cstring_size)
- {
- str_errno = STR_RC_OK;
- struct str *ret = malloc(sizeof(struct str));
- CHECK_MALLOC(ret, NULL);
- ret->_c_size = cstring_size;
- ret->size = ret->_c_size;
- ret->data = malloc(ret->_c_size);
- CHECK_MALLOC_FREE(ret, NULL, ret);
- *ret->data = -1;
- ret->_c_data = ret->data;
- memcpy(ret->data, cstring, ret->_c_size);
- if ( *ret->data == -1 ) {
- str_destroy(ret);
- str_errno = STR_RC_EFMC;
- return NULL;
- }
- return ret;
- }
- struct str*
- str_create_ns(const char *cstring)
- {
- str_errno = STR_RC_OK;
- #ifdef CSTRING_H
- return str_create(cstring, cstring_len(cstring));
- #else
- return str_create(cstring, strlen(cstring));
- #endif /* CSTRING_H */
- }
- STR_RC_TYPE
- str_destroy(struct str *str)
- {
- TEST_FOR_NULL(str);
- str_errno = STR_RC_OK;
- free(str->data);
- free(str);
- return STR_RC_OK;
- }
- STR_RC_TYPE
- str_to_lowercase(struct str *str)
- {
- TEST_FOR_NULL(str);
- TEST_FOR_NULL(str->_c_data);
- str_errno = STR_RC_OK;
- for ( size_t z = 0; z < str->_c_size; ++z ) {
- char c = str->_c_data[z];
- str->_c_data[z] += (char) ((c >= 'A' && c <= 'Z') * 32);
- }
- return STR_RC_OK;
- }
- STR_RC_TYPE
- str_to_uppercase(struct str *str)
- {
- TEST_FOR_NULL(str);
- TEST_FOR_NULL(str->_c_data);
- str_errno = STR_RC_OK;
- for ( size_t z = 0; z < str->_c_size; ++z ) {
- char c = str->_c_data[z];
- str->_c_data[z] -= (char)((c >= 'a' && c <= 'z') * 32);
- }
- return STR_RC_OK;
- }
- STR_RC_TYPE
- str_to_titlecase(struct str *str)
- {
- TEST_FOR_NULL(str);
- TEST_FOR_NULL(str->_c_data);
- str_errno = STR_RC_OK;
- size_t limit = str->_c_size - 1;
- char pc = ' ';
- for ( size_t z = 1; z < limit; ++z ) {
- char c = str->_c_data[z];
- char nc = str->_c_data[z+1];
- str->_c_data[z] = (char) (
- ((c >= 'a' && c <= 'z')
- && (nc != ' ' && pc == ' ')) * (c - 32)
- + ((c >= 'A' && c <= 'Z')
- && (pc != ' ' || nc == ' ')) * (c + 32));
- pc = c;
- }
- return STR_RC_OK;
- }
- _Bool
- str_starts_with(struct str *str, struct str* start)
- {
- TEST_FOR_NULL_SR(str, false);
- TEST_FOR_NULL_SR(str->_c_data, false);
- TEST_FOR_NULL_SR(start, false);
- TEST_FOR_NULL_SR(start->_c_data, false);
- str_errno = STR_RC_OK;
- _Bool ret = false;
- return ret;
- }
- _Bool
- str_starts_with_char(struct str *str, char chr)
- {
- TEST_FOR_NULL_SR(str, false);
- TEST_FOR_NULL_SR(str->_c_data, false);
- str_errno = STR_RC_OK;
- return (*str->data == chr);
- }
- _Bool
- str_starts_with_cstring(struct str *str, char *cstring, size_t cstring_size);
- _Bool
- str_starts_with_cstring_ns(struct str *str, char *cstring);
- _Bool
- str_ends_with(struct str *str, struct str* end);
- _Bool
- str_ends_with_char(struct str *str, char chr);
- _Bool
- str_ends_with_cstring(struct str *str, char *cstring, size_t cstring_size);
- _Bool
- str_ends_with_cstring_ns(struct str *str, char *cstring);
- _Bool
- str_is_empty(struct str *str);
- size_t
- str_count_str(struct str *str, struct str *str2);
- size_t
- str_count_char(struct str *str, char chr);
- size_t
- str_count_cstring(struct str *str, char *cstring, size_t cstring_size);
- size_t
- str_count_cstring_ns(struct str *str, char *cstring);
- #undef true
- #undef false
- #undef TEST_FOR_NULL
- #undef TEST_FOR_NULL_SR
- #undef CHECK_MALLOC
- #undef CHECK_MALLOC_FREE
- #undef LOG_ERROR
- #undef LOG_INFO
- #endif /* STR_IMP || IMPLEMENTATIONS */
- #endif /* STR_H */
|