| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #ifndef STR_H
- #define STR_H
- #include <stdint.h>
- #include <stddef.h>
- #include <stdbool.h>
- struct str {
- const char *data;
- size_t size;
- };
- const struct str STR_EMPTY = {"", 0};
- struct str_tokenizer {
- struct str str;
- size_t cur;
- char c;
- };
- struct str str_from_cstr(const char *cstr, size_t cstr_size);
- struct str str_rstrip(struct str str);
- struct str str_lstrip(struct str str);
- struct str str_strip(struct str str);
- struct str_tokenizer str_tokenize(struct str str, char c);
- struct str str_tokenizer_next(struct str_tokenizer *st);
- struct str str_slice(struct str str, size_t from, size_t to);
- bool str_eq_cstr(struct str str, const char *cstr, size_t cstr_size);
- #if defined(IMP) || defined(IMP_STR)
- #include <ctype.h>
- struct str
- str_from_cstr(const char *cstr, size_t cstr_size)
- {
- struct str str;
- str.data = cstr;
- str.size = cstr_size;
- return str;
- }
- struct str
- str_rstrip(struct str str)
- {
- while ( isspace(str.data[str.size-1]) ) {
- --str.size;
- }
- return str;
- }
- struct str
- str_lstrip(struct str str)
- {
- while ( isspace(*str.data) ) {
- ++str.data;
- --str.size;
- }
- return str;
- }
- struct str
- str_strip(struct str str)
- {
- return str_lstrip(str_rstrip(str));
- }
- struct str_tokenizer
- str_tokenize(struct str str, char c)
- {
- struct str_tokenizer st = {0};
- st.str = str;
- st.c = c;
- return st;
- }
- struct str
- str_tokenizer_next(struct str_tokenizer *st)
- {
- struct str str;
- if ( st == NULL ) {
- goto ret_err;
- }
- if ( st->cur >= st->str.size ) {
- goto ret_done;
- }
- if ( st->str.data[st->cur] == '\0' ) {
- goto ret_done;
- }
- str = st->str;
- str.data += st->cur;
- str.size = 0;
- while ( str.data[str.size] != st->c
- && st->cur < st->str.size ) {
- ++str.size;
- ++st->cur;
- }
- ++st->cur;
- if ( str.size == 0 ) {
- goto ret_empty;
- }
- return str;
- ret_empty:
- str.data = "";
- str.size = 0;
- return str;
- ret_done:
- str.data = "";
- str.size = (size_t) -1;
- return str;
- ret_err:
- str.data = "";
- str.size = (size_t) -2;
- return str;
- }
- struct str
- str_slice(struct str str, size_t from, size_t to)
- {
- if ( from > str.size ) {
- goto ret_err;
- }
- if ( from > to ) {
- goto ret_err;
- }
- to = ( to > str.size ) * str.size \
- + ( to <= str.size ) * to;
-
- str.data += from;
- str.size = to - from;
- return str;
- ret_err:
- str.data = "";
- str.size = (size_t) -2;
- return str;
- }
- bool
- str_eq_cstr(struct str str, const char *cstr, size_t cstr_size)
- {
- size_t i = 0;
- if ( str.size != cstr_size ) {
- return false;
- }
- for ( i = 0; i < str.size; ++i ) {
- if ( str.data[i] != cstr[i] ) {
- return false;
- }
- }
- return true;
- }
- #endif /* defined(IMP) || defined(IMP_STR) */
- #endif /* STR_H */
|