commit 4da19b30479d145a469b61489277d88988cb547a
parent 677dbf536f8f5a42bc25eb2f4913696b10fd464c
Author: lash <dev@holbrook.no>
Date: Wed, 12 Apr 2023 08:30:35 +0100
Catch beyond index error in browse
Diffstat:
8 files changed, 48 insertions(+), 38 deletions(-)
diff --git a/go/cache/cache.go b/go/cache/cache.go
@@ -136,7 +136,6 @@ func(ca *Cache) Reset() {
func (ca *Cache) Push() error {
m := make(map[string]string)
ca.Cache = append(ca.Cache, m)
- //ca.resetCurrent()
return nil
}
diff --git a/go/engine/engine.go b/go/engine/engine.go
@@ -118,8 +118,8 @@ func (en *Engine) Exec(input []byte, ctx context.Context) (bool, error) {
// - required data inputs to the template are not available.
// - the template for the given node point is note available for retrieval using the resource.Resource implementer.
// - the supplied writer fails to process the writes.
-func(en *Engine) WriteResult(w io.Writer) error {
- r, err := en.vm.Render()
+func(en *Engine) WriteResult(w io.Writer, ctx context.Context) error {
+ r, err := en.vm.Render(ctx)
if err != nil {
return err
}
diff --git a/go/engine/engine_test.go b/go/engine/engine_test.go
@@ -82,7 +82,7 @@ func TestEngineInit(t *testing.T) {
}
w := bytes.NewBuffer(nil)
- err = en.WriteResult(w)
+ err = en.WriteResult(w, ctx)
if err != nil {
t.Fatal(err)
}
@@ -105,7 +105,7 @@ func TestEngineInit(t *testing.T) {
t.Fatalf("expected where-string 'foo', got %s", r)
}
w = bytes.NewBuffer(nil)
- err = en.WriteResult(w)
+ err = en.WriteResult(w, ctx)
if err != nil {
t.Fatal(err)
}
diff --git a/go/engine/loop.go b/go/engine/loop.go
@@ -17,7 +17,7 @@ func Loop(en *Engine, startSym string, ctx context.Context, reader io.Reader, wr
}
b := bytes.NewBuffer(nil)
- en.WriteResult(b)
+ en.WriteResult(b, ctx)
fmt.Println(b.String())
running := true
@@ -37,7 +37,7 @@ func Loop(en *Engine, startSym string, ctx context.Context, reader io.Reader, wr
return fmt.Errorf("unexpected termination: %v\n", err)
}
//b := bytes.NewBuffer(nil)
- err = en.WriteResult(writer)
+ err = en.WriteResult(writer, ctx)
if err != nil {
return err
}
diff --git a/go/render/menu.go b/go/render/menu.go
@@ -4,6 +4,15 @@ import (
"fmt"
)
+type BrowseError struct {
+ Idx uint16
+ PageCount uint16
+}
+
+func(err *BrowseError) Error() string {
+ return fmt.Sprintf("index is out of bounds: %v", err.Idx)
+}
+
// BrowseConfig defines the availability and display parameters for page browsing.
type BrowseConfig struct {
NextAvailable bool
@@ -112,7 +121,8 @@ func(m *Menu) applyPage(idx uint16) error {
}
return nil
} else if idx >= m.pageCount {
- return fmt.Errorf("index %v out of bounds (%v)", idx, m.pageCount)
+ return &BrowseError{Idx: idx, PageCount: m.pageCount}
+ //return fmt.Errorf("index %v out of bounds (%v)", idx, m.pageCount)
}
m.reset()
diff --git a/go/render/page.go b/go/render/page.go
@@ -307,20 +307,6 @@ func(pg *Page) render(sym string, values map[string]string, idx uint16) (string,
return "", fmt.Errorf("limit exceeded: %v", pg.sizer)
}
}
-// s, err = pg.menu.Render(idx)
-// if err != nil {
-// return "", err
-// }
-// log.Printf("rendered %v bytes for menu", len(s))
-// if len(s) > 0 {
-// r += "\n" + s
-// }
-// if pg.sizer != nil {
-// _, ok = pg.sizer.Check(r)
-// if !ok {
-// return "", fmt.Errorf("limit exceeded: %v", pg.sizer)
-// }
-// }
return r, nil
}
@@ -332,12 +318,11 @@ func(pg *Page) Render(sym string, idx uint16) (string, error) {
return "", err
}
- log.Printf("nosink %v", values)
return pg.render(sym, values, idx)
}
func(pg *Page) Reset() {
pg.sink = nil
pg.sinkSize = 0
- //pg.cacheMap = make(map[string]string)
+ pg.cacheMap = make(map[string]string)
}
diff --git a/go/vm/runner.go b/go/vm/runner.go
@@ -383,7 +383,7 @@ func(vm *Vm) RunMPrev(b []byte, ctx context.Context) ([]byte, error) {
return b, nil
}
-func(vm *Vm) Render() (string, error) {
+func(vm *Vm) Render(ctx context.Context) (string, error) {
changed, err := vm.st.ResetFlag(state.FLAG_DIRTY)
if err != nil {
panic(err)
@@ -393,6 +393,15 @@ func(vm *Vm) Render() (string, error) {
}
sym, idx := vm.st.Where()
r, err := vm.pg.Render(sym, idx)
+ var ok bool
+ _, ok = err.(*render.BrowseError)
+ if ok {
+ vm.Reset()
+ b := NewLine(nil, MOVE, []string{"_catch"}, nil, nil)
+ vm.Run(b, ctx)
+ sym, idx := vm.st.Where()
+ r, err = vm.pg.Render(sym, idx)
+ }
if err != nil {
return "", err
}
diff --git a/go/vm/runner_test.go b/go/vm/runner_test.go
@@ -112,16 +112,17 @@ func TestRunLoadRender(t *testing.T) {
st.Down("bar")
var err error
+ ctx := context.TODO()
b := NewLine(nil, LOAD, []string{"one"}, []byte{0x0a}, nil)
b = NewLine(b, MAP, []string{"one"}, nil, nil)
b = NewLine(b, LOAD, []string{"two"}, []byte{0x0a}, nil)
b = NewLine(b, MAP, []string{"two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- b, err = vm.Run(b, context.TODO())
+ b, err = vm.Run(b, ctx)
if err != nil {
t.Fatal(err)
}
- r, err := vm.Render()
+ r, err := vm.Render(ctx)
if err != nil {
t.Fatal(err)
}
@@ -133,17 +134,17 @@ func TestRunLoadRender(t *testing.T) {
b = NewLine(nil, LOAD, []string{"two"}, []byte{0x0a}, nil)
b = NewLine(b, MAP, []string{"two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- b, err = vm.Run(b, context.TODO())
+ b, err = vm.Run(b, ctx)
if err != nil {
t.Fatal(err)
}
b = NewLine(nil, MAP, []string{"one"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- _, err = vm.Run(b, context.TODO())
+ _, err = vm.Run(b, ctx)
if err != nil {
t.Fatal(err)
}
- r, err = vm.Render()
+ r, err = vm.Render(ctx)
if err != nil {
t.Fatal(err)
}
@@ -159,11 +160,12 @@ func TestRunMultiple(t *testing.T) {
ca := cache.NewCache()
vm := NewVm(&st, &rs, ca, nil)
+ ctx := context.TODO()
b := NewLine(nil, MOVE, []string{"test"}, nil, nil)
b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil)
b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil)
b = NewLine(b, HALT, nil, nil, nil)
- b, err := vm.Run(b, context.TODO())
+ b, err := vm.Run(b, ctx)
if err != nil {
t.Error(err)
}
@@ -179,15 +181,16 @@ func TestRunReload(t *testing.T) {
szr := render.NewSizer(128)
vm := NewVm(&st, &rs, ca, szr)
+ ctx := context.TODO()
b := NewLine(nil, MOVE, []string{"root"}, nil, nil)
b = NewLine(b, LOAD, []string{"dyn"}, nil, []uint8{0})
b = NewLine(b, MAP, []string{"dyn"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- _, err := vm.Run(b, context.TODO())
+ _, err := vm.Run(b, ctx)
if err != nil {
t.Fatal(err)
}
- r, err := vm.Render()
+ r, err := vm.Render(ctx)
if err != nil {
t.Fatal(err)
}
@@ -197,7 +200,7 @@ func TestRunReload(t *testing.T) {
dynVal = "baz"
b = NewLine(nil, RELOAD, []string{"dyn"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- _, err = vm.Run(b, context.TODO())
+ _, err = vm.Run(b, ctx)
if err != nil {
t.Fatal(err)
}
@@ -310,12 +313,14 @@ func TestRunMenu(t *testing.T) {
var err error
+ ctx := context.TODO()
+
b := NewLine(nil, MOVE, []string{"foo"}, nil, nil)
b = NewLine(b, MOUT, []string{"0", "one"}, nil, nil)
b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- b, err = vm.Run(b, context.TODO())
+ b, err = vm.Run(b, ctx)
if err != nil {
t.Error(err)
}
@@ -324,7 +329,7 @@ func TestRunMenu(t *testing.T) {
t.Errorf("expected empty remainder, got length %v: %v", l, b)
}
- r, err := vm.Render()
+ r, err := vm.Render(ctx)
if err != nil {
t.Fatal(err)
}
@@ -343,12 +348,14 @@ func TestRunMenuBrowse(t *testing.T) {
var err error
+ ctx := context.TODO()
+
b := NewLine(nil, MOVE, []string{"foo"}, nil, nil)
b = NewLine(b, MOUT, []string{"0", "one"}, nil, nil)
b = NewLine(b, MOUT, []string{"1", "two"}, nil, nil)
b = NewLine(b, HALT, nil, nil, nil)
- b, err = vm.Run(b, context.TODO())
+ b, err = vm.Run(b, ctx)
if err != nil {
t.Error(err)
}
@@ -357,7 +364,7 @@ func TestRunMenuBrowse(t *testing.T) {
t.Errorf("expected empty remainder, got length %v: %v", l, b)
}
- r, err := vm.Render()
+ r, err := vm.Render(ctx)
if err != nil {
t.Fatal(err)
}