diff --git a/.gitignore b/.gitignore index ae65a0b..cf923d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ CMakeCache.txt +Doxygen.in .* !.clang-format !.clang-tidy diff --git a/CMakeLists.txt b/CMakeLists.txt index 11e066b..c7850dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.41.5 LANGUAGES C) +project(fun VERSION 0.41.6 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/Doxyfile b/Doxyfile index 83f0053..cc4e508 100644 --- a/Doxyfile +++ b/Doxyfile @@ -42,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = Fun +PROJECT_NAME = "Fun API Documentation" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -1130,7 +1130,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which Doxygen is # run. -EXCLUDE = +EXCLUDE = src/vm/ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/src/extensions/ini.c b/src/extensions/ini.c index f86252c..98d4483 100644 --- a/src/extensions/ini.c +++ b/src/extensions/ini.c @@ -30,5 +30,75 @@ #include #include #endif -#include "vm/ini/handles.h" -#endif +#include +#include +#include +#include + +/** + * @brief One slot in the global INI handle registry. + * @details Associates an iniparser dictionary pointer with an in-use flag. + */ +typedef struct { + dictionary *dict; + int in_use; +} IniSlot; + +IniSlot g_ini[64]; + +/** + * @brief Allocate a registry handle for a newly created dictionary. + * @param d Pointer to an iniparser dictionary. + * @return Handle id (>0) on success or 0 on failure. + */ +int ini_alloc_handle(dictionary *d) { + if (!d) return 0; + for (int i = 1; i < (int)(sizeof(g_ini) / sizeof(g_ini[0])); ++i) { + if (!g_ini[i].in_use) { + g_ini[i].in_use = 1; + g_ini[i].dict = d; + return i; + } + } + return 0; +} + +/** + * @brief Look up a dictionary pointer by registry handle. + * @param h Handle id previously returned by ini_alloc_handle(). + * @return Pointer to dictionary or NULL if not found. + */ +dictionary *ini_get(int h) { + if (h > 0 && h < (int)(sizeof(g_ini) / sizeof(g_ini[0])) && g_ini[h].in_use) return g_ini[h].dict; + return NULL; +} + +/** + * @brief Free a previously allocated handle and close its dictionary. + * @param h Handle id to free. + * @return 1 on success, 0 on error (invalid handle or not in use). + */ +int ini_free_handle(int h) { + if (h <= 0 || h >= (int)(sizeof(g_ini) / sizeof(g_ini[0])) || !g_ini[h].in_use) return 0; + if (g_ini[h].dict) iniparser_freedict(g_ini[h].dict); + g_ini[h].dict = NULL; + g_ini[h].in_use = 0; + return 1; +} + +/** + * @brief Build a fully qualified key "section:key" into a caller-provided buffer. + * @param buf Destination buffer. + * @param cap Capacity of buf in bytes (including terminator). + * @param sec Section name (may be NULL for default section). + * @param key Key name (must not be NULL). + */ +void ini_make_full_key(char *buf, size_t cap, const char *sec, const char *key) { + if (!buf || cap == 0) return; + if (!sec) sec = ""; + if (!key) key = ""; + /* iniparser expects section:key; lookup is case-insensitive internally */ + snprintf(buf, cap, "%s:%s", sec, key); +} + +#endif /* FUN_WITH_INI */ diff --git a/src/extensions/json.c b/src/extensions/json.c index 6e812fb..29b4832 100644 --- a/src/extensions/json.c +++ b/src/extensions/json.c @@ -16,16 +16,13 @@ * This unit may be included or compiled conditionally based on build flags. */ -/* json-c helpers and VM opcode cases (included from vm.c) */ - #ifdef FUN_WITH_JSON -#include "value.h" -#include "vm.h" +//#include "value.h" +//#include "vm.h" #include -#include +//#include -/* --- Conversion helpers between json-c and Fun Value --- */ /** * @brief Convert a json-c object into a Fun Value. * diff --git a/src/fun.c b/src/fun.c index 5bd2e17..127af48 100644 --- a/src/fun.c +++ b/src/fun.c @@ -19,7 +19,6 @@ #include "bytecode.h" #include "parser.h" #include "vm.h" -#include #include #include #include diff --git a/src/vm.c b/src/vm.c index 1893f26..4827948 100644 --- a/src/vm.c +++ b/src/vm.c @@ -63,17 +63,9 @@ #include "value.h" #include "vm.h" -/* Notcurses support removed */ - // Optional by extensions commonly used code. #ifdef's are in each single file. #include "extensions/curl.c" #include "extensions/ini.c" -#ifdef FUN_WITH_INI -/* Central INI handle registry and helpers */ -#include "vm/ini/handles.c" -#endif -/* Note: INI opcode handlers are included below; changes in vm/ini/ .c files - * require vm.c to rebuild. */ #include "extensions/json.c" #include "extensions/openssl.c" #include "extensions/pcre2.c" @@ -1105,11 +1097,6 @@ void vm_run(VM *vm, Bytecode *entry) { #include "vm/openssl/sha512.c" #endif - -/* Tcl/Tk support removed */ - -/* Notcurses TUI ops removed */ - /* SQLite ops */ #ifdef FUN_WITH_SQLITE #include "vm/sqlite/close.c" @@ -1119,7 +1106,7 @@ void vm_run(VM *vm, Bytecode *entry) { #endif /* C++ demo opcodes (guarded) */ -#if defined(FUN_WITH_CPP) +#ifdef FUN_WITH_CPP case OP_CPP_ADD: { int rc = fun_op_cpp_add(vm); if (rc != 0) { @@ -1134,8 +1121,6 @@ void vm_run(VM *vm, Bytecode *entry) { } #endif -/* libsql support removed */ - /* PCRE2 ops */ #ifdef FUN_WITH_PCRE2 #include "vm/pcre2/findall.c" diff --git a/src/vm/ini/handles.c b/src/vm/ini/handles.c deleted file mode 100644 index 4039506..0000000 --- a/src/vm/ini/handles.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the Fun programming language. - * https://fun-lang.xyz/ - * - * Copyright 2025 Johannes Findeisen - * Licensed under the terms of the Apache-2.0 license. - * https://opensource.org/license/apache-2-0 - */ - -/** - * @file handles.c - * @brief INI handle registry implementation used by VM INI opcodes. - * - * Provides a tiny fixed-size registry mapping small integer handles to - * iniparser dictionary pointers. Not thread-safe. Handles are positive - * integers in range [1, 63]. - */ - -#ifdef FUN_WITH_INI -#if defined(__has_include) -#if __has_include() -#include -#include -#elif __has_include() -#include -#include -#else -#error "iniparser headers not found" -#endif -#else -#include -#include -#endif - -#include -#include -#include - -#include "handles.h" - -IniSlot g_ini[64]; - -int ini_alloc_handle(dictionary *d) { - if (!d) return 0; - for (int i = 1; i < (int)(sizeof(g_ini) / sizeof(g_ini[0])); ++i) { - if (!g_ini[i].in_use) { - g_ini[i].in_use = 1; - g_ini[i].dict = d; - return i; - } - } - return 0; -} - -dictionary *ini_get(int h) { - if (h > 0 && h < (int)(sizeof(g_ini) / sizeof(g_ini[0])) && g_ini[h].in_use) return g_ini[h].dict; - return NULL; -} - -int ini_free_handle(int h) { - if (h <= 0 || h >= (int)(sizeof(g_ini) / sizeof(g_ini[0])) || !g_ini[h].in_use) return 0; - if (g_ini[h].dict) iniparser_freedict(g_ini[h].dict); - g_ini[h].dict = NULL; - g_ini[h].in_use = 0; - return 1; -} - -void ini_make_full_key(char *buf, size_t cap, const char *sec, const char *key) { - if (!buf || cap == 0) return; - if (!sec) sec = ""; - if (!key) key = ""; - /* iniparser expects section:key; lookup is case-insensitive internally */ - snprintf(buf, cap, "%s:%s", sec, key); -} - -#endif /* FUN_WITH_INI */ diff --git a/src/vm/ini/handles.h b/src/vm/ini/handles.h deleted file mode 100644 index 72d1d5d..0000000 --- a/src/vm/ini/handles.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of the Fun programming language. - * https://fun-lang.xyz/ - * - * Copyright 2025 Johannes Findeisen - * Licensed under the terms of the Apache-2.0 license. - * https://opensource.org/license/apache-2-0 - */ - -/** - * @file handles.h - * @brief INI handle registry for iniparser 4.2.6 used by INI VM opcodes. - */ - -#pragma once - -#ifdef FUN_WITH_INI -#if defined(__has_include) -#if __has_include() -#include -#include -#elif __has_include() -#include -#include -#else -#error "iniparser headers not found" -#endif -#else -#include -#include -#endif -#include - -/** - * @brief One slot in the global INI handle registry. - * @details Associates an iniparser dictionary pointer with an in-use flag. - */ -typedef struct { - dictionary *dict; - int in_use; -} IniSlot; - -/** Single global registry (defined in handles.c). */ -extern IniSlot g_ini[64]; - -/** - * @brief Allocate a registry handle for a newly created dictionary. - * @param d Pointer to an iniparser dictionary. - * @return Handle id (>0) on success or 0 on failure. - */ -int ini_alloc_handle(dictionary *d); -/** - * @brief Look up a dictionary pointer by registry handle. - * @param h Handle id previously returned by ini_alloc_handle(). - * @return Pointer to dictionary or NULL if not found. - */ -dictionary *ini_get(int h); -/** - * @brief Free a previously allocated handle and close its dictionary. - * @param h Handle id to free. - * @return 1 on success, 0 on error (invalid handle or not in use). - */ -int ini_free_handle(int h); - -/** - * @brief Build a fully qualified key "section:key" into a caller-provided buffer. - * @param buf Destination buffer. - * @param cap Capacity of buf in bytes (including terminator). - * @param sec Section name (may be NULL for default section). - * @param key Key name (must not be NULL). - */ -void ini_make_full_key(char *buf, size_t cap, const char *sec, const char *key); -#endif /* FUN_WITH_INI */