diff --git a/main.go b/main.go index 774188c..b382177 100644 --- a/main.go +++ b/main.go @@ -267,13 +267,12 @@ func goInteractiveReadline(opt *Options, ctx expr.ExprContext, r io.Reader) { if cmd, args := cmdHandler.get(source); cmd != nil { rl.SaveToHistory(source) if err = cmd.exec(ctx, args); err != nil { - break + fmt.Fprintln(os.Stderr, "Eval Error:", err) } } else { rl.SaveToHistory(source) r := strings.NewReader(source) compute(opt, ctx, r, true) - } } sb.Reset() @@ -325,6 +324,7 @@ func goBatch(opt *Options, ctx expr.ExprContext, r io.Reader) { if source != "" && !strings.HasPrefix(source, "//") { if cmd, args := cmdHandler.get(source); cmd != nil { if err = cmd.exec(ctx, args); err != nil { + fmt.Fprintln(os.Stderr, "Eval Error:", err) break } } else { @@ -349,9 +349,8 @@ func compute(opt *Options, ctx expr.ExprContext, r io.Reader, outputEnabled bool fmt.Println(r.String()) } - outputEnabled = outputEnabled && opt.output if result, err := ast.Eval(ctx); err == nil { - if outputEnabled { + if outputEnabled && opt.output { printResult(opt, result) } } else { @@ -519,7 +518,51 @@ func cmdTty(ctx expr.ExprContext, args []string) (err error) { return } +func execFile(ctx expr.ExprContext, fileName string) (err error) { + var fh *os.File + if fh, err = os.Open(fileName); err == nil { + goBatch(opt, ctx, fh) + fh.Close() + } + return +} + func cmdSource(ctx expr.ExprContext, args []string) (err error) { + var target string + for _, arg := range args { + if len(arg) == 0 { + continue + } + // TODO migliorare questa parte: eventualmente valutare un'espressione + if target, err = checkStringLiteral(arg); err != nil { + break + } + + if target, err = utils.ExpandPath(target); err != nil { + break + } + + if isPattern(target) { + var fileNames []string + if fileNames, err = matchPathPattern(target); err == nil { + for _, fileName := range fileNames { + if err = execFile(ctx, fileName); err != nil { + break + } + } + } + } else { + err = execFile(ctx, target) + } + + if err != nil { + break + } + } + return +} + +func _cmdSource(ctx expr.ExprContext, args []string) (err error) { var fh *os.File for _, arg := range args { length := len(arg) diff --git a/match.go b/match.go new file mode 100644 index 0000000..0d01f5c --- /dev/null +++ b/match.go @@ -0,0 +1,49 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// match.go +package main + +import ( + "os" + "path" + "path/filepath" + "strings" +) + +func matchFilePattern(dirName string, pattern string, join bool) (fileList []string, err error) { + var entries []os.DirEntry + if entries, err = os.ReadDir(dirName); err == nil { + for _, entry := range entries { + if entry.Type().IsRegular() { + var match bool + if match, err =filepath.Match(pattern, entry.Name()); err != nil { + fileList = nil + break + } + if match { + if fileList == nil { + fileList = make([]string, 0, 1) + } + if join { + fileList = append(fileList, path.Join(dirName, entry.Name())) + } else { + fileList = append(fileList, entry.Name()) + } + } + } + } + } + return +} + +func matchPathPattern(pathPattern string) (fileList []string, err error) { + dirName := path.Dir(pathPattern) + pattern := path.Base(pathPattern) + return matchFilePattern(dirName, pattern, true) +} + + +func isPattern(name string) bool{ + return strings.ContainsAny(name, "*?[]") +} \ No newline at end of file diff --git a/match_test.go b/match_test.go new file mode 100644 index 0000000..3cceec5 --- /dev/null +++ b/match_test.go @@ -0,0 +1,36 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// main.go +package main + +import ( + "path" + "slices" + "testing" +) + +func TestIsPattern(t *testing.T) { + target := "non-pattern" + if isPattern(target) { + t.Errorf("%q recognized as a pattern", target) + } + + target = "pattern/*.expr" + if !isPattern(target) { + t.Errorf("%q not recognized as a pattern", target) + } +} + +func TestMatchFilePattern(t *testing.T) { + target := "./go.*sum" + dirName := path.Dir(target) + pattern := path.Base(target) + if matchedFiles, err := matchFilePattern(dirName, pattern, true); err == nil { + if slices.Compare(matchedFiles, []string{"go.sum", "go.work.sum"}) != 0 { + t.Errorf("Matched file list is not correct: %v", matchedFiles) + } + } else { + t.Errorf("Got error: %v", err) + } +} diff --git a/util-string.go b/util-string.go new file mode 100644 index 0000000..dc9955a --- /dev/null +++ b/util-string.go @@ -0,0 +1,23 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// util-string.go +package main + +import ( + "fmt" +) + +func checkStringLiteral(literal string) (value string, err error) { + length := len(literal) + if length >= 2 { + if (literal[0] == '"' && literal[length-1] == '"') || literal[0] == '\'' && literal[length-1] == '\'' { + value = literal[1 : length-1] + } else { + err = fmt.Errorf("unquoted or partially quoted string literal: `%s`", literal) + } + } else { + err = fmt.Errorf("invalid string literal: `%s`", literal) + } + return +} \ No newline at end of file diff --git a/version.txt b/version.txt index 81c871d..1cac385 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.10.0 +1.11.0