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(reset)")
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, vestigial siginfo_t* dummy1, vestigial 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 or exception\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(reset)")
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
223 map.insert(std::make_pair(key, value)).first->second = value;
224 return value;
225 }
226 template<typename T> bool contains_key(T& map, typename T::key_type const& key) {
227 return map.find(key) != map.end();
228 }
229 template<typename T> typename T::mapped_type& get_or_insert(T& map, typename T::key_type const& key) {
230 return map[key];
231 }
232
233
234
235
236
237
238 :(code)
239 bool has_data(istream& in) {
240 return in && !in.eof();
241 }
242
243 :(before "End Includes")
244 #include <assert.h>
245
246 #include <iostream>
247 using std::istream;
248 using std::ostream;
249 using std::iostream;
250 using std::cin;
251 using std::cout;
252 using std::cerr;
253 #include <iomanip>
254
255 #include <string.h>
256 #include <string>
257 using std::string;
258
259 #define vestigial __attribute__((unused))
260
261 #include <algorithm>
262 using std::min;
263 using std::max;