diff --git a/include/char.h b/include/char.h index 4959d05..6aabdcc 100644 --- a/include/char.h +++ b/include/char.h @@ -27,7 +27,7 @@ int is_valid(const Vec8_t* vec); Vec8_t -create(const char* buf, const int len); +create(const char* buf, const size_t len); Vec8_t push_back(Vec8_t* vec, const char val); @@ -59,7 +59,7 @@ Vec8_t clear(const Vec8_t* vec); char -at(const Vec8_t* vec, int idx); +at(const Vec8_t* vec, const size_t idx); void print_vec(const Vec8_t* vec); diff --git a/include/utils.h b/include/utils.h index a568356..657dfa2 100644 --- a/include/utils.h +++ b/include/utils.h @@ -10,11 +10,12 @@ #define FAILURE 1 #define ERR_ALLOC_FAIL 20 #define ERR_BUF_NULL 21 -#define ERR_BAD_TYPE 22 -#define ERR_SIZE_ZERO 23 -#define ERR_VECTOR_NULL 24 -#define ERR_MAX_PASSED 25 -#define ERR_OUT_OF_BOUNDS 26 +#define ERR_SIZE_ZERO 22 +#define ERR_VECTOR_NULL 23 +#define ERR_MAX_PASSED 24 +#define ERR_OUT_OF_BOUNDS 25 +#define ERR_NULL 26 +#define ERR_DOUBLE_BUF 27 extern const char* error_messages[]; diff --git a/src/char.c b/src/char.c index 54ba389..7821264 100644 --- a/src/char.c +++ b/src/char.c @@ -24,24 +24,27 @@ is_valid(const Vec8_t* vec) return SUCCESS; } -// If -1 for len, returns a blank Vector with no allocated memory Vec8_t -create(const char* buf, const int len) +create(const char* buf, const size_t len) { Vec8_t dst = { NULL, 0, CAPACITY, VEC_MAX }; + if (len > dst.capacity) + { + while (len > dst.capacity) dst.capacity *= 2; + } if (len > 0) { - char* dst_buf = calloc(CAPACITY, sizeof(char)); + char* dst_buf = calloc(dst.capacity, sizeof(char)); + if (!dst_buf) + { + LOGERROR(ERR_ALLOC_FAIL); + return dst; + } dst.arr = dst_buf; } - if (len == -1) - { - // LOG("Warning! Buffer was forcibly not allocated."); - return dst; - } if (buf) { - for (int i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) { dst.arr[i] = buf[i]; dst.size++; @@ -55,9 +58,9 @@ push_back(Vec8_t* ptr, const char val) { if (is_valid(ptr) == ERR_VECTOR_NULL) { - return create(nullptr, -1); + return create(nullptr, 0); } - Vec8_t dst = { NULL, ptr->size, CAPACITY, ptr->max_size }; + Vec8_t dst = { NULL, ptr->size, ptr->capacity, ptr->max_size }; if (is_valid(ptr) == ERR_BUF_NULL) { @@ -81,10 +84,11 @@ push_back(Vec8_t* ptr, const char val) return dst; } dst.capacity = ptr->capacity * 2; - dst_buf = reallocf(ptr->arr, dst.capacity * sizeof(char)); + dst_buf = realloc(ptr->arr, dst.capacity * sizeof(char)); if (!dst_buf) { LOGERROR(ERR_ALLOC_FAIL); + dst = *ptr; return dst; } } @@ -101,7 +105,7 @@ push_back(Vec8_t* ptr, const char val) Vec8_t pop_back(Vec8_t* ptr) { - Vec8_t err = create(nullptr, -1); + Vec8_t err = create(nullptr, 0); if (is_valid(ptr) != SUCCESS) { return err; @@ -117,26 +121,43 @@ pop_back(Vec8_t* ptr) return dst; } +/* + * reallocf failure wipes the buffer — push_back (char.c:89-94), reserve + * (char.c:140-147). On alloc failure it frees ptr->arr, then returns arr == + * NULL; caller keeps a dangling pointer. Silent heap corruption. + * + * */ Vec8_t reserve(const Vec8_t* ptr, const size_t max_size) { - Vec8_t ret = create(nullptr, -1); - ret.arr = ptr->arr; + Vec8_t ret = create(nullptr, 0); + if (max_size == 0) + { + LOGERROR(ERR_SIZE_ZERO); + return ret; + } if (is_valid(ptr) == ERR_VECTOR_NULL) { return ret; } - if (is_valid(ptr) == ERR_BUF_NULL) + ret.arr = ptr->arr; + if (is_valid(&ret) == ERR_BUF_NULL) { ret.arr = calloc(max_size, sizeof(char)); } - if (is_valid(ptr) == SUCCESS) + else if (is_valid(ptr) == SUCCESS) { - ret.arr = reallocf(ret.arr, max_size * sizeof(char)); + ret.arr = realloc(ret.arr, max_size * sizeof(char)); + if (!ret.arr) + { + LOGERROR(ERR_ALLOC_FAIL); + ret = *ptr; + return ret; + } ret.size = ptr->size; if (ret.size > max_size) { - for (int i = max_size - 1; i > ret.size; i--) + for (size_t i = max_size; i < ret.size; i++) { ret.arr[i] = 0; } @@ -151,13 +172,19 @@ reserve(const Vec8_t* ptr, const size_t max_size) Vec8_t shrink_to_fit(Vec8_t* ptr) { + if (is_valid(ptr) != SUCCESS) return create(nullptr, 0); + if (ptr->size == 0) + { + LOGERROR(ERR_SIZE_ZERO); + return create(nullptr, 0); + } return reserve(ptr, ptr->size); } int swap(Vec8_t* ptr1, Vec8_t* ptr2) { - Vec8_t empty = create(nullptr, -1); + Vec8_t tmp = create(nullptr, 0); if (is_valid(ptr1) == ERR_VECTOR_NULL || is_valid(ptr2) == ERR_VECTOR_NULL) { @@ -167,18 +194,21 @@ swap(Vec8_t* ptr1, Vec8_t* ptr2) { return ERR_BUF_NULL; } - empty.arr = ptr1->arr; + tmp.arr = ptr1->arr; ptr1->arr = ptr2->arr; - ptr2->arr = empty.arr; + ptr2->arr = tmp.arr; - empty.capacity = ptr1->capacity; - empty.size = ptr1->size; + tmp.capacity = ptr1->capacity; + tmp.size = ptr1->size; + tmp.max_size = ptr1->max_size; ptr1->capacity = ptr2->capacity; ptr1->size = ptr2->size; + ptr1->max_size = ptr2->max_size; - ptr2->capacity = empty.capacity; - ptr2->size = empty.size; - return 0; + ptr2->capacity = tmp.capacity; + ptr2->size = tmp.size; + ptr2->max_size = tmp.max_size; + return SUCCESS; } char* @@ -192,12 +222,28 @@ data(const Vec8_t* ptr) size_t capacity(const Vec8_t* ptr) { + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return ERR_VECTOR_NULL; + } + if (is_valid(ptr) == ERR_BUF_NULL) + { + return ERR_BUF_NULL; + } return ptr->capacity; } size_t max_size(const Vec8_t* ptr) { + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return ERR_VECTOR_NULL; + } + if (is_valid(ptr) == ERR_BUF_NULL) + { + return ERR_BUF_NULL; + } return ptr->max_size; } @@ -213,15 +259,15 @@ delete(const Vec8_t* ptr) Vec8_t clear(const Vec8_t* ptr) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) { return dst; } - dst.arr = ptr->arr; - if (ptr->size > 0) + dst = *ptr; + if (dst.size > 0) { - for (int i = 0; i < ptr->size; i++) + for (size_t i = 0; i < dst.size; i++) { dst.arr[i] = 0; } @@ -231,7 +277,7 @@ clear(const Vec8_t* ptr) } char -at(const Vec8_t* ptr, const int idx) +at(const Vec8_t* ptr, const size_t idx) { if (is_valid(ptr) == ERR_VECTOR_NULL) { @@ -241,12 +287,11 @@ at(const Vec8_t* ptr, const int idx) { return ERR_BUF_NULL; } - if (ptr->size <= idx) + if (idx >= ptr->size) { fprintf(stderr, - "At Index: [%i] is out of bounds for size: [%zu]", idx, + "At Index: [%zu] is out of bounds for size: [%zu]", idx, ptr->size); - exit(-4); return ERR_OUT_OF_BOUNDS; } return ptr->arr[idx]; @@ -257,7 +302,7 @@ print_vec(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return; - for (int i = 0; i < ptr->size; i++) printf("%c ", at(ptr, i)); + for (size_t i = 0; i < ptr->size; i++) printf("%c ", ptr->arr[i]); printf("\n"); } @@ -271,22 +316,28 @@ begin(const Vec8_t* ptr) int end(const Vec8_t* ptr) { - if (is_valid(ptr) == SUCCESS) return (int)(ptr->size - 1); + if (is_valid(ptr) == SUCCESS) + { + if (ptr->size != 0) return (int)(ptr->size - 1); + else return FAILURE; + } return FAILURE; } char front(const Vec8_t* ptr) { + if (is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; + if (ptr->size == 0) return FAILURE; return at(ptr, 0); } char back(const Vec8_t* ptr) { - if (is_valid(ptr) == ERR_VECTOR_NULL) - return at(ptr, (int)ptr->size - 1); - return FAILURE; + if (is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; + if (ptr->size == 0) return FAILURE; + return at(ptr, ptr->size - 1); } int @@ -294,14 +345,14 @@ empty(const Vec8_t* ptr) { if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return FAILURE; - if (ptr->size <= 0) return SUCCESS; + if (ptr->size == 0) return SUCCESS; return FAILURE; } __attribute__((overloadable)) Vec8_t erase(const Vec8_t* ptr, const size_t iter) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL) return dst; if (is_valid(ptr) == ERR_BUF_NULL) return dst; if (iter >= ptr->size) return dst; @@ -316,10 +367,10 @@ erase(const Vec8_t* ptr, const size_t iter) __attribute__((overloadable)) Vec8_t erase(const Vec8_t* ptr, const size_t iter_start, const size_t iter_end) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL) return dst; if (is_valid(ptr) == ERR_BUF_NULL) return dst; - if (iter_start < 0 || iter_end > ptr->size) return dst; + if (iter_end > ptr->size) return dst; if (iter_start >= iter_end) return dst; dst = *ptr; size_t diff = iter_end - iter_start; @@ -333,23 +384,59 @@ erase(const Vec8_t* ptr, const size_t iter_start, const size_t iter_end) return dst; } -// TODO: Redo resize entirely __attribute__((overloadable)) Vec8_t resize(const Vec8_t* ptr, const size_t size) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; - dst = *ptr; - if ((0 < size && size != ptr->size && size < ptr->size) || - is_valid(ptr) == ERR_SIZE_ZERO) + if (ptr->size == size) { - LOGERROR(ERR_SIZE_ZERO); + LOG("ERR :- Ptr size and size are the same"); + dst = *ptr; return dst; } - for (size_t i = size - 1; i < ptr->size; i++) + + else if (ptr->size == 0) { - dst.arr[i] = '\0'; + dst = reserve(&dst, size); + } + + else if (size > ptr->max_size) + { + LOGERROR(ERR_MAX_PASSED); + dst = *ptr; + return dst; + } + else if (size > ptr->capacity) + { + size_t tmp = ptr->capacity; + while (size > tmp) + { + tmp *= 2; + } + dst = reserve(ptr, tmp); + if (!dst.arr) + { + LOGERROR(ERR_BUF_NULL); + dst = *ptr; + return dst; + } + } + if (size < ptr->size) + { + dst = *ptr; + for (size_t i = ptr->size; i > size; i--) + { + dst.arr[i] = '\0'; + } + } + if (ptr->size < size) + { + for (size_t i = ptr->size; i < size; i++) + { + dst.arr[i] = '\0'; + } } dst.size = size; return dst; @@ -358,7 +445,7 @@ resize(const Vec8_t* ptr, const size_t size) __attribute__((overloadable)) Vec8_t resize(Vec8_t* ptr, const size_t size, const char val) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); dst = *ptr; if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; @@ -382,7 +469,7 @@ resize(Vec8_t* ptr, const size_t size, const char val) for (size_t i = ptr->size; i < dst.size; i++) { - if (at(&dst, (int)i) >= 0) + if (at(&dst, i) >= 0) { dst.arr[i] = val; } @@ -395,18 +482,23 @@ __attribute__((overloadable)) Vec8_t assign(const Vec8_t* ptr, const Vec8_t* iterator, const size_t iter_start, const size_t iter_end) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; if (is_valid(iterator) == ERR_VECTOR_NULL || is_valid(iterator) == ERR_BUF_NULL) return dst; - if (iter_end <= iter_start) return dst; + if (iterator->size < iter_end || iter_end <= iter_start) + { + LOGERROR(ERR_OUT_OF_BOUNDS); + return dst; + } + dst = *ptr; dst = erase(ptr, begin(ptr), end(ptr) + 1); dst = reserve(&dst, (iter_end - iter_start)); for (size_t i = iter_start; i < iter_end; i++) { - dst = push_back(&dst, at(iterator, (int)i)); + dst = push_back(&dst, at(iterator, i)); } return dst; } @@ -414,12 +506,13 @@ assign(const Vec8_t* ptr, const Vec8_t* iterator, const size_t iter_start, __attribute__((overloadable)) Vec8_t assign(const Vec8_t* ptr, const size_t amount, const char val) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) - return create(nullptr, -1); + return create(nullptr, 0); + dst = *ptr; dst = erase(&dst, begin(&dst), end(&dst) + 1); dst = reserve(&dst, amount); - for (int i = 0; i < amount; i++) + for (size_t i = 0; i < amount; i++) { dst = push_back(&dst, val); } @@ -429,14 +522,19 @@ assign(const Vec8_t* ptr, const size_t amount, const char val) __attribute__((overloadable)) Vec8_t insert(const Vec8_t* ptr, const size_t iter, const char val) { - Vec8_t dst = create(nullptr, -1); + Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) { return dst; } - if (iter < 0) + if (ptr->max_size < ptr->size + 1) { - LOGERROR(ERR_SIZE_ZERO); + LOGERROR(ERR_MAX_PASSED); + return dst; + } + if (iter > ptr->size) + { + LOGERROR(ERR_OUT_OF_BOUNDS); return dst; } dst = *ptr; @@ -454,12 +552,18 @@ __attribute__((overloadable)) Vec8_t insert(const Vec8_t* ptr, const size_t iter, const size_t amount, const char val) { - Vec8_t dst = create(nullptr, -1); - if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) != SUCCESS) { + LOGERROR(ERR_NULL); return dst; } - if (iter < 0 || amount <= 0) + if (iter > ptr->size) + { + LOGERROR(ERR_OUT_OF_BOUNDS); + return dst; + } + if (amount <= 0) { LOGERROR(ERR_SIZE_ZERO); return dst; @@ -476,13 +580,22 @@ __attribute__((overloadable)) Vec8_t insert(const Vec8_t* dst_vec, const Vec8_t* src_vec, const size_t iter, const size_t iter_start, const size_t iter_end) { - Vec8_t dst = create(nullptr, -1); - if (is_valid(dst_vec) == ERR_VECTOR_NULL || - is_valid(dst_vec) == ERR_BUF_NULL) + Vec8_t dst = create(nullptr, 0); + if (is_valid(dst_vec) != SUCCESS || is_valid(src_vec) != SUCCESS) + { + LOGERROR(ERR_NULL); return dst; - if (is_valid(src_vec) == ERR_VECTOR_NULL || - is_valid(src_vec) == ERR_BUF_NULL) + } + if (iter_end > src_vec->size || iter > dst_vec->size) + { + LOGERROR(ERR_OUT_OF_BOUNDS); return dst; + } + if (dst_vec->arr == src_vec->arr) + { + LOGERROR(ERR_DOUBLE_BUF); + return dst; + } dst = *dst_vec; for (size_t i = iter_start; i < iter_end; i++) { diff --git a/src/main.c b/src/main.c index 25d9888..75094a5 100644 --- a/src/main.c +++ b/src/main.c @@ -6,10 +6,10 @@ */ /* * Types Wanted: - * Char - * Float - * Int - * String + * Char 8 Bits + * Float 32 Bits with suffix of 'f' + * Int 32 bits + * String 32 Bits with suffix of 's' */ #include @@ -24,12 +24,17 @@ main() { char ar1[] = { '1', '2', '3', '4' }; char ar2[] = { 'a', 'b', 'c', 'd' }; - Vec8_t v1 = create(ar1, find_len(ar1)); - Vec8_t v2 = create(ar2, find_len(ar2)); + // Vec8_t v1; + Vec8_t v1 = create(ar2, find_len(ar2)); // print_vec(&v1); // printf("Hello\n"); // v1 = assign(&v1, &v2, 0, 1); - v1 = insert(&v1, 1, 5, 'a'); + v1 = reserve(&v1, 9); + print_vec(&v1); + v1 = insert(&v1, 1, 'x'); + v1 = resize(&v1, 12); + // v1 = insert(&v1, 1, 5, 'a'); + // printf("%c", at(&v1, 1)); // printf("RESERVED SIZE: %zu", v1.max_size); print_vec(&v1); // v2 = resize(&v2, 3); @@ -54,6 +59,6 @@ main() // print_vec(&v1); // printf("SIZE: %zu\n", v1.size); delete(&v1); - delete(&v2); + // delete(&v2); return 0; } diff --git a/src/utils.c b/src/utils.c index a97d7ab..92a7a80 100644 --- a/src/utils.c +++ b/src/utils.c @@ -3,12 +3,10 @@ const char* error_messages[] = { [ERR_ALLOC_FAIL] = "Calloc :- Failed to allocate", [ERR_BUF_NULL] = "Buffer :- NULL", - [ERR_BAD_TYPE] = "Type :- Does not match vector type", [ERR_SIZE_ZERO] = "Size :- Size is or is less than 0 or invalid", [ERR_VECTOR_NULL] = "Vector :- Given vector is null", [ERR_MAX_PASSED] = "Max :- Vector Max value is overloaded", [ERR_OUT_OF_BOUNDS] = "Bounds:- Value is out of bounds", - - // [ERR_CREATION_FAIL] = "Buffer creation failed", - // [ERR_MALLOC_NULL] = "Malloc Failed to allocate", + [ERR_NULL] = "Null:- Vector or buffer is null", + [ERR_DOUBLE_BUF] = "Buffer :- Both buffers are copies of each other", };