#ifndef STR_H #define STR_H #include #include #include 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 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 */