Single Fetcher.Fetch on the Guard that holds DenyPrefixes. skipTlsVerification is ignored. No 502. keys add writes the secret only to --out. Release binary has no -test-allow-prefix.
209 lines
3.9 KiB
Go
209 lines
3.9 KiB
Go
//go:build gojq_debug
|
|
|
|
package gojq
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
debug bool
|
|
debugOut io.Writer
|
|
)
|
|
|
|
func init() {
|
|
if out := os.Getenv("GOJQ_DEBUG"); out != "" {
|
|
debug = true
|
|
if out == "stdout" {
|
|
debugOut = os.Stdout
|
|
} else {
|
|
debugOut = os.Stderr
|
|
}
|
|
}
|
|
}
|
|
|
|
type codeinfo struct {
|
|
name string
|
|
pc int
|
|
}
|
|
|
|
func (c *compiler) appendCodeInfo(x any) {
|
|
if !debug {
|
|
return
|
|
}
|
|
var name string
|
|
switch x := x.(type) {
|
|
case string:
|
|
name = x
|
|
default:
|
|
name = fmt.Sprint(x)
|
|
}
|
|
var diff int
|
|
if c.codes[len(c.codes)-1] != nil && c.codes[len(c.codes)-1].op == opret && strings.HasPrefix(name, "end of ") {
|
|
diff = -1
|
|
}
|
|
c.codeinfos = append(c.codeinfos, codeinfo{name, len(c.codes) + diff})
|
|
}
|
|
|
|
func (c *compiler) deleteCodeInfo(name string) {
|
|
for i := 0; i < len(c.codeinfos); i++ {
|
|
if strings.HasSuffix(c.codeinfos[i].name, name) {
|
|
copy(c.codeinfos[i:], c.codeinfos[i+1:])
|
|
c.codeinfos = c.codeinfos[:len(c.codeinfos)-1]
|
|
i--
|
|
}
|
|
}
|
|
}
|
|
|
|
func (env *env) lookupInfoName(pc int) string {
|
|
var name string
|
|
for _, ci := range env.codeinfos {
|
|
if ci.pc == pc {
|
|
if name != "" {
|
|
name += ", "
|
|
}
|
|
name += ci.name
|
|
}
|
|
}
|
|
return name
|
|
}
|
|
|
|
func (env *env) debugCodes() {
|
|
if !debug {
|
|
return
|
|
}
|
|
for i, c := range env.codes {
|
|
pc := i
|
|
switch c.op {
|
|
case opcall, opcallrec:
|
|
if x, ok := c.v.(int); ok {
|
|
pc = x
|
|
}
|
|
case opjump:
|
|
x := c.v.(int)
|
|
if x > 0 && env.codes[x-1].op == opscope {
|
|
pc = x - 1
|
|
}
|
|
}
|
|
var s string
|
|
if name := env.lookupInfoName(pc); name != "" {
|
|
switch c.op {
|
|
case opcall, opcallrec, opjump:
|
|
if !strings.HasPrefix(name, "module ") {
|
|
s = "\t## call " + name
|
|
break
|
|
}
|
|
fallthrough
|
|
default:
|
|
s = "\t## " + name
|
|
}
|
|
}
|
|
fmt.Fprintf(debugOut, "\t%d\t%-*s%s%s\n", i, 25, c.op, debugOperand(c), s)
|
|
}
|
|
fmt.Fprintln(debugOut, "\t"+strings.Repeat("-", 40)+"+")
|
|
}
|
|
|
|
func (env *env) debugState(pc int, backtrack bool) {
|
|
if !debug {
|
|
return
|
|
}
|
|
var sb strings.Builder
|
|
c := env.codes[pc]
|
|
op := c.op.String()
|
|
if backtrack {
|
|
op += " <backtrack>"
|
|
}
|
|
fmt.Fprintf(&sb, "\t%d\t%-*s%s\t|", pc, 25, op, debugOperand(c))
|
|
var xs []int
|
|
for i := env.stack.index; i >= 0; i = env.stack.data[i].next {
|
|
xs = append(xs, i)
|
|
}
|
|
for i := len(xs) - 1; i >= 0; i-- {
|
|
sb.WriteString("\t")
|
|
sb.WriteString(debugValue(env.stack.data[xs[i]].value))
|
|
}
|
|
switch c.op {
|
|
case opcall, opcallrec:
|
|
if x, ok := c.v.(int); ok {
|
|
pc = x
|
|
}
|
|
case opjump:
|
|
x := c.v.(int)
|
|
if x > 0 && env.codes[x-1].op == opscope {
|
|
pc = x - 1
|
|
}
|
|
}
|
|
if name := env.lookupInfoName(pc); name != "" {
|
|
switch c.op {
|
|
case opcall, opcallrec, opjump:
|
|
if !strings.HasPrefix(name, "module ") {
|
|
sb.WriteString("\t\t\t## call " + name)
|
|
break
|
|
}
|
|
fallthrough
|
|
default:
|
|
sb.WriteString("\t\t\t## " + name)
|
|
}
|
|
}
|
|
fmt.Fprintln(debugOut, sb.String())
|
|
}
|
|
|
|
func (env *env) debugForks(pc int, op string) {
|
|
if !debug {
|
|
return
|
|
}
|
|
var sb strings.Builder
|
|
for i, v := range env.forks {
|
|
if i > 0 {
|
|
sb.WriteByte('\t')
|
|
}
|
|
if i == len(env.forks)-1 {
|
|
sb.WriteByte('<')
|
|
}
|
|
fmt.Fprintf(&sb, "%d, %s", v.pc, debugValue(env.stack.data[v.stackindex].value))
|
|
if i == len(env.forks)-1 {
|
|
sb.WriteByte('>')
|
|
}
|
|
}
|
|
fmt.Fprintf(debugOut, "\t-\t%-*s%d\t|\t%s\n", 25, op, pc, sb.String())
|
|
}
|
|
|
|
func debugOperand(c *code) string {
|
|
switch c.op {
|
|
case opcall, opcallrec:
|
|
switch v := c.v.(type) {
|
|
case int:
|
|
return strconv.Itoa(v)
|
|
case [3]any:
|
|
return fmt.Sprintf("%s/%d", v[2], v[1])
|
|
default:
|
|
panic(c)
|
|
}
|
|
default:
|
|
return debugValue(c.v)
|
|
}
|
|
}
|
|
|
|
func debugValue(v any) string {
|
|
switch v := v.(type) {
|
|
case Iter:
|
|
return fmt.Sprintf("gojq.Iter(%#v)", v)
|
|
case []pathValue:
|
|
return fmt.Sprintf("[]gojq.pathValue(%v)", v)
|
|
case [2]int:
|
|
return fmt.Sprintf("[%d,%d]", v[0], v[1])
|
|
case [3]int:
|
|
return fmt.Sprintf("[%d,%d,%d]", v[0], v[1], v[2])
|
|
case [3]any:
|
|
return fmt.Sprintf("[%v,%v,%v]", v[0], v[1], v[2])
|
|
case allocator:
|
|
return fmt.Sprintf("%v", v)
|
|
default:
|
|
return Preview(v)
|
|
}
|
|
}
|