Help us shape the future of Go! Take the 2026 Go Developer Survey

kconfig

package module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

README

kconfig-go

Go Reference

English | 中文

纯 Go 标准库实现的 Linux Kconfig 解析、渲染和值处理库,可方便地使用任何前端实现 make menuconfig,并附带安全限制。

kconfig-go 读取 Kconfig 工程,支持基于文件或自定义输入解析项目树,计算配置项之间的关系,并生成菜单数据;可修改配置值并收敛修改后的可见性、默认值状态等。你可以把它用于 Web、桌面程序或其他配置界面。同时可生成 Linux .config 文件和整理后的 Kconfig 树。

这个库不提供界面。它只负责根据项目树和写入的配置信息解析、校验、收敛和生成数据。如果需要界面,可以参考 kconfig-ui。

特性

  • 支持常用的 Kconfig 结构:mainmenu、menu、config、menuconfig、choice、if 和 comment。
  • 支持 source、rsource、osource 和 orsource,检测包含循环,并将访问的文件限制在指定的项目根目录下,避免越权访问其他文件。
  • 支持 bool、tristate、string、int、hex,以及 default、range、select、imply 等常用规则。
  • 根据依赖、默认值和 choice 规则计算有效配置。无效输入会回退到可用值并返回详细的错误信息。
  • 提供静态 Schema 和当前状态下的 FrontendTree,指示当前项目的可见性,方便 UI 显示和导航。
  • 提供 Validate、Resolve、Apply、Render、OpenScreen、WriteConfig 和 WriteKconfig。
  • 支持写出 .config 用于 make,默认进行安全检查,避免内容被后续的 Make 或 shell 当成命令,可显式地关闭检查。

安装

go get github.com/Kirizu-Official/kconfig-go

快速开始

下面的例子加载 Kconfig,选择目标架构,修改一个配置项,然后写出 .config:

package main

import (
    "context"
    "errors"
    "fmt"
    "io/fs"

    kconfig "github.com/Kirizu-Official/kconfig-go"
)

func main() {
    project, diagnostics, err := kconfig.Load(context.Background(), "Kconfig", kconfig.LoadOptions{
        Root: "/work/firmware",
        Variables: map[string]string{
            "ARCH": "arm",
        },
    })
    if err != nil {
        panic(err)
    }
    if diagnostics.HasErrors() {
        for _, diagnostic := range diagnostics {
            if errors.Is(diagnostic, kconfig.ErrSourceRead) {
                var pathError *fs.PathError
                if errors.As(diagnostic, &pathError) {
                    fmt.Printf("读取 %s 失败:%v\n", pathError.Path, pathError.Err)
                }
            }
        }
        panic(diagnostics.Error())
    }

    resolved := project.Resolve(kconfig.FrontendInput{Values: map[string]any{
        "MACH_STM32":     true,
        "MACH_STM32F103": true,
    }})

    resolved = project.Apply(resolved.State, kconfig.FrontendInput{Values: map[string]any{
        "FLASH_SIZE": "0x20000",
    }})

    configText, err := kconfig.WriteConfig(resolved.State)
    if err != nil {
        panic(err)
    }
    fmt.Print(configText)
}

常用流程

flowchart LR
    A["Kconfig 文件"] --> B["Load"]
    B --> C["Project"]
    C --> D["Schema"]
    C --> E["Resolve / Apply"]
    E --> F["ConfigState"]
    E --> G["FrontendTree"]
    F --> H["WriteConfig"]
    C --> I["WriteKconfig"]
1. 加载:Load

Load(ctx, entry, LoadOptions) 读取入口文件和它包含的文件,然后返回 Project、Diagnostics 和 error。

  • LoadOptions.Root 是文件读取的根目录,包含文件不会在这个目录的上一级。
  • 不传 Loader 时,库使用 FSLoader 读取本地文件;需要读取嵌入文件、数据库或虚拟文件系统时,实现 SourceLoader 即可。
  • Variables 只做字面量替换:支持 $(NAME) 和 ${NAME}。不会自动读取环境变量,也不会把变量值当成命令执行。未定义变量和不支持的宏会返回带源码位置的诊断。
  • Macros(MacroOptions)用于显式启用函数式宏。零值保持安全:拒绝所有函数式宏,不执行任何宿主代码。
  • 加载成功后,一个 Project 可以被多个请求同时用于 Resolve。
Load 宏

宏只在包含路径和带引号的 Kconfig 字符串中展开,注释和表达式不会展开。

形式 启用方式 行为
$(NAME) / ${NAME} Variables 字面量文本替换
$(env,NAME) Macros.Environment 允许名单 读取名单中的宿主环境变量
$(shell,command) Macros.Shell = true 在 Root 下执行 shell 命令
$(python,script) Macros.Python = true 在 Root 下执行 Python 脚本
$(macro,arg1,arg2) 非 nil 的 Macros.Macro 调用自定义回调

默认执行器:Windows 使用 cmd.exe /C,其他平台使用 /bin/sh -c;Python 使用 python -c。可用 ShellCommand / PythonCommand 覆盖可执行文件和固定参数前缀。启用的 shell / Python / 自定义宏继承当前进程环境;CommandTimeout 为零时默认 30 秒,调用方 context 更早的截止时间优先生效。

project, diagnostics, err := kconfig.Load(ctx, "Kconfig", kconfig.LoadOptions{
    Root: "/work/firmware",
    Variables: map[string]string{
        "ARCH": "arm",
    },
    Macros: kconfig.MacroOptions{
        Environment: []string{"BOARD"},
        Shell:       true,
        Python:      true,
        Macro: func(_ context.Context, args []string) (string, error) {
            if len(args) == 0 {
                return "custom", nil
            }
            return args[0], nil
        },
    },
})

安全边界: 启用 shell、Python 或自定义宏意味着加载时可以执行宿主代码。不要把不可信输入拼进环境变量名、shell 命令、Python 源码或回调参数;即便做过校验和转义,执行仍有风险。超时对命令解释器再拉起的子进程只能尽力约束。

