From 0e9de80eb900e9f8ca9bc1f69adf0ee1dac6d4cb Mon Sep 17 00:00:00 2001 From: alexevier Date: Sat, 2 Dec 2023 21:20:40 -0400 Subject: [PATCH 01/22] [add] "generic" vector struct --- include/lexlib/vector.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/lexlib/vector.h diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h new file mode 100644 index 0000000..6596e84 --- /dev/null +++ b/include/lexlib/vector.h @@ -0,0 +1,18 @@ +/* Copyright 2023 alexevier + licensed under the zlib license */ + +#ifndef lexlib_vector_h +#define lexlib_vector_h + +/* generic vector via macros :) */ + +#include + +#define LEXLIB_VECTOR(V, T)\ + struct V {\ + size_t len;\ + size_t cap;\ + T *data;\ + } + +#endif -- GitLab From 5c22e69523221f33faffebd14d8964c6a48ba64d Mon Sep 17 00:00:00 2001 From: alexevier Date: Sat, 2 Dec 2023 21:22:33 -0400 Subject: [PATCH 02/22] [add] generic vector function: new --- include/lexlib/vector.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h index 6596e84..61a9327 100644 --- a/include/lexlib/vector.h +++ b/include/lexlib/vector.h @@ -7,6 +7,7 @@ /* generic vector via macros :) */ #include +#include"common.h" #define LEXLIB_VECTOR(V, T)\ struct V {\ @@ -15,4 +16,28 @@ T *data;\ } +#define LEXLIB_VECTOR_DECL(FN, V, T)\ + LEXLIB_VECTOR_DECL_NEW(FN##New, V) + +#define LEXLIB_VECTOR_IMPL(FN, V, T)\ + LEXLIB_VECTOR_IMPL_NEW(FN##New, V) + +#define LEXLIB_VECTOR_DECL_NEW(FN, V)\ + /* create a new vector with capacity. */\ + /* in case of failure V.data will be NULL. */\ + LEXLIBFN V FN(size_t capacity); + +#define LEXLIB_VECTOR_IMPL_NEW(FN, V)\ + V FN(size_t capacity){\ + V vector = {0,capacity,NULL};\ + \ + if(capacity){\ + vector.data = malloc(capacity * sizeof(*vector.data));\ + if(!vector.data)\ + vector.cap = 0;\ + }\ + \ + return vector;\ + } + #endif -- GitLab From 26ef516357d507c30e3965bbe800b3e5b5e61d69 Mon Sep 17 00:00:00 2001 From: alexevier Date: Sat, 2 Dec 2023 21:24:14 -0400 Subject: [PATCH 03/22] [add] generic vector function: push --- include/lexlib/vector.h | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h index 61a9327..bd0e2ec 100644 --- a/include/lexlib/vector.h +++ b/include/lexlib/vector.h @@ -17,16 +17,24 @@ } #define LEXLIB_VECTOR_DECL(FN, V, T)\ - LEXLIB_VECTOR_DECL_NEW(FN##New, V) + LEXLIB_VECTOR_DECL_NEW(FN##New, V)\ + LEXLIB_VECTOR_DECL_PUSH(FN##Push, V, T) #define LEXLIB_VECTOR_IMPL(FN, V, T)\ - LEXLIB_VECTOR_IMPL_NEW(FN##New, V) + LEXLIB_VECTOR_IMPL_NEW(FN##New, V)\ + LEXLIB_VECTOR_IMPL_PUSH(FN##Push, V, T) #define LEXLIB_VECTOR_DECL_NEW(FN, V)\ /* create a new vector with capacity. */\ /* in case of failure V.data will be NULL. */\ LEXLIBFN V FN(size_t capacity); +#define LEXLIB_VECTOR_DECL_PUSH(FN, V, T)\ + /* push obj into vector. */ \ + /* returns 0 on success, nonzero otherwise. */\ + LEXLIBFN int FN(V *vector, T obj); + + #define LEXLIB_VECTOR_IMPL_NEW(FN, V)\ V FN(size_t capacity){\ V vector = {0,capacity,NULL};\ @@ -40,4 +48,30 @@ return vector;\ } +#define LEXLIB_VECTOR_IMPL_PUSH(FN, V, T)\ + int FN(V *vector, T obj){\ + if(!vector->data){\ + vector->data = malloc(sizeof(T));\ + if(!vector->data)\ + return 1;\ + vector->cap = 1;\ + }\ + \ + if(vector->len >= vector->cap){\ + vector->cap += 2;\ + \ + T *newmem = realloc(vector->data, vector->cap * sizeof(T));\ + if(!newmem){\ + vector->cap -= 2;\ + return 1;\ + }\ + vector->data = newmem;\ + }\ + \ + vector->data[vector->len] = obj;\ + vector->len++;\ + \ + return 0;\ + } + #endif -- GitLab From 9181c7992e46fe438a8391b9472725923fe42bcd Mon Sep 17 00:00:00 2001 From: alexevier Date: Sat, 2 Dec 2023 21:42:07 -0400 Subject: [PATCH 04/22] [add] generic vector function: free --- include/lexlib/vector.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h index bd0e2ec..c7fbb72 100644 --- a/include/lexlib/vector.h +++ b/include/lexlib/vector.h @@ -18,10 +18,12 @@ #define LEXLIB_VECTOR_DECL(FN, V, T)\ LEXLIB_VECTOR_DECL_NEW(FN##New, V)\ + LEXLIB_VECTOR_DECL_FREE(FN##Free, V)\ LEXLIB_VECTOR_DECL_PUSH(FN##Push, V, T) #define LEXLIB_VECTOR_IMPL(FN, V, T)\ LEXLIB_VECTOR_IMPL_NEW(FN##New, V)\ + LEXLIB_VECTOR_IMPL_FREE(FN##Free, V)\ LEXLIB_VECTOR_IMPL_PUSH(FN##Push, V, T) #define LEXLIB_VECTOR_DECL_NEW(FN, V)\ @@ -29,12 +31,15 @@ /* in case of failure V.data will be NULL. */\ LEXLIBFN V FN(size_t capacity); +#define LEXLIB_VECTOR_DECL_FREE(FN, V)\ + /* free a vector's memory. */\ + LEXLIBFN void FN(V *vector); + #define LEXLIB_VECTOR_DECL_PUSH(FN, V, T)\ /* push obj into vector. */ \ /* returns 0 on success, nonzero otherwise. */\ LEXLIBFN int FN(V *vector, T obj); - #define LEXLIB_VECTOR_IMPL_NEW(FN, V)\ V FN(size_t capacity){\ V vector = {0,capacity,NULL};\ @@ -48,6 +53,11 @@ return vector;\ } +#define LEXLIB_VECTOR_IMPL_FREE(FN, V)\ + void FN(V *vector){\ + free(vector->data);\ + } + #define LEXLIB_VECTOR_IMPL_PUSH(FN, V, T)\ int FN(V *vector, T obj){\ if(!vector->data){\ -- GitLab From dc0114189c1a213e9dcb024d8d80e10e38da4b0c Mon Sep 17 00:00:00 2001 From: alexevier Date: Sat, 2 Dec 2023 21:55:31 -0400 Subject: [PATCH 05/22] [add] generic vector function: pop --- include/lexlib/vector.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h index c7fbb72..1e4804a 100644 --- a/include/lexlib/vector.h +++ b/include/lexlib/vector.h @@ -19,12 +19,14 @@ #define LEXLIB_VECTOR_DECL(FN, V, T)\ LEXLIB_VECTOR_DECL_NEW(FN##New, V)\ LEXLIB_VECTOR_DECL_FREE(FN##Free, V)\ - LEXLIB_VECTOR_DECL_PUSH(FN##Push, V, T) + LEXLIB_VECTOR_DECL_PUSH(FN##Push, V, T)\ + LEXLIB_VECTOR_DECL_POP(FN##Pop, V) #define LEXLIB_VECTOR_IMPL(FN, V, T)\ LEXLIB_VECTOR_IMPL_NEW(FN##New, V)\ LEXLIB_VECTOR_IMPL_FREE(FN##Free, V)\ - LEXLIB_VECTOR_IMPL_PUSH(FN##Push, V, T) + LEXLIB_VECTOR_IMPL_PUSH(FN##Push, V, T)\ + LEXLIB_VECTOR_IMPL_POP(FN##Pop, V) #define LEXLIB_VECTOR_DECL_NEW(FN, V)\ /* create a new vector with capacity. */\ @@ -40,6 +42,10 @@ /* returns 0 on success, nonzero otherwise. */\ LEXLIBFN int FN(V *vector, T obj); +#define LEXLIB_VECTOR_DECL_POP(FN, V)\ + /* pop the last element of the vector. */\ + LEXLIBFN void FN(V *vector); + #define LEXLIB_VECTOR_IMPL_NEW(FN, V)\ V FN(size_t capacity){\ V vector = {0,capacity,NULL};\ @@ -84,4 +90,10 @@ return 0;\ } +#define LEXLIB_VECTOR_IMPL_POP(FN, V)\ + void FN(V *vector){\ + if(vector->len != 0)\ + vector->len--;\ + } + #endif -- GitLab From 47dfb1fca2ba4c59d8e6c558332f0a158a588ee7 Mon Sep 17 00:00:00 2001 From: alexevier Date: Mon, 4 Dec 2023 02:37:54 -0400 Subject: [PATCH 06/22] [add] lexlibFsCreateDir() --- CMakeLists.txt | 4 ++++ include/lexlib/filesystem.h | 18 ++++++++++++++++++ src/unix/filesystem.c | 25 +++++++++++++++++++++++++ src/windows/filesystem.c | 20 ++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 include/lexlib/filesystem.h create mode 100644 src/unix/filesystem.c create mode 100644 src/windows/filesystem.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 48b7adb..69b13b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,11 +56,13 @@ target_sources(${PROJECT_NAME} PRIVATE if(UNIX) target_sources(${PROJECT_NAME} PRIVATE + src/unix/filesystem.c src/unix/mem.c src/unix/os.c ) elseif(WIN32) target_sources(${PROJECT_NAME} PRIVATE + src/windows/filesystem.c src/windows/mem.c src/windows/os.c ) @@ -85,6 +87,7 @@ target_sources(${PROJECT_NAME} PUBLIC FILE_SET HEADERS include/lexlib/color.h include/lexlib/common.h include/lexlib/defines.h + include/lexlib/filesystem.h include/lexlib/image.h include/lexlib/io.h include/lexlib/lexlib.h @@ -107,6 +110,7 @@ target_sources(${PROJECT_NAME} PUBLIC FILE_SET HEADERS include/lexlib/time.h include/lexlib/typedef.h include/lexlib/vec.h + include/lexlib/vector.h ) if(tests) diff --git a/include/lexlib/filesystem.h b/include/lexlib/filesystem.h new file mode 100644 index 0000000..715fd61 --- /dev/null +++ b/include/lexlib/filesystem.h @@ -0,0 +1,18 @@ +/* Copyright 2023 alexevier + licensed under the zlib license */ + +#ifndef lexlib_filesystem_h +#define lexlib_filesystem_h + +#include"common.h" +#include + +/* create a directory. + returns: + - LEXLIB_OK (0): directory succesfully created. + - LEXLIB_EXIST: directory already exists. + - LEXLIB_INVALID_PATH: a directory in the middle is mising or is not a directory. + - LEXLIB_INVALID_OPERATION: the creation was not permited by the os. */ +LEXLIBFN uint8_t lexlibFsCreateDir(const char *path); + +#endif diff --git a/src/unix/filesystem.c b/src/unix/filesystem.c new file mode 100644 index 0000000..80629fd --- /dev/null +++ b/src/unix/filesystem.c @@ -0,0 +1,25 @@ +/* Copyright 2023 alexevier + licensed under the zlib license */ + +#include +#include +#include + +uint8_t lexlibFsCreateDir(const char *path){ + if(mkdir(path, 0777) == -1){ + switch(errno){ + case EEXIST: + return LEXLIB_EXIST; + case ENOENT: + case ENOTDIR: + return LEXLIB_INVALID_PATH; + case EPERM: + return LEXLIB_INVALID_OPERATION; + default: + return LEXLIB_ERROR; + } + return LEXLIB_ERROR; + } + + return LEXLIB_OK; +} diff --git a/src/windows/filesystem.c b/src/windows/filesystem.c new file mode 100644 index 0000000..65d0e9d --- /dev/null +++ b/src/windows/filesystem.c @@ -0,0 +1,20 @@ +/* Copyright 2023 alexevier + licensed under the zlib license */ + +#include +#include + +uint8_t lexlibFsCreateDir(const char *path){ + if(CreateDirectory(path, NULL) == 0){ + switch(GetLastError()){ + case ERROR_ALREADY_EXISTS: + return LEXLIB_EXIST; + case ERROR_PATH_NOT_FOUND: + return LEXLIB_INVALID_PATH; + default: + return LEXLIB_ERROR; + } + } + + return LEXLIB_OK; +} -- GitLab From 23eb42fcb068c840540f9e3a4b7982e3160f4fa4 Mon Sep 17 00:00:00 2001 From: alexevier Date: Mon, 4 Dec 2023 03:29:42 -0400 Subject: [PATCH 07/22] [add] lexlibFsAbsolute() --- include/lexlib/filesystem.h | 5 +++++ src/unix/filesystem.c | 8 ++++++++ src/windows/filesystem.c | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/include/lexlib/filesystem.h b/include/lexlib/filesystem.h index 715fd61..cb0079c 100644 --- a/include/lexlib/filesystem.h +++ b/include/lexlib/filesystem.h @@ -15,4 +15,9 @@ - LEXLIB_INVALID_OPERATION: the creation was not permited by the os. */ LEXLIBFN uint8_t lexlibFsCreateDir(const char *path); +/* get the absolute path. + the returned pointer needs to be deallocated using free(). + returns NULL on error. */ +LEXLIBFN char *lexlibFsAbsolute(const char *path); + #endif diff --git a/src/unix/filesystem.c b/src/unix/filesystem.c index 80629fd..5dc7c67 100644 --- a/src/unix/filesystem.c +++ b/src/unix/filesystem.c @@ -1,8 +1,12 @@ /* Copyright 2023 alexevier licensed under the zlib license */ +#define _POSIX_C_SOURCE 199309L +#define _GNU_SOURCE + #include #include +#include #include uint8_t lexlibFsCreateDir(const char *path){ @@ -23,3 +27,7 @@ uint8_t lexlibFsCreateDir(const char *path){ return LEXLIB_OK; } + +char *lexlibFsAbsolute(const char *path){ + return realpath(path, NULL); +} diff --git a/src/windows/filesystem.c b/src/windows/filesystem.c index 65d0e9d..b7054ae 100644 --- a/src/windows/filesystem.c +++ b/src/windows/filesystem.c @@ -3,6 +3,7 @@ #include #include +#include uint8_t lexlibFsCreateDir(const char *path){ if(CreateDirectory(path, NULL) == 0){ @@ -18,3 +19,21 @@ uint8_t lexlibFsCreateDir(const char *path){ return LEXLIB_OK; } + +char *lexlibFsAbsolute(const char *path){ + DWORD len = GetFullPathName(path, 0, NULL, NULL); + if(len == 0) + return NULL; + + char *fullpath = malloc(len); + if(!fullpath) + return NULL; + + DWORD lenr = GetFullPathName(path, len, fullpath, NULL); + if((len-1) != lenr){ + free(fullpath); + return NULL; + } + + return fullpath; +} -- GitLab From d841665246fba81d554ba0594b8deb8d38099340 Mon Sep 17 00:00:00 2001 From: alexevier Date: Tue, 5 Dec 2023 23:47:08 -0400 Subject: [PATCH 08/22] [experimental] FsList --- include/lexlib/defines.h | 2 ++ include/lexlib/filesystem.h | 16 +++++++++++ src/unix/filesystem.c | 56 +++++++++++++++++++++++++++++++++++++ src/windows/filesystem.c | 48 +++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/include/lexlib/defines.h b/include/lexlib/defines.h index 5972b87..a21ae9f 100644 --- a/include/lexlib/defines.h +++ b/include/lexlib/defines.h @@ -14,6 +14,8 @@ typedef unsigned char LexlibBool; // errors : limited to uint8_t range. #define LEXLIB_OK 0x00 +#define LEXLIB_FILE 0xA0 +#define LEXLIB_DIRECTORY 0xA1 #define LEXLIB_INVALID_VALUE 0xB0 #define LEXLIB_INVALID_OPERATION 0xB1 #define LEXLIB_INVALID_REQUEST 0xB2 diff --git a/include/lexlib/filesystem.h b/include/lexlib/filesystem.h index cb0079c..2cc8d7a 100644 --- a/include/lexlib/filesystem.h +++ b/include/lexlib/filesystem.h @@ -5,8 +5,18 @@ #define lexlib_filesystem_h #include"common.h" +#include #include +/* experimental */ +struct LexlibFsList { + size_t count; + struct LexlibFsListElement_ { + char *name; + uint8_t type; + } *element; +}; + /* create a directory. returns: - LEXLIB_OK (0): directory succesfully created. @@ -20,4 +30,10 @@ LEXLIBFN uint8_t lexlibFsCreateDir(const char *path); returns NULL on error. */ LEXLIBFN char *lexlibFsAbsolute(const char *path); +LEXLIB_EXPERIMENTAL +LEXLIBFN uint8_t lexlibFsList(struct LexlibFsList *list, const char *path); + +LEXLIB_EXPERIMENTAL +LEXLIBFN void lexlibFsListFree(struct LexlibFsList *list); + #endif diff --git a/src/unix/filesystem.c b/src/unix/filesystem.c index 5dc7c67..738cc38 100644 --- a/src/unix/filesystem.c +++ b/src/unix/filesystem.c @@ -5,7 +5,9 @@ #define _GNU_SOURCE #include +#include #include +#include #include #include @@ -31,3 +33,57 @@ uint8_t lexlibFsCreateDir(const char *path){ char *lexlibFsAbsolute(const char *path){ return realpath(path, NULL); } + +uint8_t lexlibFsList(struct LexlibFsList *list, const char *path){ + list->count = 0; + + DIR *dir = opendir(path); + if(!dir) + return LEXLIB_INVALID_PATH; + + for(;;){ + struct dirent* dire = readdir(dir); + if(!dire) + break; + + if(lexlibStrCompare(dire->d_name, ".")) + continue; + if(lexlibStrCompare(dire->d_name, "..")) + continue; + + if(!list->element){ + list->element = malloc(sizeof(*list->element)); + } else { + struct LexlibFsListElement_ *newlist = realloc(list->element, (list->count+1) * sizeof(*list->element)); + if(!newlist){ + closedir(dir); + return LEXLIB_OUT_OF_MEMORY; + } + list->element = newlist; + } + + switch(dire->d_type){ + case DT_REG: + list->element[list->count].type = LEXLIB_FILE; + break; + case DT_DIR: + list->element[list->count].type = LEXLIB_DIRECTORY; + break; + default: + list->element[list->count].type = LEXLIB_NONE; + break; + } + + list->element[list->count].name = lexlibStrCopy(dire->d_name); + list->count++; + } + + closedir(dir); + return LEXLIB_OK; +} + +void lexlibFsListFree(struct LexlibFsList *list){ + for(size_t i = 0; i < list->count; i++) + free(list->element[i].name); + free(list->element); +} diff --git a/src/windows/filesystem.c b/src/windows/filesystem.c index b7054ae..88b83ff 100644 --- a/src/windows/filesystem.c +++ b/src/windows/filesystem.c @@ -2,6 +2,8 @@ licensed under the zlib license */ #include +#include +#include #include #include @@ -37,3 +39,49 @@ char *lexlibFsAbsolute(const char *path){ return fullpath; } + +uint8_t lexlibFsList(struct LexlibFsList *list, const char *path){ + list->count = 0; + WIN32_FIND_DATA data; + char *pathn = lexlibStrCopy(path); + if(!pathn) + return LEXLIB_OUT_OF_MEMORY; + uint8_t err; + if((err = lexlibPathAdd(&pathn, "/*")) != LEXLIB_OK){ + free(pathn); + return err; + }; + HANDLE search = FindFirstFile(pathn, &data); + + do{ + if(lexlibStrCompare(data.cFileName, ".")) + continue; + if(lexlibStrCompare(data.cFileName, "..")) + continue; + + if(!list->element){ + list->element = malloc(sizeof(*list->element)); + } else { + struct LexlibFsListElement_ *newlist = realloc(list->element, (list->count+1) * sizeof(*list->element)); + if(!newlist){ + free(pathn); + FindClose(search); + return LEXLIB_OUT_OF_MEMORY; + } + list->element = newlist; + } + + list->element[list->count].name = lexlibStrCopy(data.cFileName); + list->count++; + } while(FindNextFile(search, &data) != 0); + + free(pathn); + FindClose(search); + return LEXLIB_OK; +} + +void lexlibFsListFree(struct LexlibFsList *list){ + for(size_t i = 0; i < list->count; i++) + free(list->element[i].name); + free(list->element); +} -- GitLab From 1292c0aa6571453df43e1d7caec3dffd1f8ad574 Mon Sep 17 00:00:00 2001 From: alexevier Date: Wed, 6 Dec 2023 00:25:41 -0400 Subject: [PATCH 09/22] fuse unix/windows filesystem into one tu --- CMakeLists.txt | 3 +- src/filesystem.c | 164 +++++++++++++++++++++++++++++++++++++++ src/unix/filesystem.c | 89 --------------------- src/windows/filesystem.c | 87 --------------------- 4 files changed, 165 insertions(+), 178 deletions(-) create mode 100644 src/filesystem.c delete mode 100644 src/unix/filesystem.c delete mode 100644 src/windows/filesystem.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 69b13b9..8912f21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ target_sources(${PROJECT_NAME} PRIVATE src/color/colorf.c src/color/color16.c src/file.c + src/filesystem.c src/image.c src/image/bin.c src/image/bmp.c @@ -56,13 +57,11 @@ target_sources(${PROJECT_NAME} PRIVATE if(UNIX) target_sources(${PROJECT_NAME} PRIVATE - src/unix/filesystem.c src/unix/mem.c src/unix/os.c ) elseif(WIN32) target_sources(${PROJECT_NAME} PRIVATE - src/windows/filesystem.c src/windows/mem.c src/windows/os.c ) diff --git a/src/filesystem.c b/src/filesystem.c new file mode 100644 index 0000000..c0ee37d --- /dev/null +++ b/src/filesystem.c @@ -0,0 +1,164 @@ +/* Copyright 2023 alexevier + licensed under the zlib license */ + +#ifdef __unix__ +# define _POSIX_C_SOURCE 199309L +# define _GNU_SOURCE +#endif + +#include +#include +#include +#ifdef __unix__ +# include +# include +# include +#elif defined(_WIN32) +# include +# include +#endif + +uint8_t lexlibFsCreateDir(const char *path){ +#if defined(__unix__) + if(mkdir(path, 0777) == -1){ + switch(errno){ + case EEXIST: + return LEXLIB_EXIST; + case ENOENT: + case ENOTDIR: + return LEXLIB_INVALID_PATH; + case EPERM: + return LEXLIB_INVALID_OPERATION; + default: + return LEXLIB_ERROR; + } + } +#elif defined(_WIN32) + if(CreateDirectory(path, NULL) == 0){ + switch(GetLastError()){ + case ERROR_ALREADY_EXISTS: + return LEXLIB_EXIST; + case ERROR_PATH_NOT_FOUND: + return LEXLIB_INVALID_PATH; + default: + return LEXLIB_ERROR; + } + } +#endif + return LEXLIB_OK; +} + +char *lexlibFsAbsolute(const char *path){ +#if defined(__unix__) + return realpath(path, NULL); +#elif defined(_WIN32) + DWORD len = GetFullPathName(path, 0, NULL, NULL); + if(len == 0) + return NULL; + + char *fullpath = malloc(len); + if(!fullpath) + return NULL; + + DWORD lenr = GetFullPathName(path, len, fullpath, NULL); + if((len-1) != lenr){ + free(fullpath); + return NULL; + } + + return fullpath; +#endif +} + + +uint8_t lexlibFsList(struct LexlibFsList *list, const char *path){ + list->count = 0; + uint8_t error = LEXLIB_OK; + +#if defined(__unix__) + DIR *dir = opendir(path); + if(!dir) + return LEXLIB_INVALID_PATH; +#elif defined(_WIN32) + WIN32_FIND_DATA fdata; + char *pathn = lexlibStrCopy(path); + if(!pathn) + return LEXLIB_OUT_OF_MEMORY; + if((error = lexlibPathAdd(&pathn, "/*")) != LEXLIB_OK){ + free(pathn); + return error; + }; + HANDLE search = FindFirstFile(pathn, &fdata); // TODO check error + free(pathn); +#endif + +#if defined(__unix__) + for(;;){ +#elif defined(_WIN32) + do{ +#endif + #if defined(__unix__) + struct dirent* dire = readdir(dir); + if(!dire) + break; + #endif + + const char *name = + #if defined(__unix__) + dire->d_name; + #elif defined(_WIN32) + fdata.cFileName; + #endif + + if(lexlibStrCompare(name, ".")) + continue; + if(lexlibStrCompare(name, "..")) + continue; + + if(!list->element){ + list->element = malloc(sizeof(*list->element)); + } else { + struct LexlibFsListElement_ *newlist = realloc(list->element, (list->count+1) * sizeof(*list->element)); + if(!newlist){ + error = LEXLIB_OUT_OF_MEMORY; + goto end; + } + list->element = newlist; + } + + #if defined(__unix__) + switch(dire->d_type){ + case DT_REG: + list->element[list->count].type = LEXLIB_FILE; + break; + case DT_DIR: + list->element[list->count].type = LEXLIB_DIRECTORY; + break; + default: + list->element[list->count].type = LEXLIB_NONE; + break; + } + #endif + + list->element[list->count].name = lexlibStrCopy(name); + list->count++; + } + #if defined(_WIN32) + while(FindNextFile(search, &fdata) != 0); + // TODO check error + #endif + + end: +#if defined(__unix__) + closedir(dir); +#elif defined(_WIN32) + FindClose(search); +#endif + return error; +} + +void lexlibFsListFree(struct LexlibFsList *list){ + for(size_t i = 0; i < list->count; i++) + free(list->element[i].name); + free(list->element); +} diff --git a/src/unix/filesystem.c b/src/unix/filesystem.c deleted file mode 100644 index 738cc38..0000000 --- a/src/unix/filesystem.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright 2023 alexevier - licensed under the zlib license */ - -#define _POSIX_C_SOURCE 199309L -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include - -uint8_t lexlibFsCreateDir(const char *path){ - if(mkdir(path, 0777) == -1){ - switch(errno){ - case EEXIST: - return LEXLIB_EXIST; - case ENOENT: - case ENOTDIR: - return LEXLIB_INVALID_PATH; - case EPERM: - return LEXLIB_INVALID_OPERATION; - default: - return LEXLIB_ERROR; - } - return LEXLIB_ERROR; - } - - return LEXLIB_OK; -} - -char *lexlibFsAbsolute(const char *path){ - return realpath(path, NULL); -} - -uint8_t lexlibFsList(struct LexlibFsList *list, const char *path){ - list->count = 0; - - DIR *dir = opendir(path); - if(!dir) - return LEXLIB_INVALID_PATH; - - for(;;){ - struct dirent* dire = readdir(dir); - if(!dire) - break; - - if(lexlibStrCompare(dire->d_name, ".")) - continue; - if(lexlibStrCompare(dire->d_name, "..")) - continue; - - if(!list->element){ - list->element = malloc(sizeof(*list->element)); - } else { - struct LexlibFsListElement_ *newlist = realloc(list->element, (list->count+1) * sizeof(*list->element)); - if(!newlist){ - closedir(dir); - return LEXLIB_OUT_OF_MEMORY; - } - list->element = newlist; - } - - switch(dire->d_type){ - case DT_REG: - list->element[list->count].type = LEXLIB_FILE; - break; - case DT_DIR: - list->element[list->count].type = LEXLIB_DIRECTORY; - break; - default: - list->element[list->count].type = LEXLIB_NONE; - break; - } - - list->element[list->count].name = lexlibStrCopy(dire->d_name); - list->count++; - } - - closedir(dir); - return LEXLIB_OK; -} - -void lexlibFsListFree(struct LexlibFsList *list){ - for(size_t i = 0; i < list->count; i++) - free(list->element[i].name); - free(list->element); -} diff --git a/src/windows/filesystem.c b/src/windows/filesystem.c deleted file mode 100644 index 88b83ff..0000000 --- a/src/windows/filesystem.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright 2023 alexevier - licensed under the zlib license */ - -#include -#include -#include -#include -#include - -uint8_t lexlibFsCreateDir(const char *path){ - if(CreateDirectory(path, NULL) == 0){ - switch(GetLastError()){ - case ERROR_ALREADY_EXISTS: - return LEXLIB_EXIST; - case ERROR_PATH_NOT_FOUND: - return LEXLIB_INVALID_PATH; - default: - return LEXLIB_ERROR; - } - } - - return LEXLIB_OK; -} - -char *lexlibFsAbsolute(const char *path){ - DWORD len = GetFullPathName(path, 0, NULL, NULL); - if(len == 0) - return NULL; - - char *fullpath = malloc(len); - if(!fullpath) - return NULL; - - DWORD lenr = GetFullPathName(path, len, fullpath, NULL); - if((len-1) != lenr){ - free(fullpath); - return NULL; - } - - return fullpath; -} - -uint8_t lexlibFsList(struct LexlibFsList *list, const char *path){ - list->count = 0; - WIN32_FIND_DATA data; - char *pathn = lexlibStrCopy(path); - if(!pathn) - return LEXLIB_OUT_OF_MEMORY; - uint8_t err; - if((err = lexlibPathAdd(&pathn, "/*")) != LEXLIB_OK){ - free(pathn); - return err; - }; - HANDLE search = FindFirstFile(pathn, &data); - - do{ - if(lexlibStrCompare(data.cFileName, ".")) - continue; - if(lexlibStrCompare(data.cFileName, "..")) - continue; - - if(!list->element){ - list->element = malloc(sizeof(*list->element)); - } else { - struct LexlibFsListElement_ *newlist = realloc(list->element, (list->count+1) * sizeof(*list->element)); - if(!newlist){ - free(pathn); - FindClose(search); - return LEXLIB_OUT_OF_MEMORY; - } - list->element = newlist; - } - - list->element[list->count].name = lexlibStrCopy(data.cFileName); - list->count++; - } while(FindNextFile(search, &data) != 0); - - free(pathn); - FindClose(search); - return LEXLIB_OK; -} - -void lexlibFsListFree(struct LexlibFsList *list){ - for(size_t i = 0; i < list->count; i++) - free(list->element[i].name); - free(list->element); -} -- GitLab From 26f0f5a45f91206ff0b7b73cdc51ee5cbb2b246f Mon Sep 17 00:00:00 2001 From: alexevier Date: Fri, 15 Dec 2023 19:41:28 -0400 Subject: [PATCH 10/22] update build.rs --- build.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build.rs b/build.rs index b4ca1c9..14027d3 100644 --- a/build.rs +++ b/build.rs @@ -17,21 +17,29 @@ fn main(){ #[cfg(feature = "libpng")] lexlibc.define("LIBPNG", None); - lexlibc.define("RUST_ALLOC", None); + lexlibc.define("BUFFERSIZE", Some("256")); + lexlibc.define("VEC_RESIZE", Some("2")); lexlibc .include("include") .file("src/cfile.c") + .file("src/char.c") .file("src/color/color8.c") .file("src/color/colorf.c") .file("src/color/color16.c") .file("src/file.c") + .file("src/filesystem.c") .file("src/image.c") + .file("src/image/bin.c") .file("src/image/bmp.c") .file("src/image/png.c") .file("src/image/stbi.c") .file("src/image/stbiw.c") + .file("src/io.c") + .file("src/mem.c") + .file("src/path.c") .file("src/str.c") + .file("src/string.c") .file("src/time.c") .file("src/vec.c"); -- GitLab From e0b72a805040013e417bdaf84066f39dbbe7c5f9 Mon Sep 17 00:00:00 2001 From: alexevier Date: Wed, 28 Feb 2024 17:40:07 -0400 Subject: [PATCH 11/22] set errno back to its original value --- src/filesystem.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/filesystem.c b/src/filesystem.c index c0ee37d..2b733f8 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -1,5 +1,5 @@ -/* Copyright 2023 alexevier - licensed under the zlib license */ +/* Copyright 2023-2024 alexevier +licensed under the zlib license */ #ifdef __unix__ # define _POSIX_C_SOURCE 199309L @@ -8,7 +8,9 @@ #include #include + #include + #ifdef __unix__ # include # include @@ -19,9 +21,13 @@ #endif uint8_t lexlibFsCreateDir(const char *path){ + int errnoOg = errno; + #if defined(__unix__) if(mkdir(path, 0777) == -1){ - switch(errno){ + int errnoC = errno; + errno = errnoOg; + switch(errnoC){ case EEXIST: return LEXLIB_EXIST; case ENOENT: @@ -45,6 +51,8 @@ uint8_t lexlibFsCreateDir(const char *path){ } } #endif + + errno = errnoOg; return LEXLIB_OK; } -- GitLab From eb59d526119985ca91b8e46833868bbc85314a06 Mon Sep 17 00:00:00 2001 From: alexevier Date: Wed, 28 Feb 2024 17:41:48 -0400 Subject: [PATCH 12/22] update copyright notice --- LICENSE | 6 +++--- include/lexlib/lexlib.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index bf1ddcd..0b230e2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2023 alexevier +Copyright (C) 2023-2024 alexevier This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,5 +19,5 @@ freely, subject to the following restrictions: > Short notice -Copyright 2023 alexevier -licensed under the zlib license \ No newline at end of file +Copyright 2023-xxxx alexevier +licensed under the zlib license diff --git a/include/lexlib/lexlib.h b/include/lexlib/lexlib.h index 315bd12..8fb59ec 100644 --- a/include/lexlib/lexlib.h +++ b/include/lexlib/lexlib.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2023 alexevier +Copyright (C) 2023-2024 alexevier This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -16,7 +16,6 @@ freely, subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. - */ #ifndef lexlib_h -- GitLab From 2532790ef4a382513f955f2e2d5ab243cde0d2d6 Mon Sep 17 00:00:00 2001 From: alexevier Date: Thu, 21 Mar 2024 17:22:24 -0400 Subject: [PATCH 13/22] [experimental] lexlibRectIntersect() --- include/lexlib/math/rect.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/lexlib/math/rect.h b/include/lexlib/math/rect.h index ee91856..6d7621d 100644 --- a/include/lexlib/math/rect.h +++ b/include/lexlib/math/rect.h @@ -31,4 +31,15 @@ LEXLIB_INLINE void lexlibRectDivides(struct LexlibRect *result, const struct Lex result->h = rect->h / scalar; } +/* check if 2 rects intersect. */ +LEXLIB_EXPERIMENTAL +LEXLIB_INLINE LexlibBool lexlibRectIntersect(const struct LexlibRect *a, const struct LexlibRect *b){ + if(a->x < (b->x+b->w)) + if((a->x + a->w) > b->x) + if(a->y < (b->y+b->h)) + if((a->y + a->h) > b->y) + return LEXLIB_TRUE; + return LEXLIB_FALSE; +} + #endif -- GitLab From 3cd448e11927809a0a52921313d5b878e78a562c Mon Sep 17 00:00:00 2001 From: alexevier Date: Thu, 21 Mar 2024 17:22:58 -0400 Subject: [PATCH 14/22] missing filesystem.h include in lexlib.h --- include/lexlib/lexlib.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/lexlib/lexlib.h b/include/lexlib/lexlib.h index 8fb59ec..c0cb6cd 100644 --- a/include/lexlib/lexlib.h +++ b/include/lexlib/lexlib.h @@ -44,6 +44,7 @@ Linux and windows are officially supported. #include"color.h" #include"common.h" #include"defines.h" +#include"filesystem.h" #include"image.h" #include"io.h" /*#include"lexlib.h"*/ -- GitLab From 2c02affd7a9f70a119953aee953fee3a2cf8a31b Mon Sep 17 00:00:00 2001 From: alexevier Date: Sun, 24 Mar 2024 04:33:02 -0400 Subject: [PATCH 15/22] lexlibFsSize() --- CHANGELOG.md | 3 +++ include/lexlib/filesystem.h | 4 ++++ src/filesystem.c | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 602a67c..c8dc41c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.3.0 ++ lexlibFsSize(). + ## 2.2.0 : the IO & UTF8 update + added io.h. + added char.h. diff --git a/include/lexlib/filesystem.h b/include/lexlib/filesystem.h index 2cc8d7a..41a19f1 100644 --- a/include/lexlib/filesystem.h +++ b/include/lexlib/filesystem.h @@ -30,6 +30,10 @@ LEXLIBFN uint8_t lexlibFsCreateDir(const char *path); returns NULL on error. */ LEXLIBFN char *lexlibFsAbsolute(const char *path); +/* get the size in bytes of a file. + return -1 on error. */ +LEXLIBFN int64_t lexlibFsSize(const char *path); + LEXLIB_EXPERIMENTAL LEXLIBFN uint8_t lexlibFsList(struct LexlibFsList *list, const char *path); diff --git a/src/filesystem.c b/src/filesystem.c index 2b733f8..7675e72 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -78,6 +78,27 @@ char *lexlibFsAbsolute(const char *path){ #endif } +int64_t lexlibFsSize(const char *path){ +#if defined(__unix__) + struct stat info; + int state = stat(path, &info); + if(state != 0) + return -1; + + return (int64_t)info.st_size; +#elif defined(__WIN32) + HANDLE handle = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(handle == INVALID_HANDLE_VALUE) + return -1; + + LARGE_INTEGER size; + DWORD state = GetFileSizeEx(handle, &size); + if(state == 0) + return -1; + + return (int64_t)size.QuadPart; +#endif +} uint8_t lexlibFsList(struct LexlibFsList *list, const char *path){ list->count = 0; -- GitLab From 7fcd0ddfce08a01184587e148e79ff733115836e Mon Sep 17 00:00:00 2001 From: alexevier Date: Mon, 25 Mar 2024 02:34:01 -0400 Subject: [PATCH 16/22] lexlibVec2Rotate() --- CHANGELOG.md | 1 + include/lexlib/math/vec2.h | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8dc41c..6a6426d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 2.3.0 + lexlibFsSize(). ++ lexlibVec2Rotate(). ## 2.2.0 : the IO & UTF8 update + added io.h. diff --git a/include/lexlib/math/vec2.h b/include/lexlib/math/vec2.h index 5523e05..c698a19 100644 --- a/include/lexlib/math/vec2.h +++ b/include/lexlib/math/vec2.h @@ -82,4 +82,11 @@ LEXLIB_INLINE void lexlibVec2Neg(struct LexlibVec2 *result, const struct LexlibV result->y = -vec->y; } +LEXLIB_INLINE void lexlibVec2Rotate(struct LexlibVec2 *result, const struct LexlibVec2 *vec, float radians){ + const float x = vec->x; + const float y = vec->y; + result->x = x * cos(radians) - y * sin(radians); + result->y = x * sin(radians) + y * cos(radians); +} + #endif -- GitLab From 8d6d5d5dabf742e5afbe49a8a8e41af74e60797e Mon Sep 17 00:00:00 2001 From: alexevier Date: Wed, 27 Mar 2024 23:56:48 -0400 Subject: [PATCH 17/22] [add] generic vector function: pushPtr --- CHANGELOG.md | 7 +++++++ include/lexlib/vector.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a6426d..4a4d185 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ## 2.3.0 + lexlibFsSize(). + lexlibVec2Rotate(). ++ generic vector macro ++ generic vector: new(). ++ generic vector: push(). ++ generic vector: free(). ++ generic vector: pop(). ++ generic vector: pushPtr(). + ## 2.2.0 : the IO & UTF8 update + added io.h. diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h index 1e4804a..e3b43e7 100644 --- a/include/lexlib/vector.h +++ b/include/lexlib/vector.h @@ -20,12 +20,14 @@ LEXLIB_VECTOR_DECL_NEW(FN##New, V)\ LEXLIB_VECTOR_DECL_FREE(FN##Free, V)\ LEXLIB_VECTOR_DECL_PUSH(FN##Push, V, T)\ + LEXLIB_VECTOR_DECL_PUSH_PTR(FN##PushPtr, V, T)\ LEXLIB_VECTOR_DECL_POP(FN##Pop, V) #define LEXLIB_VECTOR_IMPL(FN, V, T)\ LEXLIB_VECTOR_IMPL_NEW(FN##New, V)\ LEXLIB_VECTOR_IMPL_FREE(FN##Free, V)\ LEXLIB_VECTOR_IMPL_PUSH(FN##Push, V, T)\ + LEXLIB_VECTOR_IMPL_PUSH_PTR(FN##PushPtr, V, T)\ LEXLIB_VECTOR_IMPL_POP(FN##Pop, V) #define LEXLIB_VECTOR_DECL_NEW(FN, V)\ @@ -42,6 +44,12 @@ /* returns 0 on success, nonzero otherwise. */\ LEXLIBFN int FN(V *vector, T obj); +#define LEXLIB_VECTOR_DECL_PUSH_PTR(FN, V, T)\ + /* push obj into vector. + takes a pointer to the object but it will get copied. + returns 0 on success, nonzero otherwise. */\ + LEXLIBFN int FN(V *vector, T *obj); + #define LEXLIB_VECTOR_DECL_POP(FN, V)\ /* pop the last element of the vector. */\ LEXLIBFN void FN(V *vector); @@ -90,10 +98,38 @@ return 0;\ } +#define LEXLIB_VECTOR_IMPL_PUSH_PTR(FN, V, T)\ + int FN(V *vector, T *obj){\ + if(!vector->data){\ + vector->data = malloc(sizeof(T));\ + if(!vector->data)\ + return 1;\ + vector->cap = 1;\ + }\ + \ + if(vector->len >= vector->cap){\ + vector->cap += 2;\ + \ + T *newmem = realloc(vector->data, vector->cap * sizeof(T));\ + if(!newmem){\ + vector->cap -= 2;\ + return 1;\ + }\ + vector->data = newmem;\ + }\ + \ + vector->data[vector->len] = *obj;\ + vector->len++;\ + \ + return 0;\ + } + #define LEXLIB_VECTOR_IMPL_POP(FN, V)\ void FN(V *vector){\ if(vector->len != 0)\ vector->len--;\ } + + #endif -- GitLab From 3a1ea97cdd1baae3de36aa85cf11a72d40a24f7d Mon Sep 17 00:00:00 2001 From: alexevier Date: Thu, 28 Mar 2024 19:43:57 -0400 Subject: [PATCH 18/22] add vector.h to the includes --- include/lexlib/lexlib.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/lexlib/lexlib.h b/include/lexlib/lexlib.h index c0cb6cd..4ca645e 100644 --- a/include/lexlib/lexlib.h +++ b/include/lexlib/lexlib.h @@ -58,6 +58,7 @@ Linux and windows are officially supported. #include"string.h" #include"time.h" #include"vec.h" +#include"vector.h" /* get the lexlib version in format: X.X.X */ LEXLIBFN const char *lexlibVersion(void); -- GitLab From 2a0ae8be1721645f422189395b1ed8e6b9542cd4 Mon Sep 17 00:00:00 2001 From: alexevier Date: Fri, 19 Apr 2024 00:59:39 -0400 Subject: [PATCH 19/22] [add] lexlibStrAppend() --- CHANGELOG.md | 1 + include/lexlib/str.h | 5 +++++ src/str.c | 15 +++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a4d185..f8cdcdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.3.0 + lexlibFsSize(). + lexlibVec2Rotate(). ++ lexlibStrAppend(). + generic vector macro + generic vector: new(). + generic vector: push(). diff --git a/include/lexlib/str.h b/include/lexlib/str.h index 9e860ea..f2d557d 100644 --- a/include/lexlib/str.h +++ b/include/lexlib/str.h @@ -17,6 +17,11 @@ LEXLIBFN char *lexlibStrNew(const char *str); // on error returns NULL (failed to allocate memory). LEXLIBFN char *lexlibStrCat(const char *str1, const char *str2); +/* append a string to another. + str gets reallocated and the returned pointer is the string. + on error NULL is returned and str is unmodified. */ +char *lexlibStrAppend(char *str, const char *str2); + /* compare 2 strings. returns: true (1): strings are equal. diff --git a/src/str.c b/src/str.c index 1a36cfb..36ef636 100644 --- a/src/str.c +++ b/src/str.c @@ -9,6 +9,7 @@ #endif #include + #include #include #include @@ -47,6 +48,20 @@ char *lexlibStrCat(const char *str1, const char *str2){ return str; } +char *lexlibStrAppend(char *str1, const char *str2){ + size_t size1 = lexlibStrSize(str1)-1; /* the -1 removes the null char */ + size_t size2 = lexlibStrSize(str2); + size_t size = size1 + size2; + + char *str = realloc(str1, size); + if(!str) + return NULL; + + memcpy(str+size1, str2, size2); + + return str; +} + LexlibBool lexlibStrCompare(const char *LEXLIB_RESTRICT str1, const char *LEXLIB_RESTRICT str2){ // TODO make check locally int len1 = lexlibStrLen(str1); -- GitLab From b2880edf7f92ecbcfd0c64f357638e7f19860ce5 Mon Sep 17 00:00:00 2001 From: alexevier Date: Mon, 22 Apr 2024 04:11:15 -0400 Subject: [PATCH 20/22] [add] lexlibStrFormat() --- CHANGELOG.md | 1 + include/lexlib/str.h | 6 ++++++ src/str.c | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8cdcdc..78d7c2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ + lexlibFsSize(). + lexlibVec2Rotate(). + lexlibStrAppend(). ++ lexlibStrFormat(). + generic vector macro + generic vector: new(). + generic vector: push(). diff --git a/include/lexlib/str.h b/include/lexlib/str.h index f2d557d..78a0292 100644 --- a/include/lexlib/str.h +++ b/include/lexlib/str.h @@ -48,6 +48,12 @@ LEXLIBFN char *lexlibStrCopy(const char *str); // returns a valid string on success, NULL on error. LEXLIBFN char *lexlibStrFile(const char *filename); +/* format a new cstring. + uses stdc formatting. + the returned string is heap allocated and null terminated. + returns: NULL if fails to format or allocate memory. */ +LEXLIBFN char *lexlibStrFormat(const char *fmt, ...); + // creates a string with a correctly formatted path. (unix: / ; windows: \) // on error returns NULL (failed to allocate memory). LEXLIB_DEPRECATED diff --git a/src/str.c b/src/str.c index 36ef636..73ed84d 100644 --- a/src/str.c +++ b/src/str.c @@ -12,6 +12,7 @@ #include #include +#include #include #ifdef _WIN32 @@ -183,6 +184,27 @@ char *lexlibStrFile(const char *filename){ return buffer; } +char *lexlibStrFormat(const char *fmt, ...){ + va_list args; + + va_start(args, fmt); + int size = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + if(size < 0) + return NULL; + + char *str = malloc(size+1); + if(!str) + return NULL; + + va_start(args, fmt); + vsnprintf(str, size+1, fmt, args); + va_end(args); + + return str; +} + char *lexlibStrPathNew(const char *str){ size_t len = strlen(str); char *path = calloc(len+1, sizeof(char)); -- GitLab From bd103070a95df342a9538eaed52472e106be70d4 Mon Sep 17 00:00:00 2001 From: alexevier Date: Tue, 23 Apr 2024 22:40:26 -0400 Subject: [PATCH 21/22] [add] lexlibCurrentExecutablePath() --- CHANGELOG.md | 1 + CMakeLists.txt | 8 +++++++- include/lexlib/os.h | 11 ++++++++--- src/linux/os.c | 32 ++++++++++++++++++++++++++++++++ src/windows/os.c | 14 +++++++++++++- 5 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 src/linux/os.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d7c2b..88aec86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ + lexlibVec2Rotate(). + lexlibStrAppend(). + lexlibStrFormat(). ++ lexlibCurrentExecutablePath(). + generic vector macro + generic vector: new(). + generic vector: push(). diff --git a/CMakeLists.txt b/CMakeLists.txt index 8912f21..f3c66aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,13 @@ target_sources(${PROJECT_NAME} PRIVATE src/unix/mem.c src/unix/os.c ) -elseif(WIN32) +endif() +if(LINUX) + target_sources(${PROJECT_NAME} PRIVATE + src/linux/os.c + ) +endif() +if(WIN32) target_sources(${PROJECT_NAME} PRIVATE src/windows/mem.c src/windows/os.c diff --git a/include/lexlib/os.h b/include/lexlib/os.h index 1987b55..ff645a3 100644 --- a/include/lexlib/os.h +++ b/include/lexlib/os.h @@ -1,10 +1,9 @@ -// Copyright 2023 alexevier -// licensed under the zlib license +/* Copyright 2023-2024 alexevier +licensed under the zlib license */ #ifndef lexlib_os_h #define lexlib_os_h -#include #include #include"common.h" @@ -22,4 +21,10 @@ LEXLIBFN unsigned int lexlibRandom(void); // returns the size of the ram in bytes, 0 in case of error. LEXLIBFN uint64_t lexlibRamSize(void); +/* get the absolute path of the current executable as a cstring. + the returned string is heap allocated so it need to be freed with free(). + NOTE: available only on windows and linux. + returns NULL on error. */ +LEXLIBFN char *lexlibCurrentExecutablePath(void); + #endif diff --git a/src/linux/os.c b/src/linux/os.c new file mode 100644 index 0000000..a597fa2 --- /dev/null +++ b/src/linux/os.c @@ -0,0 +1,32 @@ +/* Copyright 2024 alexevier +licensed under the zlib license */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +char *lexlibCurrentExecutablePath(void){ + char buf[PATH_MAX+1] = {0}; + size_t read = readlink("/proc/self/exe", buf, PATH_MAX); + + if(read == (size_t)-1) + return NULL; + if(read == PATH_MAX) + return NULL; + + size_t len = strlen(buf); + char *path = malloc(len * sizeof(*path) + 1); + if(!path) + return NULL; + + memcpy(path, buf, len); + path[len] = '\0'; + + return path; +} diff --git a/src/windows/os.c b/src/windows/os.c index c7c1bea..edd7009 100644 --- a/src/windows/os.c +++ b/src/windows/os.c @@ -1,8 +1,9 @@ -// Copyright 2023 alexevier +// Copyright 2023-2024 alexevier // licensed under the zlib license #define _CRT_RAND_S +#include #include #include @@ -30,3 +31,14 @@ uint64_t lexlibRamSize(void){ return memoryStatus.ullTotalPhys; return 0; } + +char *lexlibCurrentExecutablePath(void){ + char buffer[MAX_PATH+1]; + + if(GetModuleFileName(NULL, buffer, MAX_PATH) == 0) + return NULL; + + char *path = lexlibStrCopy(buffer); + + return path; +} -- GitLab From c41ee2a9586f262588de6a3371a69e5c3f628189 Mon Sep 17 00:00:00 2001 From: alexevier Date: Tue, 23 Apr 2024 23:05:48 -0400 Subject: [PATCH 22/22] [add] generic vector function: remove --- CHANGELOG.md | 1 + include/lexlib/vector.h | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88aec86..f2dc56d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ + generic vector: free(). + generic vector: pop(). + generic vector: pushPtr(). ++ generic vector: remove(). ## 2.2.0 : the IO & UTF8 update diff --git a/include/lexlib/vector.h b/include/lexlib/vector.h index e3b43e7..0b6770e 100644 --- a/include/lexlib/vector.h +++ b/include/lexlib/vector.h @@ -21,14 +21,16 @@ LEXLIB_VECTOR_DECL_FREE(FN##Free, V)\ LEXLIB_VECTOR_DECL_PUSH(FN##Push, V, T)\ LEXLIB_VECTOR_DECL_PUSH_PTR(FN##PushPtr, V, T)\ - LEXLIB_VECTOR_DECL_POP(FN##Pop, V) + LEXLIB_VECTOR_DECL_POP(FN##Pop, V)\ + LEXLIB_VECTOR_DECL_REMOVE(FN##Remove, V, T) #define LEXLIB_VECTOR_IMPL(FN, V, T)\ LEXLIB_VECTOR_IMPL_NEW(FN##New, V)\ LEXLIB_VECTOR_IMPL_FREE(FN##Free, V)\ LEXLIB_VECTOR_IMPL_PUSH(FN##Push, V, T)\ LEXLIB_VECTOR_IMPL_PUSH_PTR(FN##PushPtr, V, T)\ - LEXLIB_VECTOR_IMPL_POP(FN##Pop, V) + LEXLIB_VECTOR_IMPL_POP(FN##Pop, V)\ + LEXLIB_VECTOR_IMPL_REMOVE(FN##Remove, V, T) #define LEXLIB_VECTOR_DECL_NEW(FN, V)\ /* create a new vector with capacity. */\ @@ -54,6 +56,10 @@ /* pop the last element of the vector. */\ LEXLIBFN void FN(V *vector); +#define LEXLIB_VECTOR_DECL_REMOVE(FN, V, T)\ + /* remove an element in the vector. */\ + int FN(V *vector, size_t idx); + #define LEXLIB_VECTOR_IMPL_NEW(FN, V)\ V FN(size_t capacity){\ V vector = {0,capacity,NULL};\ @@ -130,6 +136,17 @@ vector->len--;\ } +#define LEXLIB_VECTOR_IMPL_REMOVE(FN, V, T)\ + int FN(V *vector, size_t idx){\ + if(!vector->data)\ + return 1;\ + if(idx >= vector->len)\ + return 1;\ + \ + memmove(vector->data+idx, vector->data+idx+1, (vector->len-idx-1) * sizeof(T));\ + vector->len--;\ + return 0;\ + } #endif -- GitLab