json repl script
[scpubgit/Tak.git] / jsonrepl
CommitLineData
03ae33ef 1#!/usr/bin/env perl
2
3use strictures 1;
4use JSON::PP qw(encode_json decode_json);
5use Eval::WithLexicals;
6use Data::Dumper::Concise;
7use IO::Handle;
8
9STDOUT->autoflush(1);
10
11my $eval = Eval::WithLexicals->new;
12
13sub out {
14 print STDOUT encode_json([ @_ ])."\n"
15 or die "Failed to print to STDOUT: $!";
16}
17
18sub run_eval {
19 my ($perl) = @_;
20 unless ($perl) {
21 out(MISTAKE => eval_input => "No code supplied");
22 return;
23 }
24 if (my $ref = ref($perl)) {
25 out(MISTAKE => eval_input => "Code was a ${ref} reference");
26 return;
27 }
28 my ($code, @ret);
29 open my $stdout, '>', \my $output;
30 open my $stderr, '>', \my $errors;
31 if (eval {
32 local *STDOUT = $stdout;
33 local *STDERR = $stderr;
34 @ret = $eval->eval($perl);
35 1
36 }) {
37 $code = 'OK';
38 } else {
39 ($code, @ret) = (FAILURE => $@);
40 }
41 my $dumped_ret;
42 unless (eval { $dumped_ret = Dumper(@ret); 1 }) {
43 $dumped_ret = "Error dumping ${code} result: $@";
44 $code = 'FAILURE';
45 }
46 out($code => { stdout => $output, stderr => $errors, return => $dumped_ret });
47}
48
49while (my $line = <STDIN>) {
50 my $data = eval { decode_json($line) };
51 if ($@) {
52 out(MISTAKE => invalid_json => $@);
53 next;
54 }
55 unless (ref($data) eq 'ARRAY') {
56 out(MISTAKE => message_format => "Not an ARRAY");
57 next;
58 }
59 unless (@$data > 0) {
60 out(MISTAKE => message_format => "No message name");
61 next;
62 }
63 if (my $ref = ref($data->[0])) {
64 out(MISTAKE => message_format => "Message name was a ${ref} ref");
65 next;
66 }
67 my ($message, @args) = @{$data};
68 if ($message eq 'EXIT') {
69 exit 0;
70 } elsif ($message eq 'EVAL') {
71 run_eval(@args);
72 } else {
73 out(MISTAKE => message_name => "Unknown message");
74 }
75}