diff --git a/docs/src/manpage.md b/docs/src/manpage.md index 5c73c631d..a4e1ae3a4 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -2994,5 +2994,5 @@ SEE ALSO - 2021-12-02 MILLER(1) + 2021-12-07 MILLER(1) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index dff35a91d..47f2a7d80 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -2973,4 +2973,4 @@ SEE ALSO - 2021-12-02 MILLER(1) + 2021-12-07 MILLER(1) diff --git a/internal/pkg/auxents/repl/session.go b/internal/pkg/auxents/repl/session.go index 68beb85e0..aad50c1d1 100644 --- a/internal/pkg/auxents/repl/session.go +++ b/internal/pkg/auxents/repl/session.go @@ -60,16 +60,9 @@ func NewRepl( // $* is the empty map {} until/unless the user opens a file and reads records from it. inrec := types.NewMlrmapAsRecord() // NR is 0, etc until/unless the user opens a file and reads records from it. - context := types.NewContext( - options.ReaderOptions.IPS, - options.ReaderOptions.IFS, - options.ReaderOptions.IRS, - options.WriterOptions.OPS, - options.WriterOptions.OFS, - options.WriterOptions.ORS, - options.WriterOptions.FLATSEP, - ) - runtimeState := runtime.NewEmptyState() + context := types.NewContext() + + runtimeState := runtime.NewEmptyState(options) runtimeState.Update(inrec, context) // The filter expression for the main Miller DSL is any non-assignment // statment like 'true' or '$x > 0.5' etc. For the REPL, we re-use this for diff --git a/internal/pkg/climain/mlrcli_parse.go b/internal/pkg/climain/mlrcli_parse.go index 0db3692ac..bf9f560b6 100644 --- a/internal/pkg/climain/mlrcli_parse.go +++ b/internal/pkg/climain/mlrcli_parse.go @@ -324,7 +324,7 @@ func parseCommandLinePassTwo( if cli.DecideFinalFlatten(&options.WriterOptions) { // E.g. '{"req": {"method": "GET", "path": "/api/check"}}' becomes // req.method=GET,req.path=/api/check. - transformer, err := transformers.NewTransformerFlatten(options.WriterOptions.FLATSEP, nil) + transformer, err := transformers.NewTransformerFlatten(options.WriterOptions.FLATSEP, options, nil) lib.InternalCodingErrorIf(err != nil) lib.InternalCodingErrorIf(transformer == nil) recordTransformers = append(recordTransformers, transformer) @@ -333,7 +333,7 @@ func parseCommandLinePassTwo( if cli.DecideFinalUnflatten(options) { // E.g. req.method=GET,req.path=/api/check becomes // '{"req": {"method": "GET", "path": "/api/check"}}' - transformer, err := transformers.NewTransformerUnflatten(options.WriterOptions.FLATSEP, nil) + transformer, err := transformers.NewTransformerUnflatten(options.WriterOptions.FLATSEP, options, nil) lib.InternalCodingErrorIf(err != nil) lib.InternalCodingErrorIf(transformer == nil) recordTransformers = append(recordTransformers, transformer) diff --git a/internal/pkg/dsl/cst/leaves.go b/internal/pkg/dsl/cst/leaves.go index 8e5011005..b39b0b16f 100644 --- a/internal/pkg/dsl/cst/leaves.go +++ b/internal/pkg/dsl/cst/leaves.go @@ -519,7 +519,7 @@ func (root *RootNode) BuildIRSNode() *IRSNode { func (node *IRSNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.IRS) + return types.MlrvalFromString(state.Options.ReaderOptions.IRS) } // ---------------------------------------------------------------- @@ -532,7 +532,7 @@ func (root *RootNode) BuildIFSNode() *IFSNode { func (node *IFSNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.IFS) + return types.MlrvalFromString(state.Options.ReaderOptions.IFS) } // ---------------------------------------------------------------- @@ -545,7 +545,7 @@ func (root *RootNode) BuildIPSNode() *IPSNode { func (node *IPSNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.IPS) + return types.MlrvalFromString(state.Options.ReaderOptions.IPS) } // ---------------------------------------------------------------- @@ -558,7 +558,7 @@ func (root *RootNode) BuildORSNode() *ORSNode { func (node *ORSNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.ORS) + return types.MlrvalFromString(state.Options.WriterOptions.ORS) } // ---------------------------------------------------------------- @@ -571,7 +571,7 @@ func (root *RootNode) BuildOFSNode() *OFSNode { func (node *OFSNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.OFS) + return types.MlrvalFromString(state.Options.WriterOptions.OFS) } // ---------------------------------------------------------------- @@ -584,7 +584,7 @@ func (root *RootNode) BuildOPSNode() *OPSNode { func (node *OPSNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.OPS) + return types.MlrvalFromString(state.Options.WriterOptions.OPS) } // ---------------------------------------------------------------- @@ -597,7 +597,7 @@ func (root *RootNode) BuildFLATSEPNode() *FLATSEPNode { func (node *FLATSEPNode) Evaluate( state *runtime.State, ) *types.Mlrval { - return types.MlrvalFromString(state.Context.FLATSEP) + return types.MlrvalFromString(state.Options.WriterOptions.FLATSEP) } // ================================================================ diff --git a/internal/pkg/runtime/state.go b/internal/pkg/runtime/state.go index 248822502..6889d188b 100644 --- a/internal/pkg/runtime/state.go +++ b/internal/pkg/runtime/state.go @@ -7,6 +7,7 @@ package runtime import ( + "github.com/johnkerl/miller/internal/pkg/cli" "github.com/johnkerl/miller/internal/pkg/lib" "github.com/johnkerl/miller/internal/pkg/types" ) @@ -21,9 +22,10 @@ type State struct { // For holding "\0".."\9" between where they are set via things like // '$x =~ "(..)_(...)"', and interpolated via things like '$y = "\2:\1"'. RegexCaptures []string + Options *cli.TOptions } -func NewEmptyState() *State { +func NewEmptyState(options *cli.TOptions) *State { oosvars := types.NewMlrmap() return &State{ Inrec: nil, @@ -36,6 +38,7 @@ func NewEmptyState() *State { // See lib.MakeEmptyRegexCaptures for context. RegexCaptures: lib.MakeEmptyRegexCaptures(), + Options: options, } } diff --git a/internal/pkg/stream/stream.go b/internal/pkg/stream/stream.go index e3b889346..622702cc1 100644 --- a/internal/pkg/stream/stream.go +++ b/internal/pkg/stream/stream.go @@ -45,15 +45,7 @@ func Stream( // Since Go is concurrent, the context struct needs to be duplicated and // passed through the channels along with each record. - initialContext := types.NewContext( - options.ReaderOptions.IPS, - options.ReaderOptions.IFS, - options.ReaderOptions.IRS, - options.WriterOptions.OPS, - options.WriterOptions.OFS, - options.WriterOptions.ORS, - options.WriterOptions.FLATSEP, - ) + initialContext := types.NewContext() // Instantiate the record-reader recordReader, err := input.Create(&options.ReaderOptions) diff --git a/internal/pkg/transformers/flatten.go b/internal/pkg/transformers/flatten.go index aeec5656f..a8dfc50b2 100644 --- a/internal/pkg/transformers/flatten.go +++ b/internal/pkg/transformers/flatten.go @@ -44,7 +44,7 @@ func transformerFlattenParseCLI( pargi *int, argc int, args []string, - _ *cli.TOptions, + options *cli.TOptions, doConstruct bool, // false for first pass of CLI-parse, true for second pass ) IRecordTransformer { @@ -87,6 +87,7 @@ func transformerFlattenParseCLI( transformer, err := NewTransformerFlatten( oFlatSep, + options, fieldNames, ) if err != nil { @@ -101,6 +102,7 @@ func transformerFlattenParseCLI( type TransformerFlatten struct { // input oFlatSep string + options *cli.TOptions fieldNameSet map[string]bool // state @@ -109,6 +111,7 @@ type TransformerFlatten struct { func NewTransformerFlatten( oFlatSep string, + options *cli.TOptions, fieldNames []string, ) (*TransformerFlatten, error) { var fieldNameSet map[string]bool = nil @@ -118,6 +121,7 @@ func NewTransformerFlatten( retval := &TransformerFlatten{ oFlatSep: oFlatSep, + options: options, fieldNameSet: fieldNameSet, } @@ -152,7 +156,7 @@ func (tr *TransformerFlatten) flattenAll( inrec := inrecAndContext.Record oFlatSep := tr.oFlatSep if oFlatSep == "" { - oFlatSep = inrecAndContext.Context.FLATSEP + oFlatSep = tr.options.WriterOptions.FLATSEP } inrec.Flatten(oFlatSep) outputChannel <- inrecAndContext @@ -172,7 +176,7 @@ func (tr *TransformerFlatten) flattenSome( inrec := inrecAndContext.Record oFlatSep := tr.oFlatSep if oFlatSep == "" { - oFlatSep = inrecAndContext.Context.FLATSEP + oFlatSep = tr.options.WriterOptions.FLATSEP } inrec.FlattenFields(tr.fieldNameSet, oFlatSep) outputChannel <- inrecAndContext diff --git a/internal/pkg/transformers/put-or-filter.go b/internal/pkg/transformers/put-or-filter.go index 1702d9cca..2454279f3 100644 --- a/internal/pkg/transformers/put-or-filter.go +++ b/internal/pkg/transformers/put-or-filter.go @@ -435,7 +435,7 @@ func NewTransformerPut( return nil, err } - runtimeState := runtime.NewEmptyState() + runtimeState := runtime.NewEmptyState(options) // E.g. // mlr put -s sum=0 diff --git a/internal/pkg/transformers/unflatten.go b/internal/pkg/transformers/unflatten.go index 67da3584b..cd0876cd8 100644 --- a/internal/pkg/transformers/unflatten.go +++ b/internal/pkg/transformers/unflatten.go @@ -44,7 +44,7 @@ func transformerUnflattenParseCLI( pargi *int, argc int, args []string, - _ *cli.TOptions, + options *cli.TOptions, doConstruct bool, // false for first pass of CLI-parse, true for second pass ) IRecordTransformer { @@ -87,6 +87,7 @@ func transformerUnflattenParseCLI( transformer, err := NewTransformerUnflatten( oFlatSep, + options, fieldNames, ) if err != nil { @@ -101,6 +102,7 @@ func transformerUnflattenParseCLI( type TransformerUnflatten struct { // input oFlatSep string + options *cli.TOptions fieldNameSet map[string]bool // state @@ -109,6 +111,7 @@ type TransformerUnflatten struct { func NewTransformerUnflatten( oFlatSep string, + options *cli.TOptions, fieldNames []string, ) (*TransformerUnflatten, error) { var fieldNameSet map[string]bool = nil @@ -118,6 +121,7 @@ func NewTransformerUnflatten( retval := &TransformerUnflatten{ oFlatSep: oFlatSep, + options: options, fieldNameSet: fieldNameSet, } retval.recordTransformerFunc = retval.unflattenAll @@ -151,7 +155,7 @@ func (tr *TransformerUnflatten) unflattenAll( inrec := inrecAndContext.Record oFlatSep := tr.oFlatSep if oFlatSep == "" { - oFlatSep = inrecAndContext.Context.FLATSEP + oFlatSep = tr.options.WriterOptions.FLATSEP } inrec.Unflatten(oFlatSep) outputChannel <- inrecAndContext @@ -171,7 +175,7 @@ func (tr *TransformerUnflatten) unflattenSome( inrec := inrecAndContext.Record oFlatSep := tr.oFlatSep if oFlatSep == "" { - oFlatSep = inrecAndContext.Context.FLATSEP + oFlatSep = tr.options.WriterOptions.FLATSEP } inrec.UnflattenFields(tr.fieldNameSet, oFlatSep) outputChannel <- inrecAndContext diff --git a/internal/pkg/types/context.go b/internal/pkg/types/context.go index 6488118fc..4faa25982 100644 --- a/internal/pkg/types/context.go +++ b/internal/pkg/types/context.go @@ -88,60 +88,19 @@ type Context struct { // NF int NR int FNR int - - IPS string - IFS string - IRS string - - OPS string - OFS string - ORS string - FLATSEP string } // TODO: comment: Remember command-line values to pass along to CST evaluators. // The options struct-pointer can be nil when invoked by non-DSL verbs such as // join or seqgen. -func NewContext( - IPS string, - IFS string, - IRS string, - - OPS string, - OFS string, - ORS string, - FLATSEP string, -) *Context { +func NewContext() *Context { context := &Context{ FILENAME: "(stdin)", FILENUM: 0, - - NR: 0, - FNR: 0, - - IPS: "=", - IFS: ",", - IRS: "\n", - - OPS: "=", - OFS: ",", - ORS: "\n", - FLATSEP: ".", + NR: 0, + FNR: 0, } - // TODO: FILENAME/FILENUM/NR/FNR should be in one struct, and the rest in - // another. The former vary per record; the latter are command-line-driven - // and do not vary per record. All they have in common is they are - // awk-like context-variables. - context.IPS = IPS - context.IFS = IFS - context.IRS = IRS - - context.OPS = OPS - context.OFS = OFS - context.ORS = ORS - context.FLATSEP = FLATSEP - return context } @@ -152,18 +111,8 @@ func NewNilContext() *Context { // TODO: rename context := &Context{ FILENAME: "(stdin)", FILENUM: 0, - - NR: 0, - FNR: 0, - - IPS: "=", - IFS: ",", - IRS: "\n", - - OPS: "=", - OFS: ",", - ORS: "\n", - FLATSEP: ".", + NR: 0, + FNR: 0, } return context diff --git a/man/manpage.txt b/man/manpage.txt index dff35a91d..47f2a7d80 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -2973,4 +2973,4 @@ SEE ALSO - 2021-12-02 MILLER(1) + 2021-12-07 MILLER(1) diff --git a/man/mlr.1 b/man/mlr.1 index e0a757605..cf26a26e2 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2021-12-02 +.\" Date: 2021-12-07 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2021-12-02" "\ \&" "\ \&" +.TH "MILLER" "1" "2021-12-07" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~