From 47dcfa0642fbcdda3aa27b4aa954f46aa4a45b17 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 16 May 2025 13:41:16 +0200 Subject: [PATCH] newt/syscfg: Expand nested MYNEWT_VAL references Now Newt will resolve references of nested MYNEWT_VAL references. Example: CONFIG_A: MYNEWT_VAL(CONFIG_B) CONFIG_B: MYNEWT_VAL(CONFIG_C) CONFIG_C: 1 Before this change the outcome of this configuration would depend on configs resolution order. If CONFIG_A would be resolved before CONFIG_B the final outcome would be: CONFIG_A: 'MYNEWT_VAL(CONFIG_C)' <- string copied from not yet resolved CONFIG_B CONFIG_B: 1 CONFIG_C: 1 Now all the configs will get value 1, as expected. --- newt/syscfg/syscfg.go | 23 ++++++++++++++++++----- newt/val/valsetting.go | 3 +-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go index 886699cca..3efa42490 100644 --- a/newt/syscfg/syscfg.go +++ b/newt/syscfg/syscfg.go @@ -209,20 +209,33 @@ func ResolveValueRefName(val string) string { } func (cfg *Cfg) ExpandRef(val string) (string, string, error) { + var visited []string + var entry CfgEntry + var ok bool + refName := ResolveValueRefName(val) if refName == "" { // Not a reference. return "", val, nil } - entry, ok := cfg.Settings[refName] - if !ok { - return "", "", util.FmtNewtError( - "setting value \"%s\" references undefined setting", val) + for refName != "" { + entry, ok = cfg.Settings[refName] + if !ok { + return "", "", util.FmtNewtError( + "setting value \"%s\" references undefined setting", val) + } + for _, v := range visited { + if entry.Name == v { + return "", "", util.FmtNewtError( + "setting value \"%s\" creates a reference loop", entry.Name) + } + } + visited = append(visited, entry.Name) + refName = ResolveValueRefName(entry.Value) } return entry.Name, entry.Value, nil - } func (cfg *Cfg) AddInjectedSettings() { diff --git a/newt/val/valsetting.go b/newt/val/valsetting.go index 0d24218a7..78c3e54e1 100644 --- a/newt/val/valsetting.go +++ b/newt/val/valsetting.go @@ -57,8 +57,7 @@ func (vs *ValSetting) IntVal() (int, error) { func ResolveValSetting(s string, cfg *syscfg.Cfg) (ValSetting, error) { refName, val, err := cfg.ExpandRef(s) if err != nil { - return ValSetting{}, - util.FmtNewtError("value \"%s\" references undefined setting", s) + return ValSetting{}, err } return ValSetting{