错误怎么处理

库有两种错误信息:

  • 普通 Go error:用于 Load、JSON 读写和 writer 的失败。
  • Diagnostics:用于能定位到 Kconfig 文件位置的问题。

显示错误时使用 Message 和 Span。代码分支请使用 ErrorCode 或 errors.Is,不要匹配错误文字。

常用字段和方法:

  • Diagnostic.Code:错误类别。
  • Diagnostic.Span:出错的文件和位置。
  • Diagnostic.Cause:底层错误,例如文件读取失败。
  • errors.Is(err, kconfig.ErrSourceRead):判断错误类别。
  • errors.As(err, &pathError):取出底层错误。
2. 静态目录:Project.Schema

Schema 是配置项、菜单和屏幕的固定说明。它适合建立表单或按 ID 查找内容,但不能用来判断当前是否显示或可修改。

字段 用途
Node.ID 菜单入口的 ID。同一配置项可以有多个菜单入口。
Node.SymbolID 配置项的 ID。提交值时用它作 key。
Screen.ID 菜单屏幕的 ID。传给 OpenScreen。
3. 配置:Resolve 和 Apply

Resolve 从头计算配置。Apply 以已有 ConfigState 为基础,只合并本次修改,然后重新计算。

类型 提交给 FrontendInput.Values / Validate 的值 示例
bool Go / JSON bool true
tristate 字符串 "n"、"m"、"y"
string 字符串 "example string data"
int 整数;也接受 JSON 解码后的整数 float64 和 json.Number 250000
hex 十六进制字符串 "0x20000"

类型不对、数值不是整数或十六进制格式不正确时,Resolve 和 Apply 会使用当前可用的默认值或空值,并在 Changes 和 Diagnostics 中说明。Validate 只返回建议值,不会改动状态。

Resolution 包含:

  • State:当前配置值。
  • Tree:完整的动态菜单树。
  • Changes:每个输入是接受、调整、回退还是忽略。
  • Diagnostics:输入和计算过程中的提示。

每次调用 Apply 后,配置项变化可能会显示或隐藏菜单和条目,可用返回的完整 Tree 刷新界面。

4. 显示、导航和校验
// 默认不返回隐藏条目,如果出于调试需求可指定 `IncludeHidden: true` 显示。
tree := project.Render(state, kconfig.RenderOptions{IncludeHidden: true})

// 旧的或已隐藏的屏幕会回退到最近可见的父级,或根屏幕。
screen := project.OpenScreen(state, tree.RootScreenID, kconfig.RenderOptions{})

// Validate 不会改动 state,可用于输入框的即时提示。
result := project.Validate(state, "FLASH_SIZE", "0x20000")
_ = screen
_ = result

Node.Visible 表示是否显示,Node.Enabled 表示现在能否修改。两者都由当前状态决定。Constraints 提供范围、可选值和 choice 选项;StateReason 说明隐藏、禁用或回退的原因。

5. 写出配置
configText, err := kconfig.WriteConfig(state)
kconfigText, err := kconfig.WriteKconfig(project)
  • WriteConfig 按 symbol 名排序。关闭的 bool 和 tristate 使用 Linux 常见写法:# CONFIG_FOO is not set。

  • WriteConfig 默认使用限制模式。它拒绝字符串中的 $、反引号、# 和控制字符,也拒绝不安全的 symbol 名。这样可以避免 Make 展开、shell 命令替换和 .config 被截断或改写。

  • 遇到不安全内容时,WriteConfig 不返回输出。可用 errors.Is(err, kconfig.ErrUnsafeConfigOutput) 判断。

  • 只有在所有 Kconfig 声明和配置值都可信时,才使用信任模式。它只跳过这项安全检查,仍会排序和转义字符串:

    configText, err := kconfig.WriteConfigWithOptions(state, kconfig.WriteConfigOptions{
        TrustInput: true,
    })
    
  • WriteKconfig 写出整理后的 Kconfig 树文本,指示当前配置加载了哪些Kconfig文件。不会保留原文件的空行、注释位置、属性顺序或缩进。

值和 JSON

Value 是库内部使用的带类型值,提交配置时会自动根据输入值类型进行解析。

读取 Node.Value、Constraints 或 ValidationResult.Normalized 时,库会保留类型:bool 是 JSON 布尔值,tristate 是 "n" / "m" / "y",string 是 JSON 字符串,int 是 JSON 数字,hex 是十六进制字符串。

如果单独读取 JSON 到 Value,请先用 ZeroValue(type) 设置类型。

源码模块

文件 作用
project.go、source.go 加载文件、处理根目录、变量、宏和包含关系。
parser.go、ast.go、token.go、expr.go 读取 Kconfig 语法和表达式。
index.go、schema.go 建立配置项、菜单和屏幕目录。
value.go、resolve.go、relations.go 处理值、默认值、依赖和 choice。
render.go、validate.go 生成菜单并校验单个输入。
writer.go 写出 Kconfig 和 .config。
test/ 公共 API、加载、安全、计算、显示和写出的测试。

开发与验证

go test ./...
go vet ./...

注意

  • 默认情况下,库不会执行 shell、Make、Python 或其他外部命令。只有在 LoadOptions.Macros 中显式启用后,才会在加载时运行对应宏;启用后会继承宿主环境,调用方必须自行校验输入。
  • 库不提供 UI、路由或导航历史。这些由调用方实现。
  • 库不是保留原文件格式的编辑器;写出的内容是整理后的结果。
  • Schema 只描述有哪些声明。当前是否可见、可否编辑以及动态约束,请看 FrontendTree。

贡献

欢迎提交 Issue 和 Pull Request。提交PR前请至少运行 go test ./... 和 go vet ./...,并补充相关测试。

许可证

本项目基于 Apache License 2.0 发布。

