Ver código fonte

Adding library str.h

Vinicius Teshima 1 ano atrás
pai
commit
7e8f66ec2d
1 arquivos alterados com 174 adições e 0 exclusões
  1. 174 0
      2015/c/str.h

+ 174 - 0
2015/c/str.h

@@ -0,0 +1,174 @@
+#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 */