From 8fa142e7633e5e0ed9d36cd1d2d907f3ac89a91a Mon Sep 17 00:00:00 2001 From: hanez Date: Sun, 30 Nov 2025 03:33:18 +0100 Subject: [PATCH] Some more .ini Fun. (0.34.1) --- CMakeLists.txt | 2 +- examples/data/complex.ini | 2 +- examples/ini_class_demo.fun | 46 ++++++++++++++++++ lib/io/ini.fun | 96 +++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 examples/ini_class_demo.fun create mode 100644 lib/io/ini.fun diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c6c921..319605a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.34.0 LANGUAGES C) +project(fun VERSION 0.34.1 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/examples/data/complex.ini b/examples/data/complex.ini index 512fbc5..18084af 100644 --- a/examples/data/complex.ini +++ b/examples/data/complex.ini @@ -2,7 +2,7 @@ [app] name = "FunApp" version = "1.2.3" -debug = "true" +debug = "1" [database] diff --git a/examples/ini_class_demo.fun b/examples/ini_class_demo.fun new file mode 100644 index 0000000..90e6598 --- /dev/null +++ b/examples/ini_class_demo.fun @@ -0,0 +1,46 @@ +#!/usr/bin/env fun + +/* + * 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 + * + * Added: 2025-11-30 + */ + +// Demonstration of the Ini stdlib class from lib/io/ini.fun +include + +ini = INI() +path = "./examples/data/complex.ini" + +if (ini.load(path) == 0) + print("Failed to load " + path) + exit(1) + +// Read a few values +app_name = ini.get_string("app", "name", "FunApp") +app_version = ini.get_string("app", "version", "0.0.0") +app_debug = ini.get_bool("app", "debug", 0) + +db_host = ini.get_string("database", "host", "localhost") +db_port = ini.get_int("database", "port", 5432) + +print("[app]") +print(" name=" + app_name) +print(" version=" + app_version) +print(" debug=" + to_string(app_debug)) + +print("[database]") +print(" host=" + db_host) +print(" port=" + to_string(db_port)) + +// Update a value and save back to the same file +ini.set("app", "debug", 1) +ok = ini.save(nil) +print("saved=" + to_string(ok)) + +ini.close() diff --git a/lib/io/ini.fun b/lib/io/ini.fun new file mode 100644 index 0000000..b6145e5 --- /dev/null +++ b/lib/io/ini.fun @@ -0,0 +1,96 @@ +/* + * 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 + * + * Added: 2025-11-30 + */ + +// INI stdlib abstraction wrapping the ini_* VM builtins (iniparser 4.2.6). +// +// Usage: +// include +// ini = INI() +// if (ini.load("./examples/data/complex.ini") > 0) +// name = ini.get_string("app", "name", "") +// retries = ini.get_int("network", "retries", 0) +// ini.set("app", "debug", 1) +// ini.save(nil) // save back to original path +// ini.close() + +class INI() + // current handle (>0 when open) and path string + h = 0 + path = "" + + // Load an INI file from path, closing previous one if open. + // Returns handle (>0) or 0 on error. + fun load(this, path) + if (this.h > 0) + ini_free(this.h) + this.h = 0 + p = to_string(path) + this.path = p + this.h = ini_load(p) + return this.h + + // True if a dictionary is open. + fun is_open(this) + return this.h > 0 + + // Close and free resources. Safe to call multiple times. + fun close(this) + if (this.h > 0) + ini_free(this.h) + this.h = 0 + return 1 + + // Getters with defaults. When not open, return the default converted. + fun get_string(this, section, key, def) + if (!this.is_open()) + return to_string(def) + return ini_get_string(this.h, to_string(section), to_string(key), to_string(def)) + + fun get_int(this, section, key, def) + if (!this.is_open()) + return to_number(def) + return ini_get_int(this.h, to_string(section), to_string(key), to_number(def)) + + fun get_double(this, section, key, def) + if (!this.is_open()) + return to_number(def) + return ini_get_double(this.h, to_string(section), to_string(key), to_number(def)) + + fun get_bool(this, section, key, def) + if (!this.is_open()) + if (def == nil) + return 0 + // treat 0/1 and boolean-like strings + return to_number(def) != 0 + return ini_get_bool(this.h, to_string(section), to_string(key), to_number(def)) + + // Set/unset return 1 on success, 0 on failure. + fun set(this, section, key, value) + if (!this.is_open()) + return 0 + return ini_set(this.h, to_string(section), to_string(key), to_string(value)) + + fun unset(this, section, key) + if (!this.is_open()) + return 0 + return ini_unset(this.h, to_string(section), to_string(key)) + + // Save to a path. If path is nil, save to the last loaded path. + fun save(this, path) + if (!this.is_open()) + return 0 + p = path + if (p == nil) + p = this.path + p = to_string(p) + if (len(p) == 0) + return 0 + return ini_save(this.h, p)