本项目使用 Vibe Coding 开发,可能仍有错误或安全风险。使用前请自行评估,避免不必要的损失。项目作者和 AI 服务提供方不对使用结果负责。

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidDirective      error = errorCodeSentinel{ErrorCodeInvalidDirective}
	ErrInvalidBlock          error = errorCodeSentinel{ErrorCodeInvalidBlock}
	ErrUnsupportedDirective  error = errorCodeSentinel{ErrorCodeUnsupportedDirective}
	ErrInvalidExpression     error = errorCodeSentinel{ErrorCodeInvalidExpression}
	ErrInvalidRange          error = errorCodeSentinel{ErrorCodeInvalidRange}
	ErrDefaultTypeMismatch   error = errorCodeSentinel{ErrorCodeDefaultTypeMismatch}
	ErrInvalidValue          error = errorCodeSentinel{ErrorCodeInvalidValue}
	ErrInvalidJSONValue      error = errorCodeSentinel{ErrorCodeInvalidJSONValue}
	ErrUnknownValueType      error = errorCodeSentinel{ErrorCodeUnknownValueType}
	ErrRootPath              error = errorCodeSentinel{ErrorCodeRootPath}
	ErrIncludeEscape         error = errorCodeSentinel{ErrorCodeIncludeEscape}
	ErrIncludeCycle          error = errorCodeSentinel{ErrorCodeIncludeCycle}
	ErrSourceRead            error = errorCodeSentinel{ErrorCodeSourceRead}
	ErrUnresolvedVariable    error = errorCodeSentinel{ErrorCodeUnresolvedVariable}
	ErrShellMacro            error = errorCodeSentinel{ErrorCodeShellMacro}
	ErrEnvironmentMacro      error = errorCodeSentinel{ErrorCodeEnvironmentMacro}
	ErrPythonMacro           error = errorCodeSentinel{ErrorCodePythonMacro}
	ErrCustomMacro           error = errorCodeSentinel{ErrorCodeCustomMacro}
	ErrMacroExecution        error = errorCodeSentinel{ErrorCodeMacroExecution}
	ErrMacroSyntax           error = errorCodeSentinel{ErrorCodeMacroSyntax}
	ErrUnsupportedMacro      error = errorCodeSentinel{ErrorCodeUnsupportedMacro}
	ErrIncompatibleSymbol    error = errorCodeSentinel{ErrorCodeIncompatibleSymbol}
	ErrUndeclaredSymbol      error = errorCodeSentinel{ErrorCodeUndeclaredSymbol}
	ErrUninitializedProject  error = errorCodeSentinel{ErrorCodeUninitializedProject}
	ErrUnknownSymbol         error = errorCodeSentinel{ErrorCodeUnknownSymbol}
	ErrResolutionConvergence error = errorCodeSentinel{ErrorCodeResolutionConvergence}
	ErrInvalidState          error = errorCodeSentinel{ErrorCodeInvalidState}
	ErrMissingRootDocument   error = errorCodeSentinel{ErrorCodeMissingRootDocument}
	ErrUnsafeConfigOutput    error = errorCodeSentinel{ErrorCodeUnsafeConfigOutput}
)

The Err variables are stable error identities for errors.Is. Their matching ErrorCode is exposed on Error and Diagnostic for callers that serialize, switch on, or display the library's error taxonomy.

Functions

func Load

func Load(ctx context.Context, entry string, options LoadOptions) (*Project, Diagnostics, error)

Load reads entry and its included documents, validates their structure, and builds an immutable Project.

func ParseDocument

func ParseDocument(source Source) (*Document, Diagnostics)

ParseDocument parses one Kconfig source document.

func ParseExpr

func ParseExpr(text string, span SourceSpan) (Expr, Diagnostics)

ParseExpr parses an expression with Kconfig operator precedence.

func ParseValue

func ParseValue(kind ValueType, raw string) (Value, Diagnostic)

ParseValue parses one Kconfig literal as the requested type.

func WriteConfig

func WriteConfig(state ConfigState) (string, error)

WriteConfig emits a deterministic Linux .config file. Disabled bool and tristate symbols use Linux's conventional unset spelling. It uses restrictive output validation; use WriteConfigWithOptions only when every value and symbol declaration is trusted.

func WriteConfigWithOptions added in v1.2.0

func WriteConfigWithOptions(state ConfigState, options WriteConfigOptions) (string, error)

WriteConfigWithOptions emits a deterministic Linux .config file. Disabled bool and tristate symbols use Linux's conventional unset spelling. Its zero value options enable restrictive validation; callers must explicitly set TrustInput to bypass that validation.

func WriteKconfig

func WriteKconfig(project *Project) (string, error)

WriteKconfig emits normalized definitions. It intentionally does not keep original whitespace or comments positioning; Project is semantic model data.

Types

type Change

type Change struct {
	// Input is the unnormalized frontend scalar supplied by the caller.
	Input any
	// Status records whether resolution accepted, normalized, fell back from, or ignored Input.
	Status ChangeStatus
	// Previous is the initial scalar and Value is the resolved final scalar.
	Previous, Value Value
	// Reason explains fallback or ignored input when applicable.
	Reason *StateReason
}

Change records the outcome of one submitted or normalized symbol value.

type ChangeStatus

type ChangeStatus uint8

ChangeStatus reports how a submitted frontend value was handled during resolution.

const (
	// ChangeAccepted means the direct frontend scalar remained valid.
	ChangeAccepted ChangeStatus = iota
	// ChangeNormalized means resolution supplied the final value without direct input.
	ChangeNormalized
	// ChangeFallback means direct input was replaced by an active default or constraint result.
	ChangeFallback
	// ChangeIgnored means the input referred to an unknown symbol.
	ChangeIgnored
)

type ConditionalValue

type ConditionalValue struct {
	// Value holds a literal default in the declared symbol type.
	Value Value
	// Expr is used for symbol-valued defaults (for example, `default FOO`).
	// Value is retained for literal defaults so callers do not need to reparse
	// source text to render a default.
	Expr Expr
	// Raw preserves the normalized source spelling for canonical writing.
	Raw string
	// Condition controls whether this default can apply; nil means unconditional.
	Condition Expr
	// Span locates the default in its source document.
	Span SourceSpan
}

