line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package JSON::JQ;
|
2
|
6
|
|
|
6
|
|
513395
|
use strict;
|
|
6
|
|
|
|
|
50
|
|
|
6
|
|
|
|
|
135
|
|
3
|
6
|
|
|
6
|
|
26
|
use warnings;
|
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
105
|
|
4
|
6
|
|
|
6
|
|
23
|
use Carp;
|
|
6
|
|
|
|
|
8
|
|
|
6
|
|
|
|
|
379
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.09';
|
7
|
|
|
|
|
|
|
# internal flags
|
8
|
|
|
|
|
|
|
our $DEBUG = 0;
|
9
|
|
|
|
|
|
|
our $DUMP_DISASM = 0;
|
10
|
|
|
|
|
|
|
|
11
|
6
|
|
|
6
|
|
1904
|
use FindBin ();
|
|
6
|
|
|
|
|
4381
|
|
|
6
|
|
|
|
|
167
|
|
12
|
|
|
|
|
|
|
FindBin::again();
|
13
|
6
|
|
|
6
|
|
30
|
use POSIX qw/isatty/;
|
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
55
|
|
14
|
6
|
|
|
6
|
|
12376
|
use Path::Tiny qw/path/;
|
|
6
|
|
|
|
|
67761
|
|
|
6
|
|
|
|
|
300
|
|
15
|
6
|
|
|
6
|
|
3286
|
use JSON qw/from_json/;
|
|
6
|
|
|
|
|
49410
|
|
|
6
|
|
|
|
|
26
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# jv_print_flags in jv.h
|
18
|
6
|
|
|
6
|
|
2810
|
use enum qw/BITMASK:JV_PRINT_ PRETTY ASCII COLOR SORTED INVALID REFCOUNT TAB ISATTY SPACE0 SPACE1 SPACE2/;
|
|
6
|
|
|
|
|
4674
|
|
|
6
|
|
|
|
|
34
|
|
19
|
|
|
|
|
|
|
# jq.h
|
20
|
6
|
|
|
6
|
|
4643
|
use enum qw/:JQ_DEBUG_=1 TRACE TRACE_DETAIL TRACE_ALL/;
|
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
15
|
|
21
|
|
|
|
|
|
|
|
22
|
6
|
|
|
6
|
|
1213
|
use XSLoader;
|
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
2496
|
|
23
|
|
|
|
|
|
|
XSLoader::load('JSON::JQ', $VERSION);
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub new {
|
26
|
51
|
|
|
51
|
1
|
2832
|
my ( $pkg, $param ) = @_;
|
27
|
|
|
|
|
|
|
|
28
|
51
|
0
|
33
|
|
|
196
|
croak "script or script_file parameter required" unless exists $param->{script} or exists $param->{script_file};
|
29
|
51
|
|
|
|
|
84
|
my $self = {};
|
30
|
|
|
|
|
|
|
# script string or script file
|
31
|
51
|
50
|
|
|
|
180
|
$self->{script} = $param->{script} if exists $param->{script};
|
32
|
51
|
50
|
|
|
|
125
|
$self->{script_file} = $param->{script_file} if exists $param->{script_file};
|
33
|
|
|
|
|
|
|
# script initial arguments
|
34
|
51
|
100
|
|
|
|
134
|
$self->{variable} = exists $param->{variable} ? $param->{variable} : {};
|
35
|
|
|
|
|
|
|
# internal attributes
|
36
|
51
|
50
|
|
|
|
233
|
$self->{_attribute}->{JQ_ORIGIN} = path($FindBin::Bin)->realpath->stringify if $FindBin::Bin;
|
37
|
|
|
|
|
|
|
$self->{_attribute}->{JQ_LIBRARY_PATH} = exists $param->{library_paths} ? $param->{library_paths} :
|
38
|
51
|
100
|
|
|
|
10829
|
[ '~/.jq', '$ORIGIN/../lib/jq', '$ORIGIN/lib' ];
|
39
|
51
|
50
|
|
|
|
141
|
$self->{_attribute}->{PROGRAM_ORIGIN} = exists $param->{script_file} ? path($param->{script_file})->parent->stringify : '.';
|
40
|
|
|
|
|
|
|
# error callback will push error messages into this array
|
41
|
51
|
|
|
|
|
98
|
$self->{_errors} = [];
|
42
|
|
|
|
|
|
|
# debug callback print flags
|
43
|
51
|
|
|
|
|
154
|
my $dump_opts = JV_PRINT_INDENT_FLAGS(2);
|
44
|
51
|
|
|
|
|
88
|
$dump_opts |= JV_PRINT_SORTED;
|
45
|
51
|
50
|
|
|
|
1205
|
$dump_opts |= JV_PRINT_COLOR | JV_PRINT_ISATTY if isatty(*STDERR);
|
46
|
51
|
|
|
|
|
1771
|
$self->{_dumpopts} = $dump_opts;
|
47
|
|
|
|
|
|
|
# jq debug flags
|
48
|
51
|
50
|
|
|
|
133
|
$self->{jq_flags} = exists $param->{debug_flag} ? $param->{debug_flag} : 0;
|
49
|
51
|
|
|
|
|
87
|
bless $self, $pkg;
|
50
|
51
|
100
|
|
|
|
3423595
|
unless ($self->_init()) {
|
51
|
1
|
|
|
|
|
4
|
croak "jq_compile_args() failed with errors:\n ". join("\n ", @{ $self->{_errors} });
|
|
1
|
|
|
|
|
229
|
|
52
|
|
|
|
|
|
|
}
|
53
|
50
|
|
|
|
|
429
|
return $self;
|
54
|
|
|
|
|
|
|
}
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub process {
|
57
|
60
|
|
|
60
|
1
|
2103
|
my ( $self, $param ) = @_;
|
58
|
|
|
|
|
|
|
|
59
|
60
|
|
|
|
|
82
|
my $input;
|
60
|
60
|
100
|
|
|
|
183
|
if (exists $param->{data}) {
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
61
|
59
|
|
|
|
|
118
|
$input = $param->{data};
|
62
|
|
|
|
|
|
|
}
|
63
|
|
|
|
|
|
|
elsif (exists $param->{json}) {
|
64
|
1
|
|
|
|
|
7
|
$input = from_json($param->{json}, { utf8 => 1 });
|
65
|
|
|
|
|
|
|
}
|
66
|
|
|
|
|
|
|
elsif (exists $param->{json_file}) {
|
67
|
0
|
|
|
|
|
0
|
my $file = path($param->{json_file});
|
68
|
0
|
|
|
|
|
0
|
$input = from_json($file->slurp, { utf8 => 1 });
|
69
|
|
|
|
|
|
|
}
|
70
|
|
|
|
|
|
|
else {
|
71
|
0
|
|
|
|
|
0
|
croak "JSON::JQ::process(): required parameter not found, check method documentation";
|
72
|
|
|
|
|
|
|
}
|
73
|
60
|
|
|
|
|
146
|
my $output = [];
|
74
|
60
|
|
|
|
|
1363
|
my $rc = $self->_process($input, $output);
|
75
|
|
|
|
|
|
|
# treat it as option EXIT_STATUS is on
|
76
|
60
|
100
|
|
|
|
183
|
$rc -= 10 if $rc >= 10;
|
77
|
60
|
100
|
66
|
|
|
226
|
if ($rc == 1) {
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# NOTE: treat this case as successful run
|
79
|
4
|
|
|
|
|
174
|
warn "JSON::JQ::process(): returned null/false (undef output), perhaps the input is undef.\n";
|
80
|
|
|
|
|
|
|
}
|
81
|
2
|
|
|
|
|
12
|
elsif ($rc == 4 and @{ $self->{_errors} } == 0) {
|
82
|
|
|
|
|
|
|
# treat it as succeeded
|
83
|
2
|
|
|
|
|
6
|
push @$output, undef;
|
84
|
|
|
|
|
|
|
}
|
85
|
|
|
|
|
|
|
elsif ($rc != 0) {
|
86
|
0
|
|
|
|
|
0
|
croak "JSON::JQ::process(): failed with return code = $rc and errors:\n ". join("\n ", @{ $self->{_errors} });
|
|
0
|
|
|
|
|
0
|
|
87
|
|
|
|
|
|
|
}
|
88
|
60
|
100
|
|
|
|
381
|
return wantarray ? @$output : $output;
|
89
|
|
|
|
|
|
|
}
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=head1 NAME
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
JSON::JQ - jq (https://stedolan.github.io/jq/) library binding
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
use JSON::JQ;
|
98
|
|
|
|
|
|
|
my $jq = JSON::JQ->new({ script => '.' });
|
99
|
|
|
|
|
|
|
# 1. process perl data
|
100
|
|
|
|
|
|
|
my $results = $jq->process({ data => { foo => 'bar' }});
|
101
|
|
|
|
|
|
|
# 2. process json string
|
102
|
|
|
|
|
|
|
my $results = $jq->process({ json => '{ "foo": "bar" }'});
|
103
|
|
|
|
|
|
|
# 3. process json file
|
104
|
|
|
|
|
|
|
my $results = $jq->process({ json_file => 'foo.json' });
|
105
|
|
|
|
|
|
|
# check items in @$results
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
This is a L library binding, making it possible to process
|
111
|
|
|
|
|
|
|
data using jq script/filter/module. Check the jq homepage for a detailed explanation and documentation.
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head1 METHODS
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head2 new({ parameter => value, ... })
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
Construct a jq engine instance and return it, jq script must be provided by either I |