Skip to content

Commit fd6e0e0

Browse files
Add JSON cmdline interface
allows reading the command line in JSON format from stdin.
1 parent 3e07354 commit fd6e0e0

File tree

3 files changed

+162
-1
lines changed

3 files changed

+162
-1
lines changed

src/json/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
SRC = json_lex.yy.cpp \
1+
SRC = json_interface.cpp \
2+
json_lex.yy.cpp \
23
json_parser.cpp \
34
json_y.tab.cpp \
45
# Empty last line

src/json/json_interface.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*******************************************************************\
2+
3+
Module: JSON Commandline Interface
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// JSON Commandline Interface
11+
12+
#include "json_interface.h"
13+
14+
#include <util/cmdline.h>
15+
#include <util/exception_utils.h>
16+
#include <util/json.h>
17+
#include <util/message.h>
18+
19+
#include "json_parser.h"
20+
21+
#include <iostream>
22+
23+
/// Parse commandline options from \p json into \p cmdline
24+
static void get_json_options(const json_objectt &json, cmdlinet &cmdline)
25+
{
26+
const jsont &arguments = json["arguments"];
27+
if(!arguments.is_array())
28+
{
29+
throw invalid_command_line_argument_exceptiont(
30+
"array expected", "'arguments'");
31+
}
32+
33+
for(const auto &argument : to_json_array(arguments))
34+
{
35+
if(!argument.is_string())
36+
{
37+
throw invalid_command_line_argument_exceptiont(
38+
"string expected", "argument");
39+
}
40+
41+
cmdline.args.push_back(argument.value);
42+
}
43+
44+
const jsont &options = json["options"];
45+
if(!options.is_object())
46+
{
47+
throw invalid_command_line_argument_exceptiont(
48+
"array expected", "'options'");
49+
}
50+
51+
for(const auto &option_pair : to_json_object(options))
52+
{
53+
if(option_pair.second.is_string() || option_pair.second.is_number())
54+
{
55+
// e.g. --option x
56+
cmdline.set(option_pair.first, option_pair.second.value);
57+
}
58+
else if(option_pair.second.is_boolean())
59+
{
60+
// e.g. --flag
61+
if(option_pair.second.is_true())
62+
cmdline.set(option_pair.first);
63+
}
64+
else if(option_pair.second.is_array())
65+
{
66+
// e.g. --option x --option y
67+
for(const auto &element : to_json_array(option_pair.second))
68+
{
69+
if(element.is_string())
70+
cmdline.set(option_pair.first, element.value);
71+
else
72+
{
73+
throw invalid_command_line_argument_exceptiont(
74+
"string expected", option_pair.first);
75+
}
76+
}
77+
}
78+
else
79+
{
80+
throw invalid_command_line_argument_exceptiont(
81+
"unrecognized commandline option format",
82+
option_pair.first,
83+
"Boolean, string, number, or string array expected");
84+
}
85+
}
86+
}
87+
88+
void json_interface(cmdlinet &cmdline, message_handlert &message_handler)
89+
{
90+
if(cmdline.isset("json-interface"))
91+
{
92+
jsont json;
93+
94+
parse_json(std::cin, "", message_handler, json);
95+
96+
try
97+
{
98+
if(!json.is_object())
99+
{
100+
throw invalid_command_line_argument_exceptiont(
101+
"JSON object expected at top-level", "command-line JSON input");
102+
}
103+
104+
get_json_options(to_json_object(json), cmdline);
105+
106+
// Add this so that it gets propagated into optionst;
107+
// the ui_message_handlert::uit has already been set on the basis
108+
// of the json-interface flag.
109+
cmdline.set("json-ui");
110+
}
111+
catch(const invalid_command_line_argument_exceptiont &e)
112+
{
113+
messaget log(message_handler);
114+
log.error() << e.what() << messaget::eom;
115+
116+
// make sure we fail with a usage error
117+
cmdline.clear();
118+
}
119+
}
120+
}

src/json/json_interface.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*******************************************************************\
2+
3+
Module: JSON Commandline Interface
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// JSON Commandline Interface
11+
12+
#ifndef CPROVER_JSON_JSON_INTERFACE_H
13+
#define CPROVER_JSON_JSON_INTERFACE_H
14+
15+
class cmdlinet;
16+
class message_handlert;
17+
18+
/// Parses the JSON-formatted command line from stdin
19+
///
20+
/// Example:
21+
/// \code{.json}
22+
/// {
23+
/// "arguments": [
24+
/// "main.c"
25+
/// ],
26+
/// "options": {
27+
/// "function": "foo",
28+
/// "unwind": 3,
29+
/// "property": [
30+
/// "foo.assertion.1",
31+
/// "foo.assertion.3"
32+
/// ],
33+
/// "trace": true,
34+
/// "show-properties": false
35+
/// }
36+
/// }
37+
/// \endcode
38+
void json_interface(cmdlinet &, message_handlert &);
39+
40+
#endif // CPROVER_JSON_JSON_INTERFACE_H

0 commit comments

Comments
 (0)