ConditionalValue is a default value whose application may depend on an expression.

type ConfigState

type ConfigState struct {
	// contains filtered or unexported fields
}

ConfigState is an immutable-by-convention resolved value set tied to one Project.

func (ConfigState) Value

func (s ConfigState) Value(symbolID string) Value

Value returns the current symbol value, or the declared zero value when the symbol is known but unset.

func (ConfigState) Values

func (s ConfigState) Values() map[string]Value

Values returns a copy of the resolved symbol map so callers cannot mutate ConfigState internals.

type Constraints

type Constraints struct {
	// Type controls the frontend scalar type and validation rules.
	Type ValueType
	// Min and Max are active inclusive bounds when the symbol has a range.
	Min, Max *Value
	// AllowedValues enumerates toggles, tristates, or choice members where applicable.
	AllowedValues []ValueOption
}

Constraints describes the current type, range, and selectable values of a node.

type Diagnostic

type Diagnostic struct {
	// Severity classifies the impact of the diagnostic.
	Severity Severity
	// Code is the stable machine-readable category. Use errors.Is with the
	// matching Err variable when callers prefer Go's error matching protocol.
	Code ErrorCode
	// Message is a human-readable explanation that does not include source position.
	Message string
	// Span identifies the relevant source location when one is available.
	Span SourceSpan
	// Cause preserves an external underlying error, such as a SourceLoader read error.
	Cause error
}

Diagnostic explains a load, semantic, or input issue.

func (Diagnostic) Error added in v1.1.0

func (d Diagnostic) Error() string

Error returns the diagnostic message for APIs that accept an individual error.

func (Diagnostic) Is added in v1.1.0

func (d Diagnostic) Is(target error) bool

Is reports whether target is the sentinel belonging to this diagnostic's Code.

func (Diagnostic) Unwrap added in v1.1.0

func (d Diagnostic) Unwrap() error

Unwrap returns the underlying external cause, when one exists.

type Diagnostics

type Diagnostics []Diagnostic

Diagnostics is an ordered collection of diagnostics.

func (Diagnostics) Error

func (d Diagnostics) Error() string

Error renders all diagnostics for use with error-returning APIs.

func (Diagnostics) HasErrors

func (d Diagnostics) HasErrors() bool

HasErrors reports whether any error-level diagnostic is present.

type Document

type Document struct {
	// Title is the optional mainmenu title declared by the document.
	Title string
	// Root is the synthetic entry that owns the document's top-level entries.
	Root *Entry
}

Document is one parsed Kconfig source file.

type Entry

type Entry struct {
	// ID is a stable, source-derived identity assigned during indexing.
	ID string
	// Kind determines which Kconfig construct this entry represents.
	Kind EntryKind
	// Name is the symbol name or include path, depending on Kind.
	Name string
	// IncludeKind preserves source/rsource/osource/orsource for include entries.
	IncludeKind string
	// Prompt is the human-readable text shown for this entry.
	Prompt string
	// PromptCondition controls whether Prompt is active.
	PromptCondition Expr
	// Type is the declared value type for configuration entries.
	Type ValueType
	// Condition is the expression attached to an if entry.
	Condition Expr
	// Selects and Implies define relationships initiated by this entry.
	Selects []Relation
	Implies []Relation
	// Defaults and Ranges retain rules in source order.
	Defaults []ConditionalValue
	Ranges   []RangeRule
	// Depends affects configuration semantics, while Visible affects presentation only.
	Depends []Expr
	Visible []Expr
	// Help is the normalized multi-line help body for this entry.
	Help string
	// OptionModules marks the symbol that controls tristate module availability.
	OptionModules bool
	// Optional permits a choice to have no selected member.
	Optional bool
	// Properties preserves source property order for canonical writing.  The
	// semantic fields above remain the efficient, typed representation.
	Properties []Property
	// Children are nested source entries in their original order.
	Children []*Entry
	// Span identifies the entry declaration in its source document.
	Span SourceSpan
}

Entry is a source-ordered menu-tree node.

type EntryKind

type EntryKind uint8

EntryKind identifies a Kconfig menu-tree entry.

const (
	// EntryRoot is the synthetic document root and is never rendered directly.
	EntryRoot EntryKind = iota
	// EntryConfig declares a regular configuration symbol.
	EntryConfig
	// EntryMenuConfig declares a configuration symbol that also opens a screen.
	EntryMenuConfig
	// EntryMenu groups nested entries into a navigable screen.
	EntryMenu
	// EntryChoice restricts nested configuration symbols to one selected member.
	EntryChoice
	// EntryIf conditionally scopes its nested entries.
	EntryIf
	// EntryComment provides non-interactive display text.
	EntryComment
	// EntryInclude points to another source document loaded into this tree.
	EntryInclude
)

type EntrySchema

type EntrySchema struct {
	// ID is a stable declaration/menu-entry identity, not a submitted-value key.
	ID string
	// SymbolID is the submitted-value key for configuration entries and empty otherwise.
	SymbolID string
	// ParentID is the static parent screen ID.
	ParentID string
	// Prompt is the source prompt visible to users when its conditions allow it.
	Prompt string
	// Kind identifies the Kconfig construct represented by this entry.
	Kind EntryKind
	// Type is the declared value type for configuration entries.
	Type ValueType
	// Source locates the declaration in its source document.
	Source SourceSpan
	// ScreenID is the child screen opened by this menu or menuconfig entry, if any.
	ScreenID string
}

EntrySchema describes one source declaration in the static menu tree.

type Error added in v1.1.0

type Error struct {
	Code    ErrorCode
	Message string
	Cause   error
}

Error is a detailed library error with a stable Code and optional external Cause. Use errors.Is with the matching Err variable and errors.As to inspect an underlying filesystem, JSON, or caller-supplied error.

func (*Error) Error added in v1.1.0

func (e *Error) Error() string

func (*Error) Is added in v1.1.0

