1
2
3
4 :(before "End Commandline Parsing")
5 if (argc <= 1 || is_equal(argv[1], "--help")) {
6
7
8 if (argc <= 1) {
9 ¦ cerr << "Please provide a Mu program to run.\n"
10 ¦ ¦ ¦ ¦<< "\n";
11 }
12 cerr << "Usage:\n"
13 ¦ ¦ ¦<< " mu [options] [test] [files]\n"
14 ¦ ¦ ¦<< "or:\n"
15 ¦ ¦ ¦<< " mu [options] [test] [files] -- [ingredients for function/recipe 'main']\n"
16 ¦ ¦ ¦<< "Square brackets surround optional arguments.\n"
17 ¦ ¦ ¦<< "\n"
18 ¦ ¦ ¦<< "Examples:\n"
19 ¦ ¦ ¦<< " To load files and run 'main':\n"
20 ¦ ¦ ¦<< " mu file1.mu file2.mu ...\n"
21 ¦ ¦ ¦<< " To run 'main' and dump a trace of all operations at the end:\n"
22 ¦ ¦ ¦<< " mu --trace file1.mu file2.mu ...\n"
23 ¦ ¦ ¦<< " To run all tests:\n"
24 ¦ ¦ ¦<< " mu test\n"
25 ¦ ¦ ¦<< " To load files and then run all tests:\n"
26 ¦ ¦ ¦<< " mu test file1.mu file2.mu ...\n"
27 ¦ ¦ ¦<< " To run a single Mu scenario:\n"
28 ¦ ¦ ¦<< " mu test file1.mu file2.mu ... scenario\n"
29 ¦ ¦ ¦<< " To run a single Mu scenario and dump a trace at the end:\n"
30 ¦ ¦ ¦<< " mu --trace test file1.mu file2.mu ... scenario\n"
31 ¦ ¦ ¦<< " To load files and run only the tests in explicitly loaded files (for apps):\n"
32 ¦ ¦ ¦<< " mu --test-only-app test file1.mu file2.mu ...\n"
33 ¦ ¦ ¦<< " To load all files with a numeric prefix in a directory:\n"
34 ¦ ¦ ¦<< " mu directory1 directory2 ...\n"
35 ¦ ¦ ¦<< " You can test directories just like files.\n"
36 ¦ ¦ ¦<< " mu test directory1 directory2 ...\n"
37 ¦ ¦ ¦<< " To pass ingredients to a mu program, provide them after '--':\n"
38 ¦ ¦ ¦<< " mu file_or_dir1 file_or_dir2 ... -- ingredient1 ingredient2 ...\n"
39 ¦ ¦ ¦<< "\n"
40 ¦ ¦ ¦<< " To browse a trace generated by a previous run:\n"
41 ¦ ¦ ¦<< " mu browse-trace file\n"
42 ¦ ¦ ¦;
43 return 0;
44 }
45
46
47
48
49 :(before "End Commandline Parsing")
50 char** arg = &argv[1];
51 while (argc > 1 && starts_with(*arg, "--")) {
52 if (false)
53 ¦ ;
54
55 else
56 ¦ cerr << "skipping unknown option " << *arg << '\n';
57 --argc; ++argv; ++arg;
58 }
59
60
61
62
63
64
65
66
67
68
69 :(code)
70 bool is_equal(char* s, const char* lit) {
71 return strncmp(s, lit, strlen(lit)) == 0;
72 }
73
74 bool starts_with(const string& s, const string& pat) {
75 string::const_iterator a=s.begin(), b=pat.begin();
76 for (; a!=s.end() && b!=pat.end(); ++a, ++b)
77 ¦ if (*a != *b) return false;
78 return b == pat.end();
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 :(before "End Includes")
138 #define SIZE(X) (assert((X).size() < (1LL<<(sizeof(int)*8-2))), static_cast<int>((X).size()))
139
140
141
142
143 :(before "atexit(teardown)")
144 initialize_signal_handlers();
145
146
147 :(code)
148
149 void initialize_signal_handlers() {
150 struct sigaction action;
151 bzero(&action, sizeof(action));
152 action.sa_sigaction = dump_and_exit;
153 sigemptyset(&action.sa_mask);
154 sigaction(SIGABRT, &action, NULL);
155 sigaction(SIGILL, &action, NULL);
156 }
157 void dump_and_exit(int sig, unused siginfo_t* dummy1, unused void* dummy2) {
158 switch (sig) {
159 ¦ case SIGABRT:
160 ¦ ¦ #ifndef __APPLE__
161 ¦ ¦ ¦ cerr << "SIGABRT: might be an integer overflow if it wasn't an assert() failure\n";
162 ¦ ¦ ¦ _Exit(1);
163 ¦ ¦ #endif
164 ¦ ¦ break;
165 ¦ case SIGILL:
166 ¦ ¦ #ifdef __APPLE__
167 ¦ ¦ ¦ cerr << "SIGILL: most likely caused by integer overflow\n";
168 ¦ ¦ ¦ _Exit(1);
169 ¦ ¦ #endif
170 ¦ ¦ break;
171 ¦ default:
172 ¦ ¦ break;
173 }
174 }
175 :(before "End Includes")
176 #include <signal.h>
177
178
179 :(before "atexit(teardown)")
180 feenableexcept(FE_OVERFLOW | FE_UNDERFLOW);
181
182
183
184
185
186
187 :(before "End Includes")
188 #include <fenv.h>
189 :(code)
190 #ifdef __APPLE__
191
192
193 int feenableexcept (unsigned int excepts) {
194 static fenv_t fenv;
195 unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
196 unsigned int old_excepts;
197 if (fegetenv(&fenv)) return -1;
198 old_excepts = fenv.__control & FE_ALL_EXCEPT;
199 fenv.__control &= ~new_excepts;
200 fenv.__mxcsr &= ~(new_excepts << 7);
201 return fesetenv(&fenv) ? -1 : old_excepts;
202 }
203 #endif
204
205
206 :(before "Globals")
207
208 template<typename T> typename T::mapped_type& get(T& map, typename T::key_type const& key) {
209 typename T::iterator iter(map.find(key));
210 assert(iter != map.end());
211 return iter->second;
212 }
213 template<typename T> typename T::mapped_type const& get(const T& map, typename T::key_type const& key) {
214 typename T::const_iterator iter(map.find(key));
215 assert(iter != map.end());
216 return iter->second;
217 }
218 template<typename T> typename T::mapped_type const& put(T& map, typename T::key_type const& key, typename T::mapped_type const& value) {
219 map[key] = value;
220 return map[key];
221 }
222 template<typename T> bool contains_key(T& map, typename T::key_type const& key) {
223 return map.find(key) != map.end();
224 }
225 template<typename T> typename T::mapped_type& get_or_insert(T& map, typename T::key_type const& key) {
226 return map[key];
227 }
228
229
230
231
232
233
234 :(code)
235 bool has_data(istream& in) {
236 return in && !in.eof();
237 }
238
239 :(before "End Includes")
240 #include <assert.h>
241
242 #include <iostream>
243 using std::istream;
244 using std::ostream;
245 using std::iostream;
246 using std::cin;
247 using std::cout;
248 using std::cerr;
249 #include <iomanip>
250
251 #include <string.h>
252 #include <string>
253 using std::string;
254
255 #define unused __attribute__((unused))