aboutsummaryrefslogtreecommitdiff
path: root/json-format.pl
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2017-01-25 20:42:32 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2017-01-25 21:05:38 +0100
commit18c25e8bff2e16796e23f921e6add38030576c84 (patch)
treefdc3f4fac10b1d594ed1281ad9b453a91304b92a /json-format.pl
parent17331073a49a30fa4295100701be54064484d6bd (diff)
downloadjson-rpc-shell-18c25e8bff2e16796e23f921e6add38030576c84.tar.gz
json-rpc-shell-18c25e8bff2e16796e23f921e6add38030576c84.tar.xz
json-rpc-shell-18c25e8bff2e16796e23f921e6add38030576c84.zip
json-format.pl: make it a streaming formatter
Always pretty-print.
Diffstat (limited to 'json-format.pl')
-rwxr-xr-xjson-format.pl41
1 files changed, 24 insertions, 17 deletions
diff --git a/json-format.pl b/json-format.pl
index 12f06f1..49fb5ce 100755
--- a/json-format.pl
+++ b/json-format.pl
@@ -56,9 +56,15 @@ my $any_token = qr/\G(${\join '|', @all_pats})/;
my $indent = 0;
sub nexttoken ($) {
- my $ref = shift;
- return unless @$ref;
- my $text = shift @$ref;
+ my $json = shift;
+ if (!@$json) {
+ return unless defined (my $line = <>);
+ push @$json, $line =~ /$any_token/gsc;
+ push @$json, substr $line, pos $line
+ if pos $line != length $line;
+ }
+
+ my $text = shift @$json;
if (my $s = $lookup{$text}) {
return $s, $text;
}
@@ -68,6 +74,15 @@ sub nexttoken ($) {
return 'ERROR', $text;
}
+sub skip_ws ($) {
+ my $json = shift;
+ while (my ($token, $text) = nexttoken $json) {
+ next if $token eq 'WS';
+ return $token, $text;
+ }
+ return;
+}
+
sub printindent () {
print "\n";
print ' ' x $indent;
@@ -78,7 +93,7 @@ sub do_object ($) {
my $json = shift;
my $in_field_name = 1;
my $first = 1;
- while (my ($token, $text) = nexttoken $json) {
+ while (my ($token, $text) = skip_ws $json) {
if ($token eq 'COLON') {
$in_field_name = 0;
} elsif ($token eq 'COMMA') {
@@ -101,7 +116,7 @@ sub do_object ($) {
sub do_array ($) {
my $json = shift;
my $first = 1;
- while (my ($token, $text) = nexttoken $json) {
+ while (my ($token, $text) = skip_ws $json) {
if ($token eq 'RBRACKET') {
$indent--;
printindent;
@@ -134,16 +149,8 @@ sub do_value ($$$) {
}
}
-while (<>) {
- # FIXME: this way it doesn't work with pre-formatted JSON
- my $json = $_;
-
- my @matches = $json =~ /$any_token/gsc;
- push @matches, substr $json, pos $json
- if pos $json != length $json;
- while (my ($token, $text) = nexttoken \@matches) {
- next if $token eq 'WS';
- do_value $token, $text, \@matches;
- }
- print "\n";
+my @buffer;
+while (my ($token, $text) = skip_ws \@buffer) {
+ do_value $token, $text, \@buffer;
}
+print "\n";