func (e *Error) Is(target error) bool

Is reports whether target is the sentinel belonging to this error's Code.

func (*Error) Unwrap added in v1.1.0

func (e *Error) Unwrap() error

Unwrap returns the underlying external failure, when one exists.

type ErrorCode added in v1.1.0

type ErrorCode string

ErrorCode is a stable, machine-readable category for a library failure. It identifies the reason and subsystem without replacing Error or Diagnostic messages, which retain the operation-specific detail intended for people.

const (
	// ErrorCodeInvalidDirective identifies a malformed Kconfig directive or argument.
	ErrorCodeInvalidDirective ErrorCode = "invalid-directive"
	// ErrorCodeInvalidBlock identifies an invalid, mismatched, or unclosed Kconfig block.
	ErrorCodeInvalidBlock ErrorCode = "invalid-block"
	// ErrorCodeUnsupportedDirective identifies an unsupported Kconfig directive.
	ErrorCodeUnsupportedDirective ErrorCode = "unsupported-directive"
	// ErrorCodeInvalidExpression identifies malformed expression syntax, tokens, or literals.
	ErrorCodeInvalidExpression ErrorCode = "invalid-expression"
	// ErrorCodeInvalidRange identifies a malformed or invalid Kconfig range.
	ErrorCodeInvalidRange ErrorCode = "invalid-range"
	// ErrorCodeDefaultTypeMismatch identifies a default whose type conflicts with its symbol.
	ErrorCodeDefaultTypeMismatch ErrorCode = "default-type-mismatch"
	// ErrorCodeInvalidValue identifies an invalid typed Kconfig scalar.
	ErrorCodeInvalidValue ErrorCode = "invalid-value"
	// ErrorCodeInvalidJSONValue identifies malformed or type-incompatible Value JSON.
	ErrorCodeInvalidJSONValue ErrorCode = "invalid-json-value"
	// ErrorCodeUnknownValueType identifies an unsupported ValueType.
	ErrorCodeUnknownValueType ErrorCode = "unknown-value-type"
	// ErrorCodeRootPath identifies failure to resolve the configured project root.
	ErrorCodeRootPath ErrorCode = "root-path"
	// ErrorCodeIncludeEscape identifies an include path that escapes the project root.
	ErrorCodeIncludeEscape ErrorCode = "include-escape"
	// ErrorCodeIncludeCycle identifies a cycle in source includes.
	ErrorCodeIncludeCycle ErrorCode = "include-cycle"
	// ErrorCodeSourceRead identifies a non-optional SourceLoader read failure.
	ErrorCodeSourceRead ErrorCode = "source-read"
	// ErrorCodeUnresolvedVariable identifies a missing caller-supplied variable.
	ErrorCodeUnresolvedVariable ErrorCode = "unresolved-variable"
	// ErrorCodeShellMacro identifies a disabled shell macro expansion.
	ErrorCodeShellMacro ErrorCode = "shell-macro"
	// ErrorCodeEnvironmentMacro identifies a disabled, disallowed, or missing environment macro lookup.
	ErrorCodeEnvironmentMacro ErrorCode = "environment-macro"
	// ErrorCodePythonMacro identifies a forbidden Python macro expansion.
	ErrorCodePythonMacro ErrorCode = "python-macro"
	// ErrorCodeCustomMacro identifies a forbidden custom macro expansion.
	ErrorCodeCustomMacro ErrorCode = "custom-macro"
	// ErrorCodeMacroExecution identifies a shell, Python, or custom macro execution failure.
	ErrorCodeMacroExecution ErrorCode = "macro-execution"
	// ErrorCodeMacroSyntax identifies malformed or excessively nested macro syntax.
	ErrorCodeMacroSyntax ErrorCode = "macro-syntax"
	// ErrorCodeUnsupportedMacro identifies an unsupported Kconfig macro expansion.
	ErrorCodeUnsupportedMacro ErrorCode = "unsupported-macro"
	// ErrorCodeIncompatibleSymbol identifies conflicting declared symbol types.
	ErrorCodeIncompatibleSymbol ErrorCode = "incompatible-symbol"
	// ErrorCodeUndeclaredSymbol identifies a symbol referenced without declaration.
	ErrorCodeUndeclaredSymbol ErrorCode = "undeclared-symbol"
	// ErrorCodeUninitializedProject identifies an operation on an uninitialized Project.
	ErrorCodeUninitializedProject ErrorCode = "uninitialized-project"
	// ErrorCodeUnknownSymbol identifies a submitted symbol absent from the project.
	ErrorCodeUnknownSymbol ErrorCode = "unknown-symbol"
	// ErrorCodeResolutionConvergence identifies resolution that cannot reach a fixed point.
	ErrorCodeResolutionConvergence ErrorCode = "resolution-convergence"
	// ErrorCodeInvalidState identifies a ConfigState unsuitable for an operation.
	ErrorCodeInvalidState ErrorCode = "invalid-state"
	// ErrorCodeMissingRootDocument identifies a Project without a root document.
	ErrorCodeMissingRootDocument ErrorCode = "missing-root-document"
	// ErrorCodeUnsafeConfigOutput identifies a .config value or symbol name
	// that is unsafe for the restrictive writer to emit for Make consumption.
	ErrorCodeUnsafeConfigOutput ErrorCode = "unsafe-config-output"
)

type Expr

type Expr interface {
	// contains filtered or unexported methods
}

Expr is a parsed Kconfig conditional expression.

type FSLoader

type FSLoader struct{}

FSLoader is the default SourceLoader implementation backed by the host filesystem.

func (FSLoader) Read

func (FSLoader) Read(_ context.Context, path string) (Source, error)

Read loads path from the host filesystem and retains the requested path for diagnostics.

type FrontendInput

type FrontendInput struct {
	// Values maps declared symbol IDs to proposed frontend scalar values.
	Values map[string]any
}

