@@ -30,15 +30,51 @@ Date: April 2016
30
30
#include < goto-programs/goto_model.h>
31
31
#include < goto-programs/remove_skip.h>
32
32
33
- // / Set up argv with up to max_argc pointers into an array of 4096 bytes.
33
+ // Escape selected character in specified string with backslashes.
34
+ //
35
+ // \param input_string: string where character will be escaped.
36
+ // \param find_substring: character to escape, e.g. \"
37
+ // \param replace_substring: string, e.g. \\\"
38
+ std::string escape_char (
39
+ std::string input_string,
40
+ std::string find_substring,
41
+ std::string replace_substring){
42
+ size_t index = 0 ;
43
+ while (true ) {
44
+ /* Locate the substring to replace. */
45
+ index = input_string.find (find_substring, index);
46
+
47
+ if (index == std::string::npos) break ;
48
+
49
+ /* Make the replacement. */
50
+ input_string.replace (index,
51
+ replace_substring.size (),
52
+ replace_substring);
53
+
54
+ /* Advance index forward so the next iteration
55
+ * doesn't pick it up as well. */
56
+ index += replace_substring.size ();
57
+ }
58
+ return input_string;
59
+ }
60
+
61
+ // / Set up argv to user-specified values (when model_argv is FALSE) or
62
+ // / (when model_argv is TRUE) set up argv with up to max_argc pointers
63
+ // / into a char array of 4096 bytes.
64
+ // /
34
65
// / \param goto_model: Contains the input program's symbol table and
35
66
// / intermediate representation
36
- // / \param max_argc: User-specified maximum number of arguments to be modelled
67
+ // / \param argv_args: User-specified cmd-line arguments (ARGV),
68
+ // / when model_argv is TRUE then size of argv_args represents
69
+ // / the maximum number of arguments to be modelled
70
+ // / \param model_argv: If set to TRUE then modelling argv with up to
71
+ // / max_argc pointers
37
72
// / \param message_handler: message logging
38
73
// / \return True, if and only if modelling succeeded
39
74
bool model_argc_argv (
40
75
goto_modelt &goto_model,
41
- unsigned max_argc,
76
+ const std::list<std::string> &argv_args,
77
+ bool model_argv,
42
78
message_handlert &message_handler)
43
79
{
44
80
messaget message (message_handler);
@@ -83,25 +119,52 @@ bool model_argc_argv(
83
119
// guaranteed by POSIX (_POSIX_ARG_MAX):
84
120
// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
85
121
std::ostringstream oss;
86
- oss << " int ARGC;\n "
87
- << " char *ARGV[1];\n "
88
- << " void " << goto_model.goto_functions .entry_point () << " ()\n "
89
- << " {\n "
90
- << " unsigned next=0u;\n "
91
- << " " CPROVER_PREFIX " assume(ARGC>=1);\n "
92
- << " " CPROVER_PREFIX " assume(ARGC<=" << max_argc << " );\n "
93
- << " char arg_string[4096];\n "
94
- << " " CPROVER_PREFIX " input(\" arg_string\" , &arg_string[0]);\n "
95
- << " for(int i=0; i<ARGC && i<" << max_argc << " ; ++i)\n "
96
- << " {\n "
97
- << " unsigned len;\n "
98
- << " " CPROVER_PREFIX " assume(len<4096);\n "
99
- << " " CPROVER_PREFIX " assume(next+len<4096);\n "
100
- << " " CPROVER_PREFIX " assume(arg_string[next+len]==0);\n "
101
- << " ARGV[i]=&(arg_string[next]);\n "
102
- << " next+=len+1;\n "
103
- << " }\n "
104
- << " }" ;
122
+ unsigned max_argc = argv_args.size ();
123
+ unsigned argc = argv_args.size ();
124
+
125
+ if (model_argv)
126
+ {
127
+ oss << " int ARGC;\n "
128
+ << " char *ARGV[1];\n "
129
+ << " void " << goto_model.goto_functions .entry_point () << " ()\n "
130
+ << " {\n "
131
+ << " unsigned next=0u;\n "
132
+ << " " CPROVER_PREFIX " assume(ARGC>=1);\n "
133
+ << " " CPROVER_PREFIX " assume(ARGC<=" << max_argc << " );\n "
134
+ << " char arg_string[4096];\n "
135
+ << " " CPROVER_PREFIX " input(\" arg_string\" , &arg_string[0]);\n "
136
+ << " for(int i=0; i<ARGC && i<" << max_argc << " ; ++i)\n "
137
+ << " {\n "
138
+ << " unsigned len;\n "
139
+ << " " CPROVER_PREFIX " assume(len<4096);\n "
140
+ << " " CPROVER_PREFIX " assume(next+len<4096);\n "
141
+ << " " CPROVER_PREFIX " assume(arg_string[next+len]==0);\n "
142
+ << " ARGV[i]=&(arg_string[next]);\n "
143
+ << " next+=len+1;\n "
144
+ << " }\n "
145
+ << " }" ;
146
+ }
147
+ else
148
+ { // model_argv = false, set each argv[i] explicitly
149
+ oss << " int ARGC = " << argc << " ;\n "
150
+ << " char *ARGV[" << argc << " ];\n "
151
+ << " void " << goto_model.goto_functions .entry_point () << " ()\n "
152
+ << " {\n "
153
+ << " ARGC = " << argc << " ;\n " ;
154
+ int i = 0 ;
155
+ for (auto &arg : argv_args)
156
+ {
157
+ oss << " ARGV[" << i << " ]=\" " << escape_char (
158
+ escape_char (
159
+ escape_char (arg, " \\ " ," \\\\ " ),
160
+ " \' " ," \\\' " ),
161
+ " \" " ," \\\" " )
162
+ << " \" ;\n " ;
163
+ i++;
164
+ }
165
+ oss << " }" ;
166
+ }
167
+
105
168
std::istringstream iss (oss.str ());
106
169
107
170
ansi_c_languaget ansi_c_language;
@@ -169,6 +232,22 @@ bool model_argc_argv(
169
232
main_call!=end;
170
233
++main_call)
171
234
{
235
+ // Turn into skip instr. the INPUT(argc ...) instruction
236
+ if (main_call->is_other () &&
237
+ main_call->get_other ().get_statement () == ID_input &&
238
+ " argc\' " == id2string (to_symbol_expr (
239
+ main_call->get_other ().op1 ()).get_identifier ())) {
240
+ main_call->turn_into_skip ();
241
+ }
242
+
243
+ // Turn into skip instr. the ASSUME(argc ...) instruction
244
+ if (main_call->is_assume () &&
245
+ " argc\' " == id2string (to_symbol_expr (
246
+ main_call->condition ().operands ()[0 ]).get_identifier ())){
247
+
248
+ main_call->turn_into_skip ();
249
+ }
250
+
172
251
if (main_call->is_function_call ())
173
252
{
174
253
const exprt &func = main_call->call_function ();
0 commit comments