commit 789f38411f8a83c69ea0968b25cbafc26bd6e84f
parent e5a158b4e5c669ce65c013de4464955055b39af3
Author: lash <dev@holbrook.no>
Date: Sat, 31 Aug 2024 22:16:30 +0100
WIP complete inline documentation, remove logger exports
Diffstat:
36 files changed, 267 insertions(+), 241 deletions(-)
diff --git a/asm/asm.go b/asm/asm.go
@@ -18,11 +18,15 @@ import (
// Asm assembles bytecode from the vise assembly mini-language.
+//
+// TODO: Conceal from outside use
type Asm struct {
Instructions []*Instruction `@@*`
}
// Arg holds all parsed argument elements of a single line of assembly code.
+//
+// TODO: Conceal from outside use
type Arg struct {
Sym *string `(@Sym Whitespace?)?`
Size *uint32 `(@Size Whitespace?)?`
@@ -32,6 +36,7 @@ type Arg struct {
//Desc *string `(Quote ((@Sym | @Size) @Whitespace?)+ Quote Whitespace?)?`
}
+// writes the parsed instruction bytes to output.
func flush(b *bytes.Buffer, w io.Writer) (int, error) {
if w != nil {
return w.Write(b.Bytes())
@@ -309,13 +314,15 @@ func (a Arg) String() string {
}
// Instruction represents one full line of assembly code.
+//
+// TODO: Conceal from outside use
type Instruction struct {
OpCode string `@Ident`
OpArg Arg `(Whitespace @@)?`
Comment string `Comment? EOL`
}
-// String implement the String interface.
+// String implements the String interface.
func (i Instruction) String() string {
return fmt.Sprintf("%s %s", i.OpCode, i.OpArg)
}
diff --git a/asm/flag.go b/asm/flag.go
@@ -113,9 +113,9 @@ func(pp *FlagParser) Load(fp string) (int, error) {
if (len(v) > 3) {
pp.flagDescription[uint32(fl)] = v[3]
- Logg.Debugf("added flag translation", "from", v[1], "to", v[2], "description", v[3])
+ logg.Debugf("added flag translation", "from", v[1], "to", v[2], "description", v[3])
} else {
- Logg.Debugf("added flag translation", "from", v[1], "to", v[2])
+ logg.Debugf("added flag translation", "from", v[1], "to", v[2])
}
}
}
diff --git a/asm/log.go b/asm/log.go
@@ -5,5 +5,5 @@ import (
)
var (
- Logg logging.Logger = logging.NewVanilla().WithDomain("asm")
+ logg logging.Logger = logging.NewVanilla().WithDomain("asm")
)
diff --git a/asm/menu.go b/asm/menu.go
@@ -11,18 +11,18 @@ type BatchCode uint16
const (
_MENU_OFFSET = 256
- MENU_DOWN = _MENU_OFFSET
- MENU_UP = _MENU_OFFSET + 1
- MENU_NEXT = _MENU_OFFSET + 2
- MENU_PREVIOUS = _MENU_OFFSET + 3
+ _MENU_DOWN = _MENU_OFFSET
+ _MENU_UP = _MENU_OFFSET + 1
+ _MENU_NEXT = _MENU_OFFSET + 2
+ _MENU_PREVIOUS = _MENU_OFFSET + 3
)
var (
batchCode = map[string]BatchCode{
- "DOWN": MENU_DOWN,
- "UP": MENU_UP,
- "NEXT": MENU_NEXT,
- "PREVIOUS": MENU_PREVIOUS,
+ "DOWN": _MENU_DOWN,
+ "UP": _MENU_UP,
+ "NEXT": _MENU_NEXT,
+ "PREVIOUS": _MENU_PREVIOUS,
}
)
@@ -54,7 +54,7 @@ func(mp *MenuProcessor) Add(bop string, choice string, display string, target st
if bopCode == 0 {
return fmt.Errorf("unknown menu instruction: %v", bop)
}
- if len(target) > 0 && bopCode != MENU_DOWN {
+ if len(target) > 0 && bopCode != _MENU_DOWN {
return fmt.Errorf("target is only valid for DOWN")
}
m := menuItem{
@@ -74,13 +74,13 @@ func (mp *MenuProcessor) ToLines() []byte {
for _, v := range mp.items {
switch v.code {
- case MENU_UP:
+ case _MENU_UP:
preLines = vm.NewLine(preLines, vm.MOUT, []string{v.display, v.choice}, nil, nil)
postLines = vm.NewLine(postLines, vm.INCMP, []string{"_", v.choice}, nil, nil)
- case MENU_NEXT:
+ case _MENU_NEXT:
preLines = vm.NewLine(preLines, vm.MNEXT, []string{v.display, v.choice}, nil, nil)
postLines = vm.NewLine(postLines, vm.INCMP, []string{">", v.choice}, nil, nil)
- case MENU_PREVIOUS:
+ case _MENU_PREVIOUS:
preLines = vm.NewLine(preLines, vm.MPREV, []string{v.display, v.choice}, nil, nil)
postLines = vm.NewLine(postLines, vm.INCMP, []string{"<", v.choice}, nil, nil)
default:
diff --git a/cache/cache.go b/cache/cache.go
@@ -5,17 +5,23 @@ import (
)
// Cache stores loaded content, enforcing size limits and keeping track of size usage.
+//
// TODO: hide values from client, while allowing cbor serialization
type Cache struct {
- CacheSize uint32 // Total allowed cumulative size of values (not code) in cache
- CacheUseSize uint32 // Currently used bytes by all values (not code) in cache
- Cache []map[string]string // All loaded cache items
- Sizes map[string]uint16 // Size limits for all loaded symbols.
- LastValue string // last inserted value
+ // Total allowed cumulative size of values (not code) in cache
+ CacheSize uint32
+ // Currently used bytes by all values (not code) in cache
+ CacheUseSize uint32
+ // All loaded cache items
+ Cache []map[string]string
+ // Size limits for all loaded symbols.
+ Sizes map[string]uint16
+ // Last inserted value (regardless of scope)
+ LastValue string
invalid bool
}
-// NewCache creates a new ready-to-use cache object
+// NewCache creates a new ready-to-use Cache object
func NewCache() *Cache {
ca := &Cache{
Cache: []map[string]string{make(map[string]string)},
@@ -24,34 +30,23 @@ func NewCache() *Cache {
return ca
}
-// Invalidate marks a cache as invalid.
-//
-// An invalid cache should not be persisted or propagated
+// Invalidate implements the Memory interface.
func(ca *Cache) Invalidate() {
ca.invalid = true
}
-// Invalid returns true if cache is invalid.
-//
-// An invalid cache should not be persisted or propagated
+// Invalid implements the Memory interface.
func(ca *Cache) Invalid() bool {
return ca.invalid
}
-// WithCacheSize applies a cumulative cache size limitation for all cached items.
+// WithCacheSize is a chainable method that applies a cumulative cache size limitation for all cached items.
func(ca *Cache) WithCacheSize(cacheSize uint32) *Cache {
ca.CacheSize = cacheSize
return ca
}
-// Add adds a cache value under a cache symbol key.
-//
-// Also stores the size limitation of for key for later updates.
-//
-// Fails if:
-// - key already defined
-// - value is longer than size limit
-// - adding value exceeds cumulative cache capacity
+// Add implements the Memory interface.
func(ca *Cache) Add(key string, value string, sizeLimit uint16) error {
if sizeLimit > 0 {
l := uint16(len(value))
@@ -63,7 +58,7 @@ func(ca *Cache) Add(key string, value string, sizeLimit uint16) error {
if checkFrame > -1 {
thisFrame := len(ca.Cache) - 1
if checkFrame == thisFrame {
- Logg.Debugf("Ignoring load request on frame that has symbol already loaded")
+ logg.Debugf("Ignoring load request on frame that has symbol already loaded")
return nil
}
return fmt.Errorf("key %v already defined in frame %v, this is frame %v", key, checkFrame, thisFrame)
@@ -75,8 +70,8 @@ func(ca *Cache) Add(key string, value string, sizeLimit uint16) error {
return fmt.Errorf("Cache capacity exceeded %v of %v", ca.CacheUseSize + sz, ca.CacheSize)
}
}
- Logg.Infof("Cache add", "key", key, "size", sz, "limit", sizeLimit)
- Logg.Tracef("", "Cache add data", value)
+ logg.Infof("Cache add", "key", key, "size", sz, "limit", sizeLimit)
+ logg.Tracef("", "Cache add data", value)
ca.Cache[len(ca.Cache)-1][key] = value
ca.CacheUseSize += sz
ca.Sizes[key] = sizeLimit
@@ -84,7 +79,7 @@ func(ca *Cache) Add(key string, value string, sizeLimit uint16) error {
return nil
}
-// ReservedSize returns the maximum byte size available for the given symbol.
+// ReservedSize implements the Memory interface.
func(ca *Cache) ReservedSize(key string) (uint16, error) {
v, ok := ca.Sizes[key]
if !ok {
@@ -93,14 +88,7 @@ func(ca *Cache) ReservedSize(key string) (uint16, error) {
return v, nil
}
-// Update sets a new value for an existing key.
-//
-// Uses the size limitation from when the key was added.
-//
-// Fails if:
-// - key not defined
-// - value is longer than size limit
-// - replacing value exceeds cumulative cache capacity
+// Update implements the Memory interface.
func(ca *Cache) Update(key string, value string) error {
sizeLimit := ca.Sizes[key]
if ca.Sizes[key] > 0 {
@@ -129,9 +117,7 @@ func(ca *Cache) Update(key string, value string) error {
return nil
}
-// Get the content currently loaded for a single key, loaded at any level.
-//
-// Fails if key has not been loaded.
+// Get implements the Memory interface.
func(ca *Cache) Get(key string) (string, error) {
i := ca.frameOf(key)
if i == -1 {
@@ -144,7 +130,7 @@ func(ca *Cache) Get(key string) (string, error) {
return r, nil
}
-// Reset flushes all state contents below the top level.
+// Reset implements the Memory interface.
func(ca *Cache) Reset() {
if len(ca.Cache) == 0 {
return
@@ -153,17 +139,14 @@ func(ca *Cache) Reset() {
ca.CacheUseSize = 0
return
}
-
-// Push adds a new level to the cache.
+// Push implements the Memory interface.
func (ca *Cache) Push() error {
m := make(map[string]string)
ca.Cache = append(ca.Cache, m)
return nil
}
-// Pop frees the cache of the current level and makes the previous level the current level.
-//
-// Fails if already on top level.
+// Pop implements the Memory interface.
func (ca *Cache) Pop() error {
l := len(ca.Cache)
if l == 0 {
@@ -174,7 +157,7 @@ func (ca *Cache) Pop() error {
for k, v := range m {
sz := len(v)
ca.CacheUseSize -= uint32(sz)
- Logg.Debugf("Cache free", "frame", l, "key", k, "size", sz)
+ logg.Debugf("Cache free", "frame", l, "key", k, "size", sz)
}
ca.Cache = ca.Cache[:l]
//ca.resetCurrent()
@@ -186,9 +169,8 @@ func(ca *Cache) Check(key string) bool {
return ca.frameOf(key) == -1
}
-// Last returns the last inserted value
+// Last implements the Memory interface.
//
-// The stored last inserter value will be reset to an empty string
// TODO: needs to be invalidated when out of scope
func(ca *Cache) Last() string {
s := ca.LastValue
@@ -221,10 +203,12 @@ func(ca *Cache) frameOf(key string) int {
return -1
}
+// Levels implements the Memory interface.
func(ca *Cache) Levels() uint32 {
return uint32(len(ca.Cache))
}
+// Keys implements the Memory interface.
func(ca *Cache) Keys(level uint32) []string {
var r []string
for k := range ca.Cache[level] {
diff --git a/cache/log.go b/cache/log.go
@@ -5,5 +5,5 @@ import (
)
var (
- Logg logging.Logger = logging.NewVanilla().WithDomain("cache")
+ logg logging.Logger = logging.NewVanilla().WithDomain("cache")
)
diff --git a/cache/memory.go b/cache/memory.go
@@ -1,17 +1,53 @@
package cache
-// Memory defines the interface for store of a symbol mapped content store.
+// Memory defines the interface for store of a symbol mapped content cache.
type Memory interface {
+ // Add adds a cache value under a cache symbol key.
+ //
+ // Also stores the size limitation of for key for later updates.
+ //
+ // Must fail if:
+ // * key already defined
+ // * value is longer than size limit
+ // * adding value exceeds cumulative cache capacity
Add(key string, val string, sizeLimit uint16) error
+ // Update sets a new value for an existing key.
+ //
+ // Uses the size limitation from when the key was added.
+ //
+ // Must fail if:
+ // - key not defined
+ // - value is longer than size limit
+ // - replacing value exceeds cumulative cache capacity
Update(key string, val string) error
+ // ReservedSize returns the maximum byte size available for the given symbol.
ReservedSize(key string) (uint16, error)
+ // Get the content currently loaded for a single key, loaded at any level.
+ //
+ // Must fail if key has not been loaded.
Get(key string) (string, error)
+ // Push adds a new level to the cache.
Push() error
+ // Pop frees the cache of the current level and makes the previous level the current level.
+ //
+ // Fails if already on top level.
Pop() error
+ // Reset flushes all state contents below the top level.
Reset()
+ // Levels returns the current number of levels.
Levels() uint32
+ // Keys returns all storage keys for the given level.
Keys(level uint32) []string
+ // Last returns the last inserted value
+ //
+ // The stored last inserter value must be reset to an empty string
Last() string
+ // Invalidate marks a cache as invalid.
+ //
+ // An invalid cache should not be persisted or propagated
Invalidate()
+ // Invalid returns true if cache is invalid.
+ //
+ // An invalid cache should not be persisted or propagated
Invalid() bool
}
diff --git a/db/error.go b/db/error.go
@@ -14,7 +14,7 @@ func NewErrNotFound(k []byte) error {
return ErrNotFound{k}
}
-// Error implements error.
+// Error implements Error.
func(e ErrNotFound) Error() string {
return fmt.Sprintf("key not found: %x", e.k)
}
diff --git a/engine/config.go b/engine/config.go
@@ -2,10 +2,16 @@ package engine
// Config globally defines behavior of all components driven by the engine.
type Config struct {
- OutputSize uint32 // Maximum size of output from a single rendered page
+ // OutputSize sets the maximum size of output from a single rendered page. If set to 0, no size limit is imposed.
+ OutputSize uint32
+ // SessionId is used to segment the context of state and application data retrieval and storage.
SessionId string
+ // Root is the node name of the bytecode entry point.
Root string
+ // FlagCount is used to set the number of user-defined signal flags used in the execution state.
FlagCount uint32
+ // CacheSize determines the total allowed cumulative cache size for a single SessionId storage segment. If set to 0, no size limit is imposed.
CacheSize uint32
+ // Language determines the ISO-639-3 code of the default translation language. If not set, no language translations will be looked up.
Language string
}
diff --git a/engine/debug.go b/engine/debug.go
@@ -9,15 +9,19 @@ import (
"git.defalsify.org/vise.git/state"
)
+// Debug implementations output details about the execution state on each execution halt.
type Debug interface {
+ // Break receives the state and cache in order to generate its output.
Break(*state.State, cache.Memory)
}
+// SimpleDebug is a vanilla implementation of the Debug interface.
type SimpleDebug struct {
pfx string
w io.Writer
}
+// NewSimpleDebug instantiates a new SimpleDebug object.
func NewSimpleDebug(w io.Writer) Debug {
if w == nil {
w = os.Stderr
@@ -28,10 +32,14 @@ func NewSimpleDebug(w io.Writer) Debug {
}
}
+// Break implements the Debug interface.
func (dbg* SimpleDebug) Break(st *state.State, ca cache.Memory) {
fmt.Fprintf(dbg.w, "%s State:\n", dbg.pfx)
+ node, lvl := st.Where()
+ fmt.Fprintf(dbg.w, "%s\tPath: %s (%d)\n", dbg.pfx, node, lvl)
+ fmt.Fprintf(dbg.w, "%s\tFlags:\n", dbg.pfx)
for _, s := range state.FlagDebugger.AsList(st.Flags, st.BitSize - 8) {
- fmt.Fprintf(dbg.w, "%s\t%s\n", dbg.pfx, s)
+ fmt.Fprintf(dbg.w, "%s\t\t%s\n", dbg.pfx, s)
}
for i := uint32(0); i < ca.Levels(); i++ {
fmt.Fprintf(dbg.w, "%s Cache[%d]:\n", dbg.pfx, i)
diff --git a/engine/default.go b/engine/default.go
@@ -31,7 +31,7 @@ func NewDefaultEngine(dir string, persistDb db.Db, session *string) (EngineIsh,
pr := persist.NewPersister(persistDb)
en, err = NewPersistedEngine(ctx, cfg, pr, rs)
if err != nil {
- Logg.Infof("persisted engine create error. trying again with persisting empty state first...")
+ logg.Infof("persisted engine create error. trying again with persisting empty state first...")
pr = pr.WithContent(&st, ca)
err = pr.Save(cfg.SessionId)
if err != nil {
@@ -67,7 +67,7 @@ func NewSizedEngine(dir string, size uint32, persistDb db.Db, session *string) (
pr := persist.NewPersister(persistDb)
en, err = NewPersistedEngine(ctx, cfg, pr, rs)
if err != nil {
- Logg.Infof("persisted engine create error. trying again with persisting empty state first...")
+ logg.Infof("persisted engine create error. trying again with persisting empty state first...")
pr = pr.WithContent(&st, ca)
err = pr.Save(cfg.SessionId)
if err != nil {
diff --git a/engine/engine.go b/engine/engine.go
@@ -57,7 +57,7 @@ func NewEngine(ctx context.Context, cfg Config, st *state.State, rs resource.Res
if err != nil {
panic(err)
}
- Logg.InfoCtxf(ctx, "set language from config", "language", cfg.Language)
+ logg.InfoCtxf(ctx, "set language from config", "language", cfg.Language)
}
}
@@ -67,6 +67,9 @@ func NewEngine(ctx context.Context, cfg Config, st *state.State, rs resource.Res
return engine
}
+// SetDebugger sets a debugger to use.
+//
+// No debugger is set by default.
func (en *Engine) SetDebugger(debugger Debug) {
en.dbg = debugger
}
@@ -78,7 +81,7 @@ func(en *Engine) SetFirst(fn resource.EntryFunc) {
// Finish implements EngineIsh interface
func(en *Engine) Finish() error {
- Logg.Tracef("that's a wrap", "engine", en)
+ logg.Tracef("that's a wrap", "engine", en)
return nil
}
@@ -90,7 +93,7 @@ func(en *Engine) restore() {
return
}
if en.root != location {
- Logg.Infof("restoring state", "sym", location)
+ logg.Infof("restoring state", "sym", location)
en.root = "."
}
}
@@ -102,7 +105,7 @@ func(en *Engine) runFirst(ctx context.Context) (bool, error) {
if en.first == nil {
return true, nil
}
- Logg.DebugCtxf(ctx, "start pre-VM check")
+ logg.DebugCtxf(ctx, "start pre-VM check")
rs := resource.NewMenuResource()
rs.AddLocalFunc("_first", en.first)
en.st.Down("_first")
@@ -119,7 +122,7 @@ func(en *Engine) runFirst(ctx context.Context) (bool, error) {
} else {
if en.st.MatchFlag(state.FLAG_TERMINATE, true) {
en.exit = en.ca.Last()
- Logg.InfoCtxf(ctx, "Pre-VM check says not to continue execution", "state", en.st)
+ logg.InfoCtxf(ctx, "Pre-VM check says not to continue execution", "state", en.st)
} else {
r = true
}
@@ -130,7 +133,7 @@ func(en *Engine) runFirst(ctx context.Context) (bool, error) {
}
en.st.ResetFlag(state.FLAG_TERMINATE)
en.st.ResetFlag(state.FLAG_DIRTY)
- Logg.DebugCtxf(ctx, "end pre-VM check")
+ logg.DebugCtxf(ctx, "end pre-VM check")
return r, err
}
@@ -140,7 +143,7 @@ func(en *Engine) runFirst(ctx context.Context) (bool, error) {
func(en *Engine) Init(ctx context.Context) (bool, error) {
en.restore()
if en.initd {
- Logg.DebugCtxf(ctx, "already initialized")
+ logg.DebugCtxf(ctx, "already initialized")
return true, nil
}
@@ -164,13 +167,13 @@ func(en *Engine) Init(ctx context.Context) (bool, error) {
}
b := vm.NewLine(nil, vm.MOVE, []string{sym}, nil, nil)
- Logg.DebugCtxf(ctx, "start new init VM run", "code", b)
+ logg.DebugCtxf(ctx, "start new init VM run", "code", b)
b, err = en.vm.Run(ctx, b)
if err != nil {
return false, err
}
- Logg.DebugCtxf(ctx, "end new init VM run", "code", b)
+ logg.DebugCtxf(ctx, "end new init VM run", "code", b)
en.st.SetCode(b)
err = en.st.SetInput(inSave)
if err != nil {
@@ -214,7 +217,7 @@ func (en *Engine) Exec(ctx context.Context, input []byte) (bool, error) {
// backend for Exec, after the input validity check
func(en *Engine) exec(ctx context.Context, input []byte) (bool, error) {
- Logg.InfoCtxf(ctx, "new VM execution with input", "input", string(input))
+ logg.InfoCtxf(ctx, "new VM execution with input", "input", string(input))
code, err := en.st.GetCode()
if err != nil {
return false, err
@@ -223,26 +226,26 @@ func(en *Engine) exec(ctx context.Context, input []byte) (bool, error) {
return false, fmt.Errorf("no code to execute")
}
- Logg.Debugf("start new VM run", "code", code)
+ logg.Debugf("start new VM run", "code", code)
code, err = en.vm.Run(ctx, code)
if err != nil {
return false, err
}
- Logg.Debugf("end new VM run", "code", code)
+ logg.Debugf("end new VM run", "code", code)
v := en.st.MatchFlag(state.FLAG_TERMINATE, true)
if v {
if len(code) > 0 {
- Logg.Debugf("terminated with code remaining", "code", code)
+ logg.Debugf("terminated with code remaining", "code", code)
}
return false, err
}
en.st.SetCode(code)
if len(code) == 0 {
- Logg.Infof("runner finished with no remaining code", "state", en.st)
+ logg.Infof("runner finished with no remaining code", "state", en.st)
if en.st.MatchFlag(state.FLAG_DIRTY, true) {
- Logg.Debugf("have output for quitting")
+ logg.Debugf("have output for quitting")
en.exit = en.ca.Last()
}
_, err = en.reset(ctx)
@@ -266,7 +269,7 @@ func(en *Engine) WriteResult(ctx context.Context, w io.Writer) (int, error) {
if en.st.Language != nil {
ctx = context.WithValue(ctx, "Language", *en.st.Language)
}
- Logg.TraceCtxf(ctx, "render with state", "state", en.st)
+ logg.TraceCtxf(ctx, "render with state", "state", en.st)
r, err := en.vm.Render(ctx)
if err != nil {
return 0, err
@@ -278,7 +281,7 @@ func(en *Engine) WriteResult(ctx context.Context, w io.Writer) (int, error) {
}
}
if len(en.exit) > 0 {
- Logg.TraceCtxf(ctx, "have exit", "exit", en.exit)
+ logg.TraceCtxf(ctx, "have exit", "exit", en.exit)
n, err := io.WriteString(w, en.exit)
if err != nil {
return l, err
diff --git a/engine/log.go b/engine/log.go
@@ -5,5 +5,5 @@ import (
)
var (
- Logg logging.Logger = logging.NewVanilla().WithDomain("engine")
+ logg logging.Logger = logging.NewVanilla().WithDomain("engine")
)
diff --git a/engine/loop.go b/engine/loop.go
@@ -32,7 +32,7 @@ func Loop(ctx context.Context, en EngineIsh, reader io.Reader, writer io.Writer)
for running {
in, err := bufReader.ReadString('\n')
if err == io.EOF {
- Logg.DebugCtxf(ctx, "EOF found, that's all folks")
+ logg.DebugCtxf(ctx, "EOF found, that's all folks")
return nil
}
if err != nil {
diff --git a/engine/persist.go b/engine/persist.go
@@ -44,7 +44,7 @@ func(pe PersistedEngine) Exec(ctx context.Context, input []byte) (bool, error) {
// Finish implements EngineIsh interface
func(pe PersistedEngine) Finish() error {
- Logg.Tracef("that's a wrap", "engine", pe)
+ logg.Tracef("that's a wrap", "engine", pe)
return pe.pr.Save(pe.Engine.session)
}
diff --git a/examples/db/main.go b/examples/db/main.go
@@ -17,9 +17,11 @@ import (
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
"git.defalsify.org/vise.git/db"
+ "git.defalsify.org/vise.git/logging"
)
var (
+ logg = logging.NewVanilla()
baseDir = testdataloader.GetBasePath()
scriptDir = path.Join(baseDir, "examples", "db")
store = db.NewFsDb()
@@ -141,11 +143,11 @@ func main() {
st := state.NewState(1)
en, err := engine.NewPersistedEngine(ctx, cfg, pr, rs)
if err != nil {
- engine.Logg.Infof("persisted engine create error. trying again with persisting empty state first...")
+ logg.Infof("persisted engine create error. trying again with persisting empty state first...")
pr = pr.WithContent(&st, ca)
err = pr.Save(cfg.SessionId)
if err != nil {
- engine.Logg.ErrorCtxf(ctx, "fail state save", "err", err)
+ logg.ErrorCtxf(ctx, "fail state save", "err", err)
os.Exit(1)
}
en, err = engine.NewPersistedEngine(ctx, cfg, pr, rs)
diff --git a/examples/languages/main.go b/examples/languages/main.go
@@ -17,6 +17,7 @@ import (
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
"git.defalsify.org/vise.git/db"
+ "git.defalsify.org/vise.git/logging"
)
const (
@@ -24,6 +25,7 @@ const (
)
var (
+ logg = logging.NewVanilla()
baseDir = testdataloader.GetBasePath()
scriptDir = path.Join(baseDir, "examples", "languages")
translationDir = path.Join(scriptDir, "locale")
@@ -31,7 +33,7 @@ var (
func codeFromCtx(ctx context.Context) string {
var code string
- engine.Logg.DebugCtxf(ctx, "in msg", "ctx", ctx, "val", code)
+ logg.DebugCtxf(ctx, "in msg", "ctx", ctx, "val", code)
if ctx.Value("Language") != nil {
lang := ctx.Value("Language").(lang.Language)
code = lang.Code
@@ -75,7 +77,7 @@ func(l *langController) moMsg(ctx context.Context, sym string, input []byte) (re
o := gotext.NewLocale(translationDir, code)
o.AddDomain("default")
r.Content = o.Get("This message is translated using gettext")
- engine.Logg.DebugCtxf(ctx, "lang", "code", code, "translateor", o)
+ logg.DebugCtxf(ctx, "lang", "code", code, "translateor", o)
return r, nil
}
@@ -101,17 +103,17 @@ func main() {
store := db.NewFsDb()
err := store.Connect(ctx, dp)
if err != nil {
- engine.Logg.ErrorCtxf(ctx, "db connect fail", "err", err)
+ logg.ErrorCtxf(ctx, "db connect fail", "err", err)
os.Exit(1)
}
pr := persist.NewPersister(store)
en, err := engine.NewPersistedEngine(ctx, cfg, pr, rs)
if err != nil {
- engine.Logg.Infof("persisted engine create error. trying again with persisting empty state first...")
+ logg.Infof("persisted engine create error. trying again with persisting empty state first...")
pr = pr.WithContent(&st, ca)
err = pr.Save(cfg.SessionId)
if err != nil {
- engine.Logg.ErrorCtxf(ctx, "fail state save", "err", err)
+ logg.ErrorCtxf(ctx, "fail state save", "err", err)
os.Exit(1)
}
en, err = engine.NewPersistedEngine(ctx, cfg, pr, rs)
diff --git a/examples/pincheck/main.go b/examples/pincheck/main.go
@@ -15,6 +15,7 @@ import (
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
+ "git.defalsify.org/vise.git/logging"
)
const (
@@ -23,6 +24,7 @@ const (
)
var (
+ logg = logging.NewVanilla()
baseDir = testdataloader.GetBasePath()
scriptDir = path.Join(baseDir, "examples", "pincheck")
pin = []byte("1234")
@@ -51,7 +53,7 @@ func(rs *pinResource) pinCheck(ctx context.Context, sym string, input []byte) (r
}
if bytes.Equal(input, pin) {
r.FlagSet = []uint32{USERFLAG_VALIDPIN}
- engine.Logg.DebugCtxf(ctx, "pin match", "state", rs.st, "rs", r.FlagSet, "rr", r.FlagReset)
+ logg.DebugCtxf(ctx, "pin match", "state", rs.st, "rs", r.FlagSet, "rr", r.FlagReset)
} else {
r.Content = "Wrong PIN please try again"
}
diff --git a/examples/session/main.go b/examples/session/main.go
@@ -15,9 +15,11 @@ import (
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
+ "git.defalsify.org/vise.git/logging"
)
var (
+ logg = logging.NewVanilla()
baseDir = testdataloader.GetBasePath()
scriptDir = path.Join(baseDir, "examples", "session")
emptyResult = resource.Result{}
@@ -32,7 +34,7 @@ func save(ctx context.Context, sym string, input []byte) (resource.Result, error
}
fp := path.Join(sessionDir, "data.txt")
if len(input) > 0 {
- engine.Logg.Debugf("write data %s session %s", input, sessionId)
+ logg.Debugf("write data %s session %s", input, sessionId)
err = ioutil.WriteFile(fp, input, 0600)
if err != nil {
return emptyResult, err
diff --git a/examples/state/main.go b/examples/state/main.go
@@ -1,4 +1,4 @@
-// Example: Toggling states with external functions.
+// Example: Toggling states with external functions, with engine debugger.
package main
import (
@@ -13,6 +13,7 @@ import (
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
+ "git.defalsify.org/vise.git/logging"
)
const (
@@ -22,6 +23,7 @@ const (
)
var (
+ logg = logging.NewVanilla()
baseDir = testdataloader.GetBasePath()
scriptDir = path.Join(baseDir, "examples", "state")
)
@@ -40,7 +42,7 @@ func(f *flagResource) get(ctx context.Context, sym string, input []byte) (resour
func(f *flagResource) do(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var r resource.Result
- engine.Logg.DebugCtxf(ctx, "in do", "sym", sym)
+ logg.DebugCtxf(ctx, "in do", "sym", sym)
switch(sym) {
case "do_foo":
diff --git a/examples/state_passive/main.go b/examples/state_passive/main.go
@@ -15,6 +15,7 @@ import (
"git.defalsify.org/vise.git/cache"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/db"
+ "git.defalsify.org/vise.git/logging"
)
const (
@@ -24,6 +25,10 @@ const (
USERFLAG_DONE
)
+var (
+ logg = logging.NewVanilla()
+)
+
type fsData struct {
path string
persister *persist.Persister
@@ -57,9 +62,9 @@ func (fsd *fsData) poke(ctx context.Context, sym string, input []byte) (resource
st := fsd.persister.GetState()
for i := 8; i < 12; i++ {
v := uint32(i)
- engine.Logg.DebugCtxf(ctx, "checking flag", "flag", v)
+ logg.DebugCtxf(ctx, "checking flag", "flag", v)
if st.MatchFlag(v, true) {
- engine.Logg.DebugCtxf(ctx, "match on flag", "flag", v)
+ logg.DebugCtxf(ctx, "match on flag", "flag", v)
res.FlagReset = append(res.FlagReset, v)
res.FlagSet = append(res.FlagSet, v + 1)
break
diff --git a/lang/lang.go b/lang/lang.go
@@ -7,14 +7,19 @@ import (
)
var (
+ // Default language (hard to get around)
Default = "eng" // ISO639-3
)
+// Language is used to set and get language translation to be used for rendering output.
type Language struct {
Code string
Name string
}
+// LanguageFromCode returns a Language object from the given ISO-639-3 (three-letter) code.
+//
+// Will fail if an unknown code is provided.
func LanguageFromCode(code string) (Language, error) {
r := iso639_3.FromAnyCode(code)
if r == nil {
@@ -26,6 +31,9 @@ func LanguageFromCode(code string) (Language, error) {
}, nil
}
+// String implements the String interface.
+//
+// Returns a representation of the Language fit for debugging.
func(l Language) String() string {
return fmt.Sprintf("%s (%s)", l.Code, l.Name)
}
diff --git a/logging/logging.go b/logging/logging.go
@@ -3,15 +3,20 @@ package logging
import (
"context"
"io"
- "os"
)
const (
+ // No logging
LVL_NONE = iota
+ // Error log level - unexpected states that need immediate developer attention.
LVL_ERROR
+ // Warning log level - unexpected states that may need developer attention.
LVL_WARN
+ // Info log level - expected states that are of general interest to the end-user.
LVL_INFO
+ // Debug log level - expected states that are of general interest to the developer.
LVL_DEBUG
+ // Trace log level - everything else.
LVL_TRACE
)
@@ -25,30 +30,39 @@ var (
}
)
-var (
- LogWriter = os.Stderr
-)
-
-
+// AsString returns the string representation used in logging output for the given log level.
func AsString(level int) string {
return levelStr[level]
}
-
type Logger interface {
+ // Writef logs a line to the given writer with the given loglevel.
Writef(w io.Writer, level int, msg string, args ...any)
+ // WriteCtxf logs a line with context to the given writer with the given loglevel.
WriteCtxf(ctx context.Context, w io.Writer, level int, msg string, args ...any)
+ // Printf logs a line to the default writer with the given loglevel.
Printf(level int, msg string, args ...any)
+ // Printf logs a line with context to the default writer with the given loglevel.
PrintCtxf(ctx context.Context, level int, msg string, args ...any)
+ // Tracef logs a line to the default writer the TRACE loglevel.
Tracef(msg string, args ...any)
+ // TraceCtxf logs a line with context to the default writer the TRACE loglevel.
TraceCtxf(ctx context.Context, msg string, args ...any)
+ // Debugf logs a line to the default writer the DEBUG loglevel.
Debugf(msg string, args ...any)
+ // DebugCtxf logs a line with context to the default writer the DEBUG loglevel.
DebugCtxf(ctx context.Context, msg string, args ...any)
+ // Infof logs a line to the default writer the INFO loglevel.
Infof(msg string, args ...any)
+ // InfoCtxf logs a line with context to the default writer the INFO loglevel.
InfoCtxf(ctx context.Context, msg string, args ...any)
+ // Warnf logs a line to the default writer the WARN loglevel.
Warnf(msg string, args ...any)
+ // WarnCtxf logs a line with context to the default writer the WARN loglevel.
WarnCtxf(ctx context.Context, msg string, args ...any)
+ // Errorf logs a line to the default writer the ERROR loglevel.
Errorf(msg string, args ...any)
+ // ErrorCtxf logs a line with context to the default writer the ERROR loglevel.
ErrorCtxf(ctx context.Context, msg string, args ...any)
}
diff --git a/logging/vanilla.go b/logging/vanilla.go
@@ -4,10 +4,16 @@ import (
"context"
"fmt"
"io"
+ "os"
"path"
"runtime"
)
+var (
+ // LogWriter is used as io.Writer the Vanilla Logger implementation.
+ LogWriter = os.Stderr
+)
+
// Vanilla is a basic single-line structured output logger for terminal output.
type Vanilla struct {
domain string
@@ -86,47 +92,47 @@ func(v Vanilla) Tracef(msg string, args ...any) {
v.printf(LVL_TRACE, msg, args...)
}
-// Tracef logs a line with level DEBUG to the global writer.
+// Debugf logs a line with level DEBUG to the global writer.
func(v Vanilla) Debugf(msg string, args ...any) {
v.printf(LVL_DEBUG, msg, args...)
}
-// Tracef logs a line with level INFO to the global writer.
+// Infof logs a line with level INFO to the global writer.
func(v Vanilla) Infof(msg string, args ...any) {
v.printf(LVL_INFO, msg, args...)
}
-// Tracef logs a line with level WARN to the global writer.
+// Warnf logs a line with level WARN to the global writer.
func(v Vanilla) Warnf(msg string, args ...any) {
v.printf(LVL_WARN, msg, args...)
}
-// Tracef logs a line with level ERROR to the global writer.
+// Errorf logs a line with level ERROR to the global writer.
func(v Vanilla) Errorf(msg string, args ...any) {
v.printf(LVL_ERROR, msg, args...)
}
-// Tracef logs a line with context with level TRACE to the global writer.
+// TraceCtxf logs a line with context with level TRACE to the global writer.
func(v Vanilla) TraceCtxf(ctx context.Context, msg string, args ...any) {
v.printCtxf(ctx, LVL_TRACE, msg, args...)
}
-// Tracef logs a line with context with level DEBUG to the global writer.
+// DebugCtxf logs a line with context with level DEBUG to the global writer.
func(v Vanilla) DebugCtxf(ctx context.Context, msg string, args ...any) {
v.printCtxf(ctx, LVL_DEBUG, msg, args...)
}
-// Tracef logs a line with context with level INFO to the global writer.
+// InfoCtxf logs a line with context with level INFO to the global writer.
func(v Vanilla) InfoCtxf(ctx context.Context, msg string, args ...any) {
v.printCtxf(ctx, LVL_INFO, msg, args...)
}
-// Tracef logs a line with context with level WARN to the global writer.
+// WarnCtxf logs a line with context with level WARN to the global writer.
func(v Vanilla) WarnCtxf(ctx context.Context, msg string, args ...any) {
v.printCtxf(ctx, LVL_WARN, msg, args...)
}
-// Tracef logs a line with context with level ERROR to the global writer.
+// ErrorCtxf logs a line with context with level ERROR to the global writer.
func(v Vanilla) ErrorCtxf(ctx context.Context, msg string, args ...any) {
v.printCtxf(ctx, LVL_ERROR, msg, args...)
}
diff --git a/persist/gdbm.go b/persist/gdbm.go
@@ -1,92 +0,0 @@
-package persist
-
-import (
- "github.com/fxamacker/cbor/v2"
- gdbm "github.com/graygnuorg/go-gdbm"
-
- "git.defalsify.org/vise.git/cache"
- "git.defalsify.org/vise.git/state"
- "git.defalsify.org/vise.git/db"
-)
-
-// gdbmPersister is an implementation of Persister that saves state to the file system.
-type gdbmPersister struct {
- State *state.State
- Memory *cache.Cache
- db *gdbm.Database
-}
-
-func NewGdbmPersiser(fp string) *gdbmPersister {
- gdb, err := gdbm.Open(fp, gdbm.ModeReader)
- if err != nil {
- panic(err)
- }
- return NewGdbmPersisterFromDatabase(gdb)
-}
-
-func NewGdbmPersisterFromDatabase(gdb *gdbm.Database) *gdbmPersister {
- return &gdbmPersister{
- db: gdb,
- }
-}
-
-// WithContent sets a current State and Cache object.
-//
-// This method is normally called before Serialize / Save.
-func(p *gdbmPersister) WithContent(st *state.State, ca *cache.Cache) *gdbmPersister {
- p.State = st
- p.Memory = ca
- return p
-}
-
-// TODO: DRY
-// GetState implements the Persister interface.
-func(p *gdbmPersister) GetState() *state.State {
- return p.State
-}
-
-// GetMemory implements the Persister interface.
-func(p *gdbmPersister) GetMemory() cache.Memory {
- return p.Memory
-}
-
-// Serialize implements the Persister interface.
-func(p *gdbmPersister) Serialize() ([]byte, error) {
- return cbor.Marshal(p)
-}
-
-// Deserialize implements the Persister interface.
-func(p *gdbmPersister) Deserialize(b []byte) error {
- err := cbor.Unmarshal(b, p)
- return err
-}
-
-// Save implements the Persister interface.
-func(p *gdbmPersister) Save(key string) error {
- b, err := p.Serialize()
- if err != nil {
- return err
- }
- k := db.ToDbKey(db.DATATYPE_STATE, []byte(key), nil)
- err = p.db.Store(k, b, true)
- if err != nil {
- return err
- }
- Logg.Debugf("saved state and cache", "key", key, "bytecode", p.State.Code, "flags", p.State.Flags)
- return nil
-}
-
-// Load implements the Persister interface.
-func(p *gdbmPersister) Load(key string) error {
- k := db.ToDbKey(db.DATATYPE_STATE, []byte(key), nil)
- b, err := p.db.Fetch(k)
- if err != nil {
- return err
- }
- err = p.Deserialize(b)
- if err != nil {
- return err
- }
- Logg.Debugf("loaded state and cache", "key", key, "bytecode", p.State.Code)
- return nil
-}
diff --git a/persist/log.go b/persist/log.go
@@ -5,5 +5,5 @@ import (
)
var (
- Logg logging.Logger = logging.NewVanilla().WithDomain("persist")
+ logg logging.Logger = logging.NewVanilla().WithDomain("persist")
)
diff --git a/persist/persist.go b/persist/persist.go
@@ -100,6 +100,6 @@ func(p *Persister) Load(key string) error {
if err != nil {
return err
}
- Logg.Debugf("loaded state and cache", "key", key, "bytecode", p.State.Code)
+ logg.Debugf("loaded state and cache", "key", key, "bytecode", p.State.Code)
return nil
}
diff --git a/render/log.go b/render/log.go
@@ -5,5 +5,5 @@ import (
)
var (
- Logg logging.Logger = logging.NewVanilla().WithDomain("render")
+ logg logging.Logger = logging.NewVanilla().WithDomain("render")
)
diff --git a/render/menu.go b/render/menu.go
@@ -9,7 +9,9 @@ import (
// BrowseError is raised when browsing outside the page range of a rendered node.
type BrowseError struct {
+ // The lateral page index where the error occurred.
Idx uint16
+ // The total number of lateral page indicies.
PageCount uint16
}
@@ -20,15 +22,21 @@ func(err *BrowseError) Error() string {
// BrowseConfig defines the availability and display parameters for page browsing.
type BrowseConfig struct {
+ // Set if a consecutive page is available for lateral navigation.
NextAvailable bool
+ // Menu selector used to navigate to next page.
NextSelector string
+ // Menu title used to label selector for next page.
NextTitle string
+ // Set if a previous page is available for lateral navigation.
PreviousAvailable bool
+ // Menu selector used to navigate to previous page.
PreviousSelector string
+ // Menu title used to label selector for previous page.
PreviousTitle string
}
-// Default browse settings for convenience.
+// Create a BrowseConfig with default values.
func DefaultBrowseConfig() BrowseConfig {
return BrowseConfig{
NextAvailable: true,
@@ -40,7 +48,9 @@ func DefaultBrowseConfig() BrowseConfig {
}
}
-// Menu renders menus. May be included in a Page object to render menus for pages.
+// Menu renders menus.
+//
+// May be included in a Page object to render menus for pages.
type Menu struct {
rs resource.Resource
menu [][2]string // selector and title for menu items.
@@ -53,6 +63,9 @@ type Menu struct {
keep bool
}
+// String implements the String interface.
+//
+// It returns debug representation of menu.
func(m Menu) String() string {
return fmt.Sprintf("pagecount: %v menusink: %v next: %v prev: %v", m.pageCount, m.sink, m.canNext, m.canPrevious)
}
@@ -64,12 +77,15 @@ func NewMenu() *Menu {
}
}
-// WithBrowseConfig defines the criteria for page browsing.
+// WithPageCount is a chainable function that defines the number of allowed pages for browsing.
func(m *Menu) WithPageCount(pageCount uint16) *Menu {
m.pageCount = pageCount
return m
}
+// WithPages is a chainable function which activates pagination in the menu.
+//
+// It is equivalent to WithPageCount(1)
func(m *Menu) WithPages() *Menu {
if m.pageCount == 0 {
m.pageCount = 1
@@ -77,11 +93,17 @@ func(m *Menu) WithPages() *Menu {
return m
}
+// WithSink is a chainable function that informs the menu that a content sink exists in the render.
+//
+// A content sink receives priority to consume all remaining space after all non-sink items have been rendered.
func(m *Menu) WithSink() *Menu {
m.sink = true
return m
}
+// WithDispose is a chainable function that preserves the menu after render is complete.
+//
+// It is used for multi-page content.
func(m *Menu) WithDispose() *Menu {
m.keep = false
return m
@@ -129,7 +151,11 @@ func(m *Menu) Put(selector string, title string) error {
// return m.outputSize
//}
- // mainSize, prevsize, nextsize, nextsize+prevsize
+// Sizes returns the size limitations for each part of the render, as a four-element array:
+// 1. mainSize
+// 2. prevsize
+// 3. nextsize
+// 4. nextsize + prevsize
func(m *Menu) Sizes(ctx context.Context) ([4]uint32, error) {
var menuSizes [4]uint32
cfg := m.GetBrowseConfig()
@@ -154,6 +180,7 @@ func(m *Menu) Sizes(ctx context.Context) ([4]uint32, error) {
return menuSizes, nil
}
+// title corresponding to the menu symbol.
func(m *Menu) titleFor(ctx context.Context, title string) (string, error) {
if m.rs == nil {
return title, nil
@@ -223,7 +250,7 @@ func(m *Menu) applyPage(idx uint16) error {
if idx == 0 {
m.canPrevious = false
}
- Logg.Debugf("applypage", "m", m, "idx", idx)
+ logg.Debugf("applypage", "m", m, "idx", idx)
if m.canNext {
err := m.Put(m.browse.NextSelector, m.browse.NextTitle)
@@ -261,6 +288,7 @@ func(m *Menu) reset() {
}
}
+// Reset clears all current state from the menu object, making it ready for re-use in a new render.
func(m *Menu) Reset() {
m.menu = [][2]string{}
m.sink = false
diff --git a/render/page.go b/render/page.go
@@ -11,7 +11,7 @@ import (
"git.defalsify.org/vise.git/resource"
)
-// Page exectues output rendering into pages constrained by size.
+// Page executes output rendering into pages constrained by size.
type Page struct {
cacheMap map[string]string // Mapped content symbols
cache cache.Memory // Content store.
@@ -56,7 +56,7 @@ func(pg *Page) WithError(err error) *Page {
return pg
}
-// Error implements error interface.
+// Error implements the Error interface.
func(pg *Page) Error() string {
if pg.err != nil {
return pg.err.Error()
@@ -111,7 +111,7 @@ func(pg *Page) Map(key string) error {
return err
}
}
- Logg.Tracef("mapped", "key", key)
+ logg.Tracef("mapped", "key", key)
return nil
}
@@ -154,7 +154,7 @@ func(pg *Page) RenderTemplate(ctx context.Context, sym string, values map[string
tpl += pg.extra
if pg.err != nil {
derr := pg.Error()
- Logg.DebugCtxf(ctx, "prepending error", "err", pg.err, "display", derr)
+ logg.DebugCtxf(ctx, "prepending error", "err", pg.err, "display", derr)
if len(tpl) == 0 {
tpl = derr
} else {
@@ -169,7 +169,7 @@ func(pg *Page) RenderTemplate(ctx context.Context, sym string, values map[string
} else if idx > 0 {
return "", fmt.Errorf("sizer needed for indexed render")
}
- Logg.Debugf("render for", "index", idx)
+ logg.Debugf("render for", "index", idx)
tp, err := template.New("tester").Option("missingkey=error").Parse(tpl)
if err != nil {
@@ -228,13 +228,13 @@ func(pg *Page) split(sym string, values map[string]string) (map[string]string, s
sink = k
sinkValues = strings.Split(v, "\n")
v = ""
- Logg.Infof("found sink", "sym", sym, "sink", k)
+ logg.Infof("found sink", "sym", sym, "sink", k)
}
noSinkValues[k] = v
}
if sink == "" {
- Logg.Tracef("no sink found", "sym", sym)
+ logg.Tracef("no sink found", "sym", sym)
return values, "", nil, nil
}
return noSinkValues, sink, sinkValues, nil
@@ -261,7 +261,7 @@ func(pg *Page) joinSink(sinkValues []string, remaining uint32, menuSizes [4]uint
for i, v := range sinkValues {
l += len(v)
- Logg.Tracef("processing sink", "idx", i, "value", v, "netremaining", netRemaining, "l", l)
+ logg.Tracef("processing sink", "idx", i, "value", v, "netremaining", netRemaining, "l", l)
if uint32(l) > netRemaining - 1 {
if tb.Len() == 0 {
return "", 0, fmt.Errorf("capacity insufficient for sink field %v", i)
@@ -329,7 +329,7 @@ func(pg *Page) prepare(ctx context.Context, sym string, values map[string]string
pg.extra = "\n{{._menu}}"
pg.sizer.sink = sink
noSinkValues[sink] = ""
- Logg.DebugCtxf(ctx, "menu is sink", "items", len(sinkValues))
+ logg.DebugCtxf(ctx, "menu is sink", "items", len(sinkValues))
}
}
@@ -355,7 +355,7 @@ func(pg *Page) prepare(ctx context.Context, sym string, values map[string]string
return nil, err
}
}
- Logg.Debugf("calculated pre-navigation allocation", "bytes", remaining, "menusizes", menuSizes)
+ logg.Debugf("calculated pre-navigation allocation", "bytes", remaining, "menusizes", menuSizes)
// process sink values array into newline-separated string
sinkString, count, err := pg.joinSink(sinkValues, remaining, menuSizes)
@@ -371,7 +371,7 @@ func(pg *Page) prepare(ctx context.Context, sym string, values map[string]string
// write all sink values to log.
for i, v := range strings.Split(sinkString, "\n") {
- Logg.Tracef("nosinkvalue", "idx", i, "value", v)
+ logg.Tracef("nosinkvalue", "idx", i, "value", v)
}
return noSinkValues, nil
@@ -385,7 +385,7 @@ func(pg *Page) render(ctx context.Context, sym string, values map[string]string,
if err != nil {
return "", err
}
- Logg.Debugf("rendered template", "bytes", len(s))
+ logg.Debugf("rendered template", "bytes", len(s))
r += s
if pg.menu != nil {
@@ -394,7 +394,7 @@ func(pg *Page) render(ctx context.Context, sym string, values map[string]string,
return "", err
}
l := len(s)
- Logg.Debugf("rendered menu", "bytes", l)
+ logg.Debugf("rendered menu", "bytes", l)
if l > 0 {
r += "\n" + s
}
diff --git a/render/size.go b/render/size.go
@@ -45,8 +45,8 @@ func(szr *Sizer) Check(s string) (uint32, bool) {
l := uint32(len(s))
if szr.outputSize > 0 {
if l > szr.outputSize {
- Logg.Infof("sized check fails", "length", l, "sizer", szr)
- Logg.Tracef("", "sizer contents", s)
+ logg.Infof("sized check fails", "length", l, "sizer", szr)
+ logg.Tracef("", "sizer contents", s)
return 0, false
}
l = szr.outputSize - l
@@ -55,6 +55,8 @@ func(szr *Sizer) Check(s string) (uint32, bool) {
}
// String implements the String interface.
+//
+// It outputs a representation of the Sizer fit for debug output.
func(szr *Sizer) String() string {
// var diff uint32
// if szr.outputSize > 0 {
@@ -82,7 +84,7 @@ func(szr *Sizer) Size(s string) (uint16, error) {
// AddCursor adds a pagination cursor for the paged sink content.
func(szr *Sizer) AddCursor(c uint32) {
- Logg.Debugf("Added cursor", "offset", c)
+ logg.Debugf("Added cursor", "offset", c)
szr.crsrs = append(szr.crsrs, c)
}
@@ -95,7 +97,7 @@ func(szr *Sizer) GetAt(values map[string]string, idx uint16) (map[string]string,
}
outValues := make(map[string]string)
for k, v := range values {
- Logg.Tracef("check values", "k", k, "v", v, "idx", idx, "cursors", szr.crsrs)
+ logg.Tracef("check values", "k", k, "v", v, "idx", idx, "cursors", szr.crsrs)
if szr.sink == k {
if idx >= uint16(len(szr.crsrs)) {
return nil, fmt.Errorf("no more values in index")
@@ -114,6 +116,7 @@ func(szr *Sizer) GetAt(values map[string]string, idx uint16) (map[string]string,
return outValues, nil
}
+// Reset flushes all size measurements, making the sizer available for reuse.
func(szr *Sizer) Reset() {
szr.crsrs = []uint32{}
}
diff --git a/render/split.go b/render/split.go
@@ -2,11 +2,9 @@ package render
import (
"fmt"
- "log"
"strings"
)
-
func bookmark(values []string) []uint32 {
var c int
var bookmarks []uint32 = []uint32{0}
@@ -95,7 +93,7 @@ func paginate(bookmarks []uint32, capacity uint32, nextSize uint32, prevSize uin
var z int
currentPage := len(pages) - 1
for i < lastIndex {
- log.Printf("have item %v:%v (%v) index %v prevsize %v nextsize %v remain %v cap %v", bookmarks[i], lookAhead[i], lookAhead[i] - bookmarks[i], i, prevSize, nextSize, remaining, capacity)
+ logg.Tracef("have render", "bookmark", bookmarks[i], "lookahead", lookAhead[i], "diff", lookAhead[i] - bookmarks[i], "index", i, "prevsize", prevSize, "nextsize", nextSize, "remain", remaining, "capacity", capacity)
v := lookAhead[i]
delta := int((v - c) + 1)
@@ -112,7 +110,7 @@ func paginate(bookmarks []uint32, capacity uint32, nextSize uint32, prevSize uin
c = v
i += 1
}
- log.Printf("more %v remaining %v c %v last %v pages %v", haveMore, remaining, c, last, pages)
+ logg.Tracef("render more", "have", haveMore, "remain", remaining, "c", c, "last", last, "pages", pages)
if haveMore {
pages = append(pages, []uint32{})
@@ -146,7 +144,7 @@ func explode(values []string, pages [][]uint32) string {
}
end = c - z
v := s[start:end]
- log.Printf("page %v part %v %v %s", i, start, end, v)
+ logg.Tracef("explode", "page", i, "part start", start, "part end", end, "part str", v)
v = s[start:end]
sb.WriteString(v)
start = end
diff --git a/resource/fs.go b/resource/fs.go
@@ -107,6 +107,7 @@ func(fsr FsResource) FuncFor(sym string) (EntryFunc, error) {
return fsr.getFunc, nil
}
+// String implements the String interface.
func(fsr FsResource) String() string {
return fmt.Sprintf("fs resource at path: %s", fsr.Path)
}
diff --git a/resource/gdbm.go b/resource/gdbm.go
@@ -87,6 +87,7 @@ func(dbr *gdbmResource) AddLocalFunc(sym string, fn EntryFunc) {
dbr.fns[sym] = fn
}
+// String implements the String interface.
func(dbr *gdbmResource) String() string {
return fmt.Sprintf("gdbm: %v", dbr.db)
}
diff --git a/vm/input.go b/vm/input.go
@@ -30,7 +30,7 @@ func NewInvalidInputError(input string) error {
return InvalidInputError{input}
}
-// Error implements error interface.
+// Error implements the Error interface.
func(e InvalidInputError) Error() string {
return fmt.Sprintf("invalid input: '%s'", e.input)
}
diff --git a/vm/runner.go b/vm/runner.go
@@ -30,7 +30,7 @@ func(e *ExternalCodeError) WithCode(code int) *ExternalCodeError {
return e
}
-// Error implements error interface
+// Error implements the Error interface.
func(e ExternalCodeError) Error() string {
Logg.Errorf("external code error: %v", e.err)
return fmt.Sprintf("error %v:%v", e.sym, e.code)