Browse Source

[str.h/.c] Adding Untested str lib

Vinicius Teshima 2 năm trước cách đây
mục cha
commit
022030f2cc
2 tập tin đã thay đổi với 282 bổ sung0 xóa
  1. 93 0
      include/toolbox/str.h
  2. 189 0
      src/toolbox/str.c

+ 93 - 0
include/toolbox/str.h

@@ -0,0 +1,93 @@
+#ifndef TOOLBOX_STR_H
+#define TOOLBOX_STR_H
+
+#include <stddef.h>
+
+#include "toolbox/errno.h"
+
+#ifdef TOOLBOX_TYPEDEF
+typedef struct str str_st;
+#endif
+
+
+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);
+
+RET_TYPE
+str_destroy(struct str *str);
+
+RET_TYPE
+str_to_lowercase(struct str *str);
+RET_TYPE
+str_to_uppercase(struct str *str);
+RET_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
+
+
+#endif

+ 189 - 0
src/toolbox/str.c

@@ -0,0 +1,189 @@
+#include "toolbox/str.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "toolbox/errno.h"
+#include "toolbox/log.h"
+#include "toolbox/cstring.h"
+
+#define true ((unsigned char) 1L)
+#define false ((unsigned char) 0L)
+
+#define TEST_FOR_NULL(POINTER)						\
+	if ( POINTER == NULL ) {					\
+		LOG_ERROR("Null Pointer Not Expected");		\
+		toolbox_errno = RET_EVN;				\
+		return toolbox_errno;					\
+	}
+
+#define TEST_FOR_NULL_SR(POINTER, RET)					\
+	if ( POINTER == NULL ) {					\
+		LOG_ERROR("Null Pointer Not Expected");		\
+		toolbox_errno = RET_EVN;				\
+		return RET;						\
+	}
+
+#define CHECK_MALLOC(POINTER, RET)					\
+	if ( POINTER == NULL ) {					\
+		LOG_ERROR("Failed to malloc");				\
+		toolbox_errno = RET_EFM;				\
+		return RET;						\
+	}
+
+#define CHECK_MALLOC_FREE(POINTER, RET, FREE)				\
+	if ( POINTER == NULL ) {					\
+		free(FREE);						\
+		LOG_ERROR("Failed to malloc");				\
+		toolbox_errno = RET_EFM;				\
+		return RET;						\
+	}
+
+struct str*
+str_create(const char *cstring, size_t cstring_size)
+{
+	toolbox_errno = RET_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);
+		LOG_ERROR("Failed to memcpy");
+		toolbox_errno = RET_EFMC;
+		return NULL;
+	}
+
+	return ret;
+}
+
+struct str*
+str_create_ns(const char *cstring)
+{
+	toolbox_errno = RET_OK;
+	return str_create(cstring, cstring_len(cstring));
+}
+
+RET_TYPE
+str_destroy(struct str *str)
+{
+	TEST_FOR_NULL(str);
+	toolbox_errno = RET_OK;
+
+	free(str->data);
+	free(str);
+
+	return RET_OK;
+}
+
+RET_TYPE
+str_to_lowercase(struct str *str)
+{
+	TEST_FOR_NULL(str);
+	TEST_FOR_NULL(str->_c_data);
+	toolbox_errno = RET_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 RET_OK;
+}
+
+RET_TYPE
+str_to_uppercase(struct str *str)
+{
+	TEST_FOR_NULL(str);
+	TEST_FOR_NULL(str->_c_data);
+	toolbox_errno = RET_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 RET_OK;
+}
+
+RET_TYPE
+str_to_titlecase(struct str *str)
+{
+	TEST_FOR_NULL(str);
+	TEST_FOR_NULL(str->_c_data);
+	toolbox_errno = RET_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 RET_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);
+	toolbox_errno = RET_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);
+	toolbox_errno = RET_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);