The source command supports file name patterns.

This allows to include other source files in the .dev-expr.rc init file.
This commit is contained in:
Celestino Amoroso 2024-07-23 06:02:03 +02:00
parent ec931268b3
commit 670d7d3f88
5 changed files with 156 additions and 5 deletions

51
main.go
View File

@ -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)

49
match.go Normal file
View File

@ -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, "*?[]")
}

36
match_test.go Normal file
View File

@ -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)
}
}

23
util-string.go Normal file
View File

@ -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
}

View File

@ -1 +1 @@
1.10.0
1.11.0