From 18c25e8bff2e16796e23f921e6add38030576c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Wed, 25 Jan 2017 20:42:32 +0100 Subject: [PATCH] json-format.pl: make it a streaming formatter Always pretty-print. --- json-format.pl | 41 ++++++++++++++++++++++++----------------- 1 file 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";