diffblue-cbmc/unit/json_symbol_table.cpp

150 lines
3.3 KiB
C++
Raw Normal View History

/// Author: Daniel Poetzl
/// \file json symbol table read/write consistency
#include <ansi-c/ansi_c_language.h>
#include <cbmc/cbmc_parse_options.h>
#include <goto-programs/goto_convert_functions.h>
#include <goto-programs/goto_model.h>
#include <goto-programs/initialize_goto_model.h>
#include <goto-programs/show_symbol_table.h>
#include <json-symtab-language/json_symbol_table.h>
#include <json/json_parser.h>
#include <langapi/language_file.h>
#include <langapi/mode.h>
#include <util/cmdline.h>
#include <util/config.h>
#include <util/message.h>
#include <util/options.h>
#include <util/symbol_table.h>
#include <testing-utils/message.h>
#include <testing-utils/use_catch.h>
#include <iosfwd>
class test_ui_message_handlert : public ui_message_handlert
{
public:
explicit test_ui_message_handlert(std::ostream &out)
: ui_message_handlert(cmdlinet(), ""), json_stream_array(out, 0)
{
}
uit get_ui() const
{
return uit::JSON_UI;
}
json_stream_arrayt &get_json_stream()
{
return json_stream_array;
}
json_stream_arrayt json_stream_array;
};
void get_goto_model(std::istream &in, goto_modelt &goto_model)
{
optionst options;
cbmc_parse_optionst::set_default_options(options);
messaget null_message(null_message_handler);
language_filest language_files;
language_files.set_message_handler(null_message_handler);
std::string filename;
language_filet &language_file = language_files.add_file(filename);
language_file.language = get_default_language();
languaget &language = *language_file.language;
language.set_message_handler(null_message_handler);
language.set_language_options(options);
{
bool r = language.parse(in, filename);
REQUIRE(!r);
}
language_file.get_modules();
{
bool r = language_files.typecheck(goto_model.symbol_table);
REQUIRE(!r);
}
REQUIRE(!goto_model.symbol_table.has_symbol(goto_functionst::entry_point()));
{
bool r = language_files.generate_support_functions(goto_model.symbol_table);
REQUIRE(!r);
}
goto_convert(
goto_model.symbol_table, goto_model.goto_functions, null_message_handler);
}
TEST_CASE("json symbol table read/write consistency")
{
register_language(new_ansi_c_language);
cmdlinet cmdline;
config.main = std::string("main");
config.set(cmdline);
goto_modelt goto_model;
// Get symbol table associated with goto program
{
std::string program = "int main() { return 0; }\n";
std::istringstream in(program);
get_goto_model(in, goto_model);
}
const symbol_tablet &symbol_table1 = goto_model.symbol_table;
// Convert symbol table to json string
std::ostringstream out;
{
test_ui_message_handlert ui_message_handler(out);
REQUIRE(ui_message_handler.get_ui() == ui_message_handlert::uit::JSON_UI);
show_symbol_table(symbol_table1, ui_message_handler);
}
// Convert json string to symbol table
symbol_tablet symbol_table2;
{
std::istringstream in(out.str());
jsont json;
bool r = parse_json(in, "", null_message_handler, json);
REQUIRE(!r);
REQUIRE(json.is_array());
const json_arrayt &json_array = to_json_array(json);
const jsont &json_symbol_table = *json_array.begin();
symbol_table_from_json(json_symbol_table, symbol_table2);
}
// Finally check if symbol tables are consistent
REQUIRE(symbol_table1 == symbol_table2);
}