This is an automated email from the ASF dual-hosted git repository. sjanc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git
commit bfe414ea4f77531551dc76f70719fd360bbe0419 Author: Szymon Janc <[email protected]> AuthorDate: Mon Oct 19 17:50:49 2026 +0200 newt/parse: Lex relational operators without surrounding spaces '<' and '>' were not delimiter characters, so "A<1" or "X>=3" was lexed as a single identifier, i.e., an undefined setting that silently evaluated to false. Treat '<' and '>' as delimiters, like '=' and '!'. Assisted-by: Claude:claude-opus-5-5 --- newt/parse/lex.go | 2 +- newt/parse/operators_test.go | 63 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/newt/parse/lex.go b/newt/parse/lex.go index 7701f4c2..678f2598 100644 --- a/newt/parse/lex.go +++ b/newt/parse/lex.go @@ -55,7 +55,7 @@ type Token struct { // Returns length of token on success; 0 if no match. type LexFn func(s string) (string, int, error) -const delimChars = "!='\"&|^() \t\n" +const delimChars = "!='\"&|^()<> \t\n" func lexString(s string, sought string) (string, int, error) { if strings.HasPrefix(s, sought) { diff --git a/newt/parse/operators_test.go b/newt/parse/operators_test.go new file mode 100644 index 00000000..a2c68179 --- /dev/null +++ b/newt/parse/operators_test.go @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package parse + +import ( + "testing" + + "mynewt.apache.org/newt/newt/cfgv" +) + +func operatorsTestSettings() *cfgv.Settings { + return cfgv.NewSettingsFromMap(map[string]string{ + "A": "0", + "B": "1", + "X": "3", + }) +} + +// Relational operators must be recognized without surrounding spaces. +func TestOperatorsNoSpaces(t *testing.T) { + tests := []struct { + expr string + exp bool + }{ + {"A<1", true}, + {"A>1", false}, + {"X>=3", true}, + {"X<=2", false}, + {"X>A", true}, + {"(X>2)&&(A<1)", true}, + {"X==3", true}, + {"X!=3", false}, + } + + settings := operatorsTestSettings() + for _, tt := range tests { + got, err := ParseAndEval(tt.expr, settings) + if err != nil { + t.Errorf("%s: unexpected error: %s", tt.expr, err) + continue + } + if got != tt.exp { + t.Errorf("%s: got %v, expected %v", tt.expr, got, tt.exp) + } + } +}
