|
|
@@ -49,6 +49,7 @@ enum err {
|
|
|
ERR_TOO_BIG,
|
|
|
ERR_NULL_ARG,
|
|
|
ERR_NOT_FOUND,
|
|
|
+ ERR_INDEX_TOO_LARGE,
|
|
|
ERR_FAILED_OPEN,
|
|
|
ERR_FAILED_CLOSE,
|
|
|
ERR_FAILED_READ,
|
|
|
@@ -69,6 +70,7 @@ const char *err_to_name[] = {
|
|
|
"ERR_TOO_BIG",
|
|
|
"ERR_NULL_ARG",
|
|
|
"ERR_NOT_FOUND",
|
|
|
+ "ERR_INDEX_TOO_LARGE",
|
|
|
"ERR_FAILED_OPEN",
|
|
|
"ERR_FAILED_CLOSE",
|
|
|
"ERR_FAILED_READ",
|
|
|
@@ -101,6 +103,12 @@ typedef unsigned char u8;
|
|
|
|
|
|
/* ------------------------------ END INT DEF ------------------------------ */
|
|
|
|
|
|
+void *malloc(u64 size);
|
|
|
+void *realloc(void *ptr, u64 new_size);
|
|
|
+void free(void *ptr);
|
|
|
+void *memcpy(void *dest, const void *src, u64 n);
|
|
|
+void *memset(void *s, int c, u64 n);
|
|
|
+
|
|
|
/* ----------------------------- START LIB DEF ----------------------------- */
|
|
|
|
|
|
# define LIB_SET_IF_NOT_NULL(var, err) \
|
|
|
@@ -249,13 +257,175 @@ struct str str_builder_to_str(const struct str_builder *str_bldr);
|
|
|
# if defined(WANT_DYN_ARR) || defined(WANT_ALL)
|
|
|
|
|
|
struct dyn_arr {
|
|
|
-
|
|
|
+ void *data;
|
|
|
+ u64 size;
|
|
|
+ u64 cap;
|
|
|
+ u16 elem_size;
|
|
|
};
|
|
|
|
|
|
+struct dyn_arr dyn_arr_create(u16 elem_size, enum err *out_err);
|
|
|
+
|
|
|
+enum err dyn_arr_append(struct dyn_arr *da, void *elem, enum err *out_err);
|
|
|
+enum err dyn_arr_prepend(struct dyn_arr *da, void *elem, enum err *out_err);
|
|
|
+enum err dyn_arr_insert(struct dyn_arr *da, void *elem, u64 index,
|
|
|
+ enum err *out_err);
|
|
|
+void *dyn_arr_pop(struct dyn_arr *da, u64 index, enum err *out_err);
|
|
|
+void *dyn_arr_pop_last(struct dyn_arr *da, enum err *out_err);
|
|
|
+
|
|
|
+enum err dyn_arr_destroy(struct dyn_arr *da, enum err *out_err);
|
|
|
+
|
|
|
|
|
|
# if defined(IMP) || defined(IMP_STR)
|
|
|
|
|
|
+struct dyn_arr
|
|
|
+dyn_arr_create(u16 elem_size, enum err *out_err)
|
|
|
+{
|
|
|
+ struct dyn_arr empty = {0};
|
|
|
+ struct dyn_arr da = {0};
|
|
|
+
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
|
|
|
+
|
|
|
+ da.size = 0;
|
|
|
+ da.cap = 64;
|
|
|
+ da.elem_size = elem_size;
|
|
|
+ da.data = malloc(da.elem_size * da.cap);
|
|
|
+ if ( da.data == NULL ) {
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
|
|
|
+ return empty;
|
|
|
+ }
|
|
|
+ memset(da.data, 0, elem_size * da.cap);
|
|
|
+
|
|
|
+
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
|
|
|
+ return da;
|
|
|
+}
|
|
|
+
|
|
|
+enum err
|
|
|
+dyn_arr_insert(struct dyn_arr *da, void *elem, u64 index, enum err *out_err)
|
|
|
+{
|
|
|
+ u64 new_size = 0;
|
|
|
+ u64 i = 0;
|
|
|
+ u8 *data = NULL;
|
|
|
+
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
|
|
|
+
|
|
|
+ new_size = da->size + 1;
|
|
|
+ if ( index >= new_size ) {
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_INDEX_TOO_LARGE);
|
|
|
+ return ERR_INDEX_TOO_LARGE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( new_size >= da->cap ) {
|
|
|
+ da->cap *= 2;
|
|
|
+ da->data = realloc(da->data, da->cap);
|
|
|
+ if ( da->data == NULL ) {
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_FAILED_ALLOC);
|
|
|
+ return ERR_FAILED_ALLOC;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ data = (u8*) da->data;
|
|
|
+
|
|
|
+ if ( da->size > 0 ) {
|
|
|
+ for ( i = da->size-1; i > index; i-- ) {
|
|
|
+ memcpy((data + i), (data + i - 1), da->elem_size);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy((data + index), elem, da->elem_size);
|
|
|
+
|
|
|
+ ++da->size;
|
|
|
+
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
|
|
|
+ return ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+enum err
|
|
|
+dyn_arr_append(struct dyn_arr *da, void *elem, enum err *out_err)
|
|
|
+{
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
|
|
|
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
|
|
|
+
|
|
|
+ return dyn_arr_insert(da, elem, da->size, out_err);
|
|
|
+}
|
|
|
+
|
|
|
+enum err
|
|
|
+dyn_arr_prepend(struct dyn_arr *da, void *elem, enum err *out_err)
|
|
|
+{
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(elem, out_err);
|
|
|
+
|
|
|
+ return dyn_arr_insert(da, elem, 0, out_err);
|
|
|
+}
|
|
|
+
|
|
|
+void *
|
|
|
+dyn_arr_pop(struct dyn_arr *da, u64 index, enum err *out_err)
|
|
|
+{
|
|
|
+ static u8 temp_mem[256] = {0};
|
|
|
+ u8 *data = NULL;
|
|
|
+ u64 i = 0;
|
|
|
+
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL(da, out_err, NULL);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL(da->data, out_err, NULL);
|
|
|
+
|
|
|
+ if ( index >= da->size ) {
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_INDEX_TOO_LARGE);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ data = (u8*) da->data;
|
|
|
+
|
|
|
+ memcpy(temp_mem, (data + index), da->elem_size);
|
|
|
+
|
|
|
+ for ( i = index; i < da->size-1; ++i ) {
|
|
|
+ memcpy((data + i), (data + i + 1), da->elem_size);
|
|
|
+ }
|
|
|
+
|
|
|
+ --da->size;
|
|
|
+
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
|
|
|
+ return temp_mem;
|
|
|
+}
|
|
|
+
|
|
|
+void *
|
|
|
+dyn_arr_pop_last(struct dyn_arr *da, enum err *out_err)
|
|
|
+{
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, NULL);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL(da, out_err, NULL);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL(da->data, out_err, NULL);
|
|
|
+
|
|
|
+ return dyn_arr_pop(da, da->size-1, out_err);
|
|
|
+}
|
|
|
+
|
|
|
+enum err
|
|
|
+dyn_arr_destroy(struct dyn_arr *da, enum err *out_err)
|
|
|
+{
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE_RET_IT(out_err, ERR_OK);
|
|
|
+
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da, out_err);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL_SET_RET_ERR(da->data, out_err);
|
|
|
+
|
|
|
+ free(da->data);
|
|
|
+
|
|
|
+ LIB_SET_IF_NOT_NULL(out_err, ERR_OK);
|
|
|
+ return ERR_OK;
|
|
|
+}
|
|
|
|
|
|
# endif /* defined(IMP) || defined(IMP_STR) */
|
|
|
|