From 492c02d34f27b516fd68170450cfceceba3110b8 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Sun, 8 Sep 2024 14:24:57 +0200 Subject: [PATCH 1/5] make build --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index ab4273d..689daee 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ VERBOSE=-v all: vendor grammar test release +build: + go build -o spiff + grammar: go generate ./... From 22fae3b7be925ef23d2028ae6aa91a0a5678cd70 Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Sun, 8 Sep 2024 19:52:37 +0200 Subject: [PATCH 2/5] Windows binaries (#17) * cross-compile also windows binaries * ignore eclipse project settings --- .gitignore | 2 ++ Makefile | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index da49504..346ff6c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ vendor/github.com/onsi/ vendor/github.com/pelletier/ vendor/github.com/pointlander/ vendor/github.com/spf13/ +/.project +/.settings/ diff --git a/Makefile b/Makefile index 689daee..de30826 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ build: grammar: go generate ./... -release: spiff_linux_amd64.zip spiff_darwin_amd64.zip spiff_linux_ppc64le.zip spiff_linux_arm64.zip +release: spiff_linux_amd64.zip spiff_darwin_amd64.zip spiff_linux_ppc64le.zip spiff_linux_arm64.zip spiff_windows_amd64.zip spiff_windows_386.zip linux: GOOS=linux GOARCH=amd64 go build -o spiff++/spiff++ . @@ -40,6 +40,18 @@ spiff_linux_ppc64le.zip: (cd spiff++; zip spiff_linux_ppc64le.zip spiff++) rm spiff++/spiff++ +spiff_windows_amd64.zip: + GOOS=windows GOARCH=amd64 go build -o spiff++/spiff++.exe . + rm -f spiff++/spiff_windows_amd64.zip + (cd spiff++; zip spiff_windows_amd64.zip spiff++.exe) + rm spiff++/spiff++.exe + +spiff_windows_386.zip: + GOOS=windows GOARCH=386 go build -o spiff++/spiff++_386.exe . + rm -f spiff++/spiff_windows_386.zip + (cd spiff++; zip spiff_windows_386.zip spiff++_386.exe) + rm spiff++/spiff++_386.exe + .PHONY: vendor vendor: go mod vendor From 48aaa424ba577021e21a119a0a102358f6929aaf Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Sun, 8 Sep 2024 19:07:06 +0200 Subject: [PATCH 3/5] fix list merge --- dynaml/catch.go | 5 ++ dynaml/concatenation.go | 4 ++ dynaml/cond.go | 4 ++ dynaml/expression.go | 13 ++++- dynaml/grouped.go | 4 ++ dynaml/merge.go | 4 ++ dynaml/or.go | 4 ++ flow/flow.go | 60 ++++++++++++++------ flow/flow2_test.go | 120 ++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- 10 files changed, 202 insertions(+), 18 deletions(-) create mode 100644 flow/flow2_test.go diff --git a/dynaml/catch.go b/dynaml/catch.go index 8f303cd..f97c0ff 100644 --- a/dynaml/catch.go +++ b/dynaml/catch.go @@ -2,6 +2,7 @@ package dynaml import ( "fmt" + "github.com/mandelsoft/spiff/debug" "github.com/mandelsoft/spiff/yaml" ) @@ -15,6 +16,10 @@ type CatchExpr struct { Lambda Expression } +func (e CatchExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.A) +} + func (e CatchExpr) Evaluate(binding Binding, locally bool) (interface{}, EvaluationInfo, bool) { resolved := true var value interface{} diff --git a/dynaml/concatenation.go b/dynaml/concatenation.go index 6b23924..ea8d7ac 100644 --- a/dynaml/concatenation.go +++ b/dynaml/concatenation.go @@ -13,6 +13,10 @@ type ConcatenationExpr struct { B Expression } +func (e ConcatenationExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.A) || IncludesDirectMerge(e.B) +} + func (e ConcatenationExpr) Evaluate(binding Binding, locally bool) (interface{}, EvaluationInfo, bool) { resolved := true diff --git a/dynaml/cond.go b/dynaml/cond.go index 27c707f..ef0d8f7 100644 --- a/dynaml/cond.go +++ b/dynaml/cond.go @@ -12,6 +12,10 @@ type CondExpr struct { F Expression } +func (e CondExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.T) || IncludesDirectMerge(e.F) +} + func (e CondExpr) Evaluate(binding Binding, locally bool) (interface{}, EvaluationInfo, bool) { resolved := true info := DefaultInfo() diff --git a/dynaml/expression.go b/dynaml/expression.go index d5bcdb7..80cceda 100644 --- a/dynaml/expression.go +++ b/dynaml/expression.go @@ -148,6 +148,17 @@ type Expression interface { Evaluate(Binding, bool) (interface{}, EvaluationInfo, bool) } +type MergeInfoExpression interface { + IncludesDirectMerge() bool +} + +func IncludesDirectMerge(e Expression) bool { + if m, ok := e.(MergeInfoExpression); ok { + return m.IncludesDirectMerge() + } + return false +} + type StaticallyScopedValue interface { StaticResolver() Binding SetStaticResolver(binding Binding) StaticallyScopedValue @@ -197,7 +208,7 @@ func (i *EvaluationInfo) PropagateError(value interface{}, state Status, msgfmt if i.LocalError { value = nil } - return value, *i, false //!i.LocalError + return value, *i, false // !i.LocalError } func (i EvaluationInfo) CleanError() EvaluationInfo { diff --git a/dynaml/grouped.go b/dynaml/grouped.go index 636967f..73ae4a4 100644 --- a/dynaml/grouped.go +++ b/dynaml/grouped.go @@ -8,6 +8,10 @@ type GroupedExpr struct { Expr Expression } +func (e GroupedExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.Expr) +} + func (e GroupedExpr) String() string { return fmt.Sprintf("( %s )", e.Expr) } diff --git a/dynaml/merge.go b/dynaml/merge.go index bc06503..78e82fd 100644 --- a/dynaml/merge.go +++ b/dynaml/merge.go @@ -15,6 +15,10 @@ type MergeExpr struct { KeyName string } +func (e MergeExpr) IncludesDirectMerge() bool { + return !e.Redirect +} + func (e MergeExpr) Evaluate(binding Binding, locally bool) (interface{}, EvaluationInfo, bool) { var info EvaluationInfo info.KeyName = e.KeyName diff --git a/dynaml/or.go b/dynaml/or.go index b8cdc01..4051006 100644 --- a/dynaml/or.go +++ b/dynaml/or.go @@ -10,6 +10,10 @@ type OrExpr struct { B Expression } +func (e OrExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.A) || IncludesDirectMerge(e.B) +} + func (e OrExpr) Evaluate(binding Binding, locally bool) (interface{}, EvaluationInfo, bool) { a, infoa, ok := e.A.Evaluate(binding, false) if ok && !infoa.Undefined { diff --git a/flow/flow.go b/flow/flow.go index e1bf145..517b644 100644 --- a/flow/flow.go +++ b/flow/flow.go @@ -449,7 +449,7 @@ func flowMap(root yaml.Node, env dynaml.Binding, shouldOverride, template bool) } } } - //flags |= yaml.FLAG_INJECTED + // flags |= yaml.FLAG_INJECTED } } var result interface{} @@ -482,7 +482,7 @@ func flowList(root yaml.Node, env dynaml.Binding, template bool) yaml.Node { rootList := root.Value().([]yaml.Node) debug.Debug("HANDLE LIST %v\n", env.Path()) - merged, process, replaced, redirectPath, keyName, ismerged, flags, tag, stub := processMerges(root, rootList, env, template) + merged, process, replaced, redirectPath, keyName, ismerged, flags, tag, stub, nomerge := processMerges(root, rootList, env, template) if process { debug.Debug("process list (key: %s) %v\n", keyName, env.Path()) @@ -494,13 +494,13 @@ func flowList(root yaml.Node, env dynaml.Binding, template bool) yaml.Node { if effkey == "" { effkey = "name" } - keys := map[string]bool{} unique := keyName != NO_LIST_KEY if unique { - resolved := true + keys := map[string]bool{} + var step string + var resolved bool for idx, val := range merged.([]yaml.Node) { - var step string - step, resolved, unique = stepName(idx, val, keyName, env, true) + step, _, resolved, unique = stepName(idx, val, keyName, env, true) if !resolved || !unique || keys[step] { unique = false break @@ -510,8 +510,12 @@ func flowList(root yaml.Node, env dynaml.Binding, template bool) yaml.Node { } for idx, val := range merged.([]yaml.Node) { - step, resolved, _ := stepName(idx, val, keyName, env, unique) + step, keyed, resolved, _ := stepName(idx, val, keyName, env, unique) debug.Debug(" step %s\n", step) + _, _ = keyed, nomerge + if !keyed && nomerge { + val = yaml.MergedNode(val) + } if resolved { val = flow(val, env.WithPath(step), false, false) } @@ -579,17 +583,16 @@ func FlowString(root yaml.Node, env dynaml.Binding) (yaml.Node, error) { return yaml.SubstituteNode(expr, root), nil } -func stepName(index int, value yaml.Node, keyName string, env dynaml.Binding, unique bool) (string, bool, bool) { +func stepName(index int, value yaml.Node, keyName string, env dynaml.Binding, unique bool) (stepName string, keyed bool, resolved bool, uni bool) { if keyName == "" { keyName = "name" } if unique { name, ok := yaml.FindString(value, env.GetFeatures(), keyName) if ok { - return keyName + ":" + name, true, true + return keyName + ":" + name, true, true, true } } - step := fmt.Sprintf("[%d]", index) v, ok := yaml.FindR(true, value, env.GetFeatures(), keyName) if ok && v.Value() != nil { @@ -599,20 +602,27 @@ func stepName(index int, value yaml.Node, keyName string, env dynaml.Binding, un v = flow(v, env.WithPath(step), false, false) _, ok := v.Value().(dynaml.Expression) if ok { - return step, false, false + return step, false, false, false } } name, ok := v.Value().(string) if ok && unique { - return keyName + ":" + name, true, true + return keyName + ":" + name, true, true, true } } else { debug.Debug("raw %s not found", keyName) } - return step, true, false + return step, false, true, false +} + +func useMerge(n yaml.Node) bool { + if e, ok := n.Value().(dynaml.Expression); ok { + return dynaml.IncludesDirectMerge(e) + } + return false } -func processMerges(orig yaml.Node, root []yaml.Node, env dynaml.Binding, template bool) (interface{}, bool, bool, []string, string, bool, yaml.NodeFlags, string, yaml.Node) { +func processMerges(orig yaml.Node, root []yaml.Node, env dynaml.Binding, template bool) (interface{}, bool, bool, []string, string, bool, yaml.NodeFlags, string, yaml.Node, bool) { var flags yaml.NodeFlags var stub yaml.Node flags, stub = get_inherited_flags(env) @@ -624,6 +634,24 @@ func processMerges(orig yaml.Node, root []yaml.Node, env dynaml.Binding, templat replaced := orig.ReplaceFlag() redirectPath := orig.RedirectPath() + // first, check for omitted stub merging for non-keyed values + nomerge := false + for _, val := range root { + if val == nil { + continue + } + + inlineNode, _, ok := yaml.UnresolvedListEntryMerge(val) + if ok { + if useMerge(inlineNode) { + // do not merge list entries for list with merge expression because + // the list order would change or the potential merge candidates will + // be inserted. + nomerge = true + } + } + } + for _, val := range root { if val == nil { continue @@ -724,7 +752,7 @@ func processMerges(orig yaml.Node, root []yaml.Node, env dynaml.Binding, templat } debug.Debug("--> %+v proc=%v replaced=%v redirect=%v key=%s\n", result, process, replaced, redirectPath, keyName) - return result, process, replaced, redirectPath, keyName, merged, flags, tag, stub + return result, process, replaced, redirectPath, keyName, merged, flags, tag, stub, nomerge } const NO_LIST_KEY = "<<>" @@ -794,7 +822,7 @@ func newEntries(a []yaml.Node, b []yaml.Node, keyName string) []yaml.Node { } } - added = append(added, val) + added = append(added, yaml.MergedNode(val)) } return added diff --git a/flow/flow2_test.go b/flow/flow2_test.go new file mode 100644 index 0000000..4bb9e43 --- /dev/null +++ b/flow/flow2_test.go @@ -0,0 +1,120 @@ +package flow + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("merging lists", func() { + It("merges map lists", func() { + source := parseYAML(` +--- +list: + - field: e + attr: f + - <<<: (( merge )) +`) + stub := parseYAML(` +--- +list: + - field: a + attr: b + - field: c + attr: d +`) + resolved := parseYAML(` +--- +list: + - field: e + attr: f + - field: a + attr: b + - field: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) + + It("merges map lists with complex merge", func() { + source := parseYAML(` +--- +list: + - field: e + attr: f + - <<<: (( ( merge || ~ ) )) +`) + stub := parseYAML(` +--- +list: + - field: a + attr: b + - field: c + attr: d +`) + resolved := parseYAML(` +--- +list: + - field: e + attr: f + - field: a + attr: b + - field: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) + + It("merges existing and adds new", func() { + source := parseYAML(` +--- +list: + - name: a + attr: b + - <<<: (( merge )) +`) + stub := parseYAML(` +--- +list: + - name: c + attr: d + - name: a + attr: e +`) + resolved := parseYAML(` +--- +list: + - name: a + attr: e + - name: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) + + It("merges existing and adds new with complex merge", func() { + source := parseYAML(` +--- +list: + - name: a + attr: b + - <<<: (( ( merge || ~ ) )) +`) + stub := parseYAML(` +--- +list: + - name: c + attr: d + - name: a + attr: e +`) + resolved := parseYAML(` +--- +list: + - name: a + attr: e + - name: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) +}) diff --git a/go.mod b/go.mod index fef778e..0d31904 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/mandelsoft/spiff -go 1.18 +go 1.22.5 require ( github.com/Masterminds/semver/v3 v3.2.0 From 0e2904660426cb4d59e37ff2cacc681b7a2942aa Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Mon, 9 Sep 2024 09:55:39 +0200 Subject: [PATCH 4/5] handler marker for merge detection --- dynaml/marker.go | 8 +++ flow/flow2_test.go | 137 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 123 insertions(+), 22 deletions(-) diff --git a/dynaml/marker.go b/dynaml/marker.go index 0835b31..071aedf 100644 --- a/dynaml/marker.go +++ b/dynaml/marker.go @@ -23,6 +23,10 @@ type MarkerExpr struct { expr Expression } +func (e MarkerExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.expr) +} + func NewTemplateMarker(expr Expression) MarkerExpr { return MarkerExpr{list: []string{TEMPLATE}, expr: expr} } @@ -144,6 +148,10 @@ type MarkerExpressionExpr struct { expr Expression } +func (e MarkerExpressionExpr) IncludesDirectMerge() bool { + return IncludesDirectMerge(e.expr) +} + func (e MarkerExpressionExpr) String() string { return e.contents } diff --git a/flow/flow2_test.go b/flow/flow2_test.go index 4bb9e43..f9a4b5e 100644 --- a/flow/flow2_test.go +++ b/flow/flow2_test.go @@ -6,15 +6,16 @@ import ( ) var _ = Describe("merging lists", func() { - It("merges map lists", func() { - source := parseYAML(` + Context("unkeyed lists", func() { + It("merges map lists", func() { + source := parseYAML(` --- list: - field: e attr: f - <<<: (( merge )) `) - stub := parseYAML(` + stub := parseYAML(` --- list: - field: a @@ -22,7 +23,7 @@ list: - field: c attr: d `) - resolved := parseYAML(` + resolved := parseYAML(` --- list: - field: e @@ -32,18 +33,48 @@ list: - field: c attr: d `) - Expect(source).To(FlowAs(resolved, stub)) - }) + Expect(source).To(FlowAs(resolved, stub)) + }) - It("merges map lists with complex merge", func() { - source := parseYAML(` + It("merges map lists with marker", func() { + source := parseYAML(` +--- +list : (( temp )) +temp: + - field: e + attr: f + - <<<: (( &temporary(merge) )) +`) + stub := parseYAML(` +--- +temp: + - field: a + attr: b + - field: c + attr: d +`) + resolved := parseYAML(` +--- +list: + - field: e + attr: f + - field: a + attr: b + - field: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) + + It("merges map lists with complex merge", func() { + source := parseYAML(` --- list: - field: e attr: f - <<<: (( ( merge || ~ ) )) `) - stub := parseYAML(` + stub := parseYAML(` --- list: - field: a @@ -51,7 +82,7 @@ list: - field: c attr: d `) - resolved := parseYAML(` + resolved := parseYAML(` --- list: - field: e @@ -61,18 +92,20 @@ list: - field: c attr: d `) - Expect(source).To(FlowAs(resolved, stub)) + Expect(source).To(FlowAs(resolved, stub)) + }) }) - It("merges existing and adds new", func() { - source := parseYAML(` + Context("keyed lists", func() { + It("merges existing and adds new", func() { + source := parseYAML(` --- list: - name: a attr: b - <<<: (( merge )) `) - stub := parseYAML(` + stub := parseYAML(` --- list: - name: c @@ -80,7 +113,7 @@ list: - name: a attr: e `) - resolved := parseYAML(` + resolved := parseYAML(` --- list: - name: a @@ -88,18 +121,46 @@ list: - name: c attr: d `) - Expect(source).To(FlowAs(resolved, stub)) - }) + Expect(source).To(FlowAs(resolved, stub)) + }) + + It("merges existing and adds new with marker", func() { + source := parseYAML(` +--- +list: (( temp )) +temp: + - name: a + attr: b + - <<<: (( &temporary(merge) )) +`) + stub := parseYAML(` +--- +temp: + - name: c + attr: d + - name: a + attr: e +`) + resolved := parseYAML(` +--- +list: + - name: a + attr: e + - name: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) - It("merges existing and adds new with complex merge", func() { - source := parseYAML(` + It("merges existing and adds new with complex merge", func() { + source := parseYAML(` --- list: - name: a attr: b - <<<: (( ( merge || ~ ) )) `) - stub := parseYAML(` + stub := parseYAML(` --- list: - name: c @@ -107,7 +168,7 @@ list: - name: a attr: e `) - resolved := parseYAML(` + resolved := parseYAML(` --- list: - name: a @@ -115,6 +176,38 @@ list: - name: c attr: d `) - Expect(source).To(FlowAs(resolved, stub)) + Expect(source).To(FlowAs(resolved, stub)) + }) + + It("merges map lists with field merge", func() { + source := parseYAML(` +--- +list: + - field: e + attr: f + - field: a + attr: x + - <<<: (( ( merge on field ) )) +`) + stub := parseYAML(` +--- +list: + - field: a + attr: b + - field: c + attr: d +`) + resolved := parseYAML(` +--- +list: + - field: e + attr: f + - field: a + attr: b + - field: c + attr: d +`) + Expect(source).To(FlowAs(resolved, stub)) + }) }) }) From b7af70637d7b7a6ca7e14b6d95abc7b53bf659e3 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Mon, 14 Oct 2024 14:06:39 +0200 Subject: [PATCH 5/5] check for OSFS for OS Access Mode --- flow/state.go | 4 +- go.mod | 13 +- go.sum | 45 +-- spiffing/spiff.go | 6 +- .../mandelsoft/filepath/pkg/filepath/orig.go | 23 ++ .../mandelsoft/filepath/pkg/filepath/path.go | 10 +- .../mandelsoft/vfs/pkg/osfs/osfs.go | 22 ++ .../mandelsoft/vfs/pkg/osfs/tempfs.go | 4 + .../vfs/pkg/projectionfs/projectionfs.go | 25 ++ .../mandelsoft/vfs/pkg/utils/file.go | 14 + .../mandelsoft/vfs/pkg/utils/fssupport.go | 11 +- .../mandelsoft/vfs/pkg/utils/mappedfs.go | 4 - .../github.com/mandelsoft/vfs/pkg/vfs/doc.go | 24 ++ .../mandelsoft/vfs/pkg/vfs/errors.go | 20 ++ .../github.com/mandelsoft/vfs/pkg/vfs/eval.go | 2 +- .../mandelsoft/vfs/pkg/vfs/interface.go | 26 +- .../github.com/mandelsoft/vfs/pkg/vfs/iofs.go | 53 ++++ .../mandelsoft/vfs/pkg/vfs/utils.go | 91 +++++- .../mandelsoft/vfs/pkg/vfs/utils_regular.go | 25 ++ .../mandelsoft/vfs/pkg/vfs/utils_windows.go | 23 ++ .../github.com/mandelsoft/vfs/pkg/vfs/vfs.go | 8 + .../github.com/mandelsoft/vfs/pkg/vfs/walk.go | 12 +- .../github.com/modern-go/reflect2/.gitignore | 2 + .../github.com/modern-go/reflect2/.travis.yml | 15 + .../github.com/modern-go/reflect2/Gopkg.lock | 9 + .../github.com/modern-go/reflect2/Gopkg.toml | 31 ++ vendor/github.com/modern-go/reflect2/LICENSE | 201 ++++++++++++ .../github.com/modern-go/reflect2/README.md | 71 +++++ .../modern-go/reflect2/go_above_118.go | 23 ++ .../modern-go/reflect2/go_above_19.go | 17 + .../modern-go/reflect2/go_below_118.go | 21 ++ .../github.com/modern-go/reflect2/reflect2.go | 300 ++++++++++++++++++ .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 ++ .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 ++++ .../github.com/modern-go/reflect2/safe_map.go | 101 ++++++ .../modern-go/reflect2/safe_slice.go | 92 ++++++ .../modern-go/reflect2/safe_struct.go | 29 ++ .../modern-go/reflect2/safe_type.go | 78 +++++ .../github.com/modern-go/reflect2/type_map.go | 70 ++++ .../modern-go/reflect2/unsafe_array.go | 65 ++++ .../modern-go/reflect2/unsafe_eface.go | 59 ++++ .../modern-go/reflect2/unsafe_field.go | 74 +++++ .../modern-go/reflect2/unsafe_iface.go | 64 ++++ .../modern-go/reflect2/unsafe_link.go | 76 +++++ .../modern-go/reflect2/unsafe_map.go | 130 ++++++++ .../modern-go/reflect2/unsafe_ptr.go | 46 +++ .../modern-go/reflect2/unsafe_slice.go | 177 +++++++++++ .../modern-go/reflect2/unsafe_struct.go | 59 ++++ .../modern-go/reflect2/unsafe_type.go | 85 +++++ vendor/modules.txt | 19 +- 59 files changed, 2385 insertions(+), 82 deletions(-) create mode 100644 vendor/github.com/mandelsoft/vfs/pkg/vfs/doc.go create mode 100644 vendor/github.com/mandelsoft/vfs/pkg/vfs/iofs.go create mode 100644 vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_regular.go create mode 100644 vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_windows.go create mode 100644 vendor/github.com/modern-go/reflect2/.gitignore create mode 100644 vendor/github.com/modern-go/reflect2/.travis.yml create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.lock create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.toml create mode 100644 vendor/github.com/modern-go/reflect2/LICENSE create mode 100644 vendor/github.com/modern-go/reflect2/README.md create mode 100644 vendor/github.com/modern-go/reflect2/go_above_118.go create mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_118.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s create mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go create mode 100644 vendor/github.com/modern-go/reflect2/type_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go diff --git a/flow/state.go b/flow/state.go index d4c01c8..61f91ef 100644 --- a/flow/state.go +++ b/flow/state.go @@ -75,7 +75,9 @@ func NewState(key string, mode int, optfs ...vfs.FileSystem) *State { if fs == nil { fs = osfs.New() } else { - mode = mode & ^MODE_OS_ACCESS + if !osfs.IsOsFileSystem(fs) { + mode = mode & ^MODE_OS_ACCESS + } } return &State{ tags: map[string]*dynaml.TagInfo{}, diff --git a/go.mod b/go.mod index 0d31904..2593c43 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ go 1.22.5 require ( github.com/Masterminds/semver/v3 v3.2.0 github.com/cloudfoundry-incubator/candiedyaml v0.0.0-20170901234223-a41693b7b7af - github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31 + github.com/mandelsoft/vfs v0.4.4 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.24.2 github.com/pointlander/peg v0.0.0-20160608205303-1d0268dfff9b github.com/spf13/cobra v1.6.1 github.com/spf13/viper v1.14.0 - golang.org/x/crypto v0.1.0 + golang.org/x/crypto v0.10.0 ) require ( @@ -20,8 +20,9 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55 // indirect + github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect @@ -32,9 +33,9 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.1 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 2bd5d15..8833872 100644 --- a/go.sum +++ b/go.sum @@ -40,7 +40,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/b4b4r07/go-pipe v0.0.0-20191010045404-84b446f57366/go.mod h1:1ymsiQNa3qebVEEVtuIdhtAXRfjO4qFCFq1bBUOT2HE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -62,6 +61,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -70,6 +70,7 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -97,6 +98,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -137,33 +139,38 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/joncalhoun/pipe v0.0.0-20170510025636-72505674a733/go.mod h1:2MNFZhLx2HMHTN4xKH6FhpoQWqmD8Ato8QOE2hp5hY4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55 h1:mFdiUG86O2iW+iDEpZKXf64efMWO4JvDT+zN3znUGIc= -github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55/go.mod h1:n4xEiUD2HNHnn2w5ZKF0qgjDecHVCWAl5DxZ7+pcFU8= -github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31 h1:5gmUtnP0NYOODvS/gTeQOJKSu4W8bOUImDiKdAb/j1A= -github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31/go.mod h1:74aV7kulg9C434HiI3zNALN79QHc9IZMN+SI4UdLn14= +github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 h1:oo9nIgnyiBgYPbcZslRT4y29siuL5EoNJ/t1tr0xEVQ= +github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= +github.com/mandelsoft/vfs v0.4.4-0.20241014115001-f20e8f398723 h1:0uXhqGTYDJqy9zaQbQVZ9uioErrNDixPT+G5hT3J4mI= +github.com/mandelsoft/vfs v0.4.4-0.20241014115001-f20e8f398723/go.mod h1:3ODt1ze/dCdOJCbhHX8ARAw7l422fDZUhbt0wqplBRs= +github.com/mandelsoft/vfs v0.4.4 h1:hq+nI7NWzLLWR3Ii/w4agup4KpWjLpw6dAGtmvWr1Vw= +github.com/mandelsoft/vfs v0.4.4/go.mod h1:3ODt1ze/dCdOJCbhHX8ARAw7l422fDZUhbt0wqplBRs= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q= +github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= @@ -185,6 +192,7 @@ github.com/pointlander/peg v0.0.0-20160608205303-1d0268dfff9b/go.mod h1:WJTMcgeW github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= @@ -207,6 +215,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -226,8 +235,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -294,8 +303,8 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -342,7 +351,6 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -356,18 +364,19 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -512,6 +521,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -519,7 +529,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544/go.mod h1:UhTeH/yXCK/KY7TX24mqPkaQ7gZeqmWd/8SSS8B3aHw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/spiffing/spiff.go b/spiffing/spiff.go index c6eb967..dc572de 100644 --- a/spiffing/spiff.go +++ b/spiffing/spiff.go @@ -170,7 +170,7 @@ func (s spiff) WithEncryptionKey(key string) Spiff { // WithMode creates a new context with the given processing mode. // (see MODE constants) func (s spiff) WithMode(mode int) Spiff { - if s.fs != nil { + if s.fs != nil && !osfs.IsOsFileSystem(s.fs) { mode = mode & ^MODE_OS_ACCESS } s.mode = mode @@ -179,11 +179,11 @@ func (s spiff) WithMode(mode int) Spiff { // WithFileSystem creates a new context with the given // virtual filesystem used for filesystem functions during -// prcessing. Setting a filesystem disables the command +// processing. Setting a filesystem disables the command // execution functions. func (s spiff) WithFileSystem(fs vfs.FileSystem) Spiff { s.fs = fs - if fs != nil { + if s.fs != nil && !osfs.IsOsFileSystem(s.fs) { s.mode = s.mode & ^MODE_OS_ACCESS } return s.Reset() diff --git a/vendor/github.com/mandelsoft/filepath/pkg/filepath/orig.go b/vendor/github.com/mandelsoft/filepath/pkg/filepath/orig.go index 734f120..dc8bd0d 100644 --- a/vendor/github.com/mandelsoft/filepath/pkg/filepath/orig.go +++ b/vendor/github.com/mandelsoft/filepath/pkg/filepath/orig.go @@ -4,6 +4,10 @@ import ( orig "path/filepath" ) +func IsAbs(path string) bool { + return orig.IsAbs(path) +} + func ToSlash(path string) string { return orig.ToSlash(path) } @@ -37,6 +41,10 @@ func Rel(basepath, targpath string) (string, error) { if err != nil { return "", err } + targpath, err = Canonical(targpath, false) + if err != nil { + return "", err + } targpath, err = EvalSymlinks(targpath) if err != nil { return "", err @@ -49,6 +57,11 @@ func Rel(basepath, targpath string) (string, error) { // as an error by any function. var SkipDir = orig.SkipDir +// SkipAll is used as a return value from WalkFuncs to indicate that +// all remaining files and directories are to be skipped. It is not returned +// as an error by any function. +// var SkipAll = orig.SkipAll + // WalkFunc is the type of the function called for each file or directory // visited by Walk. The path argument contains the argument to Walk as a // prefix; that is, if Walk is called with "dir", which is a directory @@ -69,3 +82,13 @@ type WalkFunc orig.WalkFunc func Walk(root string, walkFn WalkFunc) error { return orig.Walk(root, orig.WalkFunc(walkFn)) } + +var ErrBadPattern = orig.ErrBadPattern + +func Match(pattern, name string) (matched bool, err error) { + return orig.Match(pattern, name) +} + +func Glob(pattern string) (matches []string, err error) { + return orig.Glob(pattern) +} diff --git a/vendor/github.com/mandelsoft/filepath/pkg/filepath/path.go b/vendor/github.com/mandelsoft/filepath/pkg/filepath/path.go index 9e43f02..00e445e 100644 --- a/vendor/github.com/mandelsoft/filepath/pkg/filepath/path.go +++ b/vendor/github.com/mandelsoft/filepath/pkg/filepath/path.go @@ -41,13 +41,6 @@ func debug(f string, args ...interface{}) { } } -// IsAbs return true if the given path is an absolute one -// starting with a Separator or is quailified by a volume name. -func IsAbs(path string) bool { - return strings.HasPrefix(path, PathSeparatorString) || - strings.HasPrefix(path, VolumeName(path)+PathSeparatorString) -} - // Canonical returns the canonical absolute path of a file. // If exist=false the denoted file must not exist, but // then the part of the initial path refering to a not existing @@ -104,7 +97,7 @@ func walk(p string, parent int, exist bool) (string, error) { for !IsRoot(p) && p != "" { n, b := Split2(p) if b == "" { - fmt.Printf("debug: ignoring empty base -> %s \n", n) + debug("debug: ignoring empty base -> %s \n", n) p = n continue } @@ -250,7 +243,6 @@ func Base(path string) string { // Trim eleminates additional slashes and dot segments from a path name. // An empty path is unchanged. -// func Trim(path string) string { vol := VolumeName(path) i := len(path) - 1 diff --git a/vendor/github.com/mandelsoft/vfs/pkg/osfs/osfs.go b/vendor/github.com/mandelsoft/vfs/pkg/osfs/osfs.go index 3b0e47b..220b22b 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/osfs/osfs.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/osfs/osfs.go @@ -23,11 +23,33 @@ import ( "time" "github.com/mandelsoft/filepath/pkg/filepath" + "github.com/modern-go/reflect2" "github.com/mandelsoft/vfs/pkg/utils" "github.com/mandelsoft/vfs/pkg/vfs" ) +var OsFs = &osFileSystem{} + +// OsFsCheck should be implemented by forwarding wrappers +// to check for an OS Filesystem implementation. +type OsFsCheck interface { + IsOsFileSystem() bool +} + +func IsOsFileSystem(fs vfs.FileSystem) bool { + if reflect2.IsNil(fs) { + return false + } + if _, ok := fs.(*osFileSystem); ok { + return true + } + if c, ok := fs.(OsFsCheck); ok { + return c.IsOsFileSystem() + } + return false +} + type osFileSystem struct { } diff --git a/vendor/github.com/mandelsoft/vfs/pkg/osfs/tempfs.go b/vendor/github.com/mandelsoft/vfs/pkg/osfs/tempfs.go index 3bf1463..a26e535 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/osfs/tempfs.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/osfs/tempfs.go @@ -48,3 +48,7 @@ func NewTempFileSystem() (vfs.FileSystem, error) { func (t *tempfs) Cleanup() error { return os.RemoveAll(t.dir) } + +func (t *tempfs) Root() string { + return t.dir +} diff --git a/vendor/github.com/mandelsoft/vfs/pkg/projectionfs/projectionfs.go b/vendor/github.com/mandelsoft/vfs/pkg/projectionfs/projectionfs.go index 91e68c4..7143008 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/projectionfs/projectionfs.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/projectionfs/projectionfs.go @@ -25,6 +25,20 @@ import ( "github.com/mandelsoft/vfs/pkg/vfs" ) +// RootPath is the interface for projected filesystems +// to determine the root folder in the underlying +// filesystem. +type RootPath interface { + Root() string +} + +func Root(fs vfs.FileSystem) string { + if r, ok := fs.(RootPath); ok { + return r.Root() + } + return "" +} + type ProjectionFileSystem struct { *utils.MappedFileSystem projection string @@ -51,3 +65,14 @@ func New(base vfs.FileSystem, path string) (vfs.FileSystem, error) { func (p *ProjectionFileSystem) Name() string { return fmt.Sprintf("ProjectionFilesytem [%s]%s", p.Base().Name(), p.projection) } + +func (p *ProjectionFileSystem) Projection() string { + return p.projection +} + +func (p *ProjectionFileSystem) Root() string { + if r, ok := p.Base().(RootPath); ok { + return vfs.Join(p, r.Root(), p.projection) + } + return p.projection +} diff --git a/vendor/github.com/mandelsoft/vfs/pkg/utils/file.go b/vendor/github.com/mandelsoft/vfs/pkg/utils/file.go index 01a8e86..b12543c 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/utils/file.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/utils/file.go @@ -22,6 +22,7 @@ import ( "bytes" "errors" "io" + "io/fs" "os" "sort" "time" @@ -86,6 +87,19 @@ func (f *File) Sync() error { return nil } +func (f *File) ReadDir(count int) (files []fs.DirEntry, err error) { + o, err := f.Readdir(count) + + if err != nil { + return nil, err + } + r := make([]fs.DirEntry, len(o), len(o)) + for i, v := range o { + r[i] = fs.FileInfoToDirEntry(v) + } + return r, nil +} + func (f *File) Readdir(count int) (files []os.FileInfo, err error) { if !f.fileData.IsDir() { return nil, &os.PathError{Op: "readdir", Path: f.name, Err: ErrNotDir} diff --git a/vendor/github.com/mandelsoft/vfs/pkg/utils/fssupport.go b/vendor/github.com/mandelsoft/vfs/pkg/utils/fssupport.go index a14e8ce..de4b645 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/utils/fssupport.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/utils/fssupport.go @@ -20,6 +20,7 @@ package utils import ( "errors" + "io/fs" "os" "strings" "time" @@ -77,7 +78,15 @@ func (m *FileSystemSupport) Create(name string) (vfs.File, error) { return nil, err } if f != nil { - return nil, os.ErrExist + if f.Mode()&fs.ModeType != 0 { + return nil, fs.ErrExist + } + h := newFileHandle(n, f) + err := h.Truncate(0) + if err != nil { + return nil, err + } + return h, nil } f = m.adapter.CreateFile(os.ModePerm) diff --git a/vendor/github.com/mandelsoft/vfs/pkg/utils/mappedfs.go b/vendor/github.com/mandelsoft/vfs/pkg/utils/mappedfs.go index 6ec12c7..d530dc7 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/utils/mappedfs.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/utils/mappedfs.go @@ -53,10 +53,6 @@ func (m *MappedFileSystem) Base() vfs.FileSystem { return m.base } -func (m *MappedFileSystem) VolumeName(name string) string { - return m.base.VolumeName(name) -} - func (m *MappedFileSystem) FSTempDir() string { return vfs.PathSeparatorString } diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/doc.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/doc.go new file mode 100644 index 0000000..8a57e7f --- /dev/null +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/doc.go @@ -0,0 +1,24 @@ +/* + * Copyright 2022 Mandelsoft. All rights reserved. + * This file is licensed under the Apache Software License, v. 2 except as noted + * otherwise in the LICENSE file + * + * Licensed 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 vfs provides a virtual filesystem for GO. It is the main package +// providing the abstract interfaces and implementation-agnostic +// utility functions wrapped together with an implementation into a +// comprehensive user interface VFS. +// (see https://pkg.go.dev/github.com/mandelsoft/vfs) +package vfs diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/errors.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/errors.go index d11a2e9..b9d6de1 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/vfs/errors.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/errors.go @@ -48,6 +48,25 @@ func MatchErr(err error, match ErrorMatcher, base error) bool { return false } +func IsNotExist(err error) bool { + return IsErrNotExist(err) +} + +func IsExist(err error) bool { + return IsErrExist(err) +} + +func IsPermission(err error) bool { + return IsErrPermission(err) +} + +func IsErrPermission(err error) bool { + if os.IsPermission(err) { + return true + } + return MatchErr(err, os.IsPermission, ErrPermission) +} + func IsErrNotDir(err error) bool { return MatchErr(err, isUnderlyingErrNotDir, ErrNotDir) } @@ -76,6 +95,7 @@ func NewPathError(op string, path string, err error) error { var ErrNotDir = errors.New("is no directory") var ErrNotExist = os.ErrNotExist +var ErrPermission = os.ErrPermission var ErrExist = os.ErrExist var ErrReadOnly = errors.New("filehandle is not writable") diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/eval.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/eval.go index 4bba749..57577fb 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/vfs/eval.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/eval.go @@ -69,7 +69,7 @@ outer: } p := next if rooted { - p = PathSeparatorString + next + p = vol + PathSeparatorString + next } fi, err := fs.Lstat(p) if err != nil { diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/interface.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/interface.go index af168bd..672f237 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/vfs/interface.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/interface.go @@ -20,6 +20,7 @@ package vfs import ( "io" + "io/fs" "os" "time" ) @@ -28,6 +29,8 @@ const PathSeparatorChar = '/' const PathSeparatorString = "/" type FileMode = os.FileMode +type FileInfo = os.FileInfo +type DirEntry = fs.DirEntry const ModePerm = os.ModePerm @@ -76,17 +79,17 @@ type FileSystem interface { // Mkdir creates a directory in the filesystem, return an error if any // happens. - Mkdir(name string, perm os.FileMode) error + Mkdir(name string, perm FileMode) error // MkdirAll creates a directory path and all parents that does not exist // yet. - MkdirAll(path string, perm os.FileMode) error + MkdirAll(path string, perm FileMode) error // Open opens a file, returning it or an error, if any happens. Open(name string) (File, error) // OpenFile opens a file using the given flags and the given mode. - OpenFile(name string, flags int, perm os.FileMode) (File, error) + OpenFile(name string, flags int, perm FileMode) (File, error) // Remove removes a file identified by name, returning an error, if any // happens. @@ -101,13 +104,13 @@ type FileSystem interface { // Stat returns a FileInfo describing the named file, or an error, if any // happens. - Stat(name string) (os.FileInfo, error) + Stat(name string) (FileInfo, error) // Lstat returns a FileInfo describing the named file, or an error, if any // happens. // If the file is a symbolic link, the returned FileInfo // describes the symbolic link. Lstat makes no attempt to follow the link. - Lstat(name string) (os.FileInfo, error) + Lstat(name string) (FileInfo, error) // Create a symlink if supported Symlink(oldname, newname string) error @@ -119,7 +122,7 @@ type FileSystem interface { Name() string // Chmod changes the mode of the named file to mode. - Chmod(name string, mode os.FileMode) error + Chmod(name string, mode FileMode) error // Chtimes changes the access and modification times of the named file Chtimes(name string, atime time.Time, mtime time.Time) error @@ -151,9 +154,10 @@ type File interface { io.WriterAt Name() string - Readdir(count int) ([]os.FileInfo, error) + ReadDir(count int) ([]DirEntry, error) + Readdir(count int) ([]FileInfo, error) Readdirnames(n int) ([]string, error) - Stat() (os.FileInfo, error) + Stat() (FileInfo, error) Sync() error Truncate(size int64) error WriteString(s string) (ret int, err error) @@ -166,6 +170,7 @@ type VFS interface { Join(elems ...string) string Split(path string) (string, string) + Components(path string) (string, []string) Base(path string) string Dir(path string) string Clean(path string) string @@ -177,6 +182,7 @@ type VFS interface { Canonical(path string, exist bool) (string, error) Abs(path string) (string, error) + Rel(src, tgt string) (string, error) EvalSymlinks(path string) (string, error) Walk(path string, fn WalkFunc) error @@ -186,9 +192,9 @@ type VFS interface { IsDir(path string) (bool, error) IsFile(path string) (bool, error) - ReadDir(path string) ([]os.FileInfo, error) + ReadDir(path string) ([]FileInfo, error) ReadFile(path string) ([]byte, error) - WriteFile(path string, data []byte, mode os.FileMode) error + WriteFile(path string, data []byte, mode FileMode) error TempFile(dir, prefix string) (File, error) TempDir(dir, prefix string) (string, error) } diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/iofs.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/iofs.go new file mode 100644 index 0000000..feb4182 --- /dev/null +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/iofs.go @@ -0,0 +1,53 @@ +/* + * Copyright 2023 Mandelsoft. All rights reserved. + * This file is licensed under the Apache Software License, v. 2 except as noted + * otherwise in the LICENSE file + * + * Licensed 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 vfs + +import ( + "io/fs" + "sort" +) + +type iofs struct { + FileSystem +} + +var ( + _ fs.File = File(nil) + _ fs.ReadDirFile = File(nil) +) + +func (i *iofs) Open(name string) (fs.File, error) { + return i.FileSystem.Open(name) +} + +func (i *iofs) ReadDir(name string) ([]fs.DirEntry, error) { + f, err := i.FileSystem.Open(name) + if err != nil { + return nil, err + } + defer f.Close() + dirs, err := f.ReadDir(-1) + sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() }) + return dirs, err +} + +// AsIoFS maps a virtual filesystem +func AsIoFS(fs FileSystem) fs.ReadDirFS { + return &iofs{fs} +} diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils.go index e128531..e08deac 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils.go @@ -21,6 +21,7 @@ package vfs import ( "bytes" "errors" + "fmt" "io" "os" "path" @@ -60,12 +61,12 @@ func Join(fs FileSystem, elems ...string) string { // by purely lexical processing. It applies the following rules // iteratively until no further processing can be done: // -// 1. Replace multiple path separators with a single one. -// 2. Eliminate each . path name element (the current directory). -// 3. Eliminate each inner .. path name element (the parent directory) -// along with the non-.. element that precedes it. -// 4. Eliminate .. elements that begin a rooted path: -// that is, replace "/.." by "/" at the beginning of a path. +// 1. Replace multiple path separators with a single one. +// 2. Eliminate each . path name element (the current directory). +// 3. Eliminate each inner .. path name element (the parent directory) +// along with the non-.. element that precedes it. +// 4. Eliminate .. elements that begin a rooted path: +// that is, replace "/.." by "/" at the beginning of a path. // // The returned path ends in a slash only if it is the root "/". // @@ -192,12 +193,8 @@ func Trim(fs FileSystem, path string) string { func IsAbs(fs FileSystem, path string) bool { if fs != nil { _, path = SplitVolume(fs, path) - } else { - if strings.HasPrefix(path, string(os.PathSeparator)) { - return true - } } - return strings.HasPrefix(path, PathSeparatorString) + return len(path) > 0 && isSlash(path[0]) } // IsRoot determines whether a given path is a root path. @@ -205,7 +202,7 @@ func IsAbs(fs FileSystem, path string) bool { // a volume name. func IsRoot(fs FileSystem, path string) bool { _, path = SplitVolume(fs, path) - return path == PathSeparatorString + return len(path) == 1 && isSlash(path[0]) } func SplitVolume(fs FileSystem, path string) (string, string) { @@ -267,6 +264,68 @@ func Abs(fs FileSystem, path string) (string, error) { return Join(fs, p, path), nil } +// Rel determines the relative path from a source folder +// to a target file. +func Rel(fs FileSystem, src, tgt string) (string, error) { + if ok, _ := Exists(fs, src); ok { + if ok, _ := IsDir(fs, src); !ok { + return "", ErrNotDir + } + } + s, err := Canonical(fs, src, false) + if err != nil { + return "", fmt.Errorf("%s: %w", src, err) + } + + t, err := Canonical(fs, tgt, false) + if err != nil { + return "", fmt.Errorf("%s: %w", tgt, err) + } + + vs, sseq := Components(fs, s) + vt, tseq := Components(fs, t) + if vs != vt { + return "", fmt.Errorf("different volumes") + } + + if s == t { + return ".", nil + } + var is int + for is = 0; is < len(sseq); is++ { + if len(tseq) <= is || tseq[is] != sseq[is] { + break + } + } + + for i := is; i < len(sseq); i++ { + sseq[i] = ".." + } + + if is < len(tseq) { + return Join(fs, append(sseq[is:], tseq[is:]...)...), nil + } + return Join(fs, sseq[is:]...), nil +} + +// Components splits a path into its volume part and a list +// of path components. +func Components(fs FileSystem, p string) (string, []string) { + var seq []string + var b string + + v, p := SplitVolume(fs, p) + + for p != "" && !IsRoot(fs, p) { + p, b = Split(fs, p) + seq = append(seq, b) + } + for i := 0; i < len(seq)/2; i++ { + seq[i], seq[len(seq)-i-1] = seq[len(seq)-i-1], seq[i] + } + return v, seq +} + // Split splits path immediately following the final Separator, // separating it into a directory and file name component. // If there is no Separator in path, Split returns an empty dir @@ -312,7 +371,7 @@ func SplitPath(fs FileSystem, path string) (string, []string, bool) { } func Exists_(err error) bool { - return err == nil || !os.IsNotExist(err) + return err == nil || !IsNotExist(err) } // Exists checks if a file or directory exists. @@ -321,7 +380,7 @@ func Exists(fs FileSystem, path string) (bool, error) { if err == nil { return true, nil } - if os.IsNotExist(err) { + if IsNotExist(err) { return false, nil } return false, err @@ -333,7 +392,7 @@ func DirExists(fs FileSystem, path string) (bool, error) { if err == nil && fi.IsDir() { return true, nil } - if os.IsNotExist(err) { + if IsNotExist(err) { return false, nil } return false, err @@ -345,7 +404,7 @@ func FileExists(fs FileSystem, path string) (bool, error) { if err == nil && fi.Mode()&os.ModeType == 0 { return true, nil } - if os.IsNotExist(err) { + if IsNotExist(err) { return false, nil } return false, err diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_regular.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_regular.go new file mode 100644 index 0000000..226d61d --- /dev/null +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_regular.go @@ -0,0 +1,25 @@ +//go:build !windows +// +build !windows + +/* + * Copyright 2024 Mandelsoft. All rights reserved. + * This file is licensed under the Apache Software License, v. 2 except as noted + * otherwise in the LICENSE file + * + * Licensed 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 vfs + +func isSlash(c uint8) bool { + return c == '/' +} diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_windows.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_windows.go new file mode 100644 index 0000000..2a6947d --- /dev/null +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/utils_windows.go @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Mandelsoft. All rights reserved. + * This file is licensed under the Apache Software License, v. 2 except as noted + * otherwise in the LICENSE file + * + * Licensed 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 vfs + +func isSlash(c uint8) bool { + return c == '\\' || c == '/' +} diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/vfs.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/vfs.go index 7226e0e..85b0865 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/vfs/vfs.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/vfs.go @@ -81,6 +81,14 @@ func (fs *vfs) Abs(path string) (string, error) { return Abs(fs, path) } +func (fs *vfs) Rel(src, tgt string) (string, error) { + return Rel(fs, src, tgt) +} + +func (fs *vfs) Components(path string) (string, []string) { + return Components(fs, path) +} + func (fs *vfs) EvalSymlinks(path string) (string, error) { return EvalSymlinks(fs, path) } diff --git a/vendor/github.com/mandelsoft/vfs/pkg/vfs/walk.go b/vendor/github.com/mandelsoft/vfs/pkg/vfs/walk.go index 74e2b4f..4df35e8 100644 --- a/vendor/github.com/mandelsoft/vfs/pkg/vfs/walk.go +++ b/vendor/github.com/mandelsoft/vfs/pkg/vfs/walk.go @@ -20,7 +20,6 @@ package vfs import ( "os" - fp "path/filepath" "sort" "github.com/mandelsoft/filepath/pkg/filepath" @@ -45,9 +44,12 @@ func readDirNames(fs FileSystem, dirname string) ([]string, error) { // adapted from https://golang.org/src/path/filepath/path.go func walkFS(fs FileSystem, path string, info os.FileInfo, err error, walkFn WalkFunc) error { - err = walkFn(path, info, err) - if err != nil { - return err + err1 := walkFn(path, info, err) + if err != nil || err1 != nil { + if err1 == SkipDir { + return nil + } + return err1 } if info == nil || !info.IsDir() { @@ -57,7 +59,7 @@ func walkFS(fs FileSystem, path string, info os.FileInfo, err error, walkFn Walk names, err := readDirNames(fs, path) if err != nil { err := walkFn(path, info, err) - if err == fp.SkipDir { + if err == SkipDir { return nil } return err diff --git a/vendor/github.com/modern-go/reflect2/.gitignore b/vendor/github.com/modern-go/reflect2/.gitignore new file mode 100644 index 0000000..7b26c94 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/.gitignore @@ -0,0 +1,2 @@ +/vendor +/coverage.txt diff --git a/vendor/github.com/modern-go/reflect2/.travis.yml b/vendor/github.com/modern-go/reflect2/.travis.yml new file mode 100644 index 0000000..b097728 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/.travis.yml @@ -0,0 +1,15 @@ +language: go + +go: + - 1.9.x + - 1.x + +before_install: + - go get -t -v ./... + - go get -t -v github.com/modern-go/reflect2-tests/... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.lock b/vendor/github.com/modern-go/reflect2/Gopkg.lock new file mode 100644 index 0000000..10ef811 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/Gopkg.lock @@ -0,0 +1,9 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/modern-go/reflect2/Gopkg.toml b/vendor/github.com/modern-go/reflect2/Gopkg.toml new file mode 100644 index 0000000..a9bc506 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/Gopkg.toml @@ -0,0 +1,31 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + +ignored = [] + +[prune] + go-tests = true + unused-packages = true diff --git a/vendor/github.com/modern-go/reflect2/LICENSE b/vendor/github.com/modern-go/reflect2/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/vendor/github.com/modern-go/reflect2/README.md b/vendor/github.com/modern-go/reflect2/README.md new file mode 100644 index 0000000..6f968aa --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/README.md @@ -0,0 +1,71 @@ +# reflect2 + +[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/reflect2/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/reflect2?badge) +[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/reflect2) +[![Build Status](https://travis-ci.org/modern-go/reflect2.svg?branch=master)](https://travis-ci.org/modern-go/reflect2) +[![codecov](https://codecov.io/gh/modern-go/reflect2/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/reflect2) +[![rcard](https://goreportcard.com/badge/github.com/modern-go/reflect2)](https://goreportcard.com/report/github.com/modern-go/reflect2) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE) + +reflect api that avoids runtime reflect.Value cost + +* reflect get/set interface{}, with type checking +* reflect get/set unsafe.Pointer, without type checking +* `reflect2.TypeByName` works like `Class.forName` found in java + +[json-iterator](https://github.com/json-iterator/go) use this package to save runtime dispatching cost. +This package is designed for low level libraries to optimize reflection performance. +General application should still use reflect standard library. + +# reflect2.TypeByName + +```go +// given package is github.com/your/awesome-package +type MyStruct struct { + // ... +} + +// will return the type +reflect2.TypeByName("awesome-package.MyStruct") +// however, if the type has not been used +// it will be eliminated by compiler, so we can not get it in runtime +``` + +# reflect2 get/set interface{} + +```go +valType := reflect2.TypeOf(1) +i := 1 +j := 10 +valType.Set(&i, &j) +// i will be 10 +``` + +to get set `type`, always use its pointer `*type` + +# reflect2 get/set unsafe.Pointer + +```go +valType := reflect2.TypeOf(1) +i := 1 +j := 10 +valType.UnsafeSet(unsafe.Pointer(&i), unsafe.Pointer(&j)) +// i will be 10 +``` + +to get set `type`, always use its pointer `*type` + +# benchmark + +Benchmark is not necessary for this package. It does nothing actually. +As it is just a thin wrapper to make go runtime public. +Both `reflect2` and `reflect` call same function +provided by `runtime` package exposed by go language. + +# unsafe safety + +Instead of casting `[]byte` to `sliceHeader` in your application using unsafe. +We can use reflect2 instead. This way, if `sliceHeader` changes in the future, +only reflect2 need to be upgraded. + +reflect2 tries its best to keep the implementation same as reflect (by testing). \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/go_above_118.go b/vendor/github.com/modern-go/reflect2/go_above_118.go new file mode 100644 index 0000000..2b4116f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_above_118.go @@ -0,0 +1,23 @@ +//+build go1.18 + +package reflect2 + +import ( + "unsafe" +) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter) + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + var it hiter + mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it) + return &UnsafeMapIterator{ + hiter: &it, + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/go_above_19.go b/vendor/github.com/modern-go/reflect2/go_above_19.go new file mode 100644 index 0000000..974f768 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_above_19.go @@ -0,0 +1,17 @@ +//+build go1.9 + +package reflect2 + +import ( + "unsafe" +) + +//go:linkname resolveTypeOff reflect.resolveTypeOff +func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer + +//go:linkname makemap reflect.makemap +func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer) + +func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer { + return makemap(rtype, cap) +} diff --git a/vendor/github.com/modern-go/reflect2/go_below_118.go b/vendor/github.com/modern-go/reflect2/go_below_118.go new file mode 100644 index 0000000..00003db --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/go_below_118.go @@ -0,0 +1,21 @@ +//+build !go1.18 + +package reflect2 + +import ( + "unsafe" +) + +// m escapes into the return value, but the caller of mapiterinit +// doesn't let the return value escape. +//go:noescape +//go:linkname mapiterinit reflect.mapiterinit +func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) (val *hiter) + +func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + return &UnsafeMapIterator{ + hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)), + pKeyRType: type2.pKeyRType, + pElemRType: type2.pElemRType, + } +} \ No newline at end of file diff --git a/vendor/github.com/modern-go/reflect2/reflect2.go b/vendor/github.com/modern-go/reflect2/reflect2.go new file mode 100644 index 0000000..c43c8b9 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/reflect2.go @@ -0,0 +1,300 @@ +package reflect2 + +import ( + "reflect" + "runtime" + "sync" + "unsafe" +) + +type Type interface { + Kind() reflect.Kind + // New return pointer to data of this type + New() interface{} + // UnsafeNew return the allocated space pointed by unsafe.Pointer + UnsafeNew() unsafe.Pointer + // PackEFace cast a unsafe pointer to object represented pointer + PackEFace(ptr unsafe.Pointer) interface{} + // Indirect dereference object represented pointer to this type + Indirect(obj interface{}) interface{} + // UnsafeIndirect dereference pointer to this type + UnsafeIndirect(ptr unsafe.Pointer) interface{} + // Type1 returns reflect.Type + Type1() reflect.Type + Implements(thatType Type) bool + String() string + RType() uintptr + // interface{} of this type has pointer like behavior + LikePtr() bool + IsNullable() bool + IsNil(obj interface{}) bool + UnsafeIsNil(ptr unsafe.Pointer) bool + Set(obj interface{}, val interface{}) + UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) + AssignableTo(anotherType Type) bool +} + +type ListType interface { + Type + Elem() Type + SetIndex(obj interface{}, index int, elem interface{}) + UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) + GetIndex(obj interface{}, index int) interface{} + UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer +} + +type ArrayType interface { + ListType + Len() int +} + +type SliceType interface { + ListType + MakeSlice(length int, cap int) interface{} + UnsafeMakeSlice(length int, cap int) unsafe.Pointer + Grow(obj interface{}, newLength int) + UnsafeGrow(ptr unsafe.Pointer, newLength int) + Append(obj interface{}, elem interface{}) + UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) + LengthOf(obj interface{}) int + UnsafeLengthOf(ptr unsafe.Pointer) int + SetNil(obj interface{}) + UnsafeSetNil(ptr unsafe.Pointer) + Cap(obj interface{}) int + UnsafeCap(ptr unsafe.Pointer) int +} + +type StructType interface { + Type + NumField() int + Field(i int) StructField + FieldByName(name string) StructField + FieldByIndex(index []int) StructField + FieldByNameFunc(match func(string) bool) StructField +} + +type StructField interface { + Offset() uintptr + Name() string + PkgPath() string + Type() Type + Tag() reflect.StructTag + Index() []int + Anonymous() bool + Set(obj interface{}, value interface{}) + UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) + Get(obj interface{}) interface{} + UnsafeGet(obj unsafe.Pointer) unsafe.Pointer +} + +type MapType interface { + Type + Key() Type + Elem() Type + MakeMap(cap int) interface{} + UnsafeMakeMap(cap int) unsafe.Pointer + SetIndex(obj interface{}, key interface{}, elem interface{}) + UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) + TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) + GetIndex(obj interface{}, key interface{}) interface{} + UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer + Iterate(obj interface{}) MapIterator + UnsafeIterate(obj unsafe.Pointer) MapIterator +} + +type MapIterator interface { + HasNext() bool + Next() (key interface{}, elem interface{}) + UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer) +} + +type PtrType interface { + Type + Elem() Type +} + +type InterfaceType interface { + NumMethod() int +} + +type Config struct { + UseSafeImplementation bool +} + +type API interface { + TypeOf(obj interface{}) Type + Type2(type1 reflect.Type) Type +} + +var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze() +var ConfigSafe = Config{UseSafeImplementation: true}.Froze() + +type frozenConfig struct { + useSafeImplementation bool + cache *sync.Map +} + +func (cfg Config) Froze() *frozenConfig { + return &frozenConfig{ + useSafeImplementation: cfg.UseSafeImplementation, + cache: new(sync.Map), + } +} + +func (cfg *frozenConfig) TypeOf(obj interface{}) Type { + cacheKey := uintptr(unpackEFace(obj).rtype) + typeObj, found := cfg.cache.Load(cacheKey) + if found { + return typeObj.(Type) + } + return cfg.Type2(reflect.TypeOf(obj)) +} + +func (cfg *frozenConfig) Type2(type1 reflect.Type) Type { + if type1 == nil { + return nil + } + cacheKey := uintptr(unpackEFace(type1).data) + typeObj, found := cfg.cache.Load(cacheKey) + if found { + return typeObj.(Type) + } + type2 := cfg.wrapType(type1) + cfg.cache.Store(cacheKey, type2) + return type2 +} + +func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type { + safeType := safeType{Type: type1, cfg: cfg} + switch type1.Kind() { + case reflect.Struct: + if cfg.useSafeImplementation { + return &safeStructType{safeType} + } + return newUnsafeStructType(cfg, type1) + case reflect.Array: + if cfg.useSafeImplementation { + return &safeSliceType{safeType} + } + return newUnsafeArrayType(cfg, type1) + case reflect.Slice: + if cfg.useSafeImplementation { + return &safeSliceType{safeType} + } + return newUnsafeSliceType(cfg, type1) + case reflect.Map: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + return newUnsafeMapType(cfg, type1) + case reflect.Ptr, reflect.Chan, reflect.Func: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + return newUnsafePtrType(cfg, type1) + case reflect.Interface: + if cfg.useSafeImplementation { + return &safeMapType{safeType} + } + if type1.NumMethod() == 0 { + return newUnsafeEFaceType(cfg, type1) + } + return newUnsafeIFaceType(cfg, type1) + default: + if cfg.useSafeImplementation { + return &safeType + } + return newUnsafeType(cfg, type1) + } +} + +func TypeOf(obj interface{}) Type { + return ConfigUnsafe.TypeOf(obj) +} + +func TypeOfPtr(obj interface{}) PtrType { + return TypeOf(obj).(PtrType) +} + +func Type2(type1 reflect.Type) Type { + if type1 == nil { + return nil + } + return ConfigUnsafe.Type2(type1) +} + +func PtrTo(typ Type) Type { + return Type2(reflect.PtrTo(typ.Type1())) +} + +func PtrOf(obj interface{}) unsafe.Pointer { + return unpackEFace(obj).data +} + +func RTypeOf(obj interface{}) uintptr { + return uintptr(unpackEFace(obj).rtype) +} + +func IsNil(obj interface{}) bool { + if obj == nil { + return true + } + return unpackEFace(obj).data == nil +} + +func IsNullable(kind reflect.Kind) bool { + switch kind { + case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface: + return true + } + return false +} + +func likePtrKind(kind reflect.Kind) bool { + switch kind { + case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func: + return true + } + return false +} + +func likePtrType(typ reflect.Type) bool { + if likePtrKind(typ.Kind()) { + return true + } + if typ.Kind() == reflect.Struct { + if typ.NumField() != 1 { + return false + } + return likePtrType(typ.Field(0).Type) + } + if typ.Kind() == reflect.Array { + if typ.Len() != 1 { + return false + } + return likePtrType(typ.Elem()) + } + return false +} + +// NoEscape hides a pointer from escape analysis. noescape is +// the identity function but escape analysis doesn't think the +// output depends on the input. noescape is inlined and currently +// compiles down to zero instructions. +// USE CAREFULLY! +//go:nosplit +func NoEscape(p unsafe.Pointer) unsafe.Pointer { + x := uintptr(p) + return unsafe.Pointer(x ^ 0) +} + +func UnsafeCastString(str string) []byte { + bytes := make([]byte, 0) + stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str)) + sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&bytes)) + sliceHeader.Data = stringHeader.Data + sliceHeader.Cap = stringHeader.Len + sliceHeader.Len = stringHeader.Len + runtime.KeepAlive(str) + return bytes +} diff --git a/vendor/github.com/modern-go/reflect2/reflect2_amd64.s b/vendor/github.com/modern-go/reflect2/reflect2_amd64.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/reflect2_kind.go b/vendor/github.com/modern-go/reflect2/reflect2_kind.go new file mode 100644 index 0000000..62f299e --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/reflect2_kind.go @@ -0,0 +1,30 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +// DefaultTypeOfKind return the non aliased default type for the kind +func DefaultTypeOfKind(kind reflect.Kind) Type { + return kindTypes[kind] +} + +var kindTypes = map[reflect.Kind]Type{ + reflect.Bool: TypeOf(true), + reflect.Uint8: TypeOf(uint8(0)), + reflect.Int8: TypeOf(int8(0)), + reflect.Uint16: TypeOf(uint16(0)), + reflect.Int16: TypeOf(int16(0)), + reflect.Uint32: TypeOf(uint32(0)), + reflect.Int32: TypeOf(int32(0)), + reflect.Uint64: TypeOf(uint64(0)), + reflect.Int64: TypeOf(int64(0)), + reflect.Uint: TypeOf(uint(0)), + reflect.Int: TypeOf(int(0)), + reflect.Float32: TypeOf(float32(0)), + reflect.Float64: TypeOf(float64(0)), + reflect.Uintptr: TypeOf(uintptr(0)), + reflect.String: TypeOf(""), + reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)), +} diff --git a/vendor/github.com/modern-go/reflect2/relfect2_386.s b/vendor/github.com/modern-go/reflect2/relfect2_386.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s b/vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm.s b/vendor/github.com/modern-go/reflect2/relfect2_arm.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_arm64.s b/vendor/github.com/modern-go/reflect2/relfect2_arm64.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s b/vendor/github.com/modern-go/reflect2/relfect2_mips64x.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s b/vendor/github.com/modern-go/reflect2/relfect2_mipsx.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s b/vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/relfect2_s390x.s b/vendor/github.com/modern-go/reflect2/relfect2_s390x.s new file mode 100644 index 0000000..e69de29 diff --git a/vendor/github.com/modern-go/reflect2/safe_field.go b/vendor/github.com/modern-go/reflect2/safe_field.go new file mode 100644 index 0000000..d4ba1f4 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_field.go @@ -0,0 +1,58 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeField struct { + reflect.StructField +} + +func (field *safeField) Offset() uintptr { + return field.StructField.Offset +} + +func (field *safeField) Name() string { + return field.StructField.Name +} + +func (field *safeField) PkgPath() string { + return field.StructField.PkgPath +} + +func (field *safeField) Type() Type { + panic("not implemented") +} + +func (field *safeField) Tag() reflect.StructTag { + return field.StructField.Tag +} + +func (field *safeField) Index() []int { + return field.StructField.Index +} + +func (field *safeField) Anonymous() bool { + return field.StructField.Anonymous +} + +func (field *safeField) Set(obj interface{}, value interface{}) { + val := reflect.ValueOf(obj).Elem() + val.FieldByIndex(field.Index()).Set(reflect.ValueOf(value).Elem()) +} + +func (field *safeField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { + panic("unsafe operation is not supported") +} + +func (field *safeField) Get(obj interface{}) interface{} { + val := reflect.ValueOf(obj).Elem().FieldByIndex(field.Index()) + ptr := reflect.New(val.Type()) + ptr.Elem().Set(val) + return ptr.Interface() +} + +func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_map.go b/vendor/github.com/modern-go/reflect2/safe_map.go new file mode 100644 index 0000000..8836220 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_map.go @@ -0,0 +1,101 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeMapType struct { + safeType +} + +func (type2 *safeMapType) Key() Type { + return type2.safeType.cfg.Type2(type2.Type.Key()) +} + +func (type2 *safeMapType) MakeMap(cap int) interface{} { + ptr := reflect.New(type2.Type) + ptr.Elem().Set(reflect.MakeMap(type2.Type)) + return ptr.Interface() +} + +func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { + keyVal := reflect.ValueOf(key) + elemVal := reflect.ValueOf(elem) + val := reflect.ValueOf(obj) + val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem()) +} + +func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { + keyVal := reflect.ValueOf(key) + if key == nil { + keyVal = reflect.New(type2.Type.Key()).Elem() + } + val := reflect.ValueOf(obj).MapIndex(keyVal) + if !val.IsValid() { + return nil, false + } + return val.Interface(), true +} + +func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} { + val := reflect.ValueOf(obj).Elem() + keyVal := reflect.ValueOf(key).Elem() + elemVal := val.MapIndex(keyVal) + if !elemVal.IsValid() { + ptr := reflect.New(reflect.PtrTo(val.Type().Elem())) + return ptr.Elem().Interface() + } + ptr := reflect.New(elemVal.Type()) + ptr.Elem().Set(elemVal) + return ptr.Interface() +} + +func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeMapType) Iterate(obj interface{}) MapIterator { + m := reflect.ValueOf(obj).Elem() + return &safeMapIterator{ + m: m, + keys: m.MapKeys(), + } +} + +func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { + panic("does not support unsafe operation") +} + +type safeMapIterator struct { + i int + m reflect.Value + keys []reflect.Value +} + +func (iter *safeMapIterator) HasNext() bool { + return iter.i != len(iter.keys) +} + +func (iter *safeMapIterator) Next() (interface{}, interface{}) { + key := iter.keys[iter.i] + elem := iter.m.MapIndex(key) + iter.i += 1 + keyPtr := reflect.New(key.Type()) + keyPtr.Elem().Set(key) + elemPtr := reflect.New(elem.Type()) + elemPtr.Elem().Set(elem) + return keyPtr.Interface(), elemPtr.Interface() +} + +func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_slice.go b/vendor/github.com/modern-go/reflect2/safe_slice.go new file mode 100644 index 0000000..bcce6fd --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_slice.go @@ -0,0 +1,92 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeSliceType struct { + safeType +} + +func (type2 *safeSliceType) SetIndex(obj interface{}, index int, value interface{}) { + val := reflect.ValueOf(obj).Elem() + elem := reflect.ValueOf(value).Elem() + val.Index(index).Set(elem) +} + +func (type2 *safeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, value unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) GetIndex(obj interface{}, index int) interface{} { + val := reflect.ValueOf(obj).Elem() + elem := val.Index(index) + ptr := reflect.New(elem.Type()) + ptr.Elem().Set(elem) + return ptr.Interface() +} + +func (type2 *safeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) MakeSlice(length int, cap int) interface{} { + val := reflect.MakeSlice(type2.Type, length, cap) + ptr := reflect.New(val.Type()) + ptr.Elem().Set(val) + return ptr.Interface() +} + +func (type2 *safeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Grow(obj interface{}, newLength int) { + oldCap := type2.Cap(obj) + oldSlice := reflect.ValueOf(obj).Elem() + delta := newLength - oldCap + deltaVals := make([]reflect.Value, delta) + newSlice := reflect.Append(oldSlice, deltaVals...) + oldSlice.Set(newSlice) +} + +func (type2 *safeSliceType) UnsafeGrow(ptr unsafe.Pointer, newLength int) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Append(obj interface{}, elem interface{}) { + val := reflect.ValueOf(obj).Elem() + elemVal := reflect.ValueOf(elem).Elem() + newVal := reflect.Append(val, elemVal) + val.Set(newVal) +} + +func (type2 *safeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) SetNil(obj interface{}) { + val := reflect.ValueOf(obj).Elem() + val.Set(reflect.Zero(val.Type())) +} + +func (type2 *safeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) LengthOf(obj interface{}) int { + return reflect.ValueOf(obj).Elem().Len() +} + +func (type2 *safeSliceType) UnsafeLengthOf(ptr unsafe.Pointer) int { + panic("does not support unsafe operation") +} + +func (type2 *safeSliceType) Cap(obj interface{}) int { + return reflect.ValueOf(obj).Elem().Cap() +} + +func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int { + panic("does not support unsafe operation") +} diff --git a/vendor/github.com/modern-go/reflect2/safe_struct.go b/vendor/github.com/modern-go/reflect2/safe_struct.go new file mode 100644 index 0000000..e5fb9b3 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_struct.go @@ -0,0 +1,29 @@ +package reflect2 + +type safeStructType struct { + safeType +} + +func (type2 *safeStructType) FieldByName(name string) StructField { + field, found := type2.Type.FieldByName(name) + if !found { + panic("field " + name + " not found") + } + return &safeField{StructField: field} +} + +func (type2 *safeStructType) Field(i int) StructField { + return &safeField{StructField: type2.Type.Field(i)} +} + +func (type2 *safeStructType) FieldByIndex(index []int) StructField { + return &safeField{StructField: type2.Type.FieldByIndex(index)} +} + +func (type2 *safeStructType) FieldByNameFunc(match func(string) bool) StructField { + field, found := type2.Type.FieldByNameFunc(match) + if !found { + panic("field match condition not found in " + type2.Type.String()) + } + return &safeField{StructField: field} +} diff --git a/vendor/github.com/modern-go/reflect2/safe_type.go b/vendor/github.com/modern-go/reflect2/safe_type.go new file mode 100644 index 0000000..ee4e7bb --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/safe_type.go @@ -0,0 +1,78 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type safeType struct { + reflect.Type + cfg *frozenConfig +} + +func (type2 *safeType) New() interface{} { + return reflect.New(type2.Type).Interface() +} + +func (type2 *safeType) UnsafeNew() unsafe.Pointer { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Elem() Type { + return type2.cfg.Type2(type2.Type.Elem()) +} + +func (type2 *safeType) Type1() reflect.Type { + return type2.Type +} + +func (type2 *safeType) PackEFace(ptr unsafe.Pointer) interface{} { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Implements(thatType Type) bool { + return type2.Type.Implements(thatType.Type1()) +} + +func (type2 *safeType) RType() uintptr { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Indirect(obj interface{}) interface{} { + return reflect.Indirect(reflect.ValueOf(obj)).Interface() +} + +func (type2 *safeType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + panic("does not support unsafe operation") +} + +func (type2 *safeType) LikePtr() bool { + panic("does not support unsafe operation") +} + +func (type2 *safeType) IsNullable() bool { + return IsNullable(type2.Kind()) +} + +func (type2 *safeType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + return reflect.ValueOf(obj).Elem().IsNil() +} + +func (type2 *safeType) UnsafeIsNil(ptr unsafe.Pointer) bool { + panic("does not support unsafe operation") +} + +func (type2 *safeType) Set(obj interface{}, val interface{}) { + reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(val).Elem()) +} + +func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + panic("does not support unsafe operation") +} + +func (type2 *safeType) AssignableTo(anotherType Type) bool { + return type2.Type1().AssignableTo(anotherType.Type1()) +} diff --git a/vendor/github.com/modern-go/reflect2/type_map.go b/vendor/github.com/modern-go/reflect2/type_map.go new file mode 100644 index 0000000..4b13c31 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/type_map.go @@ -0,0 +1,70 @@ +// +build !gccgo + +package reflect2 + +import ( + "reflect" + "sync" + "unsafe" +) + +// typelinks2 for 1.7 ~ +//go:linkname typelinks2 reflect.typelinks +func typelinks2() (sections []unsafe.Pointer, offset [][]int32) + +// initOnce guards initialization of types and packages +var initOnce sync.Once + +var types map[string]reflect.Type +var packages map[string]map[string]reflect.Type + +// discoverTypes initializes types and packages +func discoverTypes() { + types = make(map[string]reflect.Type) + packages = make(map[string]map[string]reflect.Type) + + loadGoTypes() +} + +func loadGoTypes() { + var obj interface{} = reflect.TypeOf(0) + sections, offset := typelinks2() + for i, offs := range offset { + rodata := sections[i] + for _, off := range offs { + (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off) + typ := obj.(reflect.Type) + if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { + loadedType := typ.Elem() + pkgTypes := packages[loadedType.PkgPath()] + if pkgTypes == nil { + pkgTypes = map[string]reflect.Type{} + packages[loadedType.PkgPath()] = pkgTypes + } + types[loadedType.String()] = loadedType + pkgTypes[loadedType.Name()] = loadedType + } + } + } +} + +type emptyInterface struct { + typ unsafe.Pointer + word unsafe.Pointer +} + +// TypeByName return the type by its name, just like Class.forName in java +func TypeByName(typeName string) Type { + initOnce.Do(discoverTypes) + return Type2(types[typeName]) +} + +// TypeByPackageName return the type by its package and name +func TypeByPackageName(pkgPath string, name string) Type { + initOnce.Do(discoverTypes) + pkgTypes := packages[pkgPath] + if pkgTypes == nil { + return nil + } + return Type2(pkgTypes[name]) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_array.go b/vendor/github.com/modern-go/reflect2/unsafe_array.go new file mode 100644 index 0000000..76cbdba --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_array.go @@ -0,0 +1,65 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeArrayType struct { + unsafeType + elemRType unsafe.Pointer + pElemRType unsafe.Pointer + elemSize uintptr + likePtr bool +} + +func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType { + return &UnsafeArrayType{ + unsafeType: *newUnsafeType(cfg, type1), + elemRType: unpackEFace(type1.Elem()).data, + pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, + elemSize: type1.Elem().Size(), + likePtr: likePtrType(type1), + } +} + +func (type2 *UnsafeArrayType) LikePtr() bool { + return type2.likePtr +} + +func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + if type2.likePtr { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) + } + return packEFace(type2.rtype, ptr) +} + +func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) +} + +func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { + elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len") + typedmemmove(type2.elemRType, elemPtr, elem) +} + +func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} { + objEFace := unpackEFace(obj) + assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, index) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + return arrayAt(obj, index, type2.elemSize, "i < s.Len") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_eface.go b/vendor/github.com/modern-go/reflect2/unsafe_eface.go new file mode 100644 index 0000000..805010f --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_eface.go @@ -0,0 +1,59 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type eface struct { + rtype unsafe.Pointer + data unsafe.Pointer +} + +func unpackEFace(obj interface{}) *eface { + return (*eface)(unsafe.Pointer(&obj)) +} + +func packEFace(rtype unsafe.Pointer, data unsafe.Pointer) interface{} { + var i interface{} + e := (*eface)(unsafe.Pointer(&i)) + e.rtype = rtype + e.data = data + return i +} + +type UnsafeEFaceType struct { + unsafeType +} + +func newUnsafeEFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeEFaceType { + return &UnsafeEFaceType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafeEFaceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeEFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return unpackEFace(*(*interface{})(ptr)).data == nil +} + +func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return *(*interface{})(ptr) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_field.go b/vendor/github.com/modern-go/reflect2/unsafe_field.go new file mode 100644 index 0000000..5eb5313 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_field.go @@ -0,0 +1,74 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeStructField struct { + reflect.StructField + structType *UnsafeStructType + rtype unsafe.Pointer + ptrRType unsafe.Pointer +} + +func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField { + return &UnsafeStructField{ + StructField: structField, + rtype: unpackEFace(structField.Type).data, + ptrRType: unpackEFace(reflect.PtrTo(structField.Type)).data, + structType: structType, + } +} + +func (field *UnsafeStructField) Offset() uintptr { + return field.StructField.Offset +} + +func (field *UnsafeStructField) Name() string { + return field.StructField.Name +} + +func (field *UnsafeStructField) PkgPath() string { + return field.StructField.PkgPath +} + +func (field *UnsafeStructField) Type() Type { + return field.structType.cfg.Type2(field.StructField.Type) +} + +func (field *UnsafeStructField) Tag() reflect.StructTag { + return field.StructField.Tag +} + +func (field *UnsafeStructField) Index() []int { + return field.StructField.Index +} + +func (field *UnsafeStructField) Anonymous() bool { + return field.StructField.Anonymous +} + +func (field *UnsafeStructField) Set(obj interface{}, value interface{}) { + objEFace := unpackEFace(obj) + assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype) + valueEFace := unpackEFace(value) + assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype) + field.UnsafeSet(objEFace.data, valueEFace.data) +} + +func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { + fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field") + typedmemmove(field.rtype, fieldPtr, value) +} + +func (field *UnsafeStructField) Get(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype) + value := field.UnsafeGet(objEFace.data) + return packEFace(field.ptrRType, value) +} + +func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { + return add(obj, field.StructField.Offset, "same as non-reflect &v.field") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_iface.go b/vendor/github.com/modern-go/reflect2/unsafe_iface.go new file mode 100644 index 0000000..b601955 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_iface.go @@ -0,0 +1,64 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type iface struct { + itab *itab + data unsafe.Pointer +} + +type itab struct { + ignore unsafe.Pointer + rtype unsafe.Pointer +} + +func IFaceToEFace(ptr unsafe.Pointer) interface{} { + iface := (*iface)(ptr) + if iface.itab == nil { + return nil + } + return packEFace(iface.itab.rtype, iface.data) +} + +type UnsafeIFaceType struct { + unsafeType +} + +func newUnsafeIFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeIFaceType { + return &UnsafeIFaceType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafeIFaceType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeIFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return IFaceToEFace(ptr) +} + +func (type2 *UnsafeIFaceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + iface := (*iface)(ptr) + if iface.itab == nil { + return true + } + return false +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_link.go b/vendor/github.com/modern-go/reflect2/unsafe_link.go new file mode 100644 index 0000000..b49f614 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_link.go @@ -0,0 +1,76 @@ +package reflect2 + +import "unsafe" + +//go:linkname unsafe_New reflect.unsafe_New +func unsafe_New(rtype unsafe.Pointer) unsafe.Pointer + +//go:linkname typedmemmove reflect.typedmemmove +func typedmemmove(rtype unsafe.Pointer, dst, src unsafe.Pointer) + +//go:linkname unsafe_NewArray reflect.unsafe_NewArray +func unsafe_NewArray(rtype unsafe.Pointer, length int) unsafe.Pointer + +// typedslicecopy copies a slice of elemType values from src to dst, +// returning the number of elements copied. +//go:linkname typedslicecopy reflect.typedslicecopy +//go:noescape +func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int + +//go:linkname mapassign reflect.mapassign +//go:noescape +func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer, val unsafe.Pointer) + +//go:linkname mapaccess reflect.mapaccess +//go:noescape +func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer) + +//go:noescape +//go:linkname mapiternext reflect.mapiternext +func mapiternext(it *hiter) + +//go:linkname ifaceE2I reflect.ifaceE2I +func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer) + +// A hash iteration structure. +// If you modify hiter, also change cmd/internal/gc/reflect.go to indicate +// the layout of this structure. +type hiter struct { + key unsafe.Pointer + value unsafe.Pointer + t unsafe.Pointer + h unsafe.Pointer + buckets unsafe.Pointer + bptr unsafe.Pointer + overflow *[]unsafe.Pointer + oldoverflow *[]unsafe.Pointer + startBucket uintptr + offset uint8 + wrapped bool + B uint8 + i uint8 + bucket uintptr + checkBucket uintptr +} + +// add returns p+x. +// +// The whySafe string is ignored, so that the function still inlines +// as efficiently as p+x, but all call sites should use the string to +// record why the addition is safe, which is to say why the addition +// does not cause x to advance to the very end of p's allocation +// and therefore point incorrectly at the next block in memory. +func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { + return unsafe.Pointer(uintptr(p) + x) +} + +// arrayAt returns the i-th element of p, +// an array whose elements are eltSize bytes wide. +// The array pointed at by p must have at least i+1 elements: +// it is invalid (but impossible to check here) to pass i >= len, +// because then the result will point outside the array. +// whySafe must explain why i < len. (Passing "i < len" is fine; +// the benefit is to surface this assumption at the call site.) +func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer { + return add(p, uintptr(i)*eltSize, "i < len") +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_map.go b/vendor/github.com/modern-go/reflect2/unsafe_map.go new file mode 100644 index 0000000..37872da --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_map.go @@ -0,0 +1,130 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeMapType struct { + unsafeType + pKeyRType unsafe.Pointer + pElemRType unsafe.Pointer +} + +func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType { + return &UnsafeMapType{ + unsafeType: *newUnsafeType(cfg, type1), + pKeyRType: unpackEFace(reflect.PtrTo(type1.Key())).data, + pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, + } +} + +func (type2 *UnsafeMapType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return *(*unsafe.Pointer)(ptr) == nil +} + +func (type2 *UnsafeMapType) LikePtr() bool { + return true +} + +func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) +} + +func (type2 *UnsafeMapType) Key() Type { + return type2.cfg.Type2(type2.Type.Key()) +} + +func (type2 *UnsafeMapType) MakeMap(cap int) interface{} { + return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap)) +} + +func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { + m := makeMapWithSize(type2.rtype, cap) + return unsafe.Pointer(&m) +} + +func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data) +} + +func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { + mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem) +} + +func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { + objEFace := unpackEFace(obj) + assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) + if elemPtr == nil { + return nil, false + } + return packEFace(type2.pElemRType, elemPtr), true +} + +func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + keyEFace := unpackEFace(key) + assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { + return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key) +} + +func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator { + objEFace := unpackEFace(obj) + assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIterate(objEFace.data) +} + +type UnsafeMapIterator struct { + *hiter + pKeyRType unsafe.Pointer + pElemRType unsafe.Pointer +} + +func (iter *UnsafeMapIterator) HasNext() bool { + return iter.key != nil +} + +func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) { + key, elem := iter.UnsafeNext() + return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem) +} + +func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { + key := iter.key + elem := iter.value + mapiternext(iter.hiter) + return key, elem +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_ptr.go b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go new file mode 100644 index 0000000..8e5ec9c --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_ptr.go @@ -0,0 +1,46 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafePtrType struct { + unsafeType +} + +func newUnsafePtrType(cfg *frozenConfig, type1 reflect.Type) *UnsafePtrType { + return &UnsafePtrType{ + unsafeType: *newUnsafeType(cfg, type1), + } +} + +func (type2 *UnsafePtrType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafePtrType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return *(*unsafe.Pointer)(ptr) == nil +} + +func (type2 *UnsafePtrType) LikePtr() bool { + return true +} + +func (type2 *UnsafePtrType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafePtrType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_slice.go b/vendor/github.com/modern-go/reflect2/unsafe_slice.go new file mode 100644 index 0000000..1c6d876 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_slice.go @@ -0,0 +1,177 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +// sliceHeader is a safe version of SliceHeader used within this package. +type sliceHeader struct { + Data unsafe.Pointer + Len int + Cap int +} + +type UnsafeSliceType struct { + unsafeType + elemRType unsafe.Pointer + pElemRType unsafe.Pointer + elemSize uintptr +} + +func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType { + elemType := type1.Elem() + return &UnsafeSliceType{ + unsafeType: *newUnsafeType(cfg, type1), + pElemRType: unpackEFace(reflect.PtrTo(elemType)).data, + elemRType: unpackEFace(elemType).data, + elemSize: elemType.Size(), + } +} + +func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) { + objEFace := unpackEFace(obj) + assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) + valEFace := unpackEFace(val) + assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) + type2.UnsafeSet(objEFace.data, valEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + *(*sliceHeader)(ptr) = *(*sliceHeader)(val) +} + +func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool { + if obj == nil { + return true + } + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool { + if ptr == nil { + return true + } + return (*sliceHeader)(ptr).Data == nil +} + +func (type2 *UnsafeSliceType) SetNil(obj interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype) + type2.UnsafeSetNil(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { + header := (*sliceHeader)(ptr) + header.Len = 0 + header.Cap = 0 + header.Data = nil +} + +func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} { + return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap)) +} + +func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { + header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap} + return unsafe.Pointer(header) +} + +func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int { + objEFace := unpackEFace(obj) + assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeLengthOf(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int { + header := (*sliceHeader)(obj) + return header.Len +} + +func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) + type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { + header := (*sliceHeader)(obj) + elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len") + typedmemmove(type2.elemRType, elemPtr, elem) +} + +func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} { + objEFace := unpackEFace(obj) + assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) + elemPtr := type2.UnsafeGetIndex(objEFace.data, index) + return packEFace(type2.pElemRType, elemPtr) +} + +func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { + header := (*sliceHeader)(obj) + return arrayAt(header.Data, index, type2.elemSize, "i < s.Len") +} + +func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) { + objEFace := unpackEFace(obj) + assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype) + elemEFace := unpackEFace(elem) + assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype) + type2.UnsafeAppend(objEFace.data, elemEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { + header := (*sliceHeader)(obj) + oldLen := header.Len + type2.UnsafeGrow(obj, oldLen+1) + type2.UnsafeSetIndex(obj, oldLen, elem) +} + +func (type2 *UnsafeSliceType) Cap(obj interface{}) int { + objEFace := unpackEFace(obj) + assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeCap(objEFace.data) +} + +func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int { + return (*sliceHeader)(ptr).Cap +} + +func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) { + objEFace := unpackEFace(obj) + assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype) + type2.UnsafeGrow(objEFace.data, newLength) +} + +func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) { + header := (*sliceHeader)(obj) + if newLength <= header.Cap { + header.Len = newLength + return + } + newCap := calcNewCap(header.Cap, newLength) + newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap)) + typedslicecopy(type2.elemRType, *newHeader, *header) + header.Data = newHeader.Data + header.Cap = newHeader.Cap + header.Len = newLength +} + +func calcNewCap(cap int, expectedCap int) int { + if cap == 0 { + cap = expectedCap + } else { + for cap < expectedCap { + if cap < 1024 { + cap += cap + } else { + cap += cap / 4 + } + } + } + return cap +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_struct.go b/vendor/github.com/modern-go/reflect2/unsafe_struct.go new file mode 100644 index 0000000..804d916 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_struct.go @@ -0,0 +1,59 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type UnsafeStructType struct { + unsafeType + likePtr bool +} + +func newUnsafeStructType(cfg *frozenConfig, type1 reflect.Type) *UnsafeStructType { + return &UnsafeStructType{ + unsafeType: *newUnsafeType(cfg, type1), + likePtr: likePtrType(type1), + } +} + +func (type2 *UnsafeStructType) LikePtr() bool { + return type2.likePtr +} + +func (type2 *UnsafeStructType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *UnsafeStructType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { + if type2.likePtr { + return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) + } + return packEFace(type2.rtype, ptr) +} + +func (type2 *UnsafeStructType) FieldByName(name string) StructField { + structField, found := type2.Type.FieldByName(name) + if !found { + return nil + } + return newUnsafeStructField(type2, structField) +} + +func (type2 *UnsafeStructType) Field(i int) StructField { + return newUnsafeStructField(type2, type2.Type.Field(i)) +} + +func (type2 *UnsafeStructType) FieldByIndex(index []int) StructField { + return newUnsafeStructField(type2, type2.Type.FieldByIndex(index)) +} + +func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructField { + structField, found := type2.Type.FieldByNameFunc(match) + if !found { + panic("field match condition not found in " + type2.Type.String()) + } + return newUnsafeStructField(type2, structField) +} diff --git a/vendor/github.com/modern-go/reflect2/unsafe_type.go b/vendor/github.com/modern-go/reflect2/unsafe_type.go new file mode 100644 index 0000000..1394171 --- /dev/null +++ b/vendor/github.com/modern-go/reflect2/unsafe_type.go @@ -0,0 +1,85 @@ +package reflect2 + +import ( + "reflect" + "unsafe" +) + +type unsafeType struct { + safeType + rtype unsafe.Pointer + ptrRType unsafe.Pointer +} + +func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType { + return &unsafeType{ + safeType: safeType{ + Type: type1, + cfg: cfg, + }, + rtype: unpackEFace(type1).data, + ptrRType: unpackEFace(reflect.PtrTo(type1)).data, + } +} + +func (type2 *unsafeType) Set(obj interface{}, val interface{}) { + objEFace := unpackEFace(obj) + assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) + valEFace := unpackEFace(val) + assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) + type2.UnsafeSet(objEFace.data, valEFace.data) +} + +func (type2 *unsafeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { + typedmemmove(type2.rtype, ptr, val) +} + +func (type2 *unsafeType) IsNil(obj interface{}) bool { + objEFace := unpackEFace(obj) + assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIsNil(objEFace.data) +} + +func (type2 *unsafeType) UnsafeIsNil(ptr unsafe.Pointer) bool { + return ptr == nil +} + +func (type2 *unsafeType) UnsafeNew() unsafe.Pointer { + return unsafe_New(type2.rtype) +} + +func (type2 *unsafeType) New() interface{} { + return packEFace(type2.ptrRType, type2.UnsafeNew()) +} + +func (type2 *unsafeType) PackEFace(ptr unsafe.Pointer) interface{} { + return packEFace(type2.ptrRType, ptr) +} + +func (type2 *unsafeType) RType() uintptr { + return uintptr(type2.rtype) +} + +func (type2 *unsafeType) Indirect(obj interface{}) interface{} { + objEFace := unpackEFace(obj) + assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) + return type2.UnsafeIndirect(objEFace.data) +} + +func (type2 *unsafeType) UnsafeIndirect(obj unsafe.Pointer) interface{} { + return packEFace(type2.rtype, obj) +} + +func (type2 *unsafeType) LikePtr() bool { + return false +} + +func assertType(where string, expectRType unsafe.Pointer, actualRType unsafe.Pointer) { + if expectRType != actualRType { + expectType := reflect.TypeOf(0) + (*iface)(unsafe.Pointer(&expectType)).data = expectRType + actualType := reflect.TypeOf(0) + (*iface)(unsafe.Pointer(&actualType)).data = actualRType + panic(where + ": expect " + expectType.String() + ", actual " + actualType.String()) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 74f8413..77b3678 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -32,11 +32,11 @@ github.com/inconshreveable/mousetrap # github.com/magiconair/properties v1.8.6 ## explicit; go 1.13 github.com/magiconair/properties -# github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55 -## explicit; go 1.14 +# github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 +## explicit; go 1.19 github.com/mandelsoft/filepath/pkg/filepath -# github.com/mandelsoft/vfs v0.0.0-20220805210647-bf14a11bfe31 -## explicit; go 1.13 +# github.com/mandelsoft/vfs v0.4.4 +## explicit; go 1.22.5 github.com/mandelsoft/vfs/pkg/osfs github.com/mandelsoft/vfs/pkg/projectionfs github.com/mandelsoft/vfs/pkg/utils @@ -44,6 +44,9 @@ github.com/mandelsoft/vfs/pkg/vfs # github.com/mitchellh/mapstructure v1.5.0 ## explicit; go 1.14 github.com/mitchellh/mapstructure +# github.com/modern-go/reflect2 v1.0.2 +## explicit; go 1.12 +github.com/modern-go/reflect2 # github.com/nxadm/tail v1.4.8 ## explicit; go 1.13 github.com/nxadm/tail @@ -137,7 +140,7 @@ github.com/spf13/viper/internal/encoding/yaml # github.com/subosito/gotenv v1.4.1 ## explicit; go 1.18 github.com/subosito/gotenv -# golang.org/x/crypto v0.1.0 +# golang.org/x/crypto v0.10.0 ## explicit; go 1.17 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish @@ -150,18 +153,18 @@ golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/md4 golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf -# golang.org/x/net v0.4.0 +# golang.org/x/net v0.11.0 ## explicit; go 1.17 golang.org/x/net/html golang.org/x/net/html/atom golang.org/x/net/html/charset -# golang.org/x/sys v0.3.0 +# golang.org/x/sys v0.9.0 ## explicit; go 1.17 golang.org/x/sys/cpu golang.org/x/sys/internal/unsafeheader golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/text v0.5.0 +# golang.org/x/text v0.10.0 ## explicit; go 1.17 golang.org/x/text/encoding golang.org/x/text/encoding/charmap