Compare commits

...

3 Commits

Author SHA1 Message Date
Maciej Samborski ae489f5cc4 Merge branch 'ehan' 2024-10-01 22:16:05 +02:00
Maciej Samborski b1844eb9dc Added ehan error handling 2024-09-23 20:40:58 +02:00
Maciej Samborski a89544beb5 Initialized ehan.h and some other minor changes 2024-09-23 19:04:25 +02:00
4 changed files with 179 additions and 22 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
.ctags .ctags
main main
valgrind-out.txt valgrind-out.txt
*.orig
test
test.c

76
da.h
View File

@ -6,6 +6,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define EHAN_IMPLEMENTATION
#include "ehan.h"
enum daFields { enum daFields {
SIZE = 0, SIZE = 0,
CAPACITY = 1, CAPACITY = 1,
@ -14,8 +17,10 @@ enum daFields {
}; };
typedef void * dynarr; typedef void * dynarr;
dynarr _daCreate(size_t initCapacity, size_t type, size_t size); GenericReturn _daCreate(size_t initCapacity, size_t type, size_t size);
dynarr _daPush(dynarr da, void * item); GenericReturn _daPush(dynarr * da, void * item);
GenericReturn daCopy(dynarr da);
GenericReturn daResize(dynarr da);
void _daPop(dynarr da, void * element); void _daPop(dynarr da, void * element);
void daPopDiscard(dynarr da); void daPopDiscard(dynarr da);
void daFree(dynarr da); void daFree(dynarr da);
@ -36,49 +41,82 @@ void daBzero(dynarr da);
#define dynarr(type) type * #define dynarr(type) type *
#define daCreate(type, cap) _daCreate(cap, sizeof(type), 0) #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) #define daPop(da, item) _daPop(da, &item)
#endif // DA_H_ #endif // DA_H_
#ifdef DA_IMPLEMENTATION #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)
{ {
if (cap == 0) cap = 1;
size_t * da = (size_t *) malloc(type * cap + DATA * sizeof(size_t)); size_t * da = (size_t *) malloc(type * cap + DATA * sizeof(size_t));
if (da == NULL)
return ehanError("Failed to allocate resources for a dynamic array!");
da[SIZE] = size; da[SIZE] = size;
da[CAPACITY] = cap; da[CAPACITY] = cap;
da[TYPE] = type; da[TYPE] = type;
return (dynarr) (da + DATA); return ehanValue((dynarr) (da + DATA));
} }
void daFree(dynarr da) void daFree(dynarr da)
{ {
if (da == NULL) return;
free((size_t *) da - DATA); free((size_t *) da - DATA);
} }
dynarr daCopy(dynarr da) GenericReturn daCopy(dynarr da)
{ {
dynarr temp = _daCreate(daCap(da), daType(da), daSize(da)); if (da == NULL)
memcpy(temp, da, daSize(da) * daType(da)); return ehanError("Expected: 'dynarr' got 'NULL'");
return temp;
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)); if (da == NULL)
memcpy(temp, da, daSize(da) * daType(da)); return 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); 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); if (daSize(*da) >= daCap(*da))
memcpy((char *)da + daSize(da) * daType(da), item, daType(da)); {
*daField(da, SIZE) += 1; GenericReturn temp = daResize(*da);
return 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) void _daPop(dynarr da, void * elem)
@ -131,6 +169,8 @@ void daForeach(dynarr da, func f)
heapstr daToCStr(dynarr da) heapstr daToCStr(dynarr da)
{ {
char * buffer = (char *) calloc(1, daSize(da) + 1); char * buffer = (char *) calloc(1, daSize(da) + 1);
if (buffer == NULL) return NULL;
memcpy(buffer, da, daSize(da) * daType(da)); memcpy(buffer, da, daSize(da) * daType(da));
return buffer; return buffer;
} }

84
ehan.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef EHAN_H_
#define EHAN_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
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_

View File

@ -3,6 +3,9 @@
#define DA_IMPLEMENTATION #define DA_IMPLEMENTATION
#include "da.h" #include "da.h"
#define EHAN_IMPLEMENTATION
#include "ehan.h"
void printDaU16(void * item) void printDaU16(void * item)
{ {
printf("%hu\n", *((unsigned short *) item)); printf("%hu\n", *((unsigned short *) item));
@ -19,7 +22,14 @@ int main(void)
printf("DA1\n"); printf("DA1\n");
printf("----------\n"); printf("----------\n");
dynarr(unsigned short) * da = daCreate(unsigned short, 1); GenericReturn gr = daCreate(unsigned short, 1);
if (ehanCheck(gr))
{
ELog("%s\n", resultError(gr));
exit(1);
}
dynarr(unsigned short) da = resultGeneric(dynarr(unsigned short), gr);
unsigned short x = 69; unsigned short x = 69;
daPush(da, x); daPush(da, x);
@ -45,7 +55,7 @@ int main(void)
printf("DA2\n"); printf("DA2\n");
printf("----------\n"); printf("----------\n");
dynarr(char) da2 = daCreate(char, 1); dynarr(char) da2 = daCreate(char, 1).val;
char y = 'H'; char y = 'H';
daPush(da2, y); daPush(da2, y);
@ -61,6 +71,8 @@ int main(void)
daPush(da2, y); daPush(da2, y);
y = '?'; y = '?';
daPush(da2, y); daPush(da2, y);
y = '?';
daPush(da2, y);
*(char *)daGetRef(da2, 6) = '!'; *(char *)daGetRef(da2, 6) = '!';
@ -69,8 +81,26 @@ int main(void)
heapstr message = daToCStr(da2); heapstr message = daToCStr(da2);
printf("%s\n", message); printf("%s\n", message);
free(message);
daFree(da); printf("----------\n");
printf("DA3\n");
printf("----------\n");
dynarr(char *) da3 = daCreate(char *, 1).val;
const char * someString = "Test";
for (size_t i = 0; i < 100000000; ++i) {
daPush(da3, someString);
}
char * str;
daPop(da3, str);
printf("%s\n", str);
daFree(da3);
free(message);
daFree(da2); daFree(da2);
daFree(da);
return 0;
} }