diff --git a/da.h b/da.h index c32354b..87aff79 100644 --- a/da.h +++ b/da.h @@ -6,6 +6,9 @@ #include #include +#define EHAN_IMPLEMENTATION +#include "ehan.h" + enum daFields { SIZE = 0, CAPACITY = 1, @@ -14,8 +17,10 @@ enum daFields { }; typedef void * dynarr; -dynarr _daCreate(size_t initCapacity, size_t type, size_t size); -dynarr _daPush(dynarr da, void * item); +GenericReturn _daCreate(size_t initCapacity, size_t type, size_t size); +GenericReturn _daPush(dynarr * da, void * item); +GenericReturn daCopy(dynarr da); +GenericReturn daResize(dynarr da); void _daPop(dynarr da, void * element); void daPopDiscard(dynarr da); void daFree(dynarr da); @@ -36,21 +41,24 @@ void daBzero(dynarr da); #define dynarr(type) type * #define daCreate(type, cap) _daCreate(cap, sizeof(type), 0) -#define daPush(da, item) da = _daPush(da, &item) +#define daPush(da, item) _daPush((void *)&da, &item) #define daPop(da, item) _daPop(da, &item) #endif // DA_H_ #ifdef DA_IMPLEMENTATION -dynarr _daCreate(size_t cap, size_t type, size_t size) +GenericReturn _daCreate(size_t cap, size_t type, size_t size) { size_t * da = (size_t *) malloc(type * cap + DATA * sizeof(size_t)); + if (da == NULL) + ehanError("Failed to allocate resources for a dynamic array!"); + da[SIZE] = size; da[CAPACITY] = cap; da[TYPE] = type; - return (dynarr) (da + DATA); + return ehanValue((dynarr) (da + DATA)); } void daFree(dynarr da) @@ -58,27 +66,54 @@ void daFree(dynarr da) free((size_t *) da - DATA); } -dynarr daCopy(dynarr da) +GenericReturn daCopy(dynarr da) { - dynarr temp = _daCreate(daCap(da), daType(da), daSize(da)); - memcpy(temp, da, daSize(da) * daType(da)); - return temp; + if (da == NULL) + ehanError("Expected: 'dynarr' got 'NULL'"); + + GenericReturn temp = _daCreate(daCap(da), daType(da), daSize(da)); + + if (ehanCheck(temp)) + return ehanError(resultError(temp)); + + dynarr newArr = resultGeneric(dynarr, temp); + + memcpy(newArr, da, daSize(da) * daType(da)); + return ehanValue(newArr); } -dynarr daResize(dynarr da) +GenericReturn daResize(dynarr da) { - dynarr temp = _daCreate(daCap(da) * 2, daType(da), daSize(da)); - memcpy(temp, da, daSize(da) * daType(da)); + if (da == NULL) + ehanError("Expected: 'dynarr' got 'NULL'"); + + GenericReturn temp = _daCreate(daCap(da) * 2, daType(da), daSize(da)); + + if (ehanCheck(temp)) + return ehanError(resultError(temp)); + + dynarr newArr = resultGeneric(dynarr, temp); + + memcpy(newArr, da, daSize(da) * daType(da)); daFree(da); - return temp; + return ehanValue(newArr); } -dynarr _daPush(dynarr da, void * item) +GenericReturn _daPush(dynarr * da, void * item) { - if (daSize(da) >= daCap(da)) da = daResize(da); - memcpy((char *)da + daSize(da) * daType(da), item, daType(da)); - *daField(da, SIZE) += 1; - return da; + if (daSize(*da) >= daCap(*da)) + { + GenericReturn temp = daResize(*da); + + if (ehanCheck(temp)) + return ehanError(resultError(temp)); + + *da = resultGeneric(dynarr, temp); + } + + memcpy((char *)(*da) + daSize(*da) * daType(*da), item, daType(*da)); + *daField(*da, SIZE) += 1; + return ehanValue(*da); } void _daPop(dynarr da, void * elem) diff --git a/ehan.h b/ehan.h new file mode 100644 index 0000000..33aad37 --- /dev/null +++ b/ehan.h @@ -0,0 +1,84 @@ +#ifndef EHAN_H_ +#define EHAN_H_ + +#include +#include +#include +#include + +typedef struct GenericReturn { + long double fp; + void * val; + const char * err; +} GenericReturn; + +GenericReturn ehanError(const char * error); +GenericReturn _ehanValue(void * value); +GenericReturn _ehanValueFP(long double value); +#define ehanValue(v) _ehanValue((void *) v) +#define ehanValueFP(fp) _ehanValueFP((long double) fp) + +#define resultGeneric(type, ret) (*(type *) &(ret.val)) +#define resultFP(type, ret) ((type) (ret.fp)) +#define resultError(ret) (ret.err) + +#define ehanCheck(ret) strlen(ret.err) + +#define ILog(format, ...) \ +do { \ +fprintf(stderr, "\x1b[34m""info""\x1b[0m"":%s:%d: " format, __FILE__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +#define WLog(format, ...) \ +do { \ +fprintf(stderr, "\x1b[33m""warn""\x1b[0m"":%s:%d: " format, __FILE__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +#define ELog(format, ...) \ +do { \ +fprintf(stderr, "\x1b[31m""error""\x1b[0m"":%s:%d: " format, __FILE__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +#ifdef NDEBUG + +#define DLog(format, ...) + +#else + +#define DLog(format, ...) \ +do { \ +fprintf(stderr, "\x1b[32m""debug""\x1b[0m"":%s:%d: " format, __FILE__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +#endif + +#ifdef EHAN_IMPLEMENTATION + +GenericReturn _ehanValue(void * value) +{ + return (GenericReturn) { + .val = value, + .err = "", + }; +} + +GenericReturn _ehanValueFP(long double value) +{ + return (GenericReturn) { + .fp = value, + .val = 0, + .err = "", + }; +} + +GenericReturn ehanError(const char * error) +{ + return (GenericReturn) { + .val = 0, + .err = error, + }; +} + +#endif // EHAN_IMPLEMENTATION + +#endif // EHAN_H_ diff --git a/example.c b/example.c index 737d2cf..1bae5a7 100644 --- a/example.c +++ b/example.c @@ -3,6 +3,9 @@ #define DA_IMPLEMENTATION #include "da.h" +#define EHAN_IMPLEMENTATION +#include "ehan.h" + void printDaU16(void * item) { printf("%hu\n", *((unsigned short *) item)); @@ -19,7 +22,7 @@ int main(void) printf("DA1\n"); printf("----------\n"); - dynarr(unsigned short) * da = daCreate(unsigned short, 1); + dynarr(unsigned short) da = daCreate(unsigned short, 1).val; unsigned short x = 69; daPush(da, x); @@ -45,7 +48,7 @@ int main(void) printf("DA2\n"); printf("----------\n"); - dynarr(char) da2 = daCreate(char, 1); + dynarr(char) da2 = daCreate(char, 1).val; char y = 'H'; daPush(da2, y); @@ -61,6 +64,8 @@ int main(void) daPush(da2, y); y = '?'; daPush(da2, y); + y = '?'; + daPush(da2, y); *(char *)daGetRef(da2, 6) = '!';