Skip to content

Commit 187b3cb

Browse files
author
Daniel Kroening
authored
Merge pull request #448 from thk123/feature/goto2json
Support for outputting JSON version of the GOTO program
2 parents d648d57 + 5550c08 commit 187b3cb

12 files changed

+625
-56
lines changed

src/goto-programs/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ SRC = goto_convert.cpp goto_convert_function_call.cpp \
1818
graphml_witness.cpp remove_virtual_functions.cpp \
1919
class_hierarchy.cpp show_goto_functions.cpp get_goto_model.cpp \
2020
slice_global_inits.cpp goto_inline_class.cpp class_identifier.cpp \
21+
show_goto_functions_json.cpp \
22+
show_goto_functions_xml.cpp \
2123
remove_static_init_loops.cpp remove_instanceof.cpp
2224

2325
INCLUDES= -I ..

src/goto-programs/goto_program.cpp

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@ Author: Daniel Kroening, kroening@kroening.com
1919
Function: goto_programt::output_instruction
2020
2121
Inputs:
22+
ns - the namespace to resolve the expressions in
23+
identifier - the identifier used to find a symbol to identify the
24+
source language
25+
out - the stream to write the goto string to
26+
it - an iterator pointing to the instruction to convert
2227
23-
Outputs:
28+
Outputs: See below.
2429
25-
Purpose:
30+
Purpose: See below.
2631
2732
\*******************************************************************/
2833

