Skip to content

xconfig: Add shell expression support and fix choice default selection - #13

Merged
guoweikang merged 5 commits into
mainfrom
copilot/fix-xconfig-shell-expressions
Feb 12, 2026
Merged

xconfig: Add shell expression support and fix choice default selection#13
guoweikang merged 5 commits into
mainfrom
copilot/fix-xconfig-shell-expressions

Conversation

Copilot AI commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

The Kconfig parser failed on shell expressions in default values and didn't apply choice defaults, breaking configuration for multi-architecture builds.

Changes

Shell Expression Evaluation

  • Added Expr::ShellExpr variant to AST for $(if condition,then,else) and $(VAR) syntax
  • Implemented recursive evaluator in shell_expr.rs handling nested conditionals
  • Updated parser to detect and preserve shell expressions in string literals
  • Proper escape sequence handling for quoted strings

Choice Default Selection

  • Modified extract_symbols_from_entries to process Choice entries recursively
  • Apply explicit defaults or select first option per Kconfig spec
  • Integrated into both menuconfig TUI and saveconfig command

Example

This now parses and evaluates correctly:

choice
    prompt "Target Architecture"
    default ARCH_AARCH64

config ARCH_AARCH64
    bool "AArch64"

config ARCH_X86_64
    bool "x86_64"
endchoice

config ARCH_NAME
    string
    default "$(if $(ARCH_AARCH64),aarch64,$(if $(ARCH_X86_64),x86_64,unknown))"

Generated config:

ARCH_AARCH64=y
ARCH_NAME="aarch64"
Original prompt

Fix xconfig: Support shell expressions in default values and Choice default selection

Problem 1: Shell Expression Support in Default Values

Currently, the xconfig parser cannot handle Kconfig default values with shell-style conditional expressions like:

config ARCH_NAME
    string
    default "$(if $(ARCH_AARCH64),aarch64,$(if $(ARCH_RISCV64),riscv64,$(if $(ARCH_X86_64),x86_64,$(if $(ARCH_LOONGARCH64),loongarch64,unknown))))"

Root Cause:

  • The parser in xtask/xconfig/src/kconfig/parser.rs only supports simple expressions (symbols, constants, numbers)
  • It lacks support for $() shell command substitution and nested $(if ...) conditionals
  • The lexer doesn't recognize shell expression syntax

Solution:

  1. Add shell expression parsing support to handle $(if condition,then,else) syntax
  2. Create a shell expression evaluator that can:
    • Parse nested if conditions
    • Evaluate conditions based on symbol table values
    • Recursively expand nested expressions

Problem 2: Choice Default Values Not Applied in TUI

When a Kconfig choice block has a default option specified, the TUI (menuconfig) doesn't correctly select that option by default.

Root Cause:

  • In xtask/xconfig/src/ui/app.rs, the MenuConfigApp::new() method initializes values for Config and MenuConfig items
  • However, it does not process Choice items to set their default selections
  • The ConfigState::build_from_entries() method creates Choice items but doesn't apply the default value

Solution:

  1. Add Choice initialization logic in MenuConfigApp::new() after building the config state
  2. When a Choice has a default field, set the corresponding option as selected
  3. If no default is specified, select the first visible option (standard Kconfig behavior)

Implementation Details

Files to Modify:

  1. xtask/xconfig/src/kconfig/shell_expr.rs (NEW FILE)

    • Create shell expression parser and evaluator
    • Support $(if condition, then_value, else_value) syntax
    • Support variable references like $(VARIABLE_NAME)
    • Handle nested expressions recursively
  2. xtask/xconfig/src/kconfig/lexer.rs

    • Add support for recognizing shell expressions in string literals
    • Keep shell expressions as-is for later evaluation
  3. xtask/xconfig/src/kconfig/parser.rs

    • When parsing default values, check if the string contains shell expressions
    • Store shell expressions in AST for later evaluation
  4. xtask/xconfig/src/kconfig/expr.rs

    • Add Expr::ShellExpr(String) variant to the expression enum
    • Update expression evaluator to handle shell expressions
  5. xtask/xconfig/src/ui/app.rs

    • Add Choice initialization in MenuConfigApp::new() method
    • After the existing initialization loops (around line 107), add:
// Initialize Choice default selections
for item in &mut config_state.all_items {
    if let MenuItemKind::Choice { options } = &item.kind {
        // Find the Choice AST entry to get its default value
        if let Some(default_option) = find_choice_default(&entries, &item.id) {
            // Set the default option as selected in symbol_table
            symbol_table.set_value(&default_option, "y".to_string());
            
            // Update all choice options visibility/state
            for opt_name in options {
                if opt_name == &default_option {
                    // Mark this as selected
                    if let Some(opt_item) = config_state.all_items.iter_mut().find(|i| i.id == *opt_name) {
                        opt_item.value = Some(ConfigValue::Bool(true));
                    }
                } else {
                    // Mark others as unselected
                    if let Some(opt_item) = config_state.all_items.iter_mut().find(|i| i.id == *opt_name) {
                        opt_item.value = Some(ConfigValue::Bool(false));
                    }
                }
            }
        } else if let Some(first_option) = options.first() {
            // No default specified, select first option
            symbol_table.set_value(first_option, "y".to_string());
            if let Some(opt_item) = config_state.all_items.iter_mut().find(|i| &i.id == first_option) {
                opt_item.value = Some(ConfigValue::Bool(true));
            }
        }
    }
}

// Also update menu_tree
for (_, items) in config_state.menu_tree.iter_mut() {
    for item in items {
        if let MenuItemKind::Choice { options } = &item.kind {
            // Similar logic for menu_tree items
            // ... (duplicate the logic above for menu_tree)
        }
    }
}
  1. xtask/xconfig/src/kconfig/mod.rs

    • Export the new shell_expr module
  2. xtask/xconfig/src/cli/saveconfig.rs

    • Update default value evaluation to use shell expression evaluator when applicable

Testing Requirements

  1. Shell Expression Tests:
    • Test simple $(if SYMBOL,yes,no) expressions
    • Test neste...

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits February 12, 2026 05:53
Co-authored-by: guoweikang <18571063+guoweikang@users.noreply.github.com>
Co-authored-by: guoweikang <18571063+guoweikang@users.noreply.github.com>
Co-authored-by: guoweikang <18571063+guoweikang@users.noreply.github.com>
…eaningless assertions

Co-authored-by: guoweikang <18571063+guoweikang@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix xconfig parser to support shell expressions in default values xconfig: Add shell expression support and fix choice default selection Feb 12, 2026
Copilot AI requested a review from guoweikang February 12, 2026 06:02
@guoweikang
guoweikang marked this pull request as ready for review February 12, 2026 06:03
@guoweikang
guoweikang merged commit c3ee590 into main Feb 12, 2026
@guoweikang
guoweikang deleted the copilot/fix-xconfig-shell-expressions branch March 10, 2026 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants