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 ¦ ¦ ¦<< " To see where a mu program is spending its time:\n"
40 ¦ ¦ ¦<< " mu --profile file_or_dir1 file_or_dir2 ...\n"
41 ¦ ¦ ¦<< " this slices and dices time spent in various profile.* output files\n"
42 ¦ ¦ ¦<< "\n"
43 ¦ ¦ ¦<< " To browse a trace generated by a previous run:\n"
44 ¦ ¦ ¦<< " mu browse-trace file\n"
45 ¦ ¦ ¦;
46 return 0;
47 }
48
49
50
51
52 :(before "End Commandline Parsing")
53 char** arg = &argv[1];
54 while (argc > 1 && starts_with(*arg, "--")) {
55 if (false)
56 ¦ ;
57
58 else
59 ¦ cerr << "skipping unknown option " << *arg << '\n';
60 --argc; ++argv; ++arg;
61 }
62
63
64
65
66
67
68
69
70
71
72 :(code)
73 bool is_equal(char* s, const char* lit) {
74 return strncmp(s, lit, strlen(lit)) == 0;
75 }
76
77 bool starts_with(const string& s, const string& pat) {
78 string::const_iterator a=s.begin(), b=pat.begin();
79 for (; a!=s.end() && b!=pat.end(); ++a, ++b)
80 ¦ if (*a != *b) return false;
81 return b == pat.end();
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
138
139
140 :(before "End Includes")
141 #define SIZE(X) (assert((X).size() < (1LL<<(sizeof(int)*8-2))), static_cast<int>((X).size()))
142
143
144
145
146 :(before "atexit(teardown)")
147 initialize_signal_handlers();
148
149
150 :(code)
151
152 void initialize_signal_handlers() {
153 struct sigaction action;
154 bzero(&action, sizeof(action));
155 action.sa_sigaction = dump_and_exit;
156 sigemptyset(&action.sa_mask);
157 sigaction(SIGABRT, &action, NULL);
158 sigaction(SIGILL, &action, NULL);
159 }
160 void dump_and_exit(int sig, unused siginfo_t* dummy1, unused void* dummy2) {
161 switch (sig) {
162 ¦ case SIGABRT:
163 ¦ ¦ #ifndef __APPLE__
164 ¦ ¦ ¦ cerr << "SIGABRT: might be an integer overflow if it wasn't an assert() failure\n";
165 ¦ ¦ ¦ _Exit(1);
166 ¦ ¦ #endif
167 ¦ ¦ break;
168 ¦ case SIGILL:
169 ¦ ¦ #ifdef __APPLE__
170 ¦ ¦ ¦ cerr << "SIGILL: most likely caused by integer overflow\n";
171 ¦ ¦ ¦ _Exit(1);
172 ¦ ¦ #endif
173 ¦ ¦ break;
174 ¦ default:
175 ¦ ¦ break;
176 }
177 }
178 :(before "End Includes")
179 #include <signal.h>
180
181
182 :(before "atexit(teardown)")
183 feenableexcept(FE_OVERFLOW | FE_UNDERFLOW);
184
185
186
187
188
189
190 :(before "End Includes")
191 #include <fenv.h>
192 :(code)
193 #ifdef __APPLE__
194
195
196 int feenableexcept (unsigned int excepts) {
197 static fenv_t fenv;
198 unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
199 unsigned int old_excepts;
200 if (fegetenv(&fenv)) return -1;
201 old_excepts = fenv.__control & FE_ALL_EXCEPT;
202 fenv.__control &= ~new_excepts;
203 fenv.__mxcsr &= ~(new_excepts << 7);
204 return fesetenv(&fenv) ? -1 : old_excepts;
205 }
206 #endif
207
208
209 :(before "Globals")
210
211 template<typename T> typename T::mapped_type& get(T& map, typename T::key_type const& key) {
212 typename T::iterator iter(map.find(key));
213 assert(iter != map.end());
214 return iter->second;
215 }
216 template<typename T> typename T::mapped_type const& get(const T& map, typename T::key_type const& key) {
217 typename T::const_iterator iter(map.find(key));
218 assert(iter != map.end());
219 return iter->second;
220 }
221 template<typename T> typename T::mapped_type const& put(T& map, typename T::key_type const& key, typename T::mapped_type const& value) {
222 map[key] = value;
223 return map[key];
224 }
225 template<typename T> bool contains_key(T& map, typename T::key_type const& key) {
226 return map.find(key) != map.end();
227 }
228 template<typename T> typename T::mapped_type& get_or_insert(T& map, typename T::key_type const& key) {
229 return map[key];
230 }
231
232
233
234
235
236
237 :(code)
238 bool has_data(istream& in) {
239 return in && !in.eof();
240 }
241
242 :(before "End Includes")
243 #include <assert.h>
244
245 #include <iostream>
246 using std::istream;
247 using std::ostream;
248 using std::iostream;
249 using std::cin;
250 using std::cout;
251 using std::cerr;
252 #include <iomanip>
253
254 #include <string.h>
255 #include <string>
256 using std::string;
257
258 #define unused __attribute__((unused))