@@ -13,6 +13,7 @@ Author: Daniel Kroening
1313
1414#include " xml_goto_trace.h"
1515
16+ #include < util/string_constant.h>
1617#include < util/symbol.h>
1718#include < util/xml_irep.h>
1819
@@ -23,6 +24,38 @@ Author: Daniel Kroening
2324#include " structured_trace_util.h"
2425#include " xml_expr.h"
2526
27+ // / Rewrite all string constants to their array counterparts
28+ static void replace_string_constants_rec (exprt &expr)
29+ {
30+ for (auto &op : expr.operands ())
31+ replace_string_constants_rec (op);
32+
33+ if (expr.id () == ID_string_constant)
34+ expr = to_string_constant (expr).to_array_expr ();
35+ }
36+
37+ // / Given an expression \p expr, produce a string representation that is
38+ // / printable in XML 1.0. Produces an empty string if no valid XML 1.0 string
39+ // / representing \p expr can be generated.
40+ static std::string
41+ get_printable_xml (const namespacet &ns, const irep_idt &id, const exprt &expr)
42+ {
43+ std::string result = from_expr (ns, id, expr);
44+
45+ if (!xmlt::is_printable_xml (result))
46+ {
47+ exprt new_expr = expr;
48+ replace_string_constants_rec (new_expr);
49+ result = from_expr (ns, id, new_expr);
50+
51+ // give up
52+ if (!xmlt::is_printable_xml (result))
53+ return {};
54+ }
55+
56+ return result;
57+ }
58+
2659xmlt full_lhs_value (const goto_trace_stept &step, const namespacet &ns)
2760{
2861 xmlt value_xml{" full_lhs_value" };
@@ -34,7 +67,7 @@ xmlt full_lhs_value(const goto_trace_stept &step, const namespacet &ns)
3467 const auto &lhs_object = step.get_lhs_object ();
3568 const irep_idt identifier =
3669 lhs_object.has_value () ? lhs_object->get_identifier () : irep_idt ();
37- value_xml.data = from_expr (ns, identifier, value);
70+ value_xml.data = get_printable_xml (ns, identifier, value);
3871
3972 const auto &bv_type = type_try_dynamic_cast<bitvector_typet>(value.type ());
4073 const auto &constant = expr_try_dynamic_cast<constant_exprt>(value);
@@ -121,7 +154,7 @@ void convert(
121154 std::string full_lhs_string;
122155
123156 if (step.full_lhs .is_not_nil ())
124- full_lhs_string = from_expr (ns, identifier, step.full_lhs );
157+ full_lhs_string = get_printable_xml (ns, identifier, step.full_lhs );
125158
126159 xml_assignment.new_element (" full_lhs" ).data = full_lhs_string;
127160 xml_assignment.new_element (full_lhs_value (step, ns));
@@ -158,7 +191,7 @@ void convert(
158191 for (const auto &arg : step.io_args )
159192 {
160193 xml_output.new_element (" value" ).data =
161- from_expr (ns, step.function_id , arg);
194+ get_printable_xml (ns, step.function_id , arg);
162195 xml_output.new_element (" value_expression" ).new_element (xml (arg, ns));
163196 }
164197 break ;
@@ -176,7 +209,7 @@ void convert(
176209 for (const auto &arg : step.io_args )
177210 {
178211 xml_input.new_element (" value" ).data =
179- from_expr (ns, step.function_id , arg);
212+ get_printable_xml (ns, step.function_id , arg);
180213 xml_input.new_element (" value_expression" ).new_element (xml (arg, ns));
181214 }
182215
0 commit comments