-
Notifications
You must be signed in to change notification settings - Fork 277
JSON cmdline interface #4585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON cmdline interface #4585
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <assert.h> | ||
|
||
void foo(int x) | ||
{ | ||
for(int i = 0; i < 5; ++i) | ||
{ | ||
if(x) | ||
assert(0); | ||
assert(0); | ||
} | ||
assert(0); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE broken-smt-backend | ||
--json-interface | ||
< test.json | ||
activate-multi-line-match | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
Not unwinding loop foo\.0 iteration 3 file main\.c line 5 function foo thread 0 | ||
\{\n\s*"description": "assertion 0",\n\s*"property": "foo\.assertion\.(1|3)",\n\s*"status": "SUCCESS"\n\s*\} | ||
\{\n\s*"description": "assertion 0",\n\s*"property": "foo\.assertion\.(1|3)",\n\s*"status": "FAILURE",\n\s*"trace": \[ | ||
VERIFICATION FAILED | ||
-- | ||
"property": "foo\.assertion\.2" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"arguments": [ | ||
"main.c" | ||
], | ||
"options": { | ||
"function": "foo", | ||
"unwind": 3, | ||
"property": [ | ||
"foo.assertion.1", | ||
"foo.assertion.3" | ||
], | ||
"trace": true, | ||
"show-properties": false | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,6 +79,7 @@ Author: Daniel Kroening, [email protected] | |
|
||
#include <langapi/mode.h> | ||
|
||
#include <json/json_interface.h> | ||
#include <xmllang/xml_interface.h> | ||
|
||
#include "c_test_input_generator.h" | ||
|
@@ -90,6 +91,7 @@ cbmc_parse_optionst::cbmc_parse_optionst(int argc, const char **argv) | |
argv, | ||
std::string("CBMC ") + CBMC_VERSION) | ||
{ | ||
json_interface(cmdline, ui_message_handler); | ||
xml_interface(cmdline, ui_message_handler); | ||
} | ||
|
||
|
@@ -103,6 +105,7 @@ ::cbmc_parse_optionst::cbmc_parse_optionst( | |
argv, | ||
std::string("CBMC ") + CBMC_VERSION) | ||
{ | ||
json_interface(cmdline, ui_message_handler); | ||
xml_interface(cmdline, ui_message_handler); | ||
} | ||
|
||
|
@@ -1021,6 +1024,7 @@ void cbmc_parse_optionst::help() | |
" --xml-ui use XML-formatted output\n" | ||
" --xml-interface bi-directional XML interface\n" | ||
" --json-ui use JSON-formatted output\n" | ||
" --json-interface bi-directional JSON interface\n" | ||
// NOLINTNEXTLINE(whitespace/line_length) | ||
HELP_VALIDATE | ||
HELP_GOTO_TRACE | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/*******************************************************************\ | ||
|
||
Module: JSON Commandline Interface | ||
|
||
Author: Peter Schrammel | ||
|
||
\*******************************************************************/ | ||
|
||
/// \file | ||
/// JSON Commandline Interface | ||
|
||
#include "json_interface.h" | ||
|
||
#include <util/cmdline.h> | ||
#include <util/exception_utils.h> | ||
#include <util/json.h> | ||
#include <util/message.h> | ||
|
||
#include "json_parser.h" | ||
|
||
#include <iostream> | ||
|
||
/// Parse commandline options from \p json into \p cmdline | ||
static void get_json_options(const json_objectt &json, cmdlinet &cmdline) | ||
{ | ||
const jsont &arguments = json["arguments"]; | ||
if(!arguments.is_array()) | ||
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"array expected", "'arguments'"); | ||
} | ||
|
||
for(const auto &argument : to_json_array(arguments)) | ||
{ | ||
if(!argument.is_string()) | ||
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"string expected", "argument"); | ||
} | ||
|
||
cmdline.args.push_back(argument.value); | ||
} | ||
|
||
const jsont &options = json["options"]; | ||
if(!options.is_object()) | ||
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"array expected", "'options'"); | ||
} | ||
|
||
for(const auto &option_pair : to_json_object(options)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit pick: add a blank line before this one to be consistent with the code a few lines above. |
||
{ | ||
if(option_pair.second.is_string() || option_pair.second.is_number()) | ||
{ | ||
// e.g. --option x | ||
cmdline.set(option_pair.first, option_pair.second.value); | ||
} | ||
else if(option_pair.second.is_boolean()) | ||
{ | ||
// e.g. --flag | ||
if(option_pair.second.is_true()) | ||
cmdline.set(option_pair.first); | ||
} | ||
else if(option_pair.second.is_array()) | ||
{ | ||
// e.g. --option x --option y | ||
for(const auto &element : to_json_array(option_pair.second)) | ||
{ | ||
if(element.is_string()) | ||
cmdline.set(option_pair.first, element.value); | ||
else | ||
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"string expected", option_pair.first); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"unrecognized commandline option format", | ||
option_pair.first, | ||
"Boolean, string, number, or string array expected"); | ||
} | ||
} | ||
} | ||
|
||
void json_interface(cmdlinet &cmdline, message_handlert &message_handler) | ||
{ | ||
if(cmdline.isset("json-interface")) | ||
{ | ||
jsont json; | ||
|
||
parse_json(std::cin, "", message_handler, json); | ||
|
||
try | ||
{ | ||
if(!json.is_object()) | ||
{ | ||
throw invalid_command_line_argument_exceptiont( | ||
"JSON object expected at top-level", "command-line JSON input"); | ||
} | ||
|
||
get_json_options(to_json_object(json), cmdline); | ||
|
||
// Add this so that it gets propagated into optionst; | ||
// the ui_message_handlert::uit has already been set on the basis | ||
// of the json-interface flag. | ||
cmdline.set("json-ui"); | ||
} | ||
catch(const invalid_command_line_argument_exceptiont &e) | ||
{ | ||
messaget log(message_handler); | ||
log.error() << e.what() << messaget::eom; | ||
|
||
// make sure we fail with a usage error | ||
cmdline.clear(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/*******************************************************************\ | ||
|
||
Module: JSON Commandline Interface | ||
|
||
Author: Peter Schrammel | ||
|
||
\*******************************************************************/ | ||
|
||
/// \file | ||
/// JSON Commandline Interface | ||
|
||
#ifndef CPROVER_JSON_JSON_INTERFACE_H | ||
#define CPROVER_JSON_JSON_INTERFACE_H | ||
|
||
class cmdlinet; | ||
class message_handlert; | ||
|
||
/// Parses the JSON-formatted command line from stdin | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be rather important to document the expected JSON syntax! Otherwise you're bound to trial and error... |
||
/// | ||
/// Example: | ||
/// \code{.json} | ||
/// { | ||
/// "arguments": [ | ||
/// "main.c" | ||
/// ], | ||
/// "options": { | ||
/// "function": "foo", | ||
/// "unwind": 3, | ||
/// "property": [ | ||
/// "foo.assertion.1", | ||
/// "foo.assertion.3" | ||
/// ], | ||
/// "trace": true, | ||
/// "show-properties": false | ||
/// } | ||
/// } | ||
/// \endcode | ||
void json_interface(cmdlinet &, message_handlert &); | ||
|
||
#endif // CPROVER_JSON_JSON_INTERFACE_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually bi-directional?! Doesn't it only become "bi"directional when using both
--json-interface
and--json-ui
? (The same is of course true for XML.)Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering about that and have now more investigated in the XML case (see comments there). The original intention was that --xml-interface subsumes --xml-ui.
Actually, the current behaviour was broken because the UI was set before the option could have been parsed from stdin, which seems difficult to fix without splitting the
parse_optionst
constructor into two phases and adding aset_ui
toui_message_handlert
(rather no).Also, the question is what happens with errors during parsing the options - they should already be output in a proper format. Thus, I'd rather stick with the original intention of 'bi-directional',
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I fully understand - I agree that
--{json,xml}-interface
should subsume--{json,xml}-ui
- but I don't think that was actually work as such? If things can be made to work as such then we'd have the desired bi-directional interface.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--json-interface
now implies--json-ui
, and--xml-interface
now implies--xml-ui
.Not sure, I understand...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me retry, my apologies for completely broken English:
--{json,xml}-ui
set up the output side of an interface.--{json,xml}-interface
configure a bi-directional interface.--{json,xml}-interface
.--{json,xml}-interface
we also set the option for--{json,xml}-ui
.--{json,xml}-interface
and--{json,xml}-ui
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.