@@ -32,51 +37,81 @@ std::ostream& goto_programt::output_instruction(
3237
std::ostream& out,
3338
instructionst::const_iterator it) const
3439
{
35-
out << " // " << it->location_number << " ";
40+
return output_instruction(ns, identifier, out, *it);
41+
}
42+
43+
/*******************************************************************\
44+
45+
Function: goto_programt::output_instruction
46+
47+
Inputs:
48+
ns - the namespace to resolve the expressions in
49+
identifier - the identifier used to find a symbol to identify the
50+
source language
51+
out - the stream to write the goto string to
52+
instruction - the instruction to convert
3653
37-
if(!it->source_location.is_nil())
38-
out << it->source_location.as_string();
54+
Outputs: Appends to out a two line representation of the instruction
55+
56+
Purpose: Writes to out a two line string representation of the specific
57+
instruction. It is of the format:
58+
// {location} file {source file} line {line in source file}
59+
{representation of the instruction}
60+
61+
\*******************************************************************/
62+
63+
std::ostream &goto_programt::output_instruction(
64+
const namespacet &ns,
65+
const irep_idt &identifier,
66+
std::ostream &out,
67+
const goto_program_templatet::instructiont &instruction) const
68+
{
69+
out << " // " << instruction.location_number << " ";
70+
71+
if(!instruction.source_location.is_nil())
72+
out << instruction.source_location.as_string();
3973
else
4074
out << "no location";
4175

4276
out << "\n";
4377

44-
if(!it->labels.empty())
78+
if(!instruction.labels.empty())
4579
{
4680
out << " // Labels:";
47-
for(const auto &label : it->labels)
81+
for(const auto &label : instruction.labels)
4882
out << " " << label;
4983

5084
out << '\n';
5185
}
5286

53-
if(it->is_target())
54-
out << std::setw(6) << it->target_number << ": ";
87+
if(instruction.is_target())
88+
out << std::setw(6) << instruction.target_number << ": ";
5589
else
5690
out << " ";
5791

58-
switch(it->type)
92+
switch(instruction.type)
5993
{
6094
case NO_INSTRUCTION_TYPE:
6195
out << "NO INSTRUCTION TYPE SET" << '\n';
6296
break;
6397

6498
case GOTO:
65-
if(!it->guard.is_true())
99+
if(!instruction.guard.is_true())
66100
{
67101
out << "IF "
68-
<< from_expr(ns, identifier, it->guard)
102+
<< from_expr(ns, identifier, instruction.guard)
69103
<< " THEN ";
70104
}
71105

72106
out << "GOTO ";
73107

74108
for(instructiont::targetst::const_iterator
75-
gt_it=it->targets.begin();
76-
gt_it!=it->targets.end();
109+
gt_it=instruction.targets.begin();
110+
gt_it!=instruction.targets.end();
77111
gt_it++)
78112
{
79-
if(gt_it!=it->targets.begin()) out << ", ";
113+
if(gt_it!=instruction.targets.begin())
114+
out << ", ";
80115
out << (*gt_it)->target_number;
81116
}
82117

@@ -89,20 +124,20 @@ std::ostream& goto_programt::output_instruction(
89124
case DEAD:
90125
case FUNCTION_CALL:
91126
case ASSIGN:
92-
out << from_expr(ns, identifier, it->code) << '\n';
127+
out << from_expr(ns, identifier, instruction.code) << '\n';
93128
break;
94129

95130
case ASSUME:
96131
case ASSERT:
97-
if(it->is_assume())
132+
if(instruction.is_assume())
98133
out << "ASSUME ";
99134
else
100135
out << "ASSERT ";
101136

102137
{
103-
out << from_expr(ns, identifier, it->guard);
138+
out << from_expr(ns, identifier, instruction.guard);
104139

105-
const irep_idt &comment=it->source_location.get_comment();
140+
const irep_idt &comment=instruction.source_location.get_comment();
106141
if(comment!="") out << " // " << comment;
107142
}
108143

@@ -126,34 +161,35 @@ std::ostream& goto_programt::output_instruction(
126161

127162
{
128163
const irept::subt &exception_list=
129-
it->code.find(ID_exception_list).get_sub();
164+
instruction.code.find(ID_exception_list).get_sub();
130165

131166
for(const auto &ex : exception_list)
132167
out << " " << ex.id();
133168
}
134169

135-
if(it->code.operands().size()==1)
136-
out << ": " << from_expr(ns, identifier, it->code.op0());
170+
if(instruction.code.operands().size()==1)
171+
out << ": " << from_expr(ns, identifier, instruction.code.op0());
137172

138173
out << '\n';
139174
break;
140175

141176
case CATCH:
142-
if(!it->targets.empty())
177+
if(!instruction.targets.empty())
143178
{
144179
out << "CATCH-PUSH ";
145180

146181
unsigned i=0;
147182
const irept::subt &exception_list=
148-
it->code.find(ID_exception_list).get_sub();
149-
assert(it->targets.size()==exception_list.size());
183+
instruction.code.find(ID_exception_list).get_sub();
184+
assert(instruction.targets.size()==exception_list.size());
150185
for(instructiont::targetst::const_iterator
151-
gt_it=it->targets.begin();
152-
gt_it!=it->targets.end();
186+
gt_it=instruction.targets.begin();
187+
gt_it!=instruction.targets.end();
153188
gt_it++,
154189
i++)
155190
{
156-
if(gt_it!=it->targets.begin()) out << ", ";
191+
if(gt_it!=instruction.targets.begin())
192+
out << ", ";
157193
out << exception_list[i].id() << "->"
158194
<< (*gt_it)->target_number;
159195
}
@@ -175,8 +211,8 @@ std::ostream& goto_programt::output_instruction(
175211
case START_THREAD:
176212
out << "START THREAD ";
177213

178-
if(it->targets.size()==1)
179-
out << it->targets.front()->target_number;
214+
if(instruction.targets.size()==1)
215+
out << instruction.targets.front()->target_number;
180216

181217
out << '\n';
182218
break;

src/goto-programs/goto_program.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ class goto_programt:public goto_program_templatet<codet, exprt>
2828
std::ostream &out,
2929
instructionst::const_iterator it) const;
3030

31+
std::ostream &output_instruction(
32+
const class namespacet &ns,
33+
const irep_idt &identifier,
34+
std::ostream &out,
35+
const instructiont &instruction) const;
36+
3137
goto_programt() { }
3238

3339
// get the variables in decl statements

src/goto-programs/goto_program_template.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Author: Daniel Kroening, kroening@kroening.com
1515
#include <iosfwd>
1616
#include <set>
1717
#include <limits>
18+
#include <sstream>
19+
#include <string>
1820

1921
#include <util/namespace.h>
2022
#include <util/symbol_table.h>
@@ -240,6 +242,13 @@ class goto_program_templatet
240242

241243
return false;
242244
}
245+
246+
std::string to_string() const
247+
{
248+
std::ostringstream instruction_id_builder;
249+
instruction_id_builder << type;
250+
return instruction_id_builder.str();
251+
}
243252
};
244253

245254
typedef std::list<class instructiont> instructionst;

src/goto-programs/show_goto_functions.cpp

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ Author: Peter Schrammel
1010

1111
#include <util/xml.h>
1212
#include <util/json.h>
13+
#include <util/json_expr.h>
1314
#include <util/xml_expr.h>
1415
#include <util/cprover_prefix.h>
1516
#include <util/prefix.h>
1617

1718
#include <langapi/language_util.h>
19+
#include <goto-programs/show_goto_functions_json.h>
20+
#include <goto-programs/show_goto_functions_xml.h>
1821

1922
#include "show_goto_functions.h"
2023
#include "goto_functions.h"
@@ -41,36 +44,15 @@ void show_goto_functions(
4144
{
4245
case ui_message_handlert::XML_UI:
4346
{
44-
//This only prints the list of functions
45-
xmlt xml_functions("functions");
46-
forall_goto_functions(it, goto_functions)
47-
{
48-
xmlt &xml_function=xml_functions.new_element("function");
49-
xml_function.set_attribute("name", id2string(it->first));
50-
}
51-
52-
std::cout << xml_functions << std::endl;
47+
show_goto_functions_xmlt xml_show_functions(ns);
48+
xml_show_functions(goto_functions, std::cout);
5349
}
5450
break;
5551

5652
case ui_message_handlert::JSON_UI:
5753
{
58-
//This only prints the list of functions
59-
json_arrayt json_functions;
60-
forall_goto_functions(it, goto_functions)
61-
{
62-
json_objectt &json_function=
63-
json_functions.push_back(jsont()).make_object();
64-
json_function["name"]=json_stringt(id2string(it->first));
65-
json_function["isBodyAvailable"]=
66-
jsont::json_boolean(it->second.body_available());
67-
bool is_internal=(has_prefix(id2string(it->first), CPROVER_PREFIX) ||
68-
it->first==ID__start);
69-
json_function["isInternal"]=jsont::json_boolean(is_internal);
70-
}
71-
json_objectt json_result;
72-
json_result["functions"]=json_functions;
73-
std::cout << ",\n" << json_result;
54+
show_goto_functions_jsont json_show_functions(ns);
55+
json_show_functions(goto_functions, std::cout);
7456
}
7557
break;
7658

0 commit comments

Comments
 (0)