FrontendInput contains raw frontend scalars keyed by SymbolID. Resolve and Apply choose the target type from the loaded Kconfig symbol and normalize these forms internally: bool -> bool, tristate -> "n"/"m"/"y", string -> string, int -> an integral number, and hex -> a "0x..." string.

type FrontendTree

type FrontendTree struct {
	// Title is the project title used by the root screen.
	Title string
	// RootScreenID is the stable ID of the always-present root screen.
	RootScreenID string
	// Screens are rendered in static parent-before-child order.
	Screens []Screen
	// Diagnostics carries loading or rendering diagnostics relevant to this projection.
	Diagnostics Diagnostics
}

FrontendTree is the complete dynamic projection of a Project for one ConfigState.

type LoadOptions

type LoadOptions struct {
	// Root confines entry and include paths when the default filesystem loader is used.
	Root string
	// Loader optionally replaces filesystem reads with an application-provided source store.
	Loader SourceLoader
	// Variables supplies literal $(NAME) and ${NAME} substitutions. Its values are
	// never evaluated as shell, Python, environment, or custom macros.
	Variables map[string]string
	// Macros explicitly enables selected function-like macro forms. Its zero value
	// rejects every function-like macro and does not execute host code.
	Macros MacroOptions
}

type MacroFunc added in v1.3.0

type MacroFunc func(context.Context, []string) (string, error)

MacroFunc expands the arguments of an explicitly enabled $(macro,...) call. It receives the command-bounded Load context, so it must return when the context is cancelled. Callers own validation and escaping of every argument: passing untrusted data to a macro can introduce security risks.

type MacroOptions added in v1.3.0

type MacroOptions struct {
	// Environment is the exact allow-list for $(env,NAME) lookups.
	Environment []string
	// Shell enables $(shell,command).
	Shell bool
	// Python enables $(python,script).
	Python bool
	// ShellCommand overrides the shell executable and fixed argument prefix.
	// When empty, Load uses cmd.exe /C on Windows and /bin/sh -c elsewhere.
	ShellCommand []string
	// PythonCommand overrides the Python executable and fixed argument prefix.
	// Load appends -c and the macro script. When empty, it uses python -c.
	PythonCommand []string
	// CommandTimeout bounds enabled shell, Python, and custom macro work. A zero
	// value uses 30 seconds; an earlier Load context deadline always wins.
	CommandTimeout time.Duration
	// Macro enables $(macro,arg1,arg2) and receives its expanded arguments.
	Macro MacroFunc
}

MacroOptions controls the optional function-like macros evaluated during Load. The zero value is safe: it permits only literal Variables substitution.

Environment allows exact environment variable names for $(env,NAME). Shell, Python, and Macro independently enable $(shell,command), $(python,script), and $(macro,arg1,arg2). Enabled Shell and Python commands inherit the host environment and execute with LoadOptions.Root as their working directory. Do not interpolate untrusted input into any enabled macro; validation and escaping are caller responsibilities and execution always carries risk.

type Node

type Node struct {
	// ID is the stable declaration entry ID; SymbolID is the submitted-value key when applicable.
	ID, SymbolID string
	// SelectedSymbolID identifies the active choice member for choice nodes.
	SelectedSymbolID string
	// Kind determines how a frontend presents this node.
	Kind NodeKind
	// Prompt and Help are source-authored display text.
	Prompt, Help string
	// Visible controls display, while Enabled controls whether frontend edits are accepted.
	Visible, Enabled bool
	// Value is resolved state and Default is the active Kconfig default.
	Value, Default Value
	// Constraints describes valid user input at this state.
	Constraints Constraints
	// Reason explains hidden or disabled state when applicable.
	Reason *StateReason
	// Screen references the enterable child screen opened by this node, when any.
	Screen *ScreenRef
	// Source locates the original declaration.
	Source SourceSpan
}

Node is a rendered entry with its current value, visibility, and interaction constraints.

type NodeKind

type NodeKind uint8

NodeKind identifies a rendered frontend entry.

const (
	// NodeConfig renders an ordinary configuration symbol.
	NodeConfig NodeKind = iota
	// NodeMenuConfig renders a configuration symbol that may open a child screen.
	NodeMenuConfig
	// NodeMenu renders a non-value menu entry that opens a child screen.
	NodeMenu
	// NodeChoice renders a group whose member symbols are the submitted values.
	NodeChoice
	// NodeComment renders non-interactive explanatory text.
	NodeComment
)

type Project

type Project struct {
	// contains filtered or unexported fields
}

Project is an immutable, indexed Kconfig document tree ready for resolution and rendering.

func (*Project) Apply

func (p *Project) Apply(state ConfigState, patch FrontendInput) Resolution

Apply preserves valid prior user input from state, overlays patch, and resolves the complete next state.

func (*Project) OpenScreen

func (p *Project) OpenScreen(state ConfigState, id string, options RenderOptions) ScreenResult

OpenScreen returns a visible, enterable screen, falling back to an ancestor or root when id is stale or hidden.

func (*Project) Render

func (p *Project) Render(state ConfigState, options RenderOptions) FrontendTree

Render projects state into frontend screens without changing the state or Project.

func (*Project) Resolve

func (p *Project) Resolve(input FrontendInput) Resolution

Resolve applies raw frontend input to fresh defaults and converges Kconfig dependencies, relations, and choices.

func (*Project) Schema

func (p *Project) Schema() Schema

Schema returns the full static catalog, including entries hidden by current conditions.

func (*Project) Validate

func (p *Project) Validate(state ConfigState, symbolID string, candidate any) ValidationResult

Validate checks a raw frontend scalar without mutating state. Its accepted scalar forms are the same as FrontendInput.Values.

type Property

type Property struct {
	// Kind is the canonical Kconfig property keyword.
	Kind string
	// Text is the normalized property body without the keyword.
	Text string
	// Span locates the property in its source document.
	Span SourceSpan
}

Property records one source property in declaration order. It intentionally keeps only normalized text: writers are canonical rather than format-preserving.

type RangeRule

