}
var (
- dumpJSON = flag.Bool("json", false, "Dump as JSON")
MaxStrLen = flag.Uint("max-str-len", 64,
"Maximal string length to print")
MaxParseCycles = flag.Uint64("max-parse-cycles", 1<<63,
NoTotals = flag.Bool("no-totals", false, "Do not print how many bytes read")
onlyV = flag.Bool("v", false, "Print only values")
pthStr = flag.String("p", "", "Print only /that/keks/path")
+ dumpJSON = flag.Bool("json", false, "Dump as JSON")
+ dumpTcl = flag.Bool("tcl", false, "Dump as Tcl code")
pth []string
)
if err != nil {
log.Fatal(err)
}
+ } else if *dumpTcl {
+ tcl(ctx.Iter(), 1, false, false)
} else {
printer(ctx.Iter(), []string{}, 1, false, false)
}
off = ctx.Read
}
- if !*NoTotals && !*dumpJSON {
+ if !*NoTotals && !*dumpJSON && !*dumpTcl {
fmt.Println(off, "bytes")
}
}
--- /dev/null
+// pp -- KEKS pretty printer
+// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, version 3 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "encoding/hex"
+ "fmt"
+ "io"
+ "log"
+ "strconv"
+ "time"
+
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/be"
+ "go.cypherpunks.su/keks/types"
+ "go.cypherpunks.su/tai64n/v4"
+)
+
+func tclTAI(t time.Time, ns int, as uint64) {
+ utc, isLeap := tai64n.Leapsecs.Sub(t)
+ if isLeap || utc.Unix() < 0 {
+ fmt.Printf("TAI64 %d %d %d", t.Unix(), ns, as)
+ } else {
+ fmt.Printf("TAI64 [UTCFromISO \"%s\"] %d %d",
+ utc.Format("2006-01-02 15:04:05"), ns, as)
+ }
+}
+
+func tcl(iter *keks.Iterator, count int, inList, inMap bool) {
+ for range count {
+ if !iter.Next() {
+ panic("unexpected")
+ }
+ depth := iter.Depth
+ var key string
+ if inMap {
+ key = iter.Str()
+ if !iter.Next() {
+ panic("unexpected")
+ }
+ }
+ prindent(depth)
+ if inMap {
+ fmt.Print(key, " ")
+ }
+ if inList || inMap {
+ fmt.Print("{")
+ }
+ var listOrMap bool
+ switch iter.T {
+ case types.List:
+ listOrMap = true
+ fmt.Println("LIST {")
+ tcl(iter, iter.Len(), true, false)
+ prindent(depth)
+ fmt.Print("}")
+ case types.Map:
+ listOrMap = true
+ fmt.Println("MAP {")
+ tcl(iter, iter.Len(), false, true)
+ prindent(depth)
+ fmt.Print("}")
+ }
+ if !listOrMap {
+ switch iter.T {
+ case types.NIL:
+ fmt.Print("NIL")
+ case types.Bool:
+ if iter.Bool() {
+ fmt.Print("TRUE")
+ } else {
+ fmt.Print("FALSE")
+ }
+ case types.Hexlet:
+ h := iter.Hexlet()
+ fmt.Printf("HEXLET %s", h.UUID())
+ case types.UInt:
+ fmt.Printf("INT %d", iter.UInt())
+ case types.Int:
+ fmt.Printf("INT %d", iter.Int())
+ case types.BigInt:
+ fmt.Printf("INT %d", iter.BigInt())
+ case types.Blob:
+ blob := iter.Blob()
+ v, err := io.ReadAll(blob.Reader())
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("BLOB %d [binary decode hex \"%s\"]",
+ blob.ChunkLen, hex.EncodeToString(v))
+ case types.TAI64:
+ t := iter.TAI64().Time()
+ tclTAI(t, 0, 0)
+ case types.TAI64N:
+ t := iter.TAI64N().Time()
+ tclTAI(t, t.Nanosecond(), 0)
+ case types.TAI64NA:
+ tai := iter.TAI64NA()
+ var n tai64n.TAI64N
+ copy(n[:], tai[:])
+ t := n.Time()
+ tclTAI(t, t.Nanosecond(), be.Get(tai[12:]))
+ case types.Magic:
+ allPrintable := true
+ magic := iter.Magic()
+ for _, b := range []byte(magic) {
+ if !strconv.IsPrint(rune(b)) {
+ allPrintable = false
+ }
+ }
+ if allPrintable {
+ fmt.Printf("MAGIC \"%s\"", magic)
+ } else {
+ fmt.Printf("MAGIC [binary decode hex \"%s\"]", []byte(magic))
+ }
+ case types.Bin:
+ fmt.Printf("BIN [binary decode hex \"%s\"]",
+ hex.EncodeToString(iter.Bin()))
+ case types.Str:
+ fmt.Printf("STR \"%s\"", iter.Str())
+ case types.Raw:
+ fmt.Printf("RAW [binary decode hex \"%s\"]",
+ hex.EncodeToString(iter.Raw()))
+ default:
+ fmt.Print("???")
+ }
+ }
+ if inList || inMap {
+ fmt.Print("}")
+ }
+ fmt.Println("")
+ }
+}