From e365f22084c67c7b9bd4e91713b577d4d0450b9f Mon Sep 17 00:00:00 2001 From: Mattias Wadman Date: Wed, 5 Jan 2022 21:36:22 +0100 Subject: [PATCH] interp: Cleanup stdio usage and functions --- doc/usage.md | 1 + pkg/interp/assert.jq | 6 +++--- pkg/interp/decode.jq | 5 ++--- pkg/interp/funcs.jq | 4 ++-- pkg/interp/internal.jq | 16 +++++++++++----- pkg/interp/interp.go | 6 +++--- pkg/interp/interp.jq | 13 ++++++------- pkg/interp/options.jq | 14 +++++++++----- 8 files changed, 37 insertions(+), 28 deletions(-) diff --git a/doc/usage.md b/doc/usage.md index 955ff6373..5eaf96660 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -260,6 +260,7 @@ notable is support for arbitrary-precision integers. - All standard library functions from jq - Adds a few new general functions: + - `print/0`, `println/0`, `printerr/0`, `printerrln` prints to stdout and stderr. - `streaks/0`, `streaks_by/1` like `group` but groups streaks based on condition. - `count/0`, `count_by/1` like `group` but counts groups lengths. - `debug/1` like `debug/0` but uses arg to produce debug message. `{a: 123} | debug({a}) | ...`. diff --git a/pkg/interp/assert.jq b/pkg/interp/assert.jq index 00bd21a72..acdbf9f6f 100644 --- a/pkg/interp/assert.jq +++ b/pkg/interp/assert.jq @@ -1,10 +1,10 @@ -def log: if env.VERBOSE then stderr else empty end; +def log: if env.VERBOSE then printerrln else empty end; def assert($name; $expected; $actual): ( if $expected == $actual then - "PASS \($name)\n" | log + "PASS \($name)" | log else - ( "FAIL \($name): expected \($expected) got \($actual)\n" | stderr + ( "FAIL \($name): expected \($expected) got \($actual)" | printerrln , (null | halt_error(1)) ) end diff --git a/pkg/interp/decode.jq b/pkg/interp/decode.jq index 7b3cc0ddb..6856b84f2 100644 --- a/pkg/interp/decode.jq +++ b/pkg/interp/decode.jq @@ -25,18 +25,17 @@ def _decode_progress: ) else empty end - | stderr + | printerr ); def decode($name; $decode_opts): ( options as $opts - | (null | stdout) as $stdout | _decode( $name; $opts + { _progress: ( - if $opts.decode_progress and $opts.repl and $stdout.is_terminal then + if $opts.decode_progress and $opts.repl and stdout_tty.is_terminal then "_decode_progress" else null end diff --git a/pkg/interp/funcs.jq b/pkg/interp/funcs.jq index c56b90179..ecc32068b 100644 --- a/pkg/interp/funcs.jq +++ b/pkg/interp/funcs.jq @@ -2,11 +2,11 @@ def display($opts): ( options($opts) as $opts | if _can_display then _display($opts) else - ( if type == "string" and $opts.raw_string then (tostring | stdout) + ( if type == "string" and $opts.raw_string then print else _print_color_json($opts) end , ( $opts.join_string - | if . then stdout else empty end + | if . then print else empty end ) ) end diff --git a/pkg/interp/internal.jq b/pkg/interp/internal.jq index c4bf5c91f..46399fb67 100644 --- a/pkg/interp/internal.jq +++ b/pkg/interp/internal.jq @@ -1,9 +1,16 @@ # is here to be defined as early as possible to allow debugging -# TODO: move to builtin.jq etc? -def print: stdout; -def println: ., "\n" | stdout; +# TODO: move some _* to builtin.jq etc? + +def stdin_tty: null | _stdin; +def stdout_tty: null | _stdout; + +def print: tostring | _stdout; +def println: ., "\n" | print; +def printerr: tostring | _stderr; +def printerrln: ., "\n" | printerr; + def debug: - ( ((["DEBUG", .] | tojson), "\n" | stderr) + ( ((["DEBUG", .] | tojson) | printerrln) , . ); def debug(f): . as $c | f | debug | $c; @@ -118,4 +125,3 @@ def _is_scalar: def _is_context_canceled_error: . == "context canceled"; def _error_str: "error: \(.)"; -def _errorln: ., "\n" | stderr; diff --git a/pkg/interp/interp.go b/pkg/interp/interp.go index ab0fbca72..11531b299 100644 --- a/pkg/interp/interp.go +++ b/pkg/interp/interp.go @@ -54,9 +54,9 @@ func init() { return []Function{ {"_readline", 0, 2, i.readline, nil}, {"eval", 1, 2, nil, i.eval}, - {"stdin", 0, 0, nil, i.makeStdioFn(i.os.Stdin())}, - {"stdout", 0, 0, nil, i.makeStdioFn(i.os.Stdout())}, - {"stderr", 0, 0, nil, i.makeStdioFn(i.os.Stderr())}, + {"_stdin", 0, 0, nil, i.makeStdioFn(i.os.Stdin())}, + {"_stdout", 0, 0, nil, i.makeStdioFn(i.os.Stdout())}, + {"_stderr", 0, 0, nil, i.makeStdioFn(i.os.Stderr())}, {"_extkeys", 0, 0, i._extKeys, nil}, {"_exttype", 0, 0, i._extType, nil}, {"_global_state", 0, 1, i.makeStateFn(i.state), nil}, diff --git a/pkg/interp/interp.jq b/pkg/interp/interp.jq index 1302a0ad6..7e9fa58a0 100644 --- a/pkg/interp/interp.jq +++ b/pkg/interp/interp.jq @@ -58,7 +58,7 @@ def input: ( . as $err | _input_io_errors(. += {($h): $err}) as $_ | $err - | (_error_str | _errorln) + | (_error_str | printerrln) , _input($opts; f) ) | try f @@ -71,7 +71,7 @@ def input: else ": failed to decode (try -d FORMAT)" end ] | join("") - | (_error_str | _errorln) + | (_error_str | printerrln) , _input($opts; f) ) ); @@ -143,7 +143,7 @@ def var($k): . as $c | var($k; $c); def _cli_expr_on_error: ( . as $err | _cli_last_expr_error($err) as $_ - | (_error_str | _errorln) + | (_error_str | printerrln) ); def _cli_expr_on_compile_error: ( _eval_compile_error_tostring @@ -180,7 +180,6 @@ def _main: def _usage($arg0): "Usage: \($arg0) [OPTIONS] [--] [EXPR] [FILE...]"; ( . as {$version, $args, args: [$arg0]} - | (null | [stdin, stdout]) as [$stdin, $stdout] # make sure we don't unintentionally use . to make things clearer | null | ( try _args_parse($args[1:]; _opt_cli_opts) @@ -311,10 +310,10 @@ def _main: $opts.null_input == false and ($opts.repl | not) and ($opts.expr_file | not) and - $stdin.is_terminal and - $stdout.is_terminal + stdin_tty.is_terminal and + stdout_tty.is_terminal ) then - ( (( _usage($arg0), "\n") | stderr) + ( (_usage($arg0) | printerrln) , null | halt_error(_exit_code_args_error) ) else diff --git a/pkg/interp/options.jq b/pkg/interp/options.jq index 48cc7ee1f..40a0a418a 100644 --- a/pkg/interp/options.jq +++ b/pkg/interp/options.jq @@ -2,7 +2,7 @@ def _obj_to_csv_kv: [to_entries[] | [.key, .value] | join("=")] | join(","); def _opt_build_default_fixed: - ( (null | stdout) as $stdout + ( stdout_tty as $stdout | { addrbase: 16, arg: [], @@ -55,11 +55,15 @@ def _opt_build_default_fixed: ); def _opt_default_dynamic: - ( (null | stdout) as $stdout + ( stdout_tty as $stdout + # TODO: intdiv 2 * 2 to get even number, nice or maybe not needed? + | ( if $stdout.is_terminal then [_intdiv(_intdiv($stdout.width; 8); 2) * 2, 4] | max + else 16 + end + ) as $display_bytes | { - # TODO: intdiv 2 * 2 to get even number, nice or maybe not needed? - display_bytes: (if $stdout.is_terminal then [_intdiv(_intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end), - line_bytes: (if $stdout.is_terminal then [_intdiv(_intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end), + display_bytes: $display_bytes, + line_bytes: $display_bytes, } );