type RangeRule struct {
	// Min and Max are inclusive bounds expressed in the symbol's declared type.
	Min Value
	Max Value
	// Condition controls whether this range is active; nil means unconditional.
	Condition Expr
	// Span locates the range declaration in its source document.
	Span SourceSpan
}

RangeRule limits an integer or hexadecimal symbol while Condition is active.

type Relation

type Relation struct {
	// Target is the symbol name changed by this relation.
	Target string
	// Condition controls when the relation is active; nil means unconditional.
	Condition Expr
	// Span locates the relation in its source document.
	Span SourceSpan
}

Relation is a conditional select or imply target.

type RenderOptions

type RenderOptions struct {
	// IncludeHidden retains nodes and screens whose visibility conditions are false.
	IncludeHidden bool
}

RenderOptions controls which presentation-only entries Render returns.

type Resolution

type Resolution struct {
	// State is the fully resolved immutable-by-convention configuration state.
	State ConfigState
	// Tree is the complete dynamic frontend projection for State.
	Tree FrontendTree
	// Changes is keyed by symbol ID and describes every submitted or normalized value.
	Changes map[string]Change
	// Diagnostics collects malformed input and resolution diagnostics.
	Diagnostics Diagnostics
}

Resolution combines the resolved state, dynamic tree, per-symbol outcomes, and diagnostics.

type Schema

type Schema struct {
	// Title is the project title declared with mainmenu, or the default title.
	Title string
	// Symbols lists each declared configuration symbol and every declaration site.
	Symbols []SymbolSchema
	// Entries lists static menu-tree entries, independent of runtime visibility.
	Entries []EntrySchema
	// Screens lists navigable menu and menuconfig screens in parent-before-child order.
	Screens []ScreenSchema
}

Schema is a static, cacheable catalog. Visibility and constraints belong to FrontendTree and are deliberately absent here.

type Screen

type Screen struct {
	// ID, ParentID, and OwnerID form the navigation hierarchy.
	ID, ParentID, OwnerID string
	// Title is the display label for this screen.
	Title string
	// Breadcrumb lists the visible root-to-screen navigation path.
	Breadcrumb []ScreenRef
	// Visible reports presentation visibility; Enterable reports whether navigation is allowed.
	Visible, Enterable bool
	// Entries contains this screen's rendered nodes in source order.
	Entries []Node
}

Screen groups visible nodes that a frontend can navigate to.

type ScreenRef

type ScreenRef struct{ ID, Title string }

ScreenRef identifies a screen without embedding its entries.

type ScreenResult

type ScreenResult struct {
	// Screen is the visible screen ultimately selected for the request.
	Screen Screen
	// ActiveScreenID repeats Screen.ID as a convenient navigation result.
	ActiveScreenID string
	// Redirected reports that the requested ID was stale or hidden.
	Redirected bool
	// Reason explains the redirect or project error, when applicable.
	Reason *StateReason
	// Tree is the complete projection used to find the selected screen.
	Tree FrontendTree
}

ScreenResult combines a rendered tree with the screen selected after fallback.

type ScreenSchema

type ScreenSchema struct {
	// ID is the stable screen identity used by rendering and navigation.
	ID string
	// ParentID identifies the containing screen, or is empty for the root screen.
	ParentID string
	// OwnerID identifies the entry that opens this screen, or is empty for root.
	OwnerID string
	// Title is the screen label derived from its owning entry.
	Title string
	// Source locates the owning source entry when the screen is not root.
	Source SourceSpan
}

ScreenSchema describes a static navigable screen and its ownership relation.

type Severity

type Severity uint8

Severity describes how a diagnostic affects loading or resolution.

const (
	// SeverityInfo reports supplemental information that does not affect processing.
	SeverityInfo Severity = iota
	// SeverityWarning reports recoverable input or semantic conditions.
	SeverityWarning
	// SeverityError reports a condition that prevents reliable project use.
	SeverityError
)

type Source

type Source struct {
	// Path identifies the source for diagnostics and include resolution.
	Path string
	// Data contains the complete UTF-8 Kconfig document.
	Data []byte
}

Source is Kconfig text returned by a SourceLoader or supplied directly.

type SourceLoader

type SourceLoader interface {
	Read(context.Context, string) (Source, error)
}

SourceLoader permits applications to provide Kconfig files from an embedded filesystem or another trusted store. The loader receives a cleaned path rooted under LoadOptions.Root; it is never asked to expand Kconfig macros.

type SourceSpan

type SourceSpan struct {
	// Path is the document path supplied by the loader.
	Path string
	// Line and Column are one-based start coordinates.
	Line   int
	Column int
	// EndLine and EndColumn are optional one-based exclusive end coordinates.
	EndLine   int
	EndColumn int
}

SourceSpan identifies a position in a Kconfig source file.

type StateReason

type StateReason struct {
	// Code is a stable machine-readable reason category.
	Code string
	// Message is a user-facing explanation for the current state.
	Message string
	// Source identifies the related declaration when available.
	Source SourceSpan
}

StateReason explains why a value, node, or screen is unavailable or redirected.

type SymbolLookup

type SymbolLookup func(name string) Value

SymbolLookup obtains the current value of a named symbol.

type SymbolSchema

type SymbolSchema struct {
	// ID is the submitted-value key used by FrontendInput.Values.
	ID string
	// Type controls the scalar form accepted for the symbol.
	Type ValueType
	// Source is the first declaration location for the symbol.
	Source SourceSpan
	// EntryIDs identifies every static declaration entry for the symbol.
	EntryIDs []string
}

SymbolSchema describes one logical symbol that may have several declarations.

type Token

type Token struct {
	// Kind identifies the token category.
	Kind TokenKind
	// Text is the original token spelling.
	Text string
	// Span identifies the token's source position.
	Span SourceSpan
}

Token is a source-positioned expression token.

type TokenKind

type TokenKind uint8

TokenKind identifies a lexical unit in a Kconfig expression.

