扩展库 / dotenv

dotenv

2026-10-29:补齐借用键/值回传、同对象文本重解析、自别名OOM和逐组存活分配/内存边界检查;新增C/XLang安全重载对照范例。两平台严格C、13个生成原型、全部旧边界与双语JIT/AOT通过。新顶层配置对象确认M2主线阻断:JIT退出0,独立EXE打印PASS后退出期报状态错误、退出1;默认门禁保留,当前不作完整发布签收。

解析 UTF-8 .env 文件,独立管理配置,并在需要时显式导入进程环境。

版本 1.0.0 · C / xlang · 无扩展库依赖

快速开始

import dotenv

auto config = dotenv.create()
config.parse("HOST=localhost\nPORT=8080\n")
println(config.get("HOST"))
config.set("PORT", "9090")
println(config.get("PORT"))

输出 localhost 与 9090。解析和设置不会自动修改进程环境;需要时调用 config.apply(overwrite = false)。

安全重载与所有权

examples/reload.xl 与 examples/reload_c.c 使用同一黄金输出:坏配置保留旧值,成功解析整体替换,已保存的文本跨修改和clear继续有效。C查询返回借用,需要跨修改保留时显式调用 xrtStrDup 并以 xrtFree 释放;XLang普通string结果独立持有内容,不能把原生借用结果标成owned。

C对照范例与XLang范例使用不同基名,不作为自动接入的同名C companion;门禁覆盖GCC、C直跑和两种语言的独立EXE,失败保留现场。

接口

入口用途
create()创建空的独立 Config;分配失败时抛错。
parse(text, maxBytes = 4194304)按真实字节长度解析 UTF-8 文本。
load(path, maxBytes = 4194304)从 UTF-8 路径加载文件。
config.parse(text, maxBytes = 4194304)在现有对象上整体替换配置;失败保留旧条目。
config.load(path, maxBytes = 4194304)从文件替换现有对象配置;失败保留旧条目。
get(key, defaultValue = "") / has(key)读取键或检查存在性;空值与不存在有区别。
set(key, value) / clear() / count修改或查看当前对象,不影响其他 Config。
apply(overwrite = false)显式写入进程环境;默认保留已有变量。
errorCode / errorLine / errorText()查询对象最近一次底层失败。

支持 BOM、LF/CRLF、行首 export、注释和单/双引号值;孤立 CR 报格式错误,双引号解析常见转义,不做变量插值。键名遵循 [A-Za-z_][A-Za-z0-9_]*,重复键采用最后一次赋值。键值由 XRT 有序映射保存,查询和解析无需逐项扫描;clear 释放条目及桶容量。create、parse、load 都会拒绝底层创建失败;解析失败不替换已有配置;apply 的多键进程环境修改不提供事务回滚。

配置文本中的 NUL 按真实长度拒绝;键、值和路径含内嵌 NUL 也会在进入 C 字符串接口前被拒绝。XLang 的 maxBytes 必须为正;C 的零限额只允许空输入,非空输入报 LIMIT 且不替换原配置。原生 *Native 成员仅供类内部调用,包外不能自行传入文本长度。文件操作使用 XRT 的 UTF-8 路径接口。C 操作成功后不会遗留上次失败的线程错误;apply 中的内存分配失败保留内存错误并在 xlang 抛 MemoryError。

C 对照

#include "xrt_dotenv.h"
#include <stdio.h>
#include <string.h>

int main(void)
{
    const char* source = "HOST=localhost\nPORT=8080\n";
    xrtdotenv* config = xrtDotenvCreate();
    if (config == NULL || !xrtDotenvParse(config, source, strlen(source), 4194304u)) {
        xrtDotenvDestroy(config);
        return 1;
    }
    puts(xrtDotenvGet(config, "HOST"));
    if (!xrtDotenvSet(config, "PORT", "9090")) {
        xrtDotenvDestroy(config);
        return 2;
    }
    puts(xrtDotenvGet(config, "PORT"));
    /* 读取的字符串借用自 config,修改或销毁后失效。 */
    xrtDotenvDestroy(config);
    return 0;
}

公共头为 extlibs/dotenv/include/xrt_dotenv.h。C 返回的字符串借用自 Config;xlang 返回的字符串独立持有。失败时使用 xrtDotenvErrorCode、xrtDotenvErrorLine 和 xrtDotenvErrorText。

验证状态

powershell -NoProfile -ExecutionPolicy Bypass -File release/extlibs/dotenv/test/check.ps1
bash release/extlibs/dotenv/test/check.sh

2026-10-26 使用现有 Windows 发布版 xl.exe 复验,完整默认门禁通过:严格 C 测试、C/xlang 范例、xlang 边界、中央用例、四组边界与公开范例独立 EXE,以及 C 范例通过 xl build 构建并与黄金输出对照。旧发布版的 xl6ValueDataSnapshotV1 缺符号阻断已解除。Linux 包级门禁通过 C ASan/UBSan、XLang JIT、中央与四个边界程序的独立 EXE AOT、公开范例 AOT,以及 C/JIT/AOT 范例黄金输出对照。解析输入先检查字节限额,再扫描内容;分配失败矩阵验证旧配置保留、环境不变和同对象恢复。合法多行配置的截断与逐字节变异矩阵属于定向边界测试,不是完整 fuzz。双语文件范例使用独占临时目录并清理,不覆盖现有文件,C 范例可直接通过 xl run 运行。更新后的工作树重建发布版仍被主线 XRT/xlang capability matrix is stale 快照校验阻断;本页只签收现有发布版上的 dotenv 包级门禁,不等同于整个 xlang 发布版签收。