github.com/mavryk-network/mvgo@v1.19.9/micheline/debug.go (about) 1 // Copyright (c) 2020-2021 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc 3 4 package micheline 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "strconv" 11 "strings" 12 ) 13 14 func (p Prim) Dump() string { 15 buf, _ := p.MarshalJSON() 16 return string(buf) 17 } 18 19 func (p Prim) DumpLimit(n int) string { 20 buf, _ := p.MarshalJSON() 21 return limit(string(buf), n) 22 } 23 24 func (e Value) Dump() string { 25 buf := bytes.NewBuffer(nil) 26 e.DumpTo(buf) 27 return buf.String() 28 } 29 30 func (e Value) DumpLimit(n int) string { 31 return limit(e.Dump(), n) 32 } 33 34 func (e Value) DumpTo(w io.Writer) { 35 dumpTree(w, "", e.Type, e.Value) 36 } 37 38 func (s Stack) Dump() string { 39 return s.DumpIdent(0) 40 } 41 42 func (s Stack) DumpIdent(indent int) string { 43 idnt := strings.Repeat(" ", indent) 44 lines := make([]string, s.Len()) 45 for i := range s { 46 n := len(s) - i - 1 47 lines[n] = idnt + fmt.Sprintf("%02d ", n+1) + s[i].Dump() 48 } 49 return strings.Join(lines, "\n") 50 } 51 52 // TODO: improve tree output 53 func dumpTree(w io.Writer, path string, typ Type, val Prim) { 54 if s, err := dump(path, typ, val); err != nil { 55 io.WriteString(w, err.Error()) 56 } else { 57 io.WriteString(w, s) 58 } 59 switch val.Type { 60 case PrimSequence: 61 // keep the type 62 for i, v := range val.Args { 63 p := path + "." + strconv.Itoa(i) 64 dumpTree(w, p, typ, v) 65 } 66 default: 67 // advance type as well 68 for i, v := range val.Args { 69 t := Type{} 70 if len(typ.Args) > i { 71 t = Type{typ.Args[i]} 72 } 73 p := path + "." + strconv.Itoa(i) 74 dumpTree(w, p, t, v) 75 } 76 } 77 } 78 79 func dump(path string, typ Type, val Prim) (string, error) { 80 if !val.matchOpCode(typ.OpCode) { 81 return "", fmt.Errorf("Type mismatch val_type=%s type_code=%s", val.Type, typ.OpCode) 82 } 83 84 vtyp := "-" 85 switch val.Type { 86 case PrimSequence, PrimBytes, PrimInt, PrimString: 87 default: 88 vtyp = val.OpCode.String() 89 } 90 91 return fmt.Sprintf("path=%-20s val_prim=%-8s val_type=%-8s val_val=%-10s type_prim=%-8s type_code=%-8s type_name=%-8s\n", 92 path, val.Type, vtyp, val.DumpLimit(512), typ.Type, typ.OpCode, typ.Label(), 93 ), nil 94 }