const (
	// TokenEOF marks the end of an expression token stream.
	TokenEOF TokenKind = iota
	// TokenIdent is a symbol name or tristate literal spelling.
	TokenIdent
	// TokenString is a quoted Kconfig string literal.
	TokenString
	// TokenNumber is a decimal or hexadecimal numeric literal.
	TokenNumber
	// TokenNot is the unary ! operator.
	TokenNot
	// TokenAnd is the && logical operator.
	TokenAnd
	// TokenOr is the || logical operator.
	TokenOr
	// TokenEqual is the = comparison operator.
	TokenEqual
	// TokenNotEqual is the != comparison operator.
	TokenNotEqual
	// TokenLess is the < comparison operator.
	TokenLess
	// TokenLessEqual is the <= comparison operator.
	TokenLessEqual
	// TokenGreater is the > comparison operator.
	TokenGreater
	// TokenGreaterEqual is the >= comparison operator.
	TokenGreaterEqual
	// TokenLParen is an opening parenthesis.
	TokenLParen
	// TokenRParen is a closing parenthesis.
	TokenRParen
)

type TriState

type TriState uint8

TriState is the Kconfig n < m < y lattice value.

const (
	// TriNo is the disabled n state.
	TriNo TriState = iota
	// TriModule is the modular m state.
	TriModule
	// TriYes is the enabled y state.
	TriYes
)

func EvalExpr

func EvalExpr(expr Expr, lookup SymbolLookup) TriState

EvalExpr evaluates a parsed expression using Kconfig tristate logic.

func (TriState) String

func (t TriState) String() string

String returns the Kconfig spelling of a tristate value.

type ValidationResult

type ValidationResult struct {
	// Accepted reports whether candidate is immediately valid in state.
	Accepted bool
	// Normalized is candidate when accepted, otherwise the suggested active default.
	Normalized Value
	// AllowedValues contains current toggles, tristates, or choice members.
	AllowedValues []ValueOption
	// Reason explains rejection without requiring state mutation.
	Reason *StateReason
	// Diagnostics provides parsing warnings for malformed frontend scalar forms.
	Diagnostics Diagnostics
	// AffectedEntryIDs identifies static declarations that a frontend may refresh.
	AffectedEntryIDs []string
}

ValidationResult reports whether a proposed raw scalar is accepted and how a caller should recover when it is not.

type Value

type Value struct {
	// Type selects which of Tri, Text, or Int is meaningful.
	Type ValueType
	// Tri stores bool and tristate values.
	Tri TriState
	// Text stores string values without Kconfig quote syntax.
	Text string
	// Int stores decimal and hexadecimal integer values.
	Int int64
}

Value is a typed Kconfig value. Only the field matching Type is meaningful.

func BoolValue

func BoolValue(value bool) Value

BoolValue creates a bool Value from a Go boolean.

func HexValue

func HexValue(value int64) Value

HexValue creates a hexadecimal integer Value.

func IntValue

func IntValue(value int64) Value

IntValue creates a decimal integer Value.

func StringValue

func StringValue(value string) Value

StringValue creates a string Value without adding Kconfig quote syntax.

func TriValue

func TriValue(value TriState) Value

TriValue creates a tristate Value from a Kconfig lattice value.

func ZeroValue

func ZeroValue(kind ValueType) Value

ZeroValue returns the inactive value for a declared Kconfig type.

func (Value) MarshalJSON

func (v Value) MarshalJSON() ([]byte, error)

MarshalJSON writes the frontend scalar form of a typed Kconfig value. A caller obtains the value type from Schema or Node.Constraints rather than having to decode the Value struct's implementation fields.

func (Value) String

func (v Value) String() string

String returns the canonical Kconfig literal for the value.

func (*Value) UnmarshalJSON

func (v *Value) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts the scalar form emitted by MarshalJSON. When the receiver already carries a type (for example, ZeroValue(schema.Type)), JSON types are checked strictly. An untyped receiver infers only unambiguous scalar forms; callers with a string/tristate or int/hex ambiguity should initialize the receiver from schema metadata first.

type ValueOption

type ValueOption struct {
	// Value is the scalar choice value; for choices it is the member's resolved value.
	Value Value
	// SymbolID identifies a choice member when this option represents one.
	SymbolID string
	// Prompt is the human-readable label for the option or choice member.
	Prompt string
	// Selected reports whether the option is active in the current state.
	Selected bool
	// Enabled reports whether the frontend may submit this option.
	Enabled bool
	// Reason explains why an unavailable option is disabled.
	Reason *StateReason
}

ValueOption describes a value or choice member available to the frontend.

type ValueOrigin

type ValueOrigin uint8

ValueOrigin records why a resolved value was chosen.

const (
	// OriginZero marks the initial inactive value before resolution.
	OriginZero ValueOrigin = iota
	// OriginDefault marks a value selected by an active default rule.
	OriginDefault
	// OriginInput marks a value provided directly by the frontend.
	OriginInput
	// OriginRelation marks a value raised by select or imply.
	OriginRelation
	// OriginChoice marks a value selected or cleared to satisfy a choice.
	OriginChoice
)

type ValueType

type ValueType uint8

ValueType is the declared type of a Kconfig symbol.

const (
	// TypeUnknown marks an unset or invalid type.
	TypeUnknown ValueType = iota
	// TypeBool accepts only n or y.
	TypeBool
	// TypeTristate accepts n, m, or y.
	TypeTristate
	// TypeString stores quoted Kconfig string values.
	TypeString
	// TypeInt stores signed decimal integers.
	TypeInt
	// TypeHex stores non-negative hexadecimal integers.
	TypeHex
)

type WriteConfigOptions added in v1.2.0

type WriteConfigOptions struct {
	// TrustInput disables restrictive validation of string values and symbol
	// names. It must be set only when every Kconfig declaration and configuration
	// value producer is trusted; Make or shell consumers may interpret the
	// resulting output. Serialization remains canonical and quoted.
	TrustInput bool
}

WriteConfigOptions controls how WriteConfigWithOptions validates .config output before it can be consumed by GNU Make.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL