1
2
3
4
5 :(scenarios run_mu_scenario)
6 :(scenario simple_filesystem)
7 scenario simple-filesystem [
8 local-scope
9 assume-resources [
10
11 [a] <- [
12 |a bc|
13 |de f|
14 ]
15
16 [b/c] <- []
17 [b/d] <- [
18 |xyz|
19 ]
20 ]
21 data:&:@:resource <- get *resources, data:offset
22 file1:resource <- index *data, 0
23 file1-name:text <- get file1, name:offset
24 10:@:char/raw <- copy *file1-name
25 file1-contents:text <- get file1, contents:offset
26 100:@:char/raw <- copy *file1-contents
27 file2:resource <- index *data, 1
28 file2-name:text <- get file2, name:offset
29 30:@:char/raw <- copy *file2-name
30 file2-contents:text <- get file2, contents:offset
31 40:@:char/raw <- copy *file2-contents
32 file3:resource <- index *data, 2
33 file3-name:text <- get file3, name:offset
34 50:@:char/raw <- copy *file3-name
35 file3-contents:text <- get file3, contents:offset
36 60:@:char/raw <- copy *file3-contents
37 memory-should-contain [
38 10:array:character <- [a]
39 100:array:character <- [a bc
40 de f
41 ]
42 30:array:character <- [b/c]
43 40:array:character <- []
44 50:array:character <- [b/d]
45 60:array:character <- [xyz
46 ]
47 ]
48 ]
49
50 :(scenario escaping_file_contents)
51 scenario escaping-file-contents [
52 local-scope
53 assume-resources [
54
55
56 [a] <- [
57 |x\\\\|yz|
58 ]
59 ]
60 data:&:@:resource <- get *resources, data:offset
61 file1:resource <- index *data, 0
62 file1-name:text <- get file1, name:offset
63 10:@:char/raw <- copy *file1-name
64 file1-contents:text <- get file1, contents:offset
65 20:@:char/raw <- copy *file1-contents
66 memory-should-contain [
67 10:array:character <- [a]
68 20:array:character <- [x|yz
69 ]
70 ]
71 ]
72
73 :(before "End Globals")
74 extern const int RESOURCES = next_predefined_global_for_scenarios(2);
75
76 :(before "End Special Scenario Variable Names(r)")
77 Name[r]["resources"] = RESOURCES;
78
79 :(before "End is_special_name Special-cases")
80 if (s == "resources") return true;
81 :(before "End Initialize Type Of Special Name In Scenario(r)")
82 if (r.namor: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */# print msg to screen if a != b, otherwise print "."
fn check-ints-equal _a: int, b: int, msg: (addr array byte) {
var a/eax: int <- copy _a
compare a, b
{
break-if-!=
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
return
}
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
count-test-failure
}
fn test-check-ints-equal {
check-ints-equal 0, 0, "abc"
}
fn check _a: boolean, msg: (addr array byte) {
var a/eax: int <- copy _a
compare a, 0/false
{
break-if-=
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
return
}
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
count-test-failure
}
fn check-not _a: boolean, msg: (addr array byte) {
var a/eax: int <- copy _a
compare a, 0/false
{
break-if-!=
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg
return
}
draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg
count-test-failure
}
n class="Constant">": assume-resources: file contents '" << contents << "' for filename '" << filename << "' must end with a ']'\n" << end();
163 break;
164 }
165 contents.erase(0, 1);
166 contents.erase(SIZE(contents)-1);
167 put(out, filename, munge_resources_contents(contents, filename, caller));
168 }
169 }
170
171 string munge_resources_contents(const string& data, const string& filename, const string& caller) {
172 if (data.empty()) return "";
173 istringstream in(data);
174 in >> std::noskipws;
175 skip_whitespace_and_comments(in);
176 ostringstream out;
177 while (true) {
178 if (!has_data(in)) break;
179 skip_whitespace(in);
180 if (!has_data(in)) break;
181 if (in.peek() != '|') {
182 raise << caller << ": assume-resources: file contents for filename '" << filename << "' must be delimited in '|'s\n" << end();
183 break;
184 }
185 in.get();
186 string line;
187 getline(in, line);
188 for (int i = 0; i < SIZE(line); ++i) {
189 if (line.at(i) == '|') break;
190 if (line.at(i) == '\\') {
191 ++i;
192 if (i == SIZE(line)) {
193 raise << caller << ": assume-resources: file contents can't end a line with '\\'\n" << end();
194 break;
195 }
196 }
197 out << line.at(i);
198 }
199
200 out << '\n';
201 }
202 return out.str();
203 }
204
205 void construct_resources_object(const map<string, string>& contents) {
206 int resources_data_address = allocate(SIZE(contents) * 4 + 1);
207 int curr = resources_data_address + 1 + 1;
208 for (map<string, string>::const_iterator p = contents.begin(); p != contents.end(); ++p) {
209 ++curr;
210 put(Memory, curr, new_mu_text(p->first));
211 trace("mem") << "storing file name " << get(Memory, curr) << " in location " << curr << end();
212 ++curr;
213 ++curr;
214 put(Memory, curr, new_mu_text(p->second));
215 trace("mem") << "storing file contents " << get(Memory, curr) << " in location " << curr << end();
216 ++curr;
217 }
218 curr = resources_data_address + 1;
219 put(Memory, curr, SIZE(contents));
220 trace("mem") << "storing resources size " << get(Memory, curr) << " in location " << curr << end();
221
222 int resources_address = allocate(size_of_resources());
223 curr = resources_address+1+1+1;
224 put(Memory, curr, resources_data_address);
225 trace("mem") << "storing resources data address " << resources_data_address << " in location " << curr << end();
226
227 put(Memory, RESOURCES+1, resources_address);
228 trace("mem") << "storing resources address " << resources_address << " in location " << RESOURCES << end();
229 }
230
231 int size_of_resources() {
232
233 static int result = 0;
234 if (result) return result;
235 assert(get(Type_ordinal, "resources"));
236 type_tree* type = new type_tree("resources");
237 result = size_of(type);
238 delete type;
239 return result;
240 }