1
1
mirror of https://github.com/wader/fq.git synced 2024-12-25 14:23:18 +03:00

fq: Generate decode alises code

This commit is contained in:
Mattias Wadman 2021-09-04 12:54:26 +02:00
parent 834f4a5893
commit 8cb380e7d9
4 changed files with 104 additions and 57 deletions

View File

@ -20,8 +20,6 @@ import (
"net/url" "net/url"
"time" "time"
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/internal/aheadreadseeker" "github.com/wader/fq/internal/aheadreadseeker"
"github.com/wader/fq/internal/ctxreadseeker" "github.com/wader/fq/internal/ctxreadseeker"
"github.com/wader/fq/internal/gojqextra" "github.com/wader/fq/internal/gojqextra"
@ -34,7 +32,7 @@ import (
) )
// TODO: make it nicer somehow? generate generators? remove from struct? // TODO: make it nicer somehow? generate generators? remove from struct?
func (i *Interp) makeFunctions(registry *registry.Registry) []Function { func (i *Interp) makeFunctions() []Function {
fs := []Function{ fs := []Function{
{[]string{"readline"}, 0, 2, i.readline, nil}, {[]string{"readline"}, 0, 2, i.readline, nil},
{[]string{"eval"}, 1, 2, nil, i.eval}, {[]string{"eval"}, 1, 2, nil, i.eval},
@ -54,10 +52,10 @@ func (i *Interp) makeFunctions(registry *registry.Registry) []Function {
{[]string{"history"}, 0, 0, i.history, nil}, {[]string{"history"}, 0, 0, i.history, nil},
{[]string{"open"}, 0, 0, i._open, nil}, {[]string{"open"}, 0, 0, i._open, nil},
{[]string{"decode"}, 0, 1, i.makeDecodeFn(registry, registry.MustGroup(format.PROBE)), nil}, {[]string{"_decode"}, 2, 2, i._decode, nil},
{[]string{"format"}, 0, 0, i.format, nil}, {[]string{"format"}, 0, 0, i.format, nil},
{[]string{"_display"}, 1, 1, nil, i.display}, {[]string{"_display"}, 1, 1, nil, i._display},
{[]string{"preview", "p"}, 0, 1, nil, i.preview}, {[]string{"preview", "p"}, 0, 1, nil, i.preview},
{[]string{"hexdump", "hd", "h"}, 0, 1, nil, i.hexdump}, {[]string{"hexdump", "hd", "h"}, 0, 1, nil, i.hexdump},
@ -98,9 +96,6 @@ func (i *Interp) makeFunctions(registry *registry.Registry) []Function {
{[]string{"find"}, 1, 1, nil, i.find}, {[]string{"find"}, 1, 1, nil, i.find},
} }
for name, f := range i.registry.Groups {
fs = append(fs, Function{[]string{name}, 0, 0, i.makeDecodeFn(registry, f), nil})
}
return fs return fs
} }
@ -537,8 +532,7 @@ func (i *Interp) _open(c interface{}, a []interface{}) interface{} {
} }
} }
func (i *Interp) makeDecodeFn(registry *registry.Registry, decodeFormats []*decode.Format) func(c interface{}, a []interface{}) interface{} { func (i *Interp) _decode(c interface{}, a []interface{}) interface{} {
return func(c interface{}, a []interface{}) interface{} {
filename := "unnamed" filename := "unnamed"
// TODO: progress hack // TODO: progress hack
@ -559,16 +553,14 @@ func (i *Interp) makeDecodeFn(registry *registry.Registry, decodeFormats []*deco
opts := map[string]interface{}{} opts := map[string]interface{}{}
if len(a) >= 1 {
formatName, err := toString(a[0]) formatName, err := toString(a[0])
if err != nil { if err != nil {
return fmt.Errorf("%s: %w", formatName, err) return fmt.Errorf("%s: %w", formatName, err)
} }
decodeFormats, err = registry.Group(formatName) decodeFormats, err := i.registry.Group(formatName)
if err != nil { if err != nil {
return fmt.Errorf("%s: %w", formatName, err) return fmt.Errorf("%s: %w", formatName, err)
} }
}
dv, _, err := decode.Decode("", filename, bb, decodeFormats, decode.DecodeOptions{FormatOptions: opts}) dv, _, err := decode.Decode("", filename, bb, decodeFormats, decode.DecodeOptions{FormatOptions: opts})
if dv == nil { if dv == nil {
@ -586,7 +578,6 @@ func (i *Interp) makeDecodeFn(registry *registry.Registry, decodeFormats []*deco
} }
return makeDecodeValue(dv) return makeDecodeValue(dv)
}
} }
func (i *Interp) format(c interface{}, a []interface{}) interface{} { func (i *Interp) format(c interface{}, a []interface{}) interface{} {
@ -601,7 +592,7 @@ func (i *Interp) format(c interface{}, a []interface{}) interface{} {
return f return f
} }
func (i *Interp) display(c interface{}, a []interface{}) gojq.Iter { func (i *Interp) _display(c interface{}, a []interface{}) gojq.Iter {
opts, err := i.Options(a...) opts, err := i.Options(a...)
if err != nil { if err != nil {
return gojq.NewIter(err) return gojq.NewIter(err)

View File

@ -570,7 +570,7 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
} }
var compilerOpts []gojq.CompilerOption var compilerOpts []gojq.CompilerOption
for _, f := range ni.makeFunctions(ni.registry) { for _, f := range ni.makeFunctions() {
for _, n := range f.Names { for _, n := range f.Names {
if f.IterFn != nil { if f.IterFn != nil {
compilerOpts = append(compilerOpts, compilerOpts = append(compilerOpts,
@ -621,6 +621,18 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
fmt.Fprintf(sb, "include \"@format/%s\";\n", f.Name) fmt.Fprintf(sb, "include \"@format/%s\";\n", f.Name)
} }
return bytes.NewReader(sb.Bytes()), nil return bytes.NewReader(sb.Bytes()), nil
} else if filename == "decode.jq" {
sb := &bytes.Buffer{}
fmt.Fprintf(sb, "def decode($name; $opts): _decode($name; $opts);\n")
fmt.Fprintf(sb, "def decode($name): _decode($name; {});\n")
fmt.Fprintf(sb, "def decode: _decode(\"probe\"; {});\n")
for name := range i.registry.Groups {
fmt.Fprintf(sb, ""+
"def %[1]s($opts): _decode(%[1]q; $opts);\n"+
"def %[1]s: _decode(%[1]q; {});\n",
name)
}
return bytes.NewReader(sb.Bytes()), nil
} else { } else {
formatName := strings.TrimRight(filename, ".jq") formatName := strings.TrimRight(filename, ".jq")
for _, f := range allFormats { for _, f := range allFormats {

View File

@ -4,6 +4,7 @@ include "args";
include "query"; include "query";
# will include all per format specific function etc # will include all per format specific function etc
include "@format/decode";
include "@format/all"; include "@format/all";
# optional user init # optional user init

43
pkg/interp/testdata/decode.fqtest vendored Normal file
View File

@ -0,0 +1,43 @@
/test.mp3:
$ fq -i -d mp3 . /test.mp3
mp3> decode
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.: {} unnamed (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> decode("mp3")
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.: {} unnamed (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> decode("mp3"; {})
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.: {} unnamed (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> probe
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.: {} unnamed (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> probe({})
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f| |.: {} unnamed (mp3)
0x000|49 44 33 04 00 00 00 00 00 23 54 53 53 45 00 00|ID3......#TSSE..| headers: [1]
* |until 0x2c.7 (45) | |
0x020| ff fb 40| ..@| frames: [3]
0x030|c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|................|
* |until 0x283.7 (end) (599) | |
| | | footers: [0]
mp3> ^D