From b23057b2195f40084a78affd1e31f0c086939dca Mon Sep 17 00:00:00 2001 From: CPunch Date: Thu, 1 Sep 2022 20:00:37 -0500 Subject: [PATCH] Refactoring: reorganized files --- CONTRIBUTING.md | 8 +- bot/include/bot.h | 12 +- bot/include/shell.h | 2 +- bot/lin/linpersist.c | 8 +- bot/lin/linshell.c | 6 +- bot/src/bot.c | 8 +- bot/src/main.c | 6 +- bot/src/shell.c | 4 +- bot/win/winpersist.c | 8 +- bot/win/winshell.c | 4 +- cnc/include/cnc.h | 14 +- cnc/include/cpanel.h | 2 +- cnc/include/cpeer.h | 8 +- cnc/src/cnc.c | 10 +- cnc/src/cpanel.c | 4 +- cnc/src/cpeer.c | 4 +- cnc/src/main.c | 4 +- lib/CMakeLists.txt | 2 +- lib/include/{ => core}/hashmap.h | 0 lib/include/{ => core}/ini.h | 91 ++-- lib/include/{ => core}/lbox.h | 6 +- lib/include/{ => core}/lerror.h | 0 lib/include/{ => core}/lmem.h | 4 +- lib/include/{ => core}/lsodium.h | 0 lib/include/{ => core}/ltask.h | 0 lib/include/{ => core}/lvm.h | 2 +- lib/include/{ => net}/lpacket.h | 0 lib/include/{ => net}/lpeer.h | 8 +- lib/include/{ => net}/lpolllist.h | 6 +- lib/include/{ => net}/lsocket.h | 8 +- lib/{vendor => src/core}/hashmap.c | 762 ++++++++++++++++------------- lib/{vendor => src/core}/ini.c | 107 ++-- lib/src/core/lerror.c | 4 + lib/src/{ => core}/lmem.c | 4 +- lib/src/{ => core}/lsodium.c | 2 +- lib/src/{ => core}/ltask.c | 4 +- lib/src/core/lvm.c | 1 + lib/src/lerror.c | 4 - lib/src/lvm.c | 1 - lib/src/{ => net}/lpacket.c | 2 +- lib/src/{ => net}/lpeer.c | 6 +- lib/src/{ => net}/lpolllist.c | 6 +- lib/src/{ => net}/lsocket.c | 12 +- shell/include/sclient.h | 10 +- shell/include/speer.h | 4 +- shell/src/main.c | 2 +- shell/src/sclient.c | 8 +- shell/src/scmd.c | 4 +- shell/src/speer.c | 4 +- shell/src/sterm.c | 2 +- tools/genkey/src/main.c | 4 +- tools/vmtest/src/main.c | 4 +- 52 files changed, 639 insertions(+), 557 deletions(-) rename lib/include/{ => core}/hashmap.h (100%) rename lib/include/{ => core}/ini.h (54%) rename lib/include/{ => core}/lbox.h (98%) rename lib/include/{ => core}/lerror.h (100%) rename lib/include/{ => core}/lmem.h (96%) rename lib/include/{ => core}/lsodium.h (100%) rename lib/include/{ => core}/ltask.h (100%) rename lib/include/{ => core}/lvm.h (99%) rename lib/include/{ => net}/lpacket.h (100%) rename lib/include/{ => net}/lpeer.h (96%) rename lib/include/{ => net}/lpolllist.h (94%) rename lib/include/{ => net}/lsocket.h (97%) rename lib/{vendor => src/core}/hashmap.c (52%) rename lib/{vendor => src/core}/ini.c (78%) create mode 100644 lib/src/core/lerror.c rename lib/src/{ => core}/lmem.c (87%) rename lib/src/{ => core}/lsodium.c (97%) rename lib/src/{ => core}/ltask.c (98%) create mode 100644 lib/src/core/lvm.c delete mode 100644 lib/src/lerror.c delete mode 100644 lib/src/lvm.c rename lib/src/{ => net}/lpacket.c (96%) rename lib/src/{ => net}/lpeer.c (99%) rename lib/src/{ => net}/lpolllist.c (99%) rename lib/src/{ => net}/lsocket.c (98%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b91e32e..cb85e8d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ Looking for some simple tasks that need to get done for that sweet 'contributor' - Change `lib/lin/linshell.c` to use openpty() instead of forkpty() for BSD support - Fix address sanitizer for CMake DEBUG builds - Change laikaT_getTime in `lib/src/ltask.c` to not use C11 features -- Implement more LAIKA_BOX_* VMs in `lib/include/lbox.h` +- Implement more LAIKA_BOX_* VMs in `lib/include/core/lbox.h` - Import more WinAPI manually using the method listed below ## Bot: Windows API Imports Obfuscation @@ -63,7 +63,7 @@ If the `real` & `hashed` match, that means our manual runtime import and the imp Now just replace all of the calls to the raw WinAPI (in our case, ShellExecuteA) with our new manually imported oShellExecuteA function pointer. Format & commit your changes, and open a PR and I'll merge your changes. Thanks! ## Lib: Error Handling -Error handling in Laika is done via the 'lerror.h' header library. It's a small and simple error handling solution written for laika, however can be stripped and used as a simple error handling library. Error handling in Laika is used similarly to other languages, implementing a try & catch block and is achieved using setjmp(). The LAIKA_ERROR(...) is used to throw errors. +Error handling in Laika is done via the 'core/lerror.h' header library. It's a small and simple error handling solution written for laika, however can be stripped and used as a simple error handling library. Error handling in Laika is used similarly to other languages, implementing a try & catch block and is achieved using setjmp(). The LAIKA_ERROR(...) is used to throw errors. Example: ```C @@ -85,13 +85,13 @@ Some minor inconveniences include: ## Lib: Packet Handlers -Laika has a simple binary protocol & a small backend (see `lib/src/lpeer.c`) to handle packets to/from peers. `lib/include/lpacket.h` includes descriptions for each packet type. For an example of proper packet handler definitions see `bot/src/bot.c`. It boils down to passing a sLaika_peerPacketInfo table to laikaS_newPeer. To add packet handlers to the bot, add your handler info to laikaB_pktTbl in `bot/src/bot.c`. To add packet handlers to the shell, add your handler info to shellC_pktTbl in `shell/src/sclient.c`. For adding packet handlers to cnc, make sure you add them to the corresponding table in `cnc/src/cnc.c`, laikaC_botPktTbl for packets being received from a bot peer, laikaC_authPktTbl for packets being received from an auth peer (shell), or DEFAULT_PKT_TBL if it's received by all peer types (things like handshakes, keep-alive, etc.) +Laika has a simple binary protocol & a small backend (see `lib/src/lpeer.c`) to handle packets to/from peers. `lib/include/net/lpacket.h` includes descriptions for each packet type. For an example of proper packet handler definitions see `bot/src/bot.c`. It boils down to passing a sLaika_peerPacketInfo table to laikaS_newPeer. To add packet handlers to the bot, add your handler info to laikaB_pktTbl in `bot/src/bot.c`. To add packet handlers to the shell, add your handler info to shellC_pktTbl in `shell/src/sclient.c`. For adding packet handlers to cnc, make sure you add them to the corresponding table in `cnc/src/cnc.c`, laikaC_botPktTbl for packets being received from a bot peer, laikaC_authPktTbl for packets being received from an auth peer (shell), or DEFAULT_PKT_TBL if it's received by all peer types (things like handshakes, keep-alive, etc.) ## Lib: Task Service Tasks can be scheduled on a delta-period (call X function every approximate N seconds). laikaT_pollTasks() is used to check & run any currently queued tasks. This is useful for sending keep-alive packets, polling shell pipes, or other repeatably scheduled tasks. Most laikaT_pollTasks() calls are done in the peerHandler for each client/server. ## Lib: VM Boxes -Laika has a tiny VM for decrypting sensitive information. For details on the ISA read `lib/include/lvm.h`, for information on how to use them read `lib/include/lbox.h`. Feel free to write your own boxes and contribute them :D +Laika has a tiny VM for decrypting sensitive information. For details on the ISA read `lib/include/core/lvm.h`, for information on how to use them read `lib/include/core/lbox.h`. Feel free to write your own boxes and contribute them :D ## Bot: Platform-specific backends diff --git a/bot/include/bot.h b/bot/include/bot.h index 55fd20f..9dc78e7 100644 --- a/bot/include/bot.h +++ b/bot/include/bot.h @@ -1,13 +1,13 @@ #ifndef LAIKA_BOT_H #define LAIKA_BOT_H +#include "core/lsodium.h" +#include "core/ltask.h" #include "laika.h" -#include "lpacket.h" -#include "lpeer.h" -#include "lpolllist.h" -#include "lsocket.h" -#include "lsodium.h" -#include "ltask.h" +#include "net/lpacket.h" +#include "net/lpeer.h" +#include "net/lpolllist.h" +#include "net/lsocket.h" struct sLaika_shell; struct sLaika_bot diff --git a/bot/include/shell.h b/bot/include/shell.h index d86b1da..cb18706 100644 --- a/bot/include/shell.h +++ b/bot/include/shell.h @@ -2,7 +2,7 @@ #define LAIKA_SHELL_H #include "laika.h" -#include "lpacket.h" +#include "net/lpacket.h" #include diff --git a/bot/lin/linpersist.c b/bot/lin/linpersist.c index c6675dc..f95b23d 100644 --- a/bot/lin/linpersist.c +++ b/bot/lin/linpersist.c @@ -1,10 +1,10 @@ /* platform specific code for achieving persistence on linux */ -#include "lbox.h" +#include "core/lbox.h" +#include "core/lerror.h" +#include "core/lmem.h" #include "lconfig.h" -#include "lerror.h" -#include "lmem.h" -#include "lsocket.h" +#include "net/lsocket.h" #include "persist.h" #include diff --git a/bot/lin/linshell.c b/bot/lin/linshell.c index 5e35eb4..ff0d453 100644 --- a/bot/lin/linshell.c +++ b/bot/lin/linshell.c @@ -1,9 +1,9 @@ /* platform specific code for opening shells in linux */ #include "bot.h" -#include "lerror.h" -#include "lmem.h" -#include "ltask.h" +#include "core/lerror.h" +#include "core/lmem.h" +#include "core/ltask.h" #include "shell.h" #include diff --git a/bot/src/bot.c b/bot/src/bot.c index 39e0507..1905bd9 100644 --- a/bot/src/bot.c +++ b/bot/src/bot.c @@ -1,9 +1,9 @@ #include "bot.h" -#include "lbox.h" -#include "lerror.h" -#include "lmem.h" -#include "lsodium.h" +#include "core/lbox.h" +#include "core/lerror.h" +#include "core/lmem.h" +#include "core/lsodium.h" #include "shell.h" void laikaB_handleHandshakeResponse(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData) diff --git a/bot/src/main.c b/bot/src/main.c index 70f186c..c80c3d1 100644 --- a/bot/src/main.c +++ b/bot/src/main.c @@ -1,8 +1,8 @@ #include "bot.h" -#include "lbox.h" +#include "core/lbox.h" +#include "core/lerror.h" +#include "core/ltask.h" #include "lconfig.h" -#include "lerror.h" -#include "ltask.h" #include "lobf.h" #include "persist.h" #include "shell.h" diff --git a/bot/src/shell.c b/bot/src/shell.c index a63c367..02fa762 100644 --- a/bot/src/shell.c +++ b/bot/src/shell.c @@ -1,8 +1,8 @@ #include "shell.h" #include "bot.h" -#include "lerror.h" -#include "lmem.h" +#include "core/lerror.h" +#include "core/lmem.h" #include #include diff --git a/bot/win/winpersist.c b/bot/win/winpersist.c index 0ad3b49..3553b47 100644 --- a/bot/win/winpersist.c +++ b/bot/win/winpersist.c @@ -6,11 +6,11 @@ #pragma comment(lib, "Shlwapi.lib") -#include "lbox.h" +#include "core/lbox.h" +#include "core/lerror.h" +#include "core/lmem.h" +#include "core/lvm.h" #include "lconfig.h" -#include "lerror.h" -#include "lmem.h" -#include "lvm.h" #include "lobf.h" #include "persist.h" diff --git a/bot/win/winshell.c b/bot/win/winshell.c index af0beef..a4608bc 100644 --- a/bot/win/winshell.c +++ b/bot/win/winshell.c @@ -1,8 +1,8 @@ /* platform specific code for opening shells (pseudo consoles) on windows */ #include "bot.h" +#include "core/lerror.h" +#include "core/lmem.h" #include "lobf.h" -#include "lerror.h" -#include "lmem.h" #include "shell.h" #include diff --git a/cnc/include/cnc.h b/cnc/include/cnc.h index c5c6bdb..a4db786 100644 --- a/cnc/include/cnc.h +++ b/cnc/include/cnc.h @@ -1,14 +1,14 @@ #ifndef LAIKA_CNC_H #define LAIKA_CNC_H -#include "hashmap.h" +#include "core/hashmap.h" +#include "core/lmem.h" +#include "core/ltask.h" #include "laika.h" -#include "lmem.h" -#include "lpacket.h" -#include "lpeer.h" -#include "lpolllist.h" -#include "lsocket.h" -#include "ltask.h" +#include "net/lpacket.h" +#include "net/lpeer.h" +#include "net/lpolllist.h" +#include "net/lsocket.h" /* kill peers if they haven't ping'd within a minute */ #define LAIKA_PEER_TIMEOUT 60 * 1000 diff --git a/cnc/include/cpanel.h b/cnc/include/cpanel.h index 76c2e61..25240d0 100644 --- a/cnc/include/cpanel.h +++ b/cnc/include/cpanel.h @@ -2,7 +2,7 @@ #define LAIKA_CNC_PANEL_H #include "cnc.h" -#include "lpeer.h" +#include "net/lpeer.h" void laikaC_sendPeerList(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer); void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *bot); diff --git a/cnc/include/cpeer.h b/cnc/include/cpeer.h index fbb8e73..cf82842 100644 --- a/cnc/include/cpeer.h +++ b/cnc/include/cpeer.h @@ -2,10 +2,10 @@ #define LAIKA_CNC_PEER_H #include "laika.h" -#include "lpacket.h" -#include "lpeer.h" -#include "lpolllist.h" -#include "lsocket.h" +#include "net/lpacket.h" +#include "net/lpeer.h" +#include "net/lpolllist.h" +#include "net/lsocket.h" struct sLaika_peerInfo { diff --git a/cnc/src/cnc.c b/cnc/src/cnc.c index d87cdd2..c42f1c3 100644 --- a/cnc/src/cnc.c +++ b/cnc/src/cnc.c @@ -1,12 +1,12 @@ #include "cnc.h" +#include "core/lerror.h" +#include "core/lmem.h" +#include "core/lsodium.h" +#include "core/ltask.h" #include "cpanel.h" #include "cpeer.h" -#include "lerror.h" -#include "lmem.h" -#include "lsocket.h" -#include "lsodium.h" -#include "ltask.h" +#include "net/lsocket.h" /* ======================================[[ PeerHashMap ]]======================================= */ diff --git a/cnc/src/cpanel.c b/cnc/src/cpanel.c index 6ade0d9..ae4960e 100644 --- a/cnc/src/cpanel.c +++ b/cnc/src/cpanel.c @@ -1,9 +1,9 @@ #include "cpanel.h" #include "cnc.h" +#include "core/lerror.h" +#include "core/lmem.h" #include "cpeer.h" -#include "lerror.h" -#include "lmem.h" void laikaC_sendPeerList(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer) { diff --git a/cnc/src/cpeer.c b/cnc/src/cpeer.c index a911353..40a95f4 100644 --- a/cnc/src/cpeer.c +++ b/cnc/src/cpeer.c @@ -1,8 +1,8 @@ #include "cpeer.h" #include "cnc.h" -#include "lerror.h" -#include "lmem.h" +#include "core/lerror.h" +#include "core/lmem.h" /* =======================================[[ Peer Info ]]======================================= */ diff --git a/cnc/src/main.c b/cnc/src/main.c index 7c886f1..737c42f 100644 --- a/cnc/src/main.c +++ b/cnc/src/main.c @@ -1,7 +1,7 @@ #include "cnc.h" -#include "ini.h" +#include "core/ini.h" +#include "core/ltask.h" #include "lconfig.h" -#include "ltask.h" #include diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 6a26f82..bdac032 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -8,7 +8,7 @@ project(LaikaLib VERSION ${LAIKA_VERSION_MAJOR}.${LAIKA_VERSION_MINOR}) set_property(GLOBAL PROPERTY USE_FOLDERS ON) # compile LaikaLib library -file(GLOB_RECURSE LIBSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/**.c ${CMAKE_CURRENT_SOURCE_DIR}/vendor/**.c) +file(GLOB_RECURSE LIBSOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/**.c) file(GLOB_RECURSE LIBHEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/**.h) # include platform specific backends diff --git a/lib/include/hashmap.h b/lib/include/core/hashmap.h similarity index 100% rename from lib/include/hashmap.h rename to lib/include/core/hashmap.h diff --git a/lib/include/ini.h b/lib/include/core/ini.h similarity index 54% rename from lib/include/ini.h rename to lib/include/core/ini.h index 78015d1..750035d 100644 --- a/lib/include/ini.h +++ b/lib/include/core/ini.h @@ -16,129 +16,127 @@ https://github.com/benhoyt/inih /* Make this header file easier to include in C++ code */ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include /* Nonzero if ini_handler callback should accept lineno parameter. */ #ifndef INI_HANDLER_LINENO -#define INI_HANDLER_LINENO 0 +# define INI_HANDLER_LINENO 0 #endif /* Typedef for prototype of handler function. */ #if INI_HANDLER_LINENO -typedef int (*ini_handler)(void* user, const char* section, - const char* name, const char* value, - int lineno); + typedef int (*ini_handler)(void *user, const char *section, const char *name, const char *value, + int lineno); #else -typedef int (*ini_handler)(void* user, const char* section, - const char* name, const char* value); +typedef int (*ini_handler)(void *user, const char *section, const char *name, const char *value); #endif -/* Typedef for prototype of fgets-style reader function. */ -typedef char* (*ini_reader)(char* str, int num, void* stream); + /* Typedef for prototype of fgets-style reader function. */ + typedef char *(*ini_reader)(char *str, int num, void *stream); -/* Parse given INI-style file. May have [section]s, name=value pairs - (whitespace stripped), and comments starting with ';' (semicolon). Section - is "" if name=value pair parsed before any section heading. name:value - pairs are also supported as a concession to Python's configparser. + /* Parse given INI-style file. May have [section]s, name=value pairs + (whitespace stripped), and comments starting with ';' (semicolon). Section + is "" if name=value pair parsed before any section heading. name:value + pairs are also supported as a concession to Python's configparser. - For each name=value pair parsed, call handler function with given user - pointer as well as section, name, and value (data only valid for duration - of handler call). Handler should return nonzero on success, zero on error. + For each name=value pair parsed, call handler function with given user + pointer as well as section, name, and value (data only valid for duration + of handler call). Handler should return nonzero on success, zero on error. - Returns 0 on success, line number of first error on parse error (doesn't - stop on first error), -1 on file open error, or -2 on memory allocation - error (only when INI_USE_STACK is zero). -*/ -int ini_parse(const char* filename, ini_handler handler, void* user); + Returns 0 on success, line number of first error on parse error (doesn't + stop on first error), -1 on file open error, or -2 on memory allocation + error (only when INI_USE_STACK is zero). + */ + int ini_parse(const char *filename, ini_handler handler, void *user); -/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't - close the file when it's finished -- the caller must do that. */ -int ini_parse_file(FILE* file, ini_handler handler, void* user); + /* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't + close the file when it's finished -- the caller must do that. */ + int ini_parse_file(FILE *file, ini_handler handler, void *user); -/* Same as ini_parse(), but takes an ini_reader function pointer instead of - filename. Used for implementing custom or string-based I/O (see also - ini_parse_string). */ -int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, - void* user); + /* Same as ini_parse(), but takes an ini_reader function pointer instead of + filename. Used for implementing custom or string-based I/O (see also + ini_parse_string). */ + int ini_parse_stream(ini_reader reader, void *stream, ini_handler handler, void *user); -/* Same as ini_parse(), but takes a zero-terminated string with the INI data -instead of a file. Useful for parsing INI data from a network socket or -already in memory. */ -int ini_parse_string(const char* string, ini_handler handler, void* user); + /* Same as ini_parse(), but takes a zero-terminated string with the INI data + instead of a file. Useful for parsing INI data from a network socket or + already in memory. */ + int ini_parse_string(const char *string, ini_handler handler, void *user); /* Nonzero to allow multi-line value parsing, in the style of Python's configparser. If allowed, ini_parse() will call the handler with the same name for each subsequent line parsed. */ #ifndef INI_ALLOW_MULTILINE -#define INI_ALLOW_MULTILINE 1 +# define INI_ALLOW_MULTILINE 1 #endif /* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of the file. See https://github.com/benhoyt/inih/issues/21 */ #ifndef INI_ALLOW_BOM -#define INI_ALLOW_BOM 1 +# define INI_ALLOW_BOM 1 #endif /* Chars that begin a start-of-line comment. Per Python configparser, allow both ; and # comments at the start of a line by default. */ #ifndef INI_START_COMMENT_PREFIXES -#define INI_START_COMMENT_PREFIXES ";#" +# define INI_START_COMMENT_PREFIXES ";#" #endif /* Nonzero to allow inline comments (with valid inline comment characters specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match Python 3.2+ configparser behaviour. */ #ifndef INI_ALLOW_INLINE_COMMENTS -#define INI_ALLOW_INLINE_COMMENTS 1 +# define INI_ALLOW_INLINE_COMMENTS 1 #endif #ifndef INI_INLINE_COMMENT_PREFIXES -#define INI_INLINE_COMMENT_PREFIXES ";" +# define INI_INLINE_COMMENT_PREFIXES ";" #endif /* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */ #ifndef INI_USE_STACK -#define INI_USE_STACK 1 +# define INI_USE_STACK 1 #endif /* Maximum line length for any line in INI file (stack or heap). Note that this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */ #ifndef INI_MAX_LINE -#define INI_MAX_LINE 200 +# define INI_MAX_LINE 200 #endif /* Nonzero to allow heap line buffer to grow via realloc(), zero for a fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is zero. */ #ifndef INI_ALLOW_REALLOC -#define INI_ALLOW_REALLOC 0 +# define INI_ALLOW_REALLOC 0 #endif /* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK is zero. */ #ifndef INI_INITIAL_ALLOC -#define INI_INITIAL_ALLOC 200 +# define INI_INITIAL_ALLOC 200 #endif /* Stop parsing on first error (default is to keep parsing). */ #ifndef INI_STOP_ON_FIRST_ERROR -#define INI_STOP_ON_FIRST_ERROR 0 +# define INI_STOP_ON_FIRST_ERROR 0 #endif /* Nonzero to call the handler at the start of each new section (with name and value NULL). Default is to only call the handler on each name=value pair. */ #ifndef INI_CALL_HANDLER_ON_NEW_SECTION -#define INI_CALL_HANDLER_ON_NEW_SECTION 0 +# define INI_CALL_HANDLER_ON_NEW_SECTION 0 #endif /* Nonzero to allow a name without a value (no '=' or ':' on the line) and call the handler with value NULL in this case. Default is to treat no-value lines as an error. */ #ifndef INI_ALLOW_NO_VALUE -#define INI_ALLOW_NO_VALUE 0 +# define INI_ALLOW_NO_VALUE 0 #endif /* Nonzero to use custom ini_malloc, ini_free, and ini_realloc memory @@ -146,10 +144,9 @@ int ini_parse_string(const char* string, ini_handler handler, void* user); have the same signatures as malloc/free/realloc and behave in a similar way. ini_realloc is only needed if INI_ALLOW_REALLOC is set. */ #ifndef INI_CUSTOM_ALLOCATOR -#define INI_CUSTOM_ALLOCATOR 0 +# define INI_CUSTOM_ALLOCATOR 0 #endif - #ifdef __cplusplus } #endif diff --git a/lib/include/lbox.h b/lib/include/core/lbox.h similarity index 98% rename from lib/include/lbox.h rename to lib/include/core/lbox.h index 317ed2d..7c943d2 100644 --- a/lib/include/lbox.h +++ b/lib/include/core/lbox.h @@ -1,10 +1,10 @@ #ifndef LAIKA_BOX_H #define LAIKA_BOX_H +#include "core/lmem.h" +#include "core/lsodium.h" +#include "core/lvm.h" #include "laika.h" -#include "lmem.h" -#include "lsodium.h" -#include "lvm.h" #include diff --git a/lib/include/lerror.h b/lib/include/core/lerror.h similarity index 100% rename from lib/include/lerror.h rename to lib/include/core/lerror.h diff --git a/lib/include/lmem.h b/lib/include/core/lmem.h similarity index 96% rename from lib/include/lmem.h rename to lib/include/core/lmem.h index cc9aad3..cfd0bf5 100644 --- a/lib/include/lmem.h +++ b/lib/include/core/lmem.h @@ -14,8 +14,8 @@ # define ENDVLA(var) ((void)0) /* no op */ #endif -#define laikaM_malloc(sz) laikaM_realloc(NULL, sz) -#define laikaM_free(buf) laikaM_realloc(buf, 0) +#define laikaM_malloc(sz) laikaM_realloc(NULL, sz) +#define laikaM_free(buf) laikaM_realloc(buf, 0) /* ========================================[[ Vectors ]]======================================== */ diff --git a/lib/include/lsodium.h b/lib/include/core/lsodium.h similarity index 100% rename from lib/include/lsodium.h rename to lib/include/core/lsodium.h diff --git a/lib/include/ltask.h b/lib/include/core/ltask.h similarity index 100% rename from lib/include/ltask.h rename to lib/include/core/ltask.h diff --git a/lib/include/lvm.h b/lib/include/core/lvm.h similarity index 99% rename from lib/include/lvm.h rename to lib/include/core/lvm.h index f55fffe..1565134 100644 --- a/lib/include/lvm.h +++ b/lib/include/core/lvm.h @@ -9,8 +9,8 @@ fit this specific use case. */ +#include "core/lerror.h" #include "laika.h" -#include "lerror.h" #include diff --git a/lib/include/lpacket.h b/lib/include/net/lpacket.h similarity index 100% rename from lib/include/lpacket.h rename to lib/include/net/lpacket.h diff --git a/lib/include/lpeer.h b/lib/include/net/lpeer.h similarity index 96% rename from lib/include/lpeer.h rename to lib/include/net/lpeer.h index 02637c0..ea14460 100644 --- a/lib/include/lpeer.h +++ b/lib/include/net/lpeer.h @@ -1,11 +1,11 @@ #ifndef LAIKA_PEER_H #define LAIKA_PEER_H +#include "core/lsodium.h" #include "laika.h" -#include "lpacket.h" -#include "lpolllist.h" -#include "lsocket.h" -#include "lsodium.h" +#include "net/lpacket.h" +#include "net/lpolllist.h" +#include "net/lsocket.h" typedef enum { diff --git a/lib/include/lpolllist.h b/lib/include/net/lpolllist.h similarity index 94% rename from lib/include/lpolllist.h rename to lib/include/net/lpolllist.h index 6123a07..c01883d 100644 --- a/lib/include/lpolllist.h +++ b/lib/include/net/lpolllist.h @@ -1,10 +1,10 @@ #ifndef LAIKA_POLLLIST_H #define LAIKA_POLLLIST_H -#include "hashmap.h" +#include "core/hashmap.h" +#include "core/lmem.h" #include "laika.h" -#include "lmem.h" -#include "lsocket.h" +#include "net/lsocket.h" #include diff --git a/lib/include/lsocket.h b/lib/include/net/lsocket.h similarity index 97% rename from lib/include/lsocket.h rename to lib/include/net/lsocket.h index f40a40c..246ea98 100644 --- a/lib/include/lsocket.h +++ b/lib/include/net/lsocket.h @@ -3,7 +3,7 @@ /* clang-format will change the order of the included windows headers, this BREAKS THINGS. for now, make clang ignore this section */ - + /* clang-format off */ /* socket/winsock headers */ @@ -54,8 +54,8 @@ typedef void buffer_t; # define SOCKETERROR(x) (x == -1) #endif #include "laika.h" -#include "lsodium.h" -#include "lmem.h" +#include "core/lsodium.h" +#include "core/lmem.h" #include #include @@ -79,7 +79,7 @@ struct sLaika_socket pollFailEvent onPollFail; pollEvent onPollIn; pollEvent onPollOut; - void *uData; /* passed to onPollFail */ + void *uData; /* passed to onPollFail */ laikaM_newVector(uint8_t, outBuf); /* raw data to be sent() */ laikaM_newVector(uint8_t, inBuf); /* raw data we recv()'d */ bool flipEndian; diff --git a/lib/vendor/hashmap.c b/lib/src/core/hashmap.c similarity index 52% rename from lib/vendor/hashmap.c rename to lib/src/core/hashmap.c index 2efcb0e..3666e2d 100644 --- a/lib/vendor/hashmap.c +++ b/lib/src/core/hashmap.c @@ -2,7 +2,7 @@ // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file. -#include "hashmap.h" +#include "core/hashmap.h" #include #include @@ -17,24 +17,27 @@ static void (*_free)(void *) = NULL; // hashmap_set_allocator allows for configuring a custom allocator for // all hashmap library operations. This function, if needed, should be called // only once at startup and a prior to calling hashmap_new(). -void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void*)) +void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void *)) { _malloc = malloc; _free = free; } -#define panic(_msg_) { \ - fprintf(stderr, "panic: %s (%s:%d)\n", (_msg_), __FILE__, __LINE__); \ - exit(1); \ -} +#define panic(_msg_) \ + { \ + fprintf(stderr, "panic: %s (%s:%d)\n", (_msg_), __FILE__, __LINE__); \ + exit(1); \ + } -struct bucket { - uint64_t hash:48; - uint64_t dib:16; +struct bucket +{ + uint64_t hash : 48; + uint64_t dib : 16; }; // hashmap is an open addressed hash map using robinhood hashing. -struct hashmap { +struct hashmap +{ void *(*malloc)(size_t); void *(*realloc)(void *, size_t); void (*free)(void *); @@ -58,32 +61,30 @@ struct hashmap { void *edata; }; -static struct bucket *bucket_at(struct hashmap *map, size_t index) { - return (struct bucket*)(((char*)map->buckets)+(map->bucketsz*index)); +static struct bucket *bucket_at(struct hashmap *map, size_t index) +{ + return (struct bucket *)(((char *)map->buckets) + (map->bucketsz * index)); } -static void *bucket_item(struct bucket *entry) { - return ((char*)entry)+sizeof(struct bucket); +static void *bucket_item(struct bucket *entry) +{ + return ((char *)entry) + sizeof(struct bucket); } -static uint64_t get_hash(struct hashmap *map, const void *key) { +static uint64_t get_hash(struct hashmap *map, const void *key) +{ return map->hash(key, map->seed0, map->seed1) << 16 >> 16; } // hashmap_new_with_allocator returns a new hash map using a custom allocator. // See hashmap_new for more information information -struct hashmap *hashmap_new_with_allocator( - void *(*_malloc)(size_t), - void *(*_realloc)(void*, size_t), - void (*_free)(void*), - size_t elsize, size_t cap, - uint64_t seed0, uint64_t seed1, - uint64_t (*hash)(const void *item, - uint64_t seed0, uint64_t seed1), - int (*compare)(const void *a, const void *b, - void *udata), - void (*elfree)(void *item), - void *udata) +struct hashmap * +hashmap_new_with_allocator(void *(*_malloc)(size_t), void *(*_realloc)(void *, size_t), + void (*_free)(void *), size_t elsize, size_t cap, uint64_t seed0, + uint64_t seed1, + uint64_t (*hash)(const void *item, uint64_t seed0, uint64_t seed1), + int (*compare)(const void *a, const void *b, void *udata), + void (*elfree)(void *item), void *udata) { _malloc = _malloc ? _malloc : malloc; _realloc = _realloc ? _realloc : realloc; @@ -98,11 +99,11 @@ struct hashmap *hashmap_new_with_allocator( cap = ncap; } size_t bucketsz = sizeof(struct bucket) + elsize; - while (bucketsz & (sizeof(uintptr_t)-1)) { + while (bucketsz & (sizeof(uintptr_t) - 1)) { bucketsz++; } // hashmap + spare + edata - size_t size = sizeof(struct hashmap)+bucketsz*2; + size_t size = sizeof(struct hashmap) + bucketsz * 2; struct hashmap *map = _malloc(size); if (!map) { return NULL; @@ -116,100 +117,93 @@ struct hashmap *hashmap_new_with_allocator( map->compare = compare; map->elfree = elfree; map->udata = udata; - map->spare = ((char*)map)+sizeof(struct hashmap); - map->edata = (char*)map->spare+bucketsz; + map->spare = ((char *)map) + sizeof(struct hashmap); + map->edata = (char *)map->spare + bucketsz; map->cap = cap; map->nbuckets = cap; - map->mask = map->nbuckets-1; - map->buckets = _malloc(map->bucketsz*map->nbuckets); + map->mask = map->nbuckets - 1; + map->buckets = _malloc(map->bucketsz * map->nbuckets); if (!map->buckets) { _free(map); return NULL; } - memset(map->buckets, 0, map->bucketsz*map->nbuckets); - map->growat = map->nbuckets*0.75; - map->shrinkat = map->nbuckets*0.10; + memset(map->buckets, 0, map->bucketsz * map->nbuckets); + map->growat = map->nbuckets * 0.75; + map->shrinkat = map->nbuckets * 0.10; map->malloc = _malloc; map->realloc = _realloc; map->free = _free; - return map; + return map; } - -// hashmap_new returns a new hash map. +// hashmap_new returns a new hash map. // Param `elsize` is the size of each element in the tree. Every element that // is inserted, deleted, or retrieved will be this size. // Param `cap` is the default lower capacity of the hashmap. Setting this to // zero will default to 16. -// Params `seed0` and `seed1` are optional seed values that are passed to the -// following `hash` function. These can be any value you wish but it's often +// Params `seed0` and `seed1` are optional seed values that are passed to the +// following `hash` function. These can be any value you wish but it's often // best to use randomly generated values. // Param `hash` is a function that generates a hash value for an item. It's // important that you provide a good hash function, otherwise it will perform // poorly or be vulnerable to Denial-of-service attacks. This implementation // comes with two helper functions `hashmap_sip()` and `hashmap_murmur()`. -// Param `compare` is a function that compares items in the tree. See the +// Param `compare` is a function that compares items in the tree. See the // qsort stdlib function for an example of how this function works. -// The hashmap must be freed with hashmap_free(). +// The hashmap must be freed with hashmap_free(). // Param `elfree` is a function that frees a specific item. This should be NULL // unless you're storing some kind of reference data in the hash. -struct hashmap *hashmap_new(size_t elsize, size_t cap, - uint64_t seed0, uint64_t seed1, - uint64_t (*hash)(const void *item, - uint64_t seed0, uint64_t seed1), - int (*compare)(const void *a, const void *b, - void *udata), - void (*elfree)(void *item), - void *udata) +struct hashmap *hashmap_new(size_t elsize, size_t cap, uint64_t seed0, uint64_t seed1, + uint64_t (*hash)(const void *item, uint64_t seed0, uint64_t seed1), + int (*compare)(const void *a, const void *b, void *udata), + void (*elfree)(void *item), void *udata) { - return hashmap_new_with_allocator( - (_malloc?_malloc:malloc), - (_realloc?_realloc:realloc), - (_free?_free:free), - elsize, cap, seed0, seed1, hash, compare, elfree, udata - ); + return hashmap_new_with_allocator((_malloc ? _malloc : malloc), (_realloc ? _realloc : realloc), + (_free ? _free : free), elsize, cap, seed0, seed1, hash, + compare, elfree, udata); } -static void free_elements(struct hashmap *map) { +static void free_elements(struct hashmap *map) +{ if (map->elfree) { for (size_t i = 0; i < map->nbuckets; i++) { struct bucket *bucket = bucket_at(map, i); - if (bucket->dib) map->elfree(bucket_item(bucket)); + if (bucket->dib) + map->elfree(bucket_item(bucket)); } } } - -// hashmap_clear quickly clears the map. +// hashmap_clear quickly clears the map. // Every item is called with the element-freeing function given in hashmap_new, // if present, to free any data referenced in the elements of the hashmap. // When the update_cap is provided, the map's capacity will be updated to match // the currently number of allocated buckets. This is an optimization to ensure // that this operation does not perform any allocations. -void hashmap_clear(struct hashmap *map, bool update_cap) { +void hashmap_clear(struct hashmap *map, bool update_cap) +{ map->count = 0; free_elements(map); if (update_cap) { map->cap = map->nbuckets; } else if (map->nbuckets != map->cap) { - void *new_buckets = map->malloc(map->bucketsz*map->cap); + void *new_buckets = map->malloc(map->bucketsz * map->cap); if (new_buckets) { map->free(map->buckets); map->buckets = new_buckets; } map->nbuckets = map->cap; } - memset(map->buckets, 0, map->bucketsz*map->nbuckets); - map->mask = map->nbuckets-1; - map->growat = map->nbuckets*0.75; - map->shrinkat = map->nbuckets*0.10; + memset(map->buckets, 0, map->bucketsz * map->nbuckets); + map->mask = map->nbuckets - 1; + map->growat = map->nbuckets * 0.75; + map->shrinkat = map->nbuckets * 0.10; } - -static bool resize(struct hashmap *map, size_t new_cap) { - struct hashmap *map2 = hashmap_new(map->elsize, new_cap, map->seed1, - map->seed1, map->hash, map->compare, - map->elfree, map->udata); +static bool resize(struct hashmap *map, size_t new_cap) +{ + struct hashmap *map2 = hashmap_new(map->elsize, new_cap, map->seed1, map->seed1, map->hash, + map->compare, map->elfree, map->udata); if (!map2) { return false; } @@ -234,7 +228,7 @@ static bool resize(struct hashmap *map, size_t new_cap) { j = (j + 1) & map2->mask; entry->dib += 1; } - } + } map->free(map->buckets); map->buckets = map2->buckets; map->nbuckets = map2->nbuckets; @@ -249,102 +243,98 @@ static bool resize(struct hashmap *map, size_t new_cap) { // replaced then it is returned otherwise NULL is returned. This operation // may allocate memory. If the system is unable to allocate additional // memory then NULL is returned and hashmap_oom() returns true. -void *hashmap_set(struct hashmap *map, const void *item) { +void *hashmap_set(struct hashmap *map, const void *item) +{ if (!item) { panic("item is null"); } map->oom = false; if (map->count == map->growat) { - if (!resize(map, map->nbuckets*2)) { + if (!resize(map, map->nbuckets * 2)) { map->oom = true; return NULL; } } - struct bucket *entry = map->edata; entry->hash = get_hash(map, item); entry->dib = 1; memcpy(bucket_item(entry), item, map->elsize); - + size_t i = entry->hash & map->mask; - for (;;) { + for (;;) { struct bucket *bucket = bucket_at(map, i); if (bucket->dib == 0) { memcpy(bucket, entry, map->bucketsz); map->count++; - return NULL; - } - if (entry->hash == bucket->hash && - map->compare(bucket_item(entry), bucket_item(bucket), - map->udata) == 0) - { + return NULL; + } + if (entry->hash == bucket->hash && + map->compare(bucket_item(entry), bucket_item(bucket), map->udata) == 0) { memcpy(map->spare, bucket_item(bucket), map->elsize); memcpy(bucket_item(bucket), bucket_item(entry), map->elsize); return map->spare; - } + } if (bucket->dib < entry->dib) { memcpy(map->spare, bucket, map->bucketsz); memcpy(bucket, entry, map->bucketsz); memcpy(entry, map->spare, map->bucketsz); - } - i = (i + 1) & map->mask; + } + i = (i + 1) & map->mask; entry->dib += 1; - } + } } // hashmap_get returns the item based on the provided key. If the item is not // found then NULL is returned. -void *hashmap_get(struct hashmap *map, const void *key) { +void *hashmap_get(struct hashmap *map, const void *key) +{ if (!key) { panic("key is null"); } uint64_t hash = get_hash(map, key); - size_t i = hash & map->mask; - for (;;) { + size_t i = hash & map->mask; + for (;;) { struct bucket *bucket = bucket_at(map, i); - if (!bucket->dib) { - return NULL; - } - if (bucket->hash == hash && - map->compare(key, bucket_item(bucket), map->udata) == 0) - { + if (!bucket->dib) { + return NULL; + } + if (bucket->hash == hash && map->compare(key, bucket_item(bucket), map->udata) == 0) { return bucket_item(bucket); - } - i = (i + 1) & map->mask; - } + } + i = (i + 1) & map->mask; + } } // hashmap_probe returns the item in the bucket at position or NULL if an item -// is not set for that bucket. The position is 'moduloed' by the number of +// is not set for that bucket. The position is 'moduloed' by the number of // buckets in the hashmap. -void *hashmap_probe(struct hashmap *map, uint64_t position) { +void *hashmap_probe(struct hashmap *map, uint64_t position) +{ size_t i = position & map->mask; struct bucket *bucket = bucket_at(map, i); if (!bucket->dib) { - return NULL; - } + return NULL; + } return bucket_item(bucket); } - // hashmap_delete removes an item from the hash map and returns it. If the // item is not found then NULL is returned. -void *hashmap_delete(struct hashmap *map, void *key) { +void *hashmap_delete(struct hashmap *map, void *key) +{ if (!key) { panic("key is null"); } map->oom = false; uint64_t hash = get_hash(map, key); - size_t i = hash & map->mask; - for (;;) { + size_t i = hash & map->mask; + for (;;) { struct bucket *bucket = bucket_at(map, i); - if (!bucket->dib) { - return NULL; - } - if (bucket->hash == hash && - map->compare(key, bucket_item(bucket), map->udata) == 0) - { + if (!bucket->dib) { + return NULL; + } + if (bucket->hash == hash && map->compare(key, bucket_item(bucket), map->udata) == 0) { memcpy(map->spare, bucket_item(bucket), map->elsize); bucket->dib = 0; for (;;) { @@ -363,40 +353,43 @@ void *hashmap_delete(struct hashmap *map, void *key) { // Ignore the return value. It's ok for the resize operation to // fail to allocate enough memory because a shrink operation // does not change the integrity of the data. - resize(map, map->nbuckets/2); + resize(map, map->nbuckets / 2); } - return map->spare; - } - i = (i + 1) & map->mask; - } + return map->spare; + } + i = (i + 1) & map->mask; + } } // hashmap_count returns the number of items in the hash map. -size_t hashmap_count(struct hashmap *map) { +size_t hashmap_count(struct hashmap *map) +{ return map->count; } // hashmap_free frees the hash map // Every item is called with the element-freeing function given in hashmap_new, // if present, to free any data referenced in the elements of the hashmap. -void hashmap_free(struct hashmap *map) { - if (!map) return; +void hashmap_free(struct hashmap *map) +{ + if (!map) + return; free_elements(map); map->free(map->buckets); map->free(map); } -// hashmap_oom returns true if the last hashmap_set() call failed due to the +// hashmap_oom returns true if the last hashmap_set() call failed due to the // system being out of memory. -bool hashmap_oom(struct hashmap *map) { +bool hashmap_oom(struct hashmap *map) +{ return map->oom; } // hashmap_scan iterates over all items in the hash map // Param `iter` can return false to stop iteration early. // Returns false if the iteration has been stopped early. -bool hashmap_scan(struct hashmap *map, - bool (*iter)(const void *item, void *udata), void *udata) +bool hashmap_scan(struct hashmap *map, bool (*iter)(const void *item, void *udata), void *udata) { for (size_t i = 0; i < map->nbuckets; i++) { struct bucket *bucket = bucket_at(map, i); @@ -409,7 +402,6 @@ bool hashmap_scan(struct hashmap *map, return true; } - // hashmap_iter iterates one key at a time yielding a reference to an // entry at each iteration. Useful to write simple loops and avoid writing // dedicated callbacks and udata structures, as in hashmap_scan. @@ -433,7 +425,8 @@ bool hashmap_iter(struct hashmap *map, size_t *i, void **item) struct bucket *bucket; do { - if (*i >= map->nbuckets) return false; + if (*i >= map->nbuckets) + return false; bucket = bucket_at(map, *i); (*i)++; @@ -444,7 +437,6 @@ bool hashmap_iter(struct hashmap *map, size_t *i, void **item) return true; } - //----------------------------------------------------------------------------- // SipHash reference C implementation // @@ -462,34 +454,44 @@ bool hashmap_iter(struct hashmap *map, size_t *i, void **item) // // default: SipHash-2-4 //----------------------------------------------------------------------------- -static uint64_t SIP64(const uint8_t *in, const size_t inlen, - uint64_t seed0, uint64_t seed1) +static uint64_t SIP64(const uint8_t *in, const size_t inlen, uint64_t seed0, uint64_t seed1) { -#define U8TO64_LE(p) \ - { (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ - ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ - ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ - ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) } -#define U64TO8_LE(p, v) \ - { U32TO8_LE((p), (uint32_t)((v))); \ - U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); } -#define U32TO8_LE(p, v) \ - { (p)[0] = (uint8_t)((v)); \ - (p)[1] = (uint8_t)((v) >> 8); \ - (p)[2] = (uint8_t)((v) >> 16); \ - (p)[3] = (uint8_t)((v) >> 24); } +#define U8TO64_LE(p) \ + {(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | ((uint64_t)((p)[2]) << 16) | \ + ((uint64_t)((p)[3]) << 24) | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ + ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))} +#define U64TO8_LE(p, v) \ + { \ + U32TO8_LE((p), (uint32_t)((v))); \ + U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); \ + } +#define U32TO8_LE(p, v) \ + { \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); \ + } #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) -#define SIPROUND \ - { v0 += v1; v1 = ROTL(v1, 13); \ - v1 ^= v0; v0 = ROTL(v0, 32); \ - v2 += v3; v3 = ROTL(v3, 16); \ - v3 ^= v2; \ - v0 += v3; v3 = ROTL(v3, 21); \ - v3 ^= v0; \ - v2 += v1; v1 = ROTL(v1, 17); \ - v1 ^= v2; v2 = ROTL(v2, 32); } - uint64_t k0 = U8TO64_LE((uint8_t*)&seed0); - uint64_t k1 = U8TO64_LE((uint8_t*)&seed1); +#define SIPROUND \ + { \ + v0 += v1; \ + v1 = ROTL(v1, 13); \ + v1 ^= v0; \ + v0 = ROTL(v0, 32); \ + v2 += v3; \ + v3 = ROTL(v3, 16); \ + v3 ^= v2; \ + v0 += v3; \ + v3 = ROTL(v3, 21); \ + v3 ^= v0; \ + v2 += v1; \ + v1 = ROTL(v1, 17); \ + v1 ^= v2; \ + v2 = ROTL(v2, 32); \ + } + uint64_t k0 = U8TO64_LE((uint8_t *)&seed0); + uint64_t k1 = U8TO64_LE((uint8_t *)&seed1); uint64_t v3 = UINT64_C(0x7465646279746573) ^ k1; uint64_t v2 = UINT64_C(0x6c7967656e657261) ^ k0; uint64_t v1 = UINT64_C(0x646f72616e646f6d) ^ k1; @@ -498,29 +500,43 @@ static uint64_t SIP64(const uint8_t *in, const size_t inlen, for (; in != end; in += 8) { uint64_t m = U8TO64_LE(in); v3 ^= m; - SIPROUND; SIPROUND; + SIPROUND; + SIPROUND; v0 ^= m; } const int left = inlen & 7; uint64_t b = ((uint64_t)inlen) << 56; switch (left) { - case 7: b |= ((uint64_t)in[6]) << 48; - case 6: b |= ((uint64_t)in[5]) << 40; - case 5: b |= ((uint64_t)in[4]) << 32; - case 4: b |= ((uint64_t)in[3]) << 24; - case 3: b |= ((uint64_t)in[2]) << 16; - case 2: b |= ((uint64_t)in[1]) << 8; - case 1: b |= ((uint64_t)in[0]); break; - case 0: break; + case 7: + b |= ((uint64_t)in[6]) << 48; + case 6: + b |= ((uint64_t)in[5]) << 40; + case 5: + b |= ((uint64_t)in[4]) << 32; + case 4: + b |= ((uint64_t)in[3]) << 24; + case 3: + b |= ((uint64_t)in[2]) << 16; + case 2: + b |= ((uint64_t)in[1]) << 8; + case 1: + b |= ((uint64_t)in[0]); + break; + case 0: + break; } v3 ^= b; - SIPROUND; SIPROUND; + SIPROUND; + SIPROUND; v0 ^= b; v2 ^= 0xff; - SIPROUND; SIPROUND; SIPROUND; SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; b = v0 ^ v1 ^ v2 ^ v3; uint64_t out = 0; - U64TO8_LE((uint8_t*)&out, b); + U64TO8_LE((uint8_t *)&out, b); return out; } @@ -530,86 +546,151 @@ static uint64_t SIP64(const uint8_t *in, const size_t inlen, // // Murmur3_86_128 //----------------------------------------------------------------------------- -static void MM86128(const void *key, const int len, uint32_t seed, void *out) { -#define ROTL32(x, r) ((x << r) | (x >> (32 - r))) -#define FMIX32(h) h^=h>>16; h*=0x85ebca6b; h^=h>>13; h*=0xc2b2ae35; h^=h>>16; - const uint8_t * data = (const uint8_t*)key; +static void MM86128(const void *key, const int len, uint32_t seed, void *out) +{ +#define ROTL32(x, r) ((x << r) | (x >> (32 - r))) +#define FMIX32(h) \ + h ^= h >> 16; \ + h *= 0x85ebca6b; \ + h ^= h >> 13; \ + h *= 0xc2b2ae35; \ + h ^= h >> 16; + const uint8_t *data = (const uint8_t *)key; const int nblocks = len / 16; uint32_t h1 = seed; uint32_t h2 = seed; uint32_t h3 = seed; uint32_t h4 = seed; - uint32_t c1 = 0x239b961b; + uint32_t c1 = 0x239b961b; uint32_t c2 = 0xab0e9789; - uint32_t c3 = 0x38b34ae5; + uint32_t c3 = 0x38b34ae5; uint32_t c4 = 0xa1e38b93; - const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); + const uint32_t *blocks = (const uint32_t *)(data + nblocks * 16); for (int i = -nblocks; i; i++) { - uint32_t k1 = blocks[i*4+0]; - uint32_t k2 = blocks[i*4+1]; - uint32_t k3 = blocks[i*4+2]; - uint32_t k4 = blocks[i*4+3]; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; - k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; - h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; - k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; - h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; - k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; - h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; + uint32_t k1 = blocks[i * 4 + 0]; + uint32_t k2 = blocks[i * 4 + 1]; + uint32_t k3 = blocks[i * 4 + 2]; + uint32_t k4 = blocks[i * 4 + 3]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + h1 = ROTL32(h1, 19); + h1 += h2; + h1 = h1 * 5 + 0x561ccd1b; + k2 *= c2; + k2 = ROTL32(k2, 16); + k2 *= c3; + h2 ^= k2; + h2 = ROTL32(h2, 17); + h2 += h3; + h2 = h2 * 5 + 0x0bcaa747; + k3 *= c3; + k3 = ROTL32(k3, 17); + k3 *= c4; + h3 ^= k3; + h3 = ROTL32(h3, 15); + h3 += h4; + h3 = h3 * 5 + 0x96cd1c35; + k4 *= c4; + k4 = ROTL32(k4, 18); + k4 *= c1; + h4 ^= k4; + h4 = ROTL32(h4, 13); + h4 += h1; + h4 = h4 * 5 + 0x32ac3b17; } - const uint8_t * tail = (const uint8_t*)(data + nblocks*16); + const uint8_t *tail = (const uint8_t *)(data + nblocks * 16); uint32_t k1 = 0; uint32_t k2 = 0; uint32_t k3 = 0; uint32_t k4 = 0; - switch(len & 15) { - case 15: k4 ^= tail[14] << 16; - case 14: k4 ^= tail[13] << 8; - case 13: k4 ^= tail[12] << 0; - k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; - case 12: k3 ^= tail[11] << 24; - case 11: k3 ^= tail[10] << 16; - case 10: k3 ^= tail[ 9] << 8; - case 9: k3 ^= tail[ 8] << 0; - k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; - case 8: k2 ^= tail[ 7] << 24; - case 7: k2 ^= tail[ 6] << 16; - case 6: k2 ^= tail[ 5] << 8; - case 5: k2 ^= tail[ 4] << 0; - k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; - case 4: k1 ^= tail[ 3] << 24; - case 3: k1 ^= tail[ 2] << 16; - case 2: k1 ^= tail[ 1] << 8; - case 1: k1 ^= tail[ 0] << 0; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; + switch (len & 15) { + case 15: + k4 ^= tail[14] << 16; + case 14: + k4 ^= tail[13] << 8; + case 13: + k4 ^= tail[12] << 0; + k4 *= c4; + k4 = ROTL32(k4, 18); + k4 *= c1; + h4 ^= k4; + case 12: + k3 ^= tail[11] << 24; + case 11: + k3 ^= tail[10] << 16; + case 10: + k3 ^= tail[9] << 8; + case 9: + k3 ^= tail[8] << 0; + k3 *= c3; + k3 = ROTL32(k3, 17); + k3 *= c4; + h3 ^= k3; + case 8: + k2 ^= tail[7] << 24; + case 7: + k2 ^= tail[6] << 16; + case 6: + k2 ^= tail[5] << 8; + case 5: + k2 ^= tail[4] << 0; + k2 *= c2; + k2 = ROTL32(k2, 16); + k2 *= c3; + h2 ^= k2; + case 4: + k1 ^= tail[3] << 24; + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0] << 0; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; }; - h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; - h1 += h2; h1 += h3; h1 += h4; - h2 += h1; h3 += h1; h4 += h1; - FMIX32(h1); FMIX32(h2); FMIX32(h3); FMIX32(h4); - h1 += h2; h1 += h3; h1 += h4; - h2 += h1; h3 += h1; h4 += h1; - ((uint32_t*)out)[0] = h1; - ((uint32_t*)out)[1] = h2; - ((uint32_t*)out)[2] = h3; - ((uint32_t*)out)[3] = h4; + h1 ^= len; + h2 ^= len; + h3 ^= len; + h4 ^= len; + h1 += h2; + h1 += h3; + h1 += h4; + h2 += h1; + h3 += h1; + h4 += h1; + FMIX32(h1); + FMIX32(h2); + FMIX32(h3); + FMIX32(h4); + h1 += h2; + h1 += h3; + h1 += h4; + h2 += h1; + h3 += h1; + h4 += h1; + ((uint32_t *)out)[0] = h1; + ((uint32_t *)out)[1] = h2; + ((uint32_t *)out)[2] = h3; + ((uint32_t *)out)[3] = h4; } // hashmap_sip returns a hash value for `data` using SipHash-2-4. -uint64_t hashmap_sip(const void *data, size_t len, - uint64_t seed0, uint64_t seed1) +uint64_t hashmap_sip(const void *data, size_t len, uint64_t seed0, uint64_t seed1) { - return SIP64((uint8_t*)data, len, seed0, seed1); + return SIP64((uint8_t *)data, len, seed0, seed1); } // hashmap_murmur returns a hash value for `data` using Murmur3_86_128. -uint64_t hashmap_murmur(const void *data, size_t len, - uint64_t seed0, uint64_t seed1) +uint64_t hashmap_murmur(const void *data, size_t len, uint64_t seed0, uint64_t seed1) { char out[16]; MM86128(data, len, seed0, &out); - return *(uint64_t*)out; + return *(uint64_t *)out; } //============================================================================== @@ -619,7 +700,8 @@ uint64_t hashmap_murmur(const void *data, size_t len, //============================================================================== #ifdef HASHMAP_TEST -static size_t deepcount(struct hashmap *map) { +static size_t deepcount(struct hashmap *map) +{ size_t count = 0; for (size_t i = 0; i < map->nbuckets; i++) { if (bucket_at(map, i)->dib) { @@ -629,43 +711,45 @@ static size_t deepcount(struct hashmap *map) { return count; } +# pragma GCC diagnostic ignored "-Wextra" -#pragma GCC diagnostic ignored "-Wextra" +# include "core/hashmap.h" - -#include -#include -#include -#include -#include -#include "hashmap.h" +# include +# include +# include +# include +# include static bool rand_alloc_fail = false; static int rand_alloc_fail_odds = 3; // 1 in 3 chance malloc will fail. static uintptr_t total_allocs = 0; static uintptr_t total_mem = 0; -static void *xmalloc(size_t size) { - if (rand_alloc_fail && rand()%rand_alloc_fail_odds == 0) { +static void *xmalloc(size_t size) +{ + if (rand_alloc_fail && rand() % rand_alloc_fail_odds == 0) { return NULL; } - void *mem = malloc(sizeof(uintptr_t)+size); + void *mem = malloc(sizeof(uintptr_t) + size); assert(mem); - *(uintptr_t*)mem = size; + *(uintptr_t *)mem = size; total_allocs++; total_mem += size; - return (char*)mem+sizeof(uintptr_t); + return (char *)mem + sizeof(uintptr_t); } -static void xfree(void *ptr) { +static void xfree(void *ptr) +{ if (ptr) { - total_mem -= *(uintptr_t*)((char*)ptr-sizeof(uintptr_t)); - free((char*)ptr-sizeof(uintptr_t)); + total_mem -= *(uintptr_t *)((char *)ptr - sizeof(uintptr_t)); + free((char *)ptr - sizeof(uintptr_t)); total_allocs--; } } -static void shuffle(void *array, size_t numels, size_t elsize) { +static void shuffle(void *array, size_t numels, size_t elsize) +{ char tmp[elsize]; char *arr = array; for (size_t i = 0; i < numels - 1; i++) { @@ -676,39 +760,47 @@ static void shuffle(void *array, size_t numels, size_t elsize) { } } -static bool iter_ints(const void *item, void *udata) { - int *vals = *(int**)udata; - vals[*(int*)item] = 1; +static bool iter_ints(const void *item, void *udata) +{ + int *vals = *(int **)udata; + vals[*(int *)item] = 1; return true; } -static int compare_ints(const void *a, const void *b) { - return *(int*)a - *(int*)b; +static int compare_ints(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; } -static int compare_ints_udata(const void *a, const void *b, void *udata) { - return *(int*)a - *(int*)b; +static int compare_ints_udata(const void *a, const void *b, void *udata) +{ + return *(int *)a - *(int *)b; } -static int compare_strs(const void *a, const void *b, void *udata) { - return strcmp(*(char**)a, *(char**)b); +static int compare_strs(const void *a, const void *b, void *udata) +{ + return strcmp(*(char **)a, *(char **)b); } -static uint64_t hash_int(const void *item, uint64_t seed0, uint64_t seed1) { +static uint64_t hash_int(const void *item, uint64_t seed0, uint64_t seed1) +{ return hashmap_murmur(item, sizeof(int), seed0, seed1); } -static uint64_t hash_str(const void *item, uint64_t seed0, uint64_t seed1) { - return hashmap_murmur(*(char**)item, strlen(*(char**)item), seed0, seed1); +static uint64_t hash_str(const void *item, uint64_t seed0, uint64_t seed1) +{ + return hashmap_murmur(*(char **)item, strlen(*(char **)item), seed0, seed1); } -static void free_str(void *item) { - xfree(*(char**)item); +static void free_str(void *item) +{ + xfree(*(char **)item); } -static void all() { - int seed = getenv("SEED")?atoi(getenv("SEED")):time(NULL); - int N = getenv("N")?atoi(getenv("N")):2000; +static void all() +{ + int seed = getenv("SEED") ? atoi(getenv("SEED")) : time(NULL); + int N = getenv("N") ? atoi(getenv("N")) : 2000; printf("seed=%d, count=%d, item_size=%zu\n", seed, N, sizeof(int)); srand(seed); @@ -719,15 +811,17 @@ static void all() { assert(hashmap_murmur("hello", 5, 1, 2) == 1682575153221130884); int *vals; - while (!(vals = xmalloc(N * sizeof(int)))) {} + while (!(vals = xmalloc(N * sizeof(int)))) { + } for (int i = 0; i < N; i++) { vals[i] = i; } struct hashmap *map; - while (!(map = hashmap_new(sizeof(int), 0, seed, seed, - hash_int, compare_ints_udata, NULL, NULL))) {} + while (!( + map = hashmap_new(sizeof(int), 0, seed, seed, hash_int, compare_ints_udata, NULL, NULL))) { + } shuffle(vals, N, sizeof(int)); for (int i = 0; i < N; i++) { // // printf("== %d ==\n", vals[i]); @@ -743,7 +837,7 @@ static void all() { break; } } - + for (int j = 0; j < i; j++) { v = hashmap_get(map, &vals[j]); assert(v && *v == vals[j]); @@ -766,21 +860,22 @@ static void all() { assert(!hashmap_get(map, &vals[i])); assert(!hashmap_delete(map, &vals[i])); assert(!hashmap_set(map, &vals[i])); - assert(map->count == i+1); + assert(map->count == i + 1); assert(map->count == hashmap_count(map)); assert(map->count == deepcount(map)); } int *vals2; - while (!(vals2 = xmalloc(N * sizeof(int)))) {} + while (!(vals2 = xmalloc(N * sizeof(int)))) { + } memset(vals2, 0, N * sizeof(int)); assert(hashmap_scan(map, iter_ints, &vals2)); // Test hashmap_iter. This does the same as hashmap_scan above. size_t iter = 0; void *iter_val; - while (hashmap_iter (map, &iter, &iter_val)) { - assert (iter_ints(iter_val, &vals2)); + while (hashmap_iter(map, &iter, &iter_val)) { + assert(iter_ints(iter_val, &vals2)); } for (int i = 0; i < N; i++) { assert(vals2[i] == 1); @@ -793,10 +888,10 @@ static void all() { v = hashmap_delete(map, &vals[i]); assert(v && *v == vals[i]); assert(!hashmap_get(map, &vals[i])); - assert(map->count == N-i-1); + assert(map->count == N - i - 1); assert(map->count == hashmap_count(map)); assert(map->count == deepcount(map)); - for (int j = N-1; j > i; j--) { + for (int j = N - 1; j > i; j--) { v = hashmap_get(map, &vals[j]); assert(v && *v == vals[j]); } @@ -817,7 +912,6 @@ static void all() { assert(prev_cap < map->cap); assert(map->count == 0); - for (int i = 0; i < N; i++) { while (true) { assert(!hashmap_set(map, &vals[i])); @@ -835,15 +929,17 @@ static void all() { xfree(vals); - - while (!(map = hashmap_new(sizeof(char*), 0, seed, seed, - hash_str, compare_strs, free_str, NULL))); + while ( + !(map = hashmap_new(sizeof(char *), 0, seed, seed, hash_str, compare_strs, free_str, NULL))) + ; for (int i = 0; i < N; i++) { char *str; - while (!(str = xmalloc(16))); + while (!(str = xmalloc(16))) + ; sprintf(str, "s%i", i); - while(!hashmap_set(map, &str)); + while (!hashmap_set(map, &str)) + ; } hashmap_clear(map, false); @@ -851,9 +947,11 @@ static void all() { for (int i = 0; i < N; i++) { char *str; - while (!(str = xmalloc(16))); + while (!(str = xmalloc(16))) + ; sprintf(str, "s%i", i); - while(!hashmap_set(map, &str)); + while (!hashmap_set(map, &str)) + ; } hashmap_free(map); @@ -864,46 +962,46 @@ static void all() { } } -#define bench(name, N, code) {{ \ - if (strlen(name) > 0) { \ - printf("%-14s ", name); \ - } \ - size_t tmem = total_mem; \ - size_t tallocs = total_allocs; \ - uint64_t bytes = 0; \ - clock_t begin = clock(); \ - for (int i = 0; i < N; i++) { \ - (code); \ - } \ - clock_t end = clock(); \ - double elapsed_secs = (double)(end - begin) / CLOCKS_PER_SEC; \ - double bytes_sec = (double)bytes/elapsed_secs; \ - printf("%d ops in %.3f secs, %.0f ns/op, %.0f op/sec", \ - N, elapsed_secs, \ - elapsed_secs/(double)N*1e9, \ - (double)N/elapsed_secs \ - ); \ - if (bytes > 0) { \ - printf(", %.1f GB/sec", bytes_sec/1024/1024/1024); \ - } \ - if (total_mem > tmem) { \ - size_t used_mem = total_mem-tmem; \ - printf(", %.2f bytes/op", (double)used_mem/N); \ - } \ - if (total_allocs > tallocs) { \ - size_t used_allocs = total_allocs-tallocs; \ - printf(", %.2f allocs/op", (double)used_allocs/N); \ - } \ - printf("\n"); \ -}} +# define bench(name, N, code) \ + { \ + { \ + if (strlen(name) > 0) { \ + printf("%-14s ", name); \ + } \ + size_t tmem = total_mem; \ + size_t tallocs = total_allocs; \ + uint64_t bytes = 0; \ + clock_t begin = clock(); \ + for (int i = 0; i < N; i++) { \ + (code); \ + } \ + clock_t end = clock(); \ + double elapsed_secs = (double)(end - begin) / CLOCKS_PER_SEC; \ + double bytes_sec = (double)bytes / elapsed_secs; \ + printf("%d ops in %.3f secs, %.0f ns/op, %.0f op/sec", N, elapsed_secs, \ + elapsed_secs / (double)N * 1e9, (double)N / elapsed_secs); \ + if (bytes > 0) { \ + printf(", %.1f GB/sec", bytes_sec / 1024 / 1024 / 1024); \ + } \ + if (total_mem > tmem) { \ + size_t used_mem = total_mem - tmem; \ + printf(", %.2f bytes/op", (double)used_mem / N); \ + } \ + if (total_allocs > tallocs) { \ + size_t used_allocs = total_allocs - tallocs; \ + printf(", %.2f allocs/op", (double)used_allocs / N); \ + } \ + printf("\n"); \ + } \ + } -static void benchmarks() { - int seed = getenv("SEED")?atoi(getenv("SEED")):time(NULL); - int N = getenv("N")?atoi(getenv("N")):5000000; +static void benchmarks() +{ + int seed = getenv("SEED") ? atoi(getenv("SEED")) : time(NULL); + int N = getenv("N") ? atoi(getenv("N")) : 5000000; printf("seed=%d, count=%d, item_size=%zu\n", seed, N, sizeof(int)); srand(seed); - int *vals = xmalloc(N * sizeof(int)); for (int i = 0; i < N; i++) { vals[i] = i; @@ -914,44 +1012,37 @@ static void benchmarks() { struct hashmap *map; shuffle(vals, N, sizeof(int)); - map = hashmap_new(sizeof(int), 0, seed, seed, hash_int, compare_ints_udata, - NULL, NULL); + map = hashmap_new(sizeof(int), 0, seed, seed, hash_int, compare_ints_udata, NULL, NULL); bench("set", N, { int *v = hashmap_set(map, &vals[i]); assert(!v); - }) - shuffle(vals, N, sizeof(int)); + }) shuffle(vals, N, sizeof(int)); bench("get", N, { int *v = hashmap_get(map, &vals[i]); assert(v && *v == vals[i]); - }) - shuffle(vals, N, sizeof(int)); + }) shuffle(vals, N, sizeof(int)); bench("delete", N, { int *v = hashmap_delete(map, &vals[i]); assert(v && *v == vals[i]); - }) - hashmap_free(map); + }) hashmap_free(map); - map = hashmap_new(sizeof(int), N, seed, seed, hash_int, compare_ints_udata, - NULL, NULL); + map = hashmap_new(sizeof(int), N, seed, seed, hash_int, compare_ints_udata, NULL, NULL); bench("set (cap)", N, { int *v = hashmap_set(map, &vals[i]); assert(!v); - }) - shuffle(vals, N, sizeof(int)); + }) shuffle(vals, N, sizeof(int)); bench("get (cap)", N, { int *v = hashmap_get(map, &vals[i]); assert(v && *v == vals[i]); - }) - shuffle(vals, N, sizeof(int)); - bench("delete (cap)" , N, { - int *v = hashmap_delete(map, &vals[i]); - assert(v && *v == vals[i]); - }) + }) shuffle(vals, N, sizeof(int)); + bench("delete (cap)", N, + { + int *v = hashmap_delete(map, &vals[i]); + assert(v && *v == vals[i]); + }) - hashmap_free(map); + hashmap_free(map); - xfree(vals); if (total_allocs != 0) { @@ -960,7 +1051,8 @@ static void benchmarks() { } } -int main() { +int main() +{ hashmap_set_allocator(xmalloc, xfree); if (getenv("BENCH")) { @@ -973,8 +1065,4 @@ int main() { } } - #endif - - - diff --git a/lib/vendor/ini.c b/lib/src/core/ini.c similarity index 78% rename from lib/vendor/ini.c rename to lib/src/core/ini.c index f8a3ea3..960a7a4 100644 --- a/lib/vendor/ini.c +++ b/lib/src/core/ini.c @@ -12,59 +12,60 @@ https://github.com/benhoyt/inih */ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS #endif -#include +#include "core/ini.h" + #include +#include #include -#include "ini.h" - #if !INI_USE_STACK -#if INI_CUSTOM_ALLOCATOR -#include -void* ini_malloc(size_t size); -void ini_free(void* ptr); -void* ini_realloc(void* ptr, size_t size); -#else -#include -#define ini_malloc malloc -#define ini_free free -#define ini_realloc realloc -#endif +# if INI_CUSTOM_ALLOCATOR +# include +void *ini_malloc(size_t size); +void ini_free(void *ptr); +void *ini_realloc(void *ptr, size_t size); +# else +# include +# define ini_malloc malloc +# define ini_free free +# define ini_realloc realloc +# endif #endif #define MAX_SECTION 50 -#define MAX_NAME 50 +#define MAX_NAME 50 /* Used by ini_parse_string() to keep track of string parsing state. */ -typedef struct { - const char* ptr; +typedef struct +{ + const char *ptr; size_t num_left; } ini_parse_string_ctx; /* Strip whitespace chars off end of given string, in place. Return s. */ -static char* rstrip(char* s) +static char *rstrip(char *s) { - char* p = s + strlen(s); + char *p = s + strlen(s); while (p > s && isspace((unsigned char)(*--p))) *p = '\0'; return s; } /* Return pointer to first non-whitespace char in given string. */ -static char* lskip(const char* s) +static char *lskip(const char *s) { while (*s && isspace((unsigned char)(*s))) s++; - return (char*)s; + return (char *)s; } /* Return pointer to first char (of chars) or inline comment in given string, or pointer to NUL at end of string if neither found. Inline comment must be prefixed by a whitespace character to register as a comment. */ -static char* find_chars_or_comment(const char* s, const char* chars) +static char *find_chars_or_comment(const char *s, const char *chars) { #if INI_ALLOW_INLINE_COMMENTS int was_space = 0; @@ -78,12 +79,12 @@ static char* find_chars_or_comment(const char* s, const char* chars) s++; } #endif - return (char*)s; + return (char *)s; } /* Similar to strncpy, but ensures dest (size bytes) is NUL-terminated, and doesn't pad with NULs. */ -static char* strncpy0(char* dest, const char* src, size_t size) +static char *strncpy0(char *dest, const char *src, size_t size) { /* Could use strncpy internally, but it causes gcc warnings (see issue #91) */ size_t i; @@ -94,42 +95,41 @@ static char* strncpy0(char* dest, const char* src, size_t size) } /* See documentation in header file. */ -int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, - void* user) +int ini_parse_stream(ini_reader reader, void *stream, ini_handler handler, void *user) { /* Uses a fair bit of stack (use heap instead if you need to) */ #if INI_USE_STACK char line[INI_MAX_LINE]; int max_line = INI_MAX_LINE; #else - char* line; + char *line; size_t max_line = INI_INITIAL_ALLOC; #endif #if INI_ALLOW_REALLOC && !INI_USE_STACK - char* new_line; + char *new_line; size_t offset; #endif char section[MAX_SECTION] = ""; char prev_name[MAX_NAME] = ""; - char* start; - char* end; - char* name; - char* value; + char *start; + char *end; + char *name; + char *value; int lineno = 0; int error = 0; #if !INI_USE_STACK - line = (char*)ini_malloc(INI_INITIAL_ALLOC); + line = (char *)ini_malloc(INI_INITIAL_ALLOC); if (!line) { return -2; } #endif #if INI_HANDLER_LINENO -#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno) +# define HANDLER(u, s, n, v) handler(u, s, n, v, lineno) #else -#define HANDLER(u, s, n, v) handler(u, s, n, v) +# define HANDLER(u, s, n, v) handler(u, s, n, v) #endif /* Scan through stream line by line */ @@ -158,9 +158,8 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, start = line; #if INI_ALLOW_BOM - if (lineno == 1 && (unsigned char)start[0] == 0xEF && - (unsigned char)start[1] == 0xBB && - (unsigned char)start[2] == 0xBF) { + if (lineno == 1 && (unsigned char)start[0] == 0xEF && (unsigned char)start[1] == 0xBB && + (unsigned char)start[2] == 0xBF) { start += 3; } #endif @@ -188,13 +187,11 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, if (!HANDLER(user, section, NULL, NULL) && !error) error = lineno; #endif - } - else if (!error) { + } else if (!error) { /* No ']' found on section line */ error = lineno; } - } - else if (*start) { + } else if (*start) { /* Not a comment, must be a name[=:]value pair */ end = find_chars_or_comment(start, "=:"); if (*end == '=' || *end == ':') { @@ -213,8 +210,7 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, strncpy0(prev_name, name, sizeof(prev_name)); if (!HANDLER(user, section, name, value) && !error) error = lineno; - } - else if (!error) { + } else if (!error) { /* No '=' or ':' found on name[=:]value line */ #if INI_ALLOW_NO_VALUE *end = '\0'; @@ -241,15 +237,15 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, } /* See documentation in header file. */ -int ini_parse_file(FILE* file, ini_handler handler, void* user) +int ini_parse_file(FILE *file, ini_handler handler, void *user) { return ini_parse_stream((ini_reader)fgets, file, handler, user); } /* See documentation in header file. */ -int ini_parse(const char* filename, ini_handler handler, void* user) +int ini_parse(const char *filename, ini_handler handler, void *user) { - FILE* file; + FILE *file; int error; file = fopen(filename, "r"); @@ -262,11 +258,12 @@ int ini_parse(const char* filename, ini_handler handler, void* user) /* An ini_reader function to read the next line from a string buffer. This is the fgets() equivalent used by ini_parse_string(). */ -static char* ini_reader_string(char* str, int num, void* stream) { - ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream; - const char* ctx_ptr = ctx->ptr; +static char *ini_reader_string(char *str, int num, void *stream) +{ + ini_parse_string_ctx *ctx = (ini_parse_string_ctx *)stream; + const char *ctx_ptr = ctx->ptr; size_t ctx_num_left = ctx->num_left; - char* strp = str; + char *strp = str; char c; if (ctx_num_left == 0 || num < 2) @@ -288,11 +285,11 @@ static char* ini_reader_string(char* str, int num, void* stream) { } /* See documentation in header file. */ -int ini_parse_string(const char* string, ini_handler handler, void* user) { +int ini_parse_string(const char *string, ini_handler handler, void *user) +{ ini_parse_string_ctx ctx; ctx.ptr = string; ctx.num_left = strlen(string); - return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler, - user); + return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler, user); } diff --git a/lib/src/core/lerror.c b/lib/src/core/lerror.c new file mode 100644 index 0000000..3ca7dfd --- /dev/null +++ b/lib/src/core/lerror.c @@ -0,0 +1,4 @@ +#include "core/lerror.h" + +jmp_buf eLaika_errStack[LAIKA_MAXERRORS]; +int eLaika_errIndx = -1; \ No newline at end of file diff --git a/lib/src/lmem.c b/lib/src/core/lmem.c similarity index 87% rename from lib/src/lmem.c rename to lib/src/core/lmem.c index c3747ff..1fe6daf 100644 --- a/lib/src/lmem.c +++ b/lib/src/core/lmem.c @@ -1,6 +1,6 @@ -#include "lmem.h" +#include "core/lmem.h" -#include "lerror.h" +#include "core/lerror.h" void *laikaM_realloc(void *buf, size_t sz) { diff --git a/lib/src/lsodium.c b/lib/src/core/lsodium.c similarity index 97% rename from lib/src/lsodium.c rename to lib/src/core/lsodium.c index 7c87eb3..088812b 100644 --- a/lib/src/lsodium.c +++ b/lib/src/core/lsodium.c @@ -1,4 +1,4 @@ -#include "lsodium.h" +#include "core/lsodium.h" #include diff --git a/lib/src/ltask.c b/lib/src/core/ltask.c similarity index 98% rename from lib/src/ltask.c rename to lib/src/core/ltask.c index 7bae2a4..3b79ad3 100644 --- a/lib/src/ltask.c +++ b/lib/src/core/ltask.c @@ -1,6 +1,6 @@ -#include "ltask.h" +#include "core/ltask.h" -#include "lmem.h" +#include "core/lmem.h" /* this is the only reason C11 support is needed, i cba to write windows/linux specific stuff to get the current time in ms also side note: microsoft? more like micropenis */ diff --git a/lib/src/core/lvm.c b/lib/src/core/lvm.c new file mode 100644 index 0000000..2cb3553 --- /dev/null +++ b/lib/src/core/lvm.c @@ -0,0 +1 @@ +#include "core/lvm.h" diff --git a/lib/src/lerror.c b/lib/src/lerror.c deleted file mode 100644 index 79c15bc..0000000 --- a/lib/src/lerror.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "lerror.h" - -jmp_buf eLaika_errStack[LAIKA_MAXERRORS]; -int eLaika_errIndx = -1; \ No newline at end of file diff --git a/lib/src/lvm.c b/lib/src/lvm.c deleted file mode 100644 index b8e21d8..0000000 --- a/lib/src/lvm.c +++ /dev/null @@ -1 +0,0 @@ -#include "lvm.h" diff --git a/lib/src/lpacket.c b/lib/src/net/lpacket.c similarity index 96% rename from lib/src/lpacket.c rename to lib/src/net/lpacket.c index 71e44fa..6cdf533 100644 --- a/lib/src/lpacket.c +++ b/lib/src/net/lpacket.c @@ -1,4 +1,4 @@ -#include "lpacket.h" +#include "net/lpacket.h" #ifdef DEBUG const char *laikaD_getPacketName(LAIKAPKT_ID id) diff --git a/lib/src/lpeer.c b/lib/src/net/lpeer.c similarity index 99% rename from lib/src/lpeer.c rename to lib/src/net/lpeer.c index 5044f7c..df622cd 100644 --- a/lib/src/lpeer.c +++ b/lib/src/net/lpeer.c @@ -1,7 +1,7 @@ -#include "lpeer.h" +#include "net/lpeer.h" -#include "lerror.h" -#include "lmem.h" +#include "core/lerror.h" +#include "core/lmem.h" struct sLaika_peer *laikaS_newPeer(struct sLaika_peerPacketInfo *pktTbl, struct sLaika_pollList *pList, pollFailEvent onPollFail, diff --git a/lib/src/lpolllist.c b/lib/src/net/lpolllist.c similarity index 99% rename from lib/src/lpolllist.c rename to lib/src/net/lpolllist.c index 5b8c3f2..b738afc 100644 --- a/lib/src/lpolllist.c +++ b/lib/src/net/lpolllist.c @@ -1,7 +1,7 @@ -#include "lpolllist.h" +#include "net/lpolllist.h" -#include "lerror.h" -#include "lmem.h" +#include "core/lerror.h" +#include "core/lmem.h" /* ===================================[[ Helper Functions ]]==================================== */ diff --git a/lib/src/lsocket.c b/lib/src/net/lsocket.c similarity index 98% rename from lib/src/lsocket.c rename to lib/src/net/lsocket.c index bee48d1..cf42ed0 100644 --- a/lib/src/lsocket.c +++ b/lib/src/net/lsocket.c @@ -1,10 +1,10 @@ -#include "lsocket.h" +#include "net/lsocket.h" -#include "lerror.h" -#include "lmem.h" -#include "lpacket.h" -#include "lpolllist.h" -#include "lsodium.h" +#include "core/lerror.h" +#include "core/lmem.h" +#include "core/lsodium.h" +#include "net/lpacket.h" +#include "net/lpolllist.h" static int _LNSetup = 0; diff --git a/shell/include/sclient.h b/shell/include/sclient.h index c20e354..ea32fbb 100644 --- a/shell/include/sclient.h +++ b/shell/include/sclient.h @@ -1,11 +1,11 @@ #ifndef SHELLCLIENT_H #define SHELLCLIENT_H -#include "hashmap.h" -#include "lmem.h" -#include "lpeer.h" -#include "lsodium.h" -#include "ltask.h" +#include "core/hashmap.h" +#include "core/lmem.h" +#include "core/lsodium.h" +#include "core/ltask.h" +#include "net/lpeer.h" #include "speer.h" typedef struct sShell_client diff --git a/shell/include/speer.h b/shell/include/speer.h index 8f58577..4f6ff02 100644 --- a/shell/include/speer.h +++ b/shell/include/speer.h @@ -1,8 +1,8 @@ #ifndef SHELLPEER_H #define SHELLPEER_H -#include "lpeer.h" -#include "lsodium.h" +#include "core/lsodium.h" +#include "net/lpeer.h" typedef struct sShell_peer { diff --git a/shell/src/main.c b/shell/src/main.c index 9ee9995..782646c 100644 --- a/shell/src/main.c +++ b/shell/src/main.c @@ -1,4 +1,4 @@ -#include "ini.h" +#include "core/ini.h" #include "sclient.h" #include "sterm.h" diff --git a/shell/src/sclient.c b/shell/src/sclient.c index 385d65c..c842f4a 100644 --- a/shell/src/sclient.c +++ b/shell/src/sclient.c @@ -1,9 +1,9 @@ #include "sclient.h" -#include "lerror.h" -#include "lmem.h" -#include "lpacket.h" -#include "lsodium.h" +#include "core/lerror.h" +#include "core/lmem.h" +#include "core/lsodium.h" +#include "net/lpacket.h" #include "sterm.h" void shell_pingTask(struct sLaika_taskService *service, struct sLaika_task *task, clock_t currTick, diff --git a/shell/src/scmd.c b/shell/src/scmd.c index 43d2c05..b1b0f71 100644 --- a/shell/src/scmd.c +++ b/shell/src/scmd.c @@ -1,7 +1,7 @@ #include "scmd.h" -#include "lerror.h" -#include "lmem.h" +#include "core/lerror.h" +#include "core/lmem.h" #include "sclient.h" #include "speer.h" #include "sterm.h" diff --git a/shell/src/speer.c b/shell/src/speer.c index bc4a3e2..ecd3b06 100644 --- a/shell/src/speer.c +++ b/shell/src/speer.c @@ -1,7 +1,7 @@ #include "speer.h" -#include "lmem.h" -#include "lpacket.h" +#include "core/lmem.h" +#include "net/lpacket.h" #include "sterm.h" tShell_peer *shellP_newPeer(PEERTYPE type, OSTYPE osType, uint8_t *pubKey, char *hostname, diff --git a/shell/src/sterm.c b/shell/src/sterm.c index 84c211a..a59a75b 100644 --- a/shell/src/sterm.c +++ b/shell/src/sterm.c @@ -1,6 +1,6 @@ #include "sterm.h" -#include "lmem.h" +#include "core/lmem.h" #include "scmd.h" #define KEY_ESCAPE 0x001b diff --git a/tools/genkey/src/main.c b/tools/genkey/src/main.c index 09c9607..8ab8730 100644 --- a/tools/genkey/src/main.c +++ b/tools/genkey/src/main.c @@ -1,5 +1,5 @@ -#include "lerror.h" -#include "lsodium.h" +#include "core/lerror.h" +#include "core/lsodium.h" #include #include diff --git a/tools/vmtest/src/main.c b/tools/vmtest/src/main.c index c5e3d18..2977712 100644 --- a/tools/vmtest/src/main.c +++ b/tools/vmtest/src/main.c @@ -1,5 +1,5 @@ -#include "lbox.h" -#include "lvm.h" +#include "core/lbox.h" +#include "core/lvm.h" #include #include