asar coverage - build #264


src/asar/
File: src/asar/assembleblock.cpp
Date: 2025-02-28 06:49:25
Lines:
1332/1437
92.7%
Functions:
39/40
97.5%
Branches:
2149/3106
69.2%

Line Branch Exec Source
1 #include "addr2line.h"
2 #include "asar.h"
3 #include "assembleblock.h"
4 #include "asar_math.h"
5 #include "macro.h"
6 #include "platform/file-helpers.h"
7 #include "table.h"
8 #include "unicode.h"
9 #include <cinttypes>
10
11 #include "interface-shared.h"
12 #include "arch-shared.h"
13
14 int arch=arch_65816;
15
16 bool snespos_valid = false;
17 int snespos;
18 int realsnespos;
19 int startpos;
20 int realstartpos;
21
22 static bool mapper_set = false;
23 int label_counter = 0;
24
25 static int old_snespos;
26 static int old_startpos;
27 static int old_optimizeforbank;
28 static bool old_snespos_valid;
29 static int struct_base;
30 static string struct_name;
31 static string struct_parent;
32 static bool in_struct = false;
33 static bool in_sub_struct = false;
34 static bool static_struct = false;
35 static bool in_spcblock = false;
36
37 assocarr<snes_struct> structs;
38
39 static bool movinglabelspossible = false;
40
41 static bool disable_bank_cross_errors = false;
42 static bool check_half_banks_crossed = false;
43
44 int bytes;
45 static int freespaceuse=0;
46
47 static enum {
48 ratsmeta_ban,
49 ratsmeta_allow,
50 ratsmeta_used,
51 } ratsmetastate=ratsmeta_ban;
52
53 enum spcblock_type{
54 spcblock_nspc,
55 spcblock_custom
56 };
57
58 static struct spcblock_data{
59 unsigned int destination;
60 spcblock_type type;
61 string macro_name;
62
63 unsigned int size_address;
64 mapper_t old_mapper;
65 }spcblock;
66
67 437821 static inline void verifysnespos()
68 {
69
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 437821 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 219014 times.
437821 if (!snespos_valid)
70 {
71 asar_throw_error(0, error_type_block, error_id_missing_org);
72 snespos=0x008000;
73 realsnespos=0x008000;
74 startpos=0x008000;
75 realstartpos=0x008000;
76 snespos_valid = true;
77 }
78 437821 }
79
80 552 static int fixsnespos(int inaddr, int step)
81 {
82 // randomdude999: turns out it wasn't very reliable at all.
83 /* // RPG Hacker: No idea how reliable this is.
84 // Might not work with some of the more exotic mappers.
85 return pctosnes(snestopc(inaddr) + step); */
86
4/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 504 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 228 times.
552 if (mapper == lorom) {
87
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 84 times.
96 if ((inaddr&0xFFFF)+step > 0xFFFF) {
88 // bank crossed
89 12 return inaddr+step+0x8000;
90 }
91 84 return inaddr+step;
92
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
456 } else if (mapper == hirom) {
93 if ((inaddr&0x400000) == 0 && freespaceid == 0) {
94 // we shouldn't get here in pass 2 inside a freespace anyways i think
95 // system pages, need to account for low pages and stuff
96 if ((inaddr&0xFFFF)+step > 0xFFFF) {
97 return inaddr+step+0x8000;
98 }
99 }
100 return inaddr+step;
101
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
456 } else if (mapper == exlorom) {
102 // exlorom has no mirroring so this should work fine
103 return pctosnes(snestopc(inaddr)+step);
104
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
456 } else if (mapper == exhirom) {
105 // apparently exhirom is pretty similar to hirom after all
106 if ((inaddr&0x400000) == 0) {
107 // system pages, need to account for low pages and stuff
108 if ((inaddr&0xFFFF)+step > 0xFFFF) {
109 return inaddr+step+0x8000;
110 }
111 }
112 return inaddr+step;
113
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
456 } else if (mapper == sa1rom) {
114 if((inaddr&0x400000) == 0) {
115 // lorom area
116 if ((inaddr&0xFFFF)+step > 0xFFFF) {
117 return inaddr+step+0x8000;
118 }
119 return inaddr+step;
120 } else {
121 // hirom area
122 return inaddr+step;
123 }
124
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
456 } else if (mapper == sfxrom) {
125 if ((inaddr&0x400000) == 0) {
126 // lorom area
127 if ((inaddr&0xFFFF)+step > 0xFFFF) {
128 return inaddr+step+0x8000;
129 }
130 } else {
131 // hirom area
132 return inaddr+step;
133 }
134
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
456 } else if (mapper == bigsa1rom) {
135 // no mirrors here, so this should work
136 return pctosnes(snestopc(inaddr)+step);
137
3/4
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 228 times.
✓ Branch 2 taken 228 times.
✗ Branch 3 not taken.
456 } else if (mapper == norom) {
138 456 return inaddr+step;
139 }
140 return -1;
141 }
142
143 437338 static inline void step(int num)
144 {
145
4/4
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 437200 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 218621 times.
437338 if (disable_bank_cross_errors)
146 {
147 276 snespos = fixsnespos(snespos, num);
148 276 realsnespos = fixsnespos(realsnespos, num);
149
150 // RPG Hacker: Not adjusting startpos here will eventually throw
151 // an error in checkbankcross() if we set warn bankcross on again.
152 // As far as I can tell, those are pretty much just used for
153 // checking bank crossing, anyways, so it's hopefully save to just
154 // adjust them here.
155 276 startpos = snespos;
156 276 realstartpos = realsnespos;
157 }
158 else
159 {
160 437062 snespos += num;
161 437062 realsnespos += num;
162 }
163 437338 bytes+=num;
164 437338 }
165
166 436738 void write1(unsigned int num)
167 {
168 436738 verifysnespos();
169
2/2
✓ Branch 0 taken 145556 times.
✓ Branch 1 taken 291182 times.
436738 if (pass==2)
170 {
171 145556 int pcpos=snestopc(realsnespos&0xFFFFFF);
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 145556 times.
145556 if (pcpos<0)
173 {
174 movinglabelspossible=true;
175 asar_throw_error(2, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex((unsigned int)realsnespos, 6).data());
176 }
177 145556 writeromdata_byte(pcpos, (unsigned char)num, freespaceid != 0);
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 145556 times.
145556 if (pcpos>=romlen) {
179 if(pcpos - romlen > 0) writeromdata_bytes(romlen, freespacebyte, pcpos - romlen, false);
180 romlen=pcpos+1;
181 }
182 }
183
4/4
✓ Branch 0 taken 145590 times.
✓ Branch 1 taken 291148 times.
✓ Branch 2 taken 9136 times.
✓ Branch 3 taken 136454 times.
436738 if(pass == 1 && freespaceid == 0) {
184 9136 int pcpos = snestopc(realsnespos & 0xFFFFFF);
185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9136 times.
9136 if(pcpos < 0)
186 {
187 movinglabelspossible=true;
188 asar_throw_error(2, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex((unsigned int)realsnespos, 6).data());
189 }
190 9136 addromwrite(pcpos, 1);
191
2/2
✓ Branch 0 taken 8719 times.
✓ Branch 1 taken 417 times.
9136 if (pcpos>=romlen) {
192
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 8633 times.
8719 if(pcpos - romlen > 0) writeromdata_bytes(romlen, freespacebyte, pcpos - romlen, false);
193 8719 romlen=pcpos+1;
194 }
195 }
196 436738 step(1);
197 436738 ratsmetastate=ratsmeta_ban;
198 436738 }
199
200 26559 static bool asblock_pick(char** word, int numwords)
201 {
202
6/6
✓ Branch 0 taken 24213 times.
✓ Branch 1 taken 2346 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 24198 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 11394 times.
26559 if (arch==arch_spc700 || in_spcblock) return asblock_spc700(word, numwords);
203
2/2
✓ Branch 0 taken 20529 times.
✓ Branch 1 taken 3654 times.
24183 if (arch==arch_65816) return asblock_65816(word, numwords);
204
1/2
✓ Branch 0 taken 3654 times.
✗ Branch 1 not taken.
3654 if (arch==arch_superfx) return asblock_superfx(word, numwords);
205 return true;
206 }
207
208 6515 const char * safedequote(char * str)
209 {
210 6515 const char * tmp=dequote(str);
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6515 times.
6515 if (!tmp) asar_throw_error(0, error_type_block, error_id_garbage_near_quoted_string);
212 6515 return tmp;
213 }
214
215 1849 void write2(unsigned int num)
216 {
217 1849 write1(num);
218 1849 write1(num/256);
219 1849 }
220
221 1198 void write3(unsigned int num)
222 {
223 1198 write1(num);
224 1198 write1(num/256);
225 1198 write1(num/65536);
226 1198 }
227
228 114 void write4(unsigned int num)
229 {
230 114 write1(num);
231 114 write1(num/256);
232 114 write1(num/65536);
233 114 write1(num/16777216);
234 114 }
235
236 //these are NOT used by the math parser - see asar_math.cpp for that
237 22 static int read2(int insnespos)
238 {
239 22 int addr=snestopc(insnespos);
240
2/4
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
22 if (addr<0 || addr+2>romlen_r) return -1;
241 return
242 22 romdata_r[addr ] |
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
33 (romdata_r[addr+1]<< 8);
244 }
245
246 54 static int read3(int insnespos)
247 {
248 54 int addr=snestopc(insnespos);
249
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
54 if (addr<0 || addr+3>romlen_r) return -1;
250 return
251 54 romdata_r[addr ] |
252 81 (romdata_r[addr+1]<< 8)|
253
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
81 (romdata_r[addr+2]<<16);
254 }
255
256 1452 int getlenfromchar(char c)
257 {
258 1452 c=(char)to_lower(c);
259
2/2
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 792 times.
1452 if (c=='b') return 1;
260
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 102 times.
792 if (c=='w') return 2;
261
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 6 times.
102 if (c=='l') return 3;
262 6 asar_throw_error(0, error_type_block, error_id_invalid_opcode_length);
263 }
264
265 assocarr<snes_label> labels;
266 static autoarray<int> poslabels;
267 static autoarray<int> neglabels;
268
269 autoarray<int>* macroposlabels;
270 autoarray<int>* macroneglabels;
271
272 autoarray<string> sublabels;
273 autoarray<string>* macrosublabels;
274
275 // randomdude999: ns is still the string to prefix to all labels, it's calculated whenever namespace_list is changed
276 string ns;
277 static string ns_backup;
278 autoarray<string> namespace_list;
279
280 autoarray<string> includeonce;
281
282 autoarray<freespace_data> freespaces;
283
284 // id of the next unused freespace.
285 static int freespaceidnext;
286 // id of the current freespace, or 0 if not in freespace.
287 int freespaceid;
288 // start address of the current freespace, used for computing the length of the
289 // current freespace.
290 static int freespacestart;
291 static freespace_data default_freespace_settings;
292
293 2534 bool confirmname(const char * name)
294 {
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2534 times.
2534 if (!name[0]) return false;
296
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 1922 times.
2534 if (is_digit(name[0])) return false;
297
2/2
✓ Branch 0 taken 15826 times.
✓ Branch 1 taken 1916 times.
17742 for (int i=0;name[i];i++)
298 {
299
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15820 times.
15826 if (!is_ualnum(name[i])) return false;
300 }
301 1916 return true;
302 }
303
304 48913 string posneglabelname(const char ** input, bool define)
305 {
306 48913 const char* label = *input;
307
308 48913 string output;
309
310 48913 int depth = 0;
311 48913 bool ismacro = false;
312
313
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 48867 times.
48913 if (label[0] == '?')
314 {
315 46 ismacro = true;
316 46 label++;
317 }
318
4/4
✓ Branch 0 taken 48844 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 139 times.
✓ Branch 3 taken 48705 times.
48913 if (label[0] == '-' || label[0] == '+')
319 {
320 208 char first = label[0];
321
4/4
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 208 times.
✓ Branch 3 taken 70 times.
416 for (depth = 0; label[0] && label[0] == first; depth++) label++;
322
323
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 16 times.
208 if (!ismacro)
324 {
325
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 61 times.
192 if (first == '+')
326 {
327 131 *input = label;
328
7/14
✓ Branch 0 taken 131 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 131 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 131 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 131 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 131 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 131 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 131 times.
✗ Branch 13 not taken.
131 output = STR":pos_" + dec(depth) + "_" + dec(poslabels[depth]);
329
3/4
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 105 times.
✗ Branch 3 not taken.
131 if (define) poslabels[depth]++;
330 }
331 else
332 {
333 61 *input = label;
334
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
61 if (define) neglabels[depth]++;
335
7/14
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 61 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 61 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 61 times.
✗ Branch 13 not taken.
61 output = STR":neg_" + dec(depth) + "_" + dec(neglabels[depth]);
336 }
337 }
338 else
339 {
340
3/6
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16 times.
16 if (macrorecursion == 0 || macroposlabels == nullptr || macroneglabels == nullptr)
341 {
342 if (!macrorecursion) asar_throw_error(0, error_type_block, error_id_macro_label_outside_of_macro);
343 }
344 else
345 {
346
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (first == '+')
347 {
348 8 *input = label;
349
10/20
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
8 output = STR":macro_" + dec(calledmacros) + "_pos_" + dec(depth) + "_" + dec((*macroposlabels)[depth]);
350
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
8 if (define) (*macroposlabels)[depth]++;
351 }
352 else
353 {
354 8 *input = label;
355
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
8 if (define) (*macroneglabels)[depth]++;
356
10/20
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
8 output = STR":macro_" + dec(calledmacros) + "_neg_" + dec(depth) + "_" + dec((*macroneglabels)[depth]);
357 }
358 }
359 }
360 }
361
362 48913 return output;
363 }
364
365 2581 string labelname(const char ** rawname, bool define)
366 {
367 #define deref_rawname (*rawname)
368 2581 autoarray<string>* sublabellist = &sublabels;
369
370 2581 bool ismacro = (deref_rawname[0] == '?');
371 2581 bool issublabel = false;
372
373
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2557 times.
2581 if (ismacro)
374 {
375 24 deref_rawname++;
376 24 sublabellist = macrosublabels;
377 }
378
379 2581 string name;
380 2581 int i=-1;
381
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2581 times.
2581 if (is_digit(*deref_rawname)) asar_throw_error(2, error_type_block, error_id_invalid_label_name);
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2581 times.
2581 if (*deref_rawname ==':')
384 {
385 deref_rawname++;
386 name=":";
387 }
388
7/8
✓ Branch 0 taken 1177 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 2371 times.
✓ Branch 3 taken 111 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1206 times.
✓ Branch 6 taken 1194 times.
✓ Branch 7 taken 12 times.
2581 else if (!in_struct && !in_sub_struct)
389 {
390
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 2359 times.
2459 for (i=0;(*deref_rawname =='.');i++) deref_rawname++;
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2359 times.
2359 if (!is_ualnum(*deref_rawname)) asar_throw_error(2, error_type_block, error_id_invalid_label_name);
392
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 2265 times.
2359 if (i)
393 {
394
4/8
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 94 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 94 times.
94 if (!sublabellist || !(*sublabellist)[i - 1]) asar_throw_error(2, error_type_block, error_id_label_missing_parent);
395
4/8
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 94 times.
✗ Branch 7 not taken.
94 name+=STR(*sublabellist)[i-1]+"_";
396 94 issublabel = true;
397 }
398 }
399
400
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2557 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 8 times.
2581 if (ismacro && !issublabel)
401 {
402 // RPG Hacker: Don't add the prefix for sublabels, because they already inherit it from
403 // their parents' names.
404
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
16 if (!macrorecursion || macrosublabels == nullptr) asar_throw_error(2, error_type_block, error_id_macro_label_outside_of_macro);
405
5/10
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
10 name = STR":macro_" + dec(calledmacros) + "_" + name;
406 }
407
408
409
7/8
✓ Branch 0 taken 1174 times.
✓ Branch 1 taken 1401 times.
✓ Branch 2 taken 1215 times.
✓ Branch 3 taken 1261 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1203 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 1191 times.
2575 if (in_struct || in_sub_struct)
410 {
411
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 210 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 99 times.
222 if(in_sub_struct)
412 {
413
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 name += struct_parent + ".";
414 }
415
1/2
✓ Branch 0 taken 222 times.
✗ Branch 1 not taken.
222 name += struct_name;
416
1/2
✓ Branch 0 taken 222 times.
✗ Branch 1 not taken.
222 name += '.';
417
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 216 times.
222 if(*deref_rawname != '.') asar_throw_error(2, error_type_block, error_id_invalid_label_name); //probably should be a better error. TODO!!!
418 216 deref_rawname++;
419 }
420
421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2569 times.
2569 if (!is_ualnum(*deref_rawname)) asar_throw_error(2, error_type_block, error_id_invalid_label_name);
422
423
6/6
✓ Branch 0 taken 2805 times.
✓ Branch 1 taken 17504 times.
✓ Branch 2 taken 236 times.
✓ Branch 3 taken 2569 times.
✓ Branch 4 taken 17740 times.
✓ Branch 5 taken 2569 times.
20309 while (is_ualnum(*deref_rawname) || *deref_rawname == '.')
424 {
425
1/2
✓ Branch 0 taken 17740 times.
✗ Branch 1 not taken.
17740 name+=*(deref_rawname++);
426 }
427
428
4/4
✓ Branch 0 taken 957 times.
✓ Branch 1 taken 1612 times.
✓ Branch 2 taken 741 times.
✓ Branch 3 taken 216 times.
2569 if (define && i>=0)
429 {
430 741 (*sublabellist).reset(i);
431
2/4
✓ Branch 0 taken 741 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 741 times.
✗ Branch 3 not taken.
741 (*sublabellist)[i]=name;
432 }
433 2569 return name;
434 #undef deref_rawname
435 12 }
436
437 200 static inline bool labelvalcore(const char ** rawname, snes_label * rval, bool define, bool shouldthrow)
438 {
439
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 string name=labelname(rawname, define);
440
10/22
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 198 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 198 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 198 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 102 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
200 if (ns && labels.exists(ns+name)) {*rval = labels.find(ns+name);}
441
4/6
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 170 times.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 170 times.
✗ Branch 5 not taken.
200 else if (labels.exists(name)) {*rval = labels.find(name);}
442 else
443 {
444
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 22 times.
30 if (shouldthrow && pass)
445 {
446 2 asar_throw_error(2, error_type_block, error_id_label_not_found, name.data());
447 }
448 28 rval->pos = (unsigned int)-1;
449 28 rval->freespace_id = 0;
450 28 rval->is_static = false;
451 28 return false;
452 }
453 170 return true;
454 200 }
455
456 172 snes_label labelval(const char ** rawname, bool define)
457 {
458 172 snes_label rval;
459
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2 times.
172 labelvalcore(rawname, &rval, define, true);
460 170 return rval;
461 }
462
463 16 snes_label labelval(string name, bool define)
464 {
465 16 const char * rawname=name;
466 16 snes_label rval;
467
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 labelvalcore(&rawname, &rval, define, true);
468 32 return rval;
469 }
470
471 bool labelval(const char ** rawname, snes_label * rval, bool define)
472 {
473 return labelvalcore(rawname, rval, define, false);
474 }
475
476 12 bool labelval(string name, snes_label * rval, bool define)
477 {
478 12 const char * str=name;
479
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 return labelvalcore(&str, rval, define, false);
480 }
481
482 1296 static void setlabel(string name, int loc=-1, bool is_static=false)
483 {
484 1296 int lbl_fs_id = 0;
485
2/2
✓ Branch 0 taken 1077 times.
✓ Branch 1 taken 219 times.
1296 if (loc==-1)
486 {
487
1/2
✓ Branch 0 taken 1077 times.
✗ Branch 1 not taken.
1077 verifysnespos();
488 1077 loc = snespos;
489 // if base is not active:
490
2/2
✓ Branch 0 taken 837 times.
✓ Branch 1 taken 240 times.
1077 if(snespos == realsnespos) lbl_fs_id = freespaceid;
491 // if base is active, always treat the label as freespace 0, i.e. not freespace.
492 }
493
494 1296 snes_label label_data;
495 1296 label_data.pos = (unsigned int)loc;
496 1296 label_data.is_static = is_static;
497 1296 label_data.freespace_id = lbl_fs_id;
498
499 unsigned int labelpos;
500
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 864 times.
1296 if (pass==0)
501 {
502
3/4
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 430 times.
432 if (labels.exists(name))
503 {
504 2 movinglabelspossible=true;
505 2 asar_throw_error(0, error_type_block, error_id_label_redefined, name.data());
506 }
507
1/2
✓ Branch 0 taken 430 times.
✗ Branch 1 not taken.
430 labels.create(name) = label_data;
508 }
509
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 432 times.
864 else if (pass==1)
510 {
511
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 labels.create(name) = label_data;
512 }
513
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 else if (pass==2)
514 {
515 //all label locations are known at this point, add a sanity check
516
2/4
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 432 times.
432 if (!labels.exists(name)) asar_throw_error(2, error_type_block, error_id_internal_error, "label created on 3rd pass");
517
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 labelpos = labels.find(name).pos;
518
5/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 428 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
432 if ((int)labelpos != loc && !movinglabelspossible)
519 {
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if((unsigned int)loc>>16 != labelpos>>16) asar_throw_error(2, error_type_block, error_id_label_ambiguous, name.raw());
521
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 else if(labelpos == (dp_base + 0xFFu)) asar_throw_error(2, error_type_block, error_id_label_ambiguous, name.raw());
522
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 else if(errored) return;
523 else asar_throw_error(2, error_type_block, error_id_internal_error, "moving label");
524 }
525 }
526 }
527
528 table thetable;
529 static autoarray<table> tablestack;
530
531 826 static void cleartable()
532 {
533
2/4
✓ Branch 0 taken 826 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 826 times.
✗ Branch 3 not taken.
826 thetable = table();
534 826 }
535
536 struct pushable {
537 int arch;
538 int snespos;
539 int snesstart;
540 int snesposreal;
541 int snesstartreal;
542 int freeid;
543 int freest;
544 int arch1;
545 int arch2;
546 int arch3;
547 int arch4;
548 };
549 static autoarray<pushable> pushpc;
550 static int pushpcnum;
551
552 static autoarray<int> basestack;
553 static int basestacknum;
554
555 struct ns_pushable {
556 string ns;
557 autoarray<string> namespace_list;
558 bool nested_namespaces;
559 };
560
561 static autoarray<ns_pushable> pushns;
562 static int pushnsnum;
563
564
565 static unsigned char fillbyte[12];
566 static unsigned char padbyte[12];
567
568 static bool nested_namespaces = false;
569
570 46694 void checkbankcross()
571 {
572
4/4
✓ Branch 0 taken 4753 times.
✓ Branch 1 taken 41941 times.
✓ Branch 2 taken 4828 times.
✓ Branch 3 taken 18699 times.
46694 if (!snespos_valid) return;
573
4/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 36924 times.
✓ Branch 2 taken 189 times.
✓ Branch 3 taken 18510 times.
37113 if (disable_bank_cross_errors) return;
574
4/4
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 36589 times.
✓ Branch 2 taken 146 times.
✓ Branch 3 taken 18364 times.
36735 unsigned int mask = 0x7FFF0000 | (check_half_banks_crossed ? 0x8000 : 0);
575
4/4
✓ Branch 0 taken 591 times.
✓ Branch 1 taken 36144 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 587 times.
36735 if (((snespos^startpos) & mask) && (((snespos - 1) ^ startpos) & mask))
576 {
577 4 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, snespos);
578 }
579 // don't verify realsnespos when using norom. this allows making custom mappers where the file layout doesn't follow bank borders
580
7/8
✓ Branch 0 taken 18082 times.
✓ Branch 1 taken 18649 times.
✓ Branch 2 taken 18614 times.
✓ Branch 3 taken 17976 times.
✓ Branch 4 taken 301 times.
✓ Branch 5 taken 18313 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 301 times.
36731 else if (mapper != norom && ((realsnespos^realstartpos) & mask) && (((realsnespos - 1) ^ realstartpos) & mask))
581 {
582 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, realsnespos);
583 }
584 }
585
586 3279 static void freespaceend()
587 {
588
2/2
✓ Branch 0 taken 1572 times.
✓ Branch 1 taken 1707 times.
3279 if (freespaceid > 0)
589 {
590 1572 freespaces[freespaceid].len = realsnespos-freespacestart;
591 1572 snespos=(int)0xFFFFFFFF;
592 1572 snespos_valid = false;
593 }
594 3279 freespaceid = 0;
595 3279 }
596
597 2490 static void adddefine(const string & key, string & value)
598 {
599
1/2
✓ Branch 0 taken 2490 times.
✗ Branch 1 not taken.
2490 if (!defines.exists(key)) defines.create(key) = value;
600 2490 }
601
602 820 void initstuff()
603 {
604
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 540 times.
820 if (pass==0)
605 {
606 280 freespaces.reset();
607 280 movinglabelspossible = false;
608 280 found_rats_tags_initialized = false;
609 280 found_rats_tags.clear();
610 }
611 820 arch=arch_65816;
612 820 mapper=lorom;
613 820 mapper_set = false;
614 820 calledmacros = 0;
615 820 reallycalledmacros = 0;
616 820 macrorecursion = 0;
617 820 defines.reset();
618 820 builtindefines.each(adddefine);
619 820 clidefines.each(adddefine);
620 820 ns="";
621 820 namespace_list.reset();
622 820 sublabels.reset();
623 820 poslabels.reset();
624 820 neglabels.reset();
625 820 macroposlabels = nullptr;
626 820 macroneglabels = nullptr;
627 820 macrosublabels = nullptr;
628 820 cleartable();
629 820 pushpc.reset();
630 820 pushpcnum=0;
631 820 pushns.reset();
632 820 pushnsnum = 0;
633 820 bytes=0;
634 820 freespaceuse=0;
635
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 458 times.
820 memset(fillbyte, 0, sizeof(fillbyte));
636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 458 times.
820 memset(padbyte, 0, sizeof(padbyte));
637 820 snespos_valid = false;
638 820 snespos=(int)0xFFFFFFFF;
639 820 realsnespos= (int)0xFFFFFFFF;
640 820 startpos= (int)0xFFFFFFFF;
641 820 realstartpos= (int)0xFFFFFFFF;
642 820 freespaceidnext=1;
643 820 freespaceid=0;
644 820 freespacebyte=0x00;
645 820 incsrcdepth = 0;
646
647 820 optimizeforbank = -1;
648 820 optimize_dp = optimize_dp_flag::ALWAYS;
649 820 dp_base = 0;
650 820 optimize_address = optimize_address_flag::MIRRORS;
651
652 820 in_struct = false;
653 820 in_sub_struct = false;
654 820 in_spcblock = false;
655
656 820 disable_bank_cross_errors = false;
657 820 check_half_banks_crossed = false;
658 820 nested_namespaces = false;
659
660 820 includeonce.reset();
661
662 extern AddressToLineMapping addressToLineMapping;
663 820 addressToLineMapping.reset();
664
665 820 push_warnings(false);
666
667 820 initmathcore();
668
669 1278 default_freespace_settings = {};
670 820 default_freespace_settings.bank = -3;
671 820 default_freespace_settings.search_start = -1;
672 820 default_freespace_settings.write_rats = true;
673 // rest are initialized to false/0/empty string
674
675 820 callstack.reset();
676 #if defined(_WIN32) || !defined(NO_USE_THREADS)
677 820 init_stack_use_check();
678 #endif
679 820 }
680
681 1572 static void parse_freespace_arguments(freespace_data& thisfs, string& arguments) {
682
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1362 times.
1572 if(arguments == "") return;
683
1/2
✓ Branch 0 taken 1362 times.
✗ Branch 1 not taken.
1362 autoptr<char**> pars=split(arguments.temp_raw(), ',');
684
685
2/2
✓ Branch 0 taken 1380 times.
✓ Branch 1 taken 1362 times.
2742 for (int i=0;pars[i];i++)
686 {
687
3/4
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 690 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1380 times.
1380 if (!stricmp(pars[i], "ram")) { thisfs.bank = -2; }
688
4/4
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 690 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1374 times.
1380 else if (!stricmp(pars[i], "noram")) { thisfs.bank = -1; }
689
4/4
✓ Branch 0 taken 687 times.
✓ Branch 1 taken 687 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1362 times.
1374 else if (!stricmp(pars[i], "static")) { thisfs.is_static = true; }
690
3/4
✓ Branch 0 taken 681 times.
✓ Branch 1 taken 681 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1362 times.
1362 else if (!stricmp(pars[i], "nostatic")) { thisfs.is_static = false; }
691
4/4
✓ Branch 0 taken 681 times.
✓ Branch 1 taken 681 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1350 times.
1362 else if (!stricmp(pars[i], "align")) { thisfs.flag_align = true; }
692
3/4
✓ Branch 0 taken 675 times.
✓ Branch 1 taken 675 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1350 times.
1350 else if (!stricmp(pars[i], "noalign")) { thisfs.flag_align = false; }
693
4/4
✓ Branch 0 taken 675 times.
✓ Branch 1 taken 675 times.
✓ Branch 2 taken 1272 times.
✓ Branch 3 taken 78 times.
1350 else if (!stricmp(pars[i], "cleaned")) { thisfs.flag_cleaned = true; }
694
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
78 else if (!stricmp(pars[i], "nocleaned")) { thisfs.flag_cleaned = false; }
695
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
78 else if (!stricmp(pars[i], "rats")) { thisfs.write_rats = true; }
696
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
78 else if (!stricmp(pars[i], "norats")) { thisfs.write_rats = false; }
697
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
78 else if (!stricmp(pars[i], "bankcross")) { thisfs.allow_bankcross = true; }
698
3/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
78 else if (!stricmp(pars[i], "nobankcross")) { thisfs.allow_bankcross = false; }
699
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 48 times.
78 else if (stribegin(pars[i], "bank="))
700 {
701
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 thisfs.bank = getnum(pars[i] + 5);
702
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
30 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
703 }
704
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 else if (stribegin(pars[i], "start="))
705 {
706
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 thisfs.search_start = getnum(pars[i] + 6);
707
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
708 }
709
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 else if (stribegin(pars[i], "pin="))
710 {
711 // TODO: should we handle posneg labels here too?
712
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 string pin_to = pars[i] + 4;
713 24 const char* pin_to_c = pin_to.data();
714
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 thisfs.pin_target = labelname(&pin_to_c);
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if(*pin_to_c) asar_throw_error(0, error_type_block, error_id_invalid_label_name);
716 // this is to throw an "undefined label" error with the proper callstack
717
4/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
24 if(pass) labelval(pin_to);
718
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 thisfs.pin_target_ns = ns;
719 24 }
720 else asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
721 }
722 1362 }
723
724 530 static int get_freespace_pin_target(int target_id) {
725 // union-find algorithm
726
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 530 times.
534 while(freespaces[target_id].pin_target_id != target_id) {
727 // i love programming
728 6 freespaces[target_id].pin_target_id =
729 4 freespaces[freespaces[target_id].pin_target_id].pin_target_id;
730 4 target_id = freespaces[target_id].pin_target_id;
731 }
732 530 return target_id;
733 }
734
735 270 static void resolve_pinned_freespaces() {
736
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 270 times.
792 for(int i = 1; i < freespaces.count; i++)
737 // default to everyone being in a separate component
738 522 freespaces[i].pin_target_id = i;
739
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 270 times.
792 for(int i = 1; i < freespaces.count; i++) {
740
1/2
✓ Branch 0 taken 522 times.
✗ Branch 1 not taken.
522 freespace_data& fs = freespaces[i];
741
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 8 times.
522 if(fs.pin_target == "") continue;
742 8 snes_label value;
743
4/18
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
8 if(fs.pin_target_ns && labels.exists(fs.pin_target_ns + fs.pin_target))
744 value = labels.find(fs.pin_target_ns + fs.pin_target);
745
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 else if(labels.exists(fs.pin_target))
746
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 value = labels.find(fs.pin_target);
747 else continue; // the error for this is thrown in the freespace command during pass 2
748
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 fs.pin_target_id = get_freespace_pin_target(value.freespace_id);
749 8 fs.len = 0;
750 }
751 270 }
752
753 270 static void allocate_freespaces() {
754 // compute real size of all pinned freespace blocks
755
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 270 times.
792 for(int i = 1; i < freespaces.count; i++) {
756 522 freespace_data& fs = freespaces[i];
757 // just in case the pin target changed again or something
758 522 fs.pin_target_id = get_freespace_pin_target(fs.pin_target_id);
759 522 freespace_data& target = freespaces[fs.pin_target_id];
760 522 target.total_len += fs.len;
761 522 target.search_start = std::max(fs.search_start, target.search_start);
762 }
763
764
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 270 times.
792 for(int i = 1; i < freespaces.count; i++) {
765 522 freespace_data& fs = freespaces[i];
766
6/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 520 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 260 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
522 if(fs.is_static && fs.orgpos > 0) {
767 2 fs.pos = fs.orgpos;
768 2 continue;
769 }
770 // if this freespace is pinned to another one, set it later
771
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 514 times.
520 if(fs.pin_target_id != i) continue;
772 // TODO: possibly fancier align
773
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 257 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 257 times.
514 fs.pos = getsnesfreespace(fs.total_len, fs.bank, true, !fs.allow_bankcross, fs.flag_align, fs.write_rats, fs.search_start);
774 514 fs.used_len = fs.len;
775 }
776 // set pos for all pinned freespaces
777
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 270 times.
792 for(int i = 1; i < freespaces.count; i++) {
778 522 freespace_data& fs = freespaces[i];
779
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 6 times.
522 if(fs.pin_target_id == i) continue;
780 6 freespace_data& tgt = freespaces[fs.pin_target_id];
781 6 fs.pos = tgt.pos + tgt.used_len;
782 6 tgt.used_len += fs.len;
783 }
784
785 // relocate all labels that were in freespace to point them to their real location
786 270 labels.each([](const char * key, snes_label & val) {
787
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 340 times.
430 if(val.freespace_id != 0) {
788 90 val.pos += freespaces[val.freespace_id].pos;
789 }
790 430 });
791 270 }
792
793 810 void finishpass()
794 {
795 810 verify_warnings();
796 810 pull_warnings(false);
797
798
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 810 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 453 times.
810 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_missing_endspcblock);
799
6/8
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 453 times.
✓ Branch 2 taken 453 times.
✓ Branch 3 taken 357 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 453 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 453 times.
810 if (in_struct || in_sub_struct) asar_throw_error(0, error_type_null, error_id_struct_without_endstruct);
800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 810 times.
810 else if (pushpcnum) asar_throw_error(0, error_type_null, error_id_pushpc_without_pullpc);
801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 810 times.
810 else if (pushnsnum) asar_throw_error(0, error_type_null, error_id_pushns_without_pullns);
802 810 freespaceend();
803
804 810 deinitmathcore();
805
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 540 times.
810 if(pass == 0) {
806 270 resolve_pinned_freespaces();
807
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 270 times.
540 } else if(pass == 1) {
808 270 allocate_freespaces();
809 270 handle_cleared_rats_tags();
810 }
811 #if defined(_WIN32) || !defined(NO_USE_THREADS)
812 810 deinit_stack_use_check();
813 #endif
814 810 }
815
816 27159 static bool addlabel(const char * label, int pos=-1, bool global_label = false)
817 {
818
2/4
✓ Branch 0 taken 27159 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27159 times.
27159 if (!label[0] || label[0]==':') return false;//colons are reserved for special labels
819
820 27159 const char* posneglabel = label;
821
1/2
✓ Branch 0 taken 27159 times.
✗ Branch 1 not taken.
27159 string posnegname = posneglabelname(&posneglabel, true);
822
823
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 27033 times.
27159 if (posnegname.length() > 0)
824 {
825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (global_label) return false;
826
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
126 if (*posneglabel != '\0' && *posneglabel != ':') asar_throw_error(0, error_type_block, error_id_broken_label_definition);
827
2/4
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 126 times.
✗ Branch 3 not taken.
126 setlabel(posnegname, pos);
828 126 return true;
829 }
830
9/10
✓ Branch 0 taken 13743 times.
✓ Branch 1 taken 13290 times.
✓ Branch 2 taken 26061 times.
✓ Branch 3 taken 510 times.
✓ Branch 4 taken 26025 times.
✓ Branch 5 taken 36 times.
✓ Branch 6 taken 12312 times.
✓ Branch 7 taken 13713 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12312 times.
27033 if (label[strlen(label)-1]==':' || label[0]=='.' || label[0]=='?' || label[0] == '#')
831 {
832
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 999 times.
1011 if (!label[1]) return false;
833
10/12
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 957 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 21 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 18 times.
999 if(global_label && (in_struct || in_sub_struct || label[0]=='?')) return false;
834
835 993 bool define = true;
836
837
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 969 times.
993 if (label[0] == '#')
838 {
839 24 define = false;
840 24 label++;
841 }
842
843 // RPG Hacker: Also checking label[1] now, since it might be a macro sublabel.
844 // Also, apparently this here doesn't account for main labels. I guess because
845 // we don't even get here in the first place if they don't include a colon?
846
10/12
✓ Branch 0 taken 693 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 687 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 333 times.
✓ Branch 5 taken 354 times.
✓ Branch 6 taken 348 times.
✓ Branch 7 taken 336 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 348 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 348 times.
993 bool requirecolon = (label[0] != '.' && label[1] != '.') && (in_struct || in_sub_struct);
847
2/2
✓ Branch 0 taken 981 times.
✓ Branch 1 taken 12 times.
993 string name=labelname(&label, define);
848
2/2
✓ Branch 0 taken 912 times.
✓ Branch 1 taken 69 times.
981 if (label[0]==':') label++;
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 else if (requirecolon) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
850
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 63 times.
69 else if (global_label) return false;
851
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 951 times.
975 if (label[0]) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
852
7/8
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 840 times.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 99 times.
✓ Branch 5 taken 852 times.
✓ Branch 6 taken 99 times.
✗ Branch 7 not taken.
951 if (ns && !global_label) name=ns+name;
853
15/16
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 405 times.
✓ Branch 3 taken 453 times.
✓ Branch 4 taken 75 times.
✓ Branch 5 taken 423 times.
✓ Branch 6 taken 477 times.
✓ Branch 7 taken 381 times.
✓ Branch 8 taken 463 times.
✓ Branch 9 taken 107 times.
✓ Branch 10 taken 75 times.
✓ Branch 11 taken 30 times.
✓ Branch 12 taken 486 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 484 times.
✓ Branch 15 taken 2 times.
955 setlabel(name, pos, ((in_struct || in_sub_struct) && static_struct));
854 947 return true;
855 981 }
856 26022 return false;
857 27159 }
858
859 15557 static void add_addr_to_line(int pos)
860 {
861
2/2
✓ Branch 0 taken 5493 times.
✓ Branch 1 taken 10064 times.
15557 if (pass == 2)
862 5493 addressToLineMapping.includeMapping(get_current_file_name(), get_current_line() + 1, pos);
863 15557 }
864
865 static autoarray<bool> elsestatus;
866 int numtrue=0;//if 1 -> increase both
867 int numif = 0; //if 0 or inside if 0 -> increase only numif
868
869 autoarray<whiletracker> whilestatus;
870
871
872 96 static void push_pc()
873 {
874 96 pushpc[pushpcnum].arch=arch;
875 96 pushpc[pushpcnum].snespos=snespos;
876 96 pushpc[pushpcnum].snesstart=startpos;
877 96 pushpc[pushpcnum].snesposreal=realsnespos;
878 96 pushpc[pushpcnum].snesstartreal=realstartpos;
879 96 pushpc[pushpcnum].freeid=freespaceid;
880 96 pushpc[pushpcnum].freest=freespacestart;
881 96 pushpcnum++;
882 96 }
883
884 96 static void pop_pc()
885 {
886 96 pushpcnum--;
887 96 snespos=pushpc[pushpcnum].snespos;
888 96 startpos=pushpc[pushpcnum].snesstart;
889 96 realsnespos=pushpc[pushpcnum].snesposreal;
890 96 realstartpos=pushpc[pushpcnum].snesstartreal;
891 96 freespaceid=pushpc[pushpcnum].freeid;
892 96 freespacestart=pushpc[pushpcnum].freest;
893 96 }
894
895
896 372 static string handle_print(char* input)
897 {
898 // evaluating this math can be unsafe in pass 0
899
3/4
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 244 times.
✗ Branch 3 not taken.
372 if(pass != 2) return "";
900 128 string out;
901
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 autoptr<char**> pars = qpsplit(input, ',');
902
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 verify_paren(pars);
903
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 120 times.
329 for (int i = 0; pars[i]; i++)
904 {
905 if (0);
906
4/6
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 150 times.
✗ Branch 5 not taken.
209 else if (pars[i][0] == '"') out += safedequote(pars[i]);
907
6/8
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 55 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
59 else if (!stricmp(pars[i], "bytes")) out += dec(bytes);
908
6/8
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
55 else if (!stricmp(pars[i], "freespaceuse")) out += dec(freespaceuse);
909
3/8
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
53 else if (!stricmp(pars[i], "pc")) out += hex((unsigned int)(snespos & 0xFFFFFF), 6);
910
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 28 times.
53 else if (!strncasecmp(pars[i], "bin(", strlen("bin(")) ||
911
4/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 15 times.
43 !strncasecmp(pars[i], "dec(", strlen("dec(")) ||
912
8/8
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 51 times.
✓ Branch 7 taken 2 times.
112 !strncasecmp(pars[i], "hex(", strlen("hex(")) ||
913
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 2 times.
16 !strncasecmp(pars[i], "double(", strlen("double(")))
914 {
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
51 char * arg1pos = strchr(pars[i], '(') + 1;
916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
51 char * endpos = strchr(arg1pos, '\0');
917
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 51 times.
102 while (*endpos == ' ' || *endpos == '\0') endpos--;
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (*endpos != ')') asar_throw_error(2, error_type_block, error_id_invalid_print_function_syntax);
919
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 string paramstr = string(arg1pos, (int)(endpos - arg1pos));
920
921 27 int numargs;
922
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 autoptr<char**> params = qpsplit(paramstr.temp_raw(), ',', &numargs);
923
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 verify_paren(params);
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (numargs > 2) asar_throw_error(2, error_type_block, error_id_wrong_num_parameters);
925 51 int precision = 0;
926 51 bool hasprec = numargs == 2;
927
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 25 times.
51 if (hasprec)
928 {
929
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 precision = getnum(params[1]);
930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (precision < 0) precision = 0;
931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (precision > 64) precision = 64;
932 }
933 51 *(arg1pos - 1) = '\0'; // allows more convenient comparsion functions
934
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 41 times.
51 if (!stricmp(pars[i], "bin"))
935 {
936 // sadly printf doesn't have binary, so let's roll our own
937
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 int64_t value = getnum(params[0]);
938 5 char buffer[65];
939
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
10 if (value < 0) {
940
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 out += '-';
941 2 value = -value;
942 // decrement precision because we've output one char already
943 2 precision -= 1;
944
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (precision<0) precision = 0;
945 }
946
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 10 times.
650 for (int j = 0; j < 64; j++) {
947
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320 times.
640 buffer[63 - j] = '0' + ((value & (1ull << j)) >> j);
948 }
949 10 buffer[64] = 0;
950 10 int startidx = 0;
951
4/4
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 574 times.
✓ Branch 3 taken 2 times.
584 while (startidx < 64 - precision && buffer[startidx] == '0') startidx++;
952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (startidx == 64) startidx--; // always want to print at least one digit
953
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 out += buffer + startidx;
954 }
955
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 26 times.
41 else if (!stricmp(pars[i], "dec"))
956 {
957
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 6 times.
15 int64_t value = getnum(params[0]);
958 5 char buffer[65];
959
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
9 snprintf(buffer, 65, "%0*" PRId64, precision, value);
960
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 out += buffer;
961 }
962
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 14 times.
26 else if (!stricmp(pars[i], "hex"))
963 {
964
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 int64_t value = getnum(params[0]);
965 7 char buffer[65];
966
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
12 snprintf(buffer, 65, "%0*" PRIX64, precision, value);
967
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 out += buffer;
968 }
969
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 else if (!stricmp(pars[i], "double"))
970 {
971
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 if (!hasprec) precision = 5;
972
3/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 out += ftostrvar(getnumdouble(params[0]), precision);
973 }
974 57 }
975 2 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
976 }
977 120 return out;
978 136 }
979
980 114 void handle_autoclean(string& arg, int checkbyte, int write_pos)
981 {
982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if(freespaceid > 0) asar_throw_error(0, error_type_block, error_id_autoclean_in_freespace);
983
984 114 const char* labeltest = arg.data();
985
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 snes_label lblval = labelval(&labeltest);
986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if (*labeltest) asar_throw_error(0, error_type_block, error_id_label_not_found, arg.data());
987 114 int num = lblval.pos;
988
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 auto& targetfs = freespaces[lblval.freespace_id];
989
990
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 60 times.
114 if (pass == 1) {
991 54 targetfs.leaked = false;
992
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6 times.
54 int orig_pos = read3(checkbyte != -1 ? write_pos+1 : write_pos);
993 54 int write_pos_pc = snestopc(write_pos);
994 54 targetfs.orgpos = targetfs.orglen = -1;
995
6/8
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 26 times.
54 if(write_pos_pc >= 0 && write_pos_pc < romlen_r && (checkbyte == -1 || romdata_r[write_pos_pc] == checkbyte)) {
996
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 int rats_loc = ratsstart(orig_pos);
997
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6 times.
28 if(rats_loc != -1) {
998 22 targetfs.orgpos = rats_loc + 8;
999 22 targetfs.orglen = read2(rats_loc + 4) + 1;
1000
5/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
22 if(!targetfs.is_static) removerats(rats_loc + 8, freespacebyte);
1001 }
1002 }
1003
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 6 times.
60 } else if(pass == 2) {
1004
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 int start = ratsstart(num);
1005
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
54 if(start >= num || start < 0) asar_throw_error(2, error_type_block, error_id_autoclean_label_at_freespace_end);
1006 }
1007 114 }
1008
1009 // single_line_for_tracker is:
1010 // 0 if not in first block of line, not in (single-line) for loop
1011 // 1 if first block of line
1012 // 2 if in single-line for loop
1013 // 3 if after endfor (of a single-line loop)
1014 51860 void assembleblock(const char * block, int& single_line_for_tracker)
1015 {
1016 #define is(test) (!stricmpwithlower(word[0], test))
1017 #define is0(test) (numwords==1 && !stricmpwithlower(word[0], test))
1018 #define is1(test) (numwords==2 && !stricmpwithlower(word[0], test))
1019 #define is2(test) (numwords==3 && !stricmpwithlower(word[0], test))
1020 #define is3(test) (numwords==4 && !stricmpwithlower(word[0], test))
1021 #define par word[1]
1022
1023
1/2
✓ Branch 0 taken 51860 times.
✗ Branch 1 not taken.
51860 callstack_push cs_push(callstack_entry_type::BLOCK, block);
1024
1025 25276 int numwords;
1026
1/2
✓ Branch 0 taken 51860 times.
✗ Branch 1 not taken.
51860 string splitblock = block;
1027
1/2
✓ Branch 0 taken 51860 times.
✗ Branch 1 not taken.
51860 char ** word = qsplit(splitblock.temp_raw(), ' ', &numwords);
1028 51860 autoptr<char **> scope_word = word;
1029 // when writing out the data for the addrToLine mapping,
1030 // we want to write out the snespos we had before writing opcodes
1031 51860 int addrToLinePos = realsnespos & 0xFFFFFF;
1032
1033
3/4
✓ Branch 0 taken 51860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16562 times.
✓ Branch 3 taken 35298 times.
51860 if (!word[0] || !word[0][0]) return;
1034
10/10
✓ Branch 0 taken 34776 times.
✓ Branch 1 taken 522 times.
✓ Branch 2 taken 34446 times.
✓ Branch 3 taken 330 times.
✓ Branch 4 taken 32520 times.
✓ Branch 5 taken 1926 times.
✓ Branch 6 taken 348 times.
✓ Branch 7 taken 32172 times.
✓ Branch 8 taken 3126 times.
✓ Branch 9 taken 32172 times.
35298 if (is("if") || is("elseif") || is("while") || is("for"))
1035 {
1036 3126 whiletracker wstatus;
1037
1/2
✓ Branch 0 taken 3126 times.
✗ Branch 1 not taken.
3126 wstatus.startline = get_current_line();
1038 3126 wstatus.iswhile = is("while");
1039 3126 wstatus.cond = false;
1040 3126 wstatus.is_for = false;
1041 3126 wstatus.for_start = wstatus.for_end = wstatus.for_cur = 0;
1042 3126 wstatus.for_has_var_backup = false;
1043
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 2778 times.
3126 if(is("for")) wstatus.is_for = true;
1044
1045 3126 bool is_for_cont = false;
1046 // if this is a for loop and a whilestatus entry already exists at this level,
1047 // and the for loop isn't finished, this is a continuation of the for loop
1048
6/8
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 348 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 166 times.
✓ Branch 5 taken 182 times.
✓ Branch 6 taken 166 times.
✓ Branch 7 taken 8 times.
3474 if (is("for") && whilestatus.count > numif && whilestatus[numif].is_for
1049
8/10
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 2778 times.
✓ Branch 2 taken 332 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 332 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 246 times.
✓ Branch 7 taken 86 times.
✓ Branch 8 taken 246 times.
✓ Branch 9 taken 2880 times.
3474 && whilestatus[numif].for_cur < whilestatus[numif].for_end)
1050 246 is_for_cont = true;
1051
5/8
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 2880 times.
✓ Branch 2 taken 246 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2880 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2880 times.
✗ Branch 7 not taken.
3126 whiletracker& addedwstatus = is_for_cont ? whilestatus[numif] : (whilestatus[numif] = wstatus);
1052 //handle nested if statements
1053
8/8
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 2790 times.
✓ Branch 2 taken 222 times.
✓ Branch 3 taken 114 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 174 times.
✓ Branch 6 taken 162 times.
✓ Branch 7 taken 2964 times.
3126 if (numtrue!=numif && !(is("elseif") && numtrue+1==numif))
1054 {
1055
8/8
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 114 times.
✓ Branch 7 taken 48 times.
162 if ((is("if") || is("while") || is("for"))) numif++;
1056 162 return;
1057 }
1058
8/8
✓ Branch 0 taken 2490 times.
✓ Branch 1 taken 474 times.
✓ Branch 2 taken 612 times.
✓ Branch 3 taken 1878 times.
✓ Branch 4 taken 330 times.
✓ Branch 5 taken 282 times.
✓ Branch 6 taken 2682 times.
✓ Branch 7 taken 282 times.
2964 if ((is("if") || is("while") || is("for"))) numif++;
1059
1060
2/2
✓ Branch 0 taken 5304 times.
✓ Branch 1 taken 2964 times.
8268 for(int i = 1; i < numwords - 1; i++)
1061 {
1062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2652 times.
5304 word[i][strlen(word[i])] = ' ';
1063 }
1064 2964 numwords = 2;
1065
1066 bool cond;
1067
2/2
✓ Branch 0 taken 2634 times.
✓ Branch 1 taken 330 times.
2964 if(!is("for"))
1068 {
1069
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2634 times.
2634 if(word[1] == NULL) asar_throw_error(0, error_type_block, error_id_broken_command, word[0], "Missing condition.");
1070
1/2
✓ Branch 0 taken 2634 times.
✗ Branch 1 not taken.
2634 cond = getnum(word[1]);
1071
7/8
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 2601 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 1299 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 15 times.
2634 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_in_conditional, word[0]);
1072 }
1073
1074
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 2598 times.
2928 if (is("for"))
1075 {
1076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 330 times.
330 if(word[1] == NULL) asar_throw_error(0, error_type_block, error_id_broken_command, word[0], "Missing loop range.");
1077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 330 times.
330 if(single_line_for_tracker != 1)
1078 {
1079 numif--;
1080 asar_throw_error(0, error_type_line, error_id_bad_single_line_for);
1081 }
1082
1083
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 246 times.
330 if(!is_for_cont)
1084 {
1085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
84 char* past_eq = strchr(word[1], '=');
1086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if(!past_eq)
1087 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "missing loop range");
1088
1089
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 string varname(word[1], past_eq - word[1]);
1090 84 past_eq += 1;
1091
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 strip_whitespace(varname);
1092
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 if(!validatedefinename(varname))
1093 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "invalid define name");
1094
1095
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 char* range_sep = strqpstr(past_eq, "..");
1096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if(!range_sep)
1097 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "invalid loop range");
1098
1099
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 string for_start(past_eq, range_sep - past_eq);
1100
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 strip_whitespace(for_start);
1101
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 string for_end(range_sep+2);
1102
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 strip_whitespace(for_end);
1103
1104
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_start = getnum(for_start);
1105
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
84 if(foundlabel && !foundlabel_static)
1106 asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1107
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_end = getnum(for_end);
1108
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
84 if(foundlabel && !foundlabel_static)
1109 asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1110
1111
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_variable = varname;
1112 84 addedwstatus.for_cur = addedwstatus.for_start;
1113 84 }
1114 246 else addedwstatus.for_cur++;
1115
1116 330 addedwstatus.cond = addedwstatus.for_cur < addedwstatus.for_end;
1117 330 single_line_for_tracker = 2;
1118
4/4
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 207 times.
✓ Branch 2 taken 123 times.
✓ Branch 3 taken 42 times.
330 if(addedwstatus.cond)
1119 {
1120 246 numtrue++;
1121
3/4
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
✓ Branch 3 taken 54 times.
246 if(defines.exists(addedwstatus.for_variable))
1122 {
1123 192 addedwstatus.for_has_var_backup = true;
1124
2/4
✓ Branch 0 taken 192 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
192 addedwstatus.for_var_backup = defines.find(addedwstatus.for_variable);
1125 }
1126
2/4
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 246 times.
✗ Branch 3 not taken.
246 defines.create(addedwstatus.for_variable) = ftostr(addedwstatus.for_cur);
1127 }
1128 }
1129
6/6
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 438 times.
✓ Branch 2 taken 1878 times.
✓ Branch 3 taken 282 times.
✓ Branch 4 taken 2316 times.
✓ Branch 5 taken 282 times.
2598 else if (is("if") || is("while"))
1130 {
1131 if(0);
1132
2/2
✓ Branch 0 taken 1884 times.
✓ Branch 1 taken 432 times.
2316 else if (cond)
1133 {
1134 1884 numtrue++;
1135
1/2
✓ Branch 0 taken 1884 times.
✗ Branch 1 not taken.
1884 elsestatus[numif]=true;
1136 }
1137
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 else if (!cond)
1138 {
1139
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 elsestatus[numif]=false;
1140 }
1141 2316 addedwstatus.cond = cond;
1142 }
1143
1/2
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
282 else if (is("elseif"))
1144 {
1145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 282 times.
282 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_elseif);
1146
3/6
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 282 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 141 times.
282 if (whilestatus[numif - 1].iswhile) asar_throw_error(1, error_type_block, error_id_elseif_in_while);
1147
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 174 times.
282 if (numif==numtrue) numtrue--;
1148
9/10
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 174 times.
✓ Branch 2 taken 108 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 78 times.
✓ Branch 7 taken 117 times.
✓ Branch 8 taken 39 times.
✓ Branch 9 taken 102 times.
282 if (cond && !elsestatus[numif])
1149 {
1150 78 numtrue++;
1151
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 elsestatus[numif]=true;
1152 }
1153 }
1154 2928 return;
1155 3126 }
1156
14/14
✓ Branch 0 taken 7110 times.
✓ Branch 1 taken 25062 times.
✓ Branch 2 taken 6588 times.
✓ Branch 3 taken 522 times.
✓ Branch 4 taken 6588 times.
✓ Branch 5 taken 25062 times.
✓ Branch 6 taken 4662 times.
✓ Branch 7 taken 1926 times.
✓ Branch 8 taken 4662 times.
✓ Branch 9 taken 25062 times.
✓ Branch 10 taken 348 times.
✓ Branch 11 taken 4314 times.
✓ Branch 12 taken 2796 times.
✓ Branch 13 taken 29376 times.
32172 else if (is0("endif") || is0("endwhile") || is0("endfor"))
1157 {
1158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2796 times.
2796 if (!numif)
1159 asar_throw_error(1, error_type_block, error_id_misplaced_endif);
1160
1/2
✓ Branch 0 taken 2796 times.
✗ Branch 1 not taken.
2796 whiletracker& thisws = whilestatus[numif - 1];
1161
1162
7/8
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 2361 times.
✓ Branch 2 taken 261 times.
✓ Branch 3 taken 1224 times.
✓ Branch 4 taken 261 times.
✓ Branch 5 taken 963 times.
✓ Branch 6 taken 261 times.
✗ Branch 7 not taken.
3846 if((!thisws.is_for && !thisws.iswhile && !is("endif")) ||
1163
9/10
✓ Branch 0 taken 2448 times.
✓ Branch 1 taken 348 times.
✓ Branch 2 taken 963 times.
✓ Branch 3 taken 1833 times.
✓ Branch 4 taken 1926 times.
✓ Branch 5 taken 435 times.
✓ Branch 6 taken 963 times.
✓ Branch 7 taken 1398 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1398 times.
8040 (thisws.iswhile && !is("endwhile")) ||
1164
5/6
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 2622 times.
✓ Branch 2 taken 174 times.
✓ Branch 3 taken 1398 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 174 times.
2796 (thisws.is_for && !is("endfor")))
1165 asar_throw_error(1, error_type_block, error_id_misplaced_endif);
1166
1167
2/2
✓ Branch 0 taken 2088 times.
✓ Branch 1 taken 708 times.
2796 if (numif==numtrue) numtrue--;
1168 2796 numif--;
1169
1170
4/4
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 2622 times.
✓ Branch 2 taken 174 times.
✓ Branch 3 taken 1224 times.
2796 if(thisws.is_for)
1171 {
1172
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 288 times.
348 if(single_line_for_tracker == 2) single_line_for_tracker = 3;
1173
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 174 times.
348 if(moreonline)
1174 {
1175 // sabotage the whilestatus to prevent the loop running again
1176 // and spamming more of the same error
1177 thisws.for_cur = thisws.for_end;
1178 thisws.cond = false;
1179 asar_throw_error(0, error_type_block, error_id_bad_single_line_for);
1180 }
1181
1182
4/4
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 225 times.
✓ Branch 2 taken 123 times.
✓ Branch 3 taken 51 times.
348 if(thisws.cond)
1183 {
1184
4/4
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 27 times.
246 if(thisws.for_has_var_backup)
1185
2/4
✓ Branch 0 taken 192 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
192 defines.create(thisws.for_variable) = thisws.for_var_backup;
1186 else
1187
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 defines.remove(thisws.for_variable);
1188 }
1189 }
1190 2796 return;
1191 }
1192
6/6
✓ Branch 0 taken 4314 times.
✓ Branch 1 taken 25062 times.
✓ Branch 2 taken 234 times.
✓ Branch 3 taken 4080 times.
✓ Branch 4 taken 234 times.
✓ Branch 5 taken 29142 times.
29376 else if (is0("else"))
1193 {
1194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 234 times.
234 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_else);
1195
9/14
✓ Branch 0 taken 234 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 117 times.
✓ Branch 4 taken 234 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 117 times.
✓ Branch 7 taken 117 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 234 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 117 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 117 times.
234 if (whilestatus[numif - 1].iswhile || whilestatus[numif - 1].is_for) asar_throw_error(1, error_type_block, error_id_else_in_while_loop);
1196
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 162 times.
234 else if (numif==numtrue) numtrue--;
1197
9/10
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 120 times.
✓ Branch 6 taken 60 times.
✓ Branch 7 taken 96 times.
✓ Branch 8 taken 30 times.
✓ Branch 9 taken 51 times.
162 else if (numif==numtrue+1 && !elsestatus[numif])
1198 {
1199 60 numtrue++;
1200
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 elsestatus[numif]=true;
1201 }
1202 234 return;
1203 }
1204
2/2
✓ Branch 0 taken 1770 times.
✓ Branch 1 taken 27372 times.
29142 else if (numif!=numtrue) return;
1205
1206
14/14
✓ Branch 0 taken 27642 times.
✓ Branch 1 taken 773 times.
✓ Branch 2 taken 24006 times.
✓ Branch 3 taken 3636 times.
✓ Branch 4 taken 12459 times.
✓ Branch 5 taken 11547 times.
✓ Branch 6 taken 25246 times.
✓ Branch 7 taken 284 times.
✓ Branch 8 taken 13361 times.
✓ Branch 9 taken 13736 times.
✓ Branch 10 taken 1043 times.
✓ Branch 11 taken 26671 times.
✓ Branch 12 taken 535 times.
✓ Branch 13 taken 12979 times.
28415 while (word[0] && (!word[1] || strcmp(word[1], "=")) && addlabel(word[0]))
1207 {
1208 1043 word++;
1209 1043 numwords--;
1210 }
1211
3/4
✓ Branch 0 taken 26559 times.
✓ Branch 1 taken 773 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 26559 times.
27332 if (!word[0] || !word[0][0]) return;
1212
1213 // recheck for any of the conditionals tested above
1214
3/6
✓ Branch 0 taken 26559 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26559 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 26559 times.
✗ Branch 5 not taken.
53118 if(is("if") || is("elseif") || is("while") || is("for")
1215
14/20
✓ Branch 0 taken 26559 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2823 times.
✓ Branch 3 taken 23736 times.
✓ Branch 4 taken 2823 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2823 times.
✓ Branch 7 taken 23736 times.
✓ Branch 8 taken 2823 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2823 times.
✓ Branch 11 taken 23736 times.
✓ Branch 12 taken 2823 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2823 times.
✓ Branch 15 taken 23736 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 2823 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 26559 times.
53118 || is0("endif") || is0("endwhile") || is0("endfor") || is0("else"))
1216 {
1217 asar_throw_error(0, error_type_block, error_id_label_before_if, word[0]);
1218 }
1219
4/4
✓ Branch 0 taken 26539 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 10081 times.
✓ Branch 3 taken 16458 times.
26559 else if (asblock_pick(word, numwords))
1220 {
1221
1/2
✓ Branch 0 taken 10081 times.
✗ Branch 1 not taken.
10081 add_addr_to_line(addrToLinePos);
1222 }
1223
12/12
✓ Branch 0 taken 15189 times.
✓ Branch 1 taken 1269 times.
✓ Branch 2 taken 11121 times.
✓ Branch 3 taken 4068 times.
✓ Branch 4 taken 11061 times.
✓ Branch 5 taken 60 times.
✓ Branch 6 taken 10461 times.
✓ Branch 7 taken 600 times.
✓ Branch 8 taken 96 times.
✓ Branch 9 taken 10365 times.
✓ Branch 10 taken 4824 times.
✓ Branch 11 taken 11634 times.
16458 else if (numwords > 1 && (is("db") || is("dw") || is("dl") || is("dd")))
1224 {
1225 4824 string line;
1226
2/2
✓ Branch 0 taken 4824 times.
✓ Branch 1 taken 4824 times.
9648 for(int i = 1; i < numwords; i++){
1227
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4824 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4824 if(i > 1) line += " ";
1228
1/2
✓ Branch 0 taken 4824 times.
✗ Branch 1 not taken.
4824 line += word[i];
1229 }
1230
1/2
✓ Branch 0 taken 4824 times.
✗ Branch 1 not taken.
4824 autoptr<char**> pars=qpsplit(line.temp_raw(), ',');
1231
1/2
✓ Branch 0 taken 4824 times.
✗ Branch 1 not taken.
4824 verify_paren(pars);
1232
1233 void (*do_write)(unsigned int);
1234 4824 char first = to_lower(word[0][1]);
1235
2/2
✓ Branch 0 taken 4068 times.
✓ Branch 1 taken 756 times.
4824 if (first == 'b') do_write = &write1;
1236
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 696 times.
756 else if (first == 'w') do_write = &write2;
1237
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 96 times.
696 else if (first == 'l') do_write = &write3;
1238 96 else do_write = &write4;
1239
1240
2/2
✓ Branch 0 taken 5670 times.
✓ Branch 1 taken 4802 times.
10472 for (int i=0;pars[i];i++)
1241 {
1242
2/2
✓ Branch 0 taken 225 times.
✓ Branch 1 taken 5445 times.
5670 if (pars[i][0]=='"')
1243 {
1244
1/2
✓ Branch 0 taken 225 times.
✗ Branch 1 not taken.
225 char * str=const_cast<char*>(safedequote(pars[i]));
1245 225 int codepoint = 0u;
1246
1/2
✓ Branch 0 taken 225 times.
✗ Branch 1 not taken.
225 str += utf8_val(&codepoint, str);
1247
3/4
✓ Branch 0 taken 918 times.
✓ Branch 1 taken 225 times.
✓ Branch 2 taken 918 times.
✗ Branch 3 not taken.
1143 while ( codepoint != 0 && codepoint != -1 )
1248 {
1249
2/4
✓ Branch 0 taken 918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 918 times.
✗ Branch 3 not taken.
918 do_write(thetable.get_val(codepoint));
1250
1/2
✓ Branch 0 taken 918 times.
✗ Branch 1 not taken.
918 str += utf8_val(&codepoint, str);
1251 }
1252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 225 times.
225 if (codepoint == -1) asar_throw_error(0, error_type_block, error_id_invalid_utf8);
1253 }
1254 else
1255 {
1256
5/6
✓ Branch 0 taken 1813 times.
✓ Branch 1 taken 3632 times.
✓ Branch 2 taken 1791 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 5423 times.
✗ Branch 5 not taken.
5445 do_write((pass==2)?getnum(pars[i]):0);
1257 }
1258 }
1259
1/2
✓ Branch 0 taken 4802 times.
✗ Branch 1 not taken.
4802 add_addr_to_line(addrToLinePos);
1260 4846 }
1261
2/2
✓ Branch 0 taken 258 times.
✓ Branch 1 taken 11376 times.
11634 else if (is("assert"))
1262 {
1263 258 string errmsg;
1264
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
258 if(numwords > 1) {
1265
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 258 times.
678 for(int i = 1; i < numwords - 1; i++)
1266 {
1267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
420 word[i][strlen(word[i])] = ' ';
1268 }
1269 258 numwords = 2;
1270
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
258 autoptr<char**> tokens = qpsplit(word[1], ',');
1271
1/2
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
258 verify_paren(tokens);
1272
5/6
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 228 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 228 times.
258 if (tokens[0] != NULL && tokens[1] != NULL)
1273 {
1274 30 size_t pos = 1;
1275
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 30 times.
102 while (tokens[pos])
1276 {
1277
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 errmsg += tokens[pos];
1278
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 30 times.
72 if (tokens[pos + 1] != NULL)
1279 {
1280
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 errmsg += ",";
1281 }
1282 72 pos++;
1283 }
1284 }
1285 258 }
1286
1287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 258 times.
258 if(word[1] == NULL) asar_throw_error(0, error_type_block, error_id_broken_command, "assert", "Missing condition.");
1288
2/2
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 54 times.
258 bool cond = getnum(word[1]);
1289
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 136 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 56 times.
204 if (pass == 2 && !cond)
1290 {
1291
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
36 if (errmsg) asar_throw_error(2, error_type_block, error_id_assertion_failed, (string(": ") + handle_print(errmsg.raw())).data());
1292 6 else asar_throw_error(2, error_type_block, error_id_assertion_failed, ".");
1293 }
1294 258 }
1295
2/2
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 10842 times.
11376 else if(word[0][0]=='%')
1296 {
1297
4/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 279 times.
✓ Branch 2 taken 267 times.
✓ Branch 3 taken 6 times.
534 callmacro(strchr(block, '%')+1);
1298 }
1299
6/6
✓ Branch 0 taken 9152 times.
✓ Branch 1 taken 1690 times.
✓ Branch 2 taken 120 times.
✓ Branch 3 taken 9032 times.
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 10722 times.
10842 else if (is1("undef"))
1300 {
1301
2/4
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
120 string def = safedequote(par);
1302
1303
3/4
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 6 times.
120 if (defines.exists(def))
1304 {
1305
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 defines.remove(def);
1306 }
1307 else
1308 {
1309 6 asar_throw_error(0, error_type_block, error_id_define_not_found, def.data());
1310 }
1311 120 }
1312
6/6
✓ Branch 0 taken 741 times.
✓ Branch 1 taken 9981 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 735 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 10716 times.
10722 else if (is0("error"))
1313 {
1314 6 asar_throw_error(0, error_type_block, error_id_error_command, ".");
1315 }
1316
6/6
✓ Branch 0 taken 735 times.
✓ Branch 1 taken 9981 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 729 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 10710 times.
10716 else if (is0("warn"))
1317 {
1318
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(2, warning_id_warn_command, ".");
1319 }
1320
6/6
✓ Branch 0 taken 9032 times.
✓ Branch 1 taken 1678 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 9017 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 10695 times.
10710 else if (is1("error"))
1321 {
1322
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 string out = handle_print(par);
1323 // RPG Hacker: This used to be on pass 0, which had its merits (you don't want to miss a potentially critical
1324 // user-generated error, just because a bazillion other errors are thrown in passes before it). However, I
1325 // don't see how to support print functions with this without moving it to pass 2. Suggestions are welcome.
1326
2/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
54 asar_throw_error(2, error_type_block, error_id_error_command, (string(": ") + out).data());
1327 15 }
1328
6/6
✓ Branch 0 taken 9017 times.
✓ Branch 1 taken 1678 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 8984 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 10662 times.
10695 else if (is1("warn"))
1329 {
1330
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 string out = handle_print(par);
1331
3/6
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
33 asar_throw_warning(2, warning_id_warn_command, (string(": ") + out).data());
1332 33 }
1333
6/6
✓ Branch 0 taken 8984 times.
✓ Branch 1 taken 1678 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 8936 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 10614 times.
10662 else if (is1("warnings"))
1334 {
1335
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 24 times.
48 if (stricmp(word[1], "push") == 0)
1336 {
1337
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 push_warnings();
1338 }
1339
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 else if (stricmp(word[1], "pull") == 0)
1340 {
1341
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 pull_warnings();
1342 }
1343 else
1344 {
1345 asar_throw_error(0, error_type_block, error_id_broken_command, "warnings", "Unknown parameter");
1346 }
1347 }
1348
6/6
✓ Branch 0 taken 877 times.
✓ Branch 1 taken 9737 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 793 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 10530 times.
10614 else if (is2("warnings"))
1349 {
1350
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 66 times.
84 if (stricmp(word[1], "enable") == 0)
1351 {
1352
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1353
1354
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (warnid != warning_id_end)
1355 {
1356
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 set_warning_enabled(warnid, true);
1357 }
1358 else
1359 {
1360
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(0, warning_id_invalid_warning_id, word[2], "warnings enable");
1361 }
1362 }
1363
3/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
66 else if (stricmp(word[1], "disable") == 0)
1364 {
1365
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1366
1367
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 12 times.
66 if (warnid != warning_id_end)
1368 {
1369
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 set_warning_enabled(warnid, false);
1370 }
1371 else
1372 {
1373
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 asar_throw_warning(0, warning_id_invalid_warning_id, word[2], "warnings disable");
1374 }
1375 }
1376 else
1377 {
1378 asar_throw_error(0, error_type_block, error_id_broken_command, "warnings", "Unknown parameter");
1379 }
1380 }
1381
6/6
✓ Branch 0 taken 8936 times.
✓ Branch 1 taken 1594 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 8894 times.
✓ Branch 4 taken 42 times.
✓ Branch 5 taken 10488 times.
10530 else if(is1("global"))
1382 {
1383
3/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 30 times.
42 if (!addlabel(word[1], -1, true))
1384 {
1385 12 asar_throw_error(1, error_type_block, error_id_invalid_global_label, word[1]);
1386 }
1387 }
1388
6/6
✓ Branch 0 taken 793 times.
✓ Branch 1 taken 9695 times.
✓ Branch 2 taken 70 times.
✓ Branch 3 taken 723 times.
✓ Branch 4 taken 70 times.
✓ Branch 5 taken 10418 times.
10488 else if (is2("check"))
1389 {
1390
4/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 64 times.
70 if (stricmp(word[1], "title") == 0)
1391 {
1392 // RPG Hacker: Removed trimming for now - I think requiring an exact match is probably
1393 // better here (not sure, though, it's worth discussing)
1394
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 string expected_title = safedequote(word[2]);
1395 // randomdude999: this also removes leading spaces because itrim gets stuck in an endless
1396 // loop when multi is true and one argument is empty
1397 // in hirom the rom needs to be an entire bank for it to have a title, other modes only need 0x8000 bytes
1398
7/10
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
6 if (romlen < ((mapper == hirom || mapper == exhirom) ? 0x10000 : 0x8000)) // too short
1399 {
1400 if (!ignoretitleerrors) // title errors shouldn't be ignored
1401 asar_throw_error(0, error_type_block, error_id_rom_too_short, expected_title.data());
1402 else // title errors should be ignored, throw a warning anyways
1403 asar_throw_warning(0, warning_id_rom_too_short, expected_title.data());
1404 }
1405 else {
1406 6 string actual_title;
1407 6 string actual_display_title;
1408
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 6 times.
132 for (int i = 0;i < 21;i++)
1409 {
1410 126 unsigned char c = romdata[snestopc(0x00FFC0 + i)];
1411
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 actual_title += (char)c;
1412 // the replacements are from interface-cli.cpp
1413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == 7) c = 14;
1414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == 8) c = 27;
1415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == 9) c = 26;
1416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == '\r') c = 17;
1417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == '\n') c = 25;
1418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == '\0') c = 155;
1419
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 actual_display_title += (char)c;
1420 }
1421
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
6 if (strncmp(expected_title, actual_title, 21) != 0)
1422 {
1423 if (!ignoretitleerrors) // title errors shouldn't be ignored
1424 asar_throw_error(0, error_type_block, error_id_rom_title_incorrect, expected_title.data(), actual_display_title.data());
1425 else // title errors should be ignored, throw a warning anyways
1426 asar_throw_warning(0, warning_id_rom_title_incorrect, expected_title.data(), actual_display_title.data());
1427 }
1428 6 }
1429 6 }
1430
3/4
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
64 else if (stricmp(word[1], "bankcross") == 0)
1431 {
1432 if (0);
1433
4/4
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 34 times.
64 else if (!stricmp(word[2], "off"))
1434 {
1435 30 disable_bank_cross_errors = true;
1436 }
1437
4/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 2 times.
34 else if (!stricmp(word[2], "half"))
1438 {
1439 32 disable_bank_cross_errors = false;
1440 32 check_half_banks_crossed = true;
1441 }
1442
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 else if (!stricmp(word[2], "full"))
1443 {
1444 2 disable_bank_cross_errors = false;
1445 2 check_half_banks_crossed = false;
1446 }
1447 else asar_throw_error(0, error_type_block, error_id_invalid_check);
1448
1449 }
1450 else
1451 {
1452 asar_throw_error(0, error_type_block, error_id_invalid_check);
1453 }
1454 }
1455
9/10
✓ Branch 0 taken 729 times.
✓ Branch 1 taken 9689 times.
✓ Branch 2 taken 729 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8894 times.
✓ Branch 5 taken 1524 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 8858 times.
✓ Branch 8 taken 36 times.
✓ Branch 9 taken 10382 times.
10418 else if (is0("asar") || is1("asar"))
1456 {
1457
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
36 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
51 if (!par) return;
1459 36 int dots=0;
1460 36 int dig=0;
1461
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 36 times.
186 for (int i=0;par[i];i++)
1462 {
1463
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 108 times.
150 if (par[i]=='.')
1464 {
1465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (!dig) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1466 42 dig=0;
1467 42 dots++;
1468 }
1469
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 else if (is_digit(par[i])) dig++;
1470 else asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1471 }
1472
3/6
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36 times.
36 if (!dig || !dots || dots>2) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1473
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 autoptr<char**> vers=split(par, '.');
1474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
36 int vermaj=atoi(vers[0]);
1475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (vermaj > asarver_maj) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1476
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 6 times.
36 if (vermaj<asarver_maj) return;
1477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (dots==1)
1478 {
1479 if (strlen(vers[1])!=2) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1480 //if (asarver_min<10 && asarver_bug<10 && strlen(vers[1])>2) error(0, "This version of Asar is too old for this patch.");
1481 int verminbug=atoi(vers[1]);
1482 int tmpver=asarver_bug;
1483 if (tmpver>9) tmpver=9;
1484 if (asarver_min*10+tmpver<verminbug) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1485 }
1486 else
1487 {
1488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 int vermin=atoi(vers[1]);
1489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (vermin>asarver_min) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 int verbug=atoi(vers[2]);
1491
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (vermin==asarver_min && verbug>asarver_bug) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1492 }
1493
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 }
1494
10/10
✓ Branch 0 taken 729 times.
✓ Branch 1 taken 9653 times.
✓ Branch 2 taken 727 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 8858 times.
✓ Branch 5 taken 1522 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 8852 times.
✓ Branch 8 taken 8 times.
✓ Branch 9 taken 10374 times.
10382 else if (is0("include") || is1("includefrom"))
1495 {
1496
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
8 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1497
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if (in_top_level_file())
1498 {
1499
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2 if (par) asar_throw_error(pass, error_type_fatal, error_id_cant_be_main_file, (string(" The main file is '") + par + "'.").data());
1500 2 else asar_throw_error(pass, error_type_fatal, error_id_cant_be_main_file, "");
1501 }
1502 }
1503
6/6
✓ Branch 0 taken 727 times.
✓ Branch 1 taken 9647 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 697 times.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 10344 times.
10374 else if (is0("includeonce"))
1504 {
1505
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 const char* current_file = get_current_file_name();
1506
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 if (!file_included_once(current_file))
1507 {
1508
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 includeonce.append(current_file);
1509 }
1510 }
1511
8/8
✓ Branch 0 taken 723 times.
✓ Branch 1 taken 9621 times.
✓ Branch 2 taken 360 times.
✓ Branch 3 taken 363 times.
✓ Branch 4 taken 525 times.
✓ Branch 5 taken 198 times.
✓ Branch 6 taken 261 times.
✓ Branch 7 taken 5673 times.
10344 else if (numwords==3 && !stricmp(word[1], "="))
1512 {
1513
3/4
✓ Branch 0 taken 402 times.
✓ Branch 1 taken 123 times.
✓ Branch 2 taken 402 times.
✗ Branch 3 not taken.
525 if(word[0][0] == '\'' && word[0][1])
1514 {
1515 201 int codepoint;
1516 402 const char* char_start = word[0]+1;
1517
1/2
✓ Branch 0 taken 402 times.
✗ Branch 1 not taken.
402 const char* after = char_start + utf8_val(&codepoint, char_start);
1518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402 times.
402 if (codepoint == -1) asar_throw_error(0, error_type_block, error_id_invalid_utf8);
1519
2/4
✓ Branch 0 taken 402 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 402 times.
✗ Branch 3 not taken.
402 if(after[0] == '\'' && after[1] == '\0') {
1520
3/4
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 396 times.
✗ Branch 3 not taken.
402 thetable.set_val(codepoint, getnum(word[2]));
1521
6/8
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 393 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 198 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
396 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
1522 396 return;
1523 } // todo: error checking here
1524 }
1525
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 int num=(int)getnum(word[2]);
1526
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 63 times.
123 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_label_forward);
1527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
123 bool is_static = foundlabel_static;
1528
1529 123 const char* newlabelname = word[0];
1530 123 bool ismacro = false;
1531
1532
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 117 times.
123 if (newlabelname[0] == '?')
1533 {
1534 6 ismacro = true;
1535 6 newlabelname++;
1536 }
1537
1538
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
123 if (ismacro && macrorecursion == 0)
1539 {
1540 asar_throw_error(0, error_type_block, error_id_macro_label_outside_of_macro);
1541 }
1542
1543
3/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 63 times.
123 if (!confirmname(newlabelname)) asar_throw_error(0, error_type_block, error_id_invalid_label_name);
1544
1545 123 string completename;
1546
1547
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 117 times.
123 if (ismacro)
1548 {
1549
5/10
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
6 completename += STR":macro_" + dec(calledmacros) + "_";
1550 }
1551
1552
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 completename += newlabelname;
1553
1554
2/4
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
✗ Branch 3 not taken.
123 setlabel(ns + completename, num, is_static);
1555 186 }
1556
3/4
✓ Branch 0 taken 9819 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9560 times.
✓ Branch 3 taken 259 times.
9819 else if (assemblemapper(word, numwords)) {}
1557
6/6
✓ Branch 0 taken 8831 times.
✓ Branch 1 taken 729 times.
✓ Branch 2 taken 897 times.
✓ Branch 3 taken 7934 times.
✓ Branch 4 taken 897 times.
✓ Branch 5 taken 8663 times.
9560 else if (is1("org"))
1558 {
1559
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 897 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 489 times.
897 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1560
1/2
✓ Branch 0 taken 897 times.
✗ Branch 1 not taken.
897 freespaceend();
1561
1/2
✓ Branch 0 taken 897 times.
✗ Branch 1 not taken.
897 unsigned int num=getnum(par);
1562
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 897 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 489 times.
897 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_label_forward);
1563
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 897 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
897 if (num&~0xFFFFFF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex(num, 6).data());
1564
8/14
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 762 times.
✓ Branch 2 taken 150 times.
✓ Branch 3 taken 474 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 423 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 144 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 345 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
897 if ((mapper==lorom || mapper==exlorom) && (num&0x408000)==0x400000 && (num&0x700000)!=0x700000) asar_throw_warning(0, warning_id_set_middle_byte);
1565 897 snespos=(int)num;
1566 897 realsnespos=(int)num;
1567 897 startpos=(int)num;
1568 897 realstartpos=(int)num;
1569 897 snespos_valid = true;
1570 }
1571 #define ret_error(errid) { asar_throw_error(0, error_type_block, errid); return; }
1572 #define ret_error_params(errid, ...) { asar_throw_error(0, error_type_block, errid, __VA_ARGS__); return; }
1573
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 8567 times.
8663 else if (is("struct"))
1574 {
1575 //verifysnespos();
1576
6/8
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
96 if (in_struct || in_sub_struct) ret_error(error_id_nested_struct);
1577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (numwords < 2) ret_error(error_id_missing_struct_params);
1578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (numwords > 4) ret_error(error_id_too_many_struct_params);
1579
3/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
96 if (!confirmname(word[1])) ret_error(error_id_invalid_struct_name);
1580
1581
5/8
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 96 times.
96 if (structs.exists(word[1]) && pass == 0) ret_error_params(error_id_struct_redefined, word[1]);
1582
1583 96 static_struct = false;
1584 96 old_snespos = snespos;
1585 96 old_startpos = startpos;
1586 96 old_optimizeforbank = optimizeforbank;
1587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
96 old_snespos_valid = snespos_valid;
1588 96 unsigned int base = 0;
1589
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 66 times.
96 if (numwords == 3)
1590 {
1591 30 static_struct = true;
1592
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 base = getnum(word[2]);
1593
1594
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
30 if (foundlabel && !foundlabel_static) static_struct = false;
1595
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 if (pass > 0) {
1596 // foundlabel_static isn't accurate anymore
1597
5/10
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 10 times.
20 if(structs.exists(word[1])) static_struct &= structs.find(word[1]).is_static;
1598 }
1599 }
1600
1601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
96 bool old_in_struct = in_struct;
1602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
96 bool old_in_sub_struct = in_sub_struct;
1603
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 30 times.
96 in_struct = numwords == 2 || numwords == 3;
1604 96 in_sub_struct = numwords == 4;
1605
1606 #define ret_error_cleanup(errid) { in_struct = old_in_struct; in_sub_struct = old_in_sub_struct; asar_throw_error(0, error_type_block, errid); return; }
1607 #define ret_error_params_cleanup(errid, ...) { in_struct = old_in_struct; in_sub_struct = old_in_sub_struct; asar_throw_error(0, error_type_block, errid, __VA_ARGS__); return; }
1608
1609
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 66 times.
96 if (numwords == 3)
1610 {
1611
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (base&~0xFFFFFF) ret_error_params_cleanup(error_id_snes_address_out_of_bounds, hex((unsigned int)base, 6).data());
1612 30 snespos = (int)base;
1613 30 startpos = (int)base;
1614 }
1615
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 36 times.
66 else if (numwords == 4)
1616 {
1617
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 if (strcasecmp(word[2], "extends")) ret_error_cleanup(error_id_missing_extends);
1618
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
30 if (!confirmname(word[3])) ret_error_cleanup(error_id_struct_invalid_parent_name);
1619
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 string tmp_struct_parent = word[3];
1620
1621
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 if (!structs.exists(tmp_struct_parent)) ret_error_params_cleanup(error_id_struct_not_found, tmp_struct_parent.data());
1622
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 snes_struct structure = structs.find(tmp_struct_parent);
1623
1624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
30 static_struct = structure.is_static;
1625
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 struct_parent = tmp_struct_parent;
1626 30 snespos = structure.base_end;
1627 30 startpos = structure.base_end;
1628
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 }
1629
1630
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 push_pc();
1631
1632 96 optimizeforbank = -1;
1633
1634
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 struct_name = word[1];
1635 96 struct_base = snespos;
1636 96 realsnespos = 0;
1637 96 realstartpos = 0;
1638 96 snespos_valid = true;
1639
1640
4/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 33 times.
96 if(in_sub_struct) {
1641
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 string labelname = struct_parent + "." + struct_name;
1642
4/6
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
30 setlabel(ns + labelname, snespos, static_struct);
1643 30 } else {
1644
4/6
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
66 setlabel(ns + struct_name, snespos, static_struct);
1645 }
1646
1647 #undef ret_error_cleanup
1648 #undef ret_error_params_cleanup
1649 }
1650
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 8471 times.
8567 else if (is("endstruct"))
1651 {
1652
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
96 if (numwords != 1 && numwords != 3) ret_error(error_id_invalid_endstruct_count);
1653
6/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
96 if (numwords == 3 && strcasecmp(word[1], "align")) ret_error(error_id_expected_align);
1654
6/8
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 15 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 15 times.
96 if (!in_struct && !in_sub_struct) ret_error(error_id_endstruct_without_struct);
1655
1656
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
96 int alignment = numwords == 3 ? (int)getnum(word[2]) : 1;
1657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (alignment < 1) ret_error(error_id_alignment_too_small);
1658
1659 96 snes_struct structure;
1660 96 structure.base_end = snespos;
1661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
96 structure.struct_size = alignment * ((snespos - struct_base + alignment - 1) / alignment);
1662 96 structure.object_size = structure.struct_size;
1663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
96 structure.is_static = static_struct;
1664
1665
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 15 times.
96 if (in_struct)
1666 {
1667
2/4
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
66 structs.create(struct_name) = structure;
1668 }
1669
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
30 else if (in_sub_struct)
1670 {
1671 30 snes_struct parent;
1672
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 parent = structs.find(struct_parent);
1673
1674
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 if (parent.object_size < parent.struct_size + structure.struct_size) {
1675 24 parent.object_size = parent.struct_size + structure.struct_size;
1676 }
1677
1678
4/8
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
30 structs.create(struct_parent + "." + struct_name) = structure;
1679
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 structs.create(struct_parent) = parent;
1680 30 }
1681
1682
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 pop_pc();
1683 96 in_struct = false;
1684 96 in_sub_struct = false;
1685 96 snespos = old_snespos;
1686 96 startpos = old_startpos;
1687 96 optimizeforbank = old_optimizeforbank;
1688
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
96 snespos_valid = old_snespos_valid;
1689 96 static_struct = false;
1690 96 }
1691 #undef ret_error
1692
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8459 times.
8471 else if(is("spcblock"))
1693 {
1694 //banned features when active: org, freespace(and variants), arch, mapper,namespace,pushns
1695
6/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
12 if(in_struct || in_sub_struct) asar_throw_error(0, error_type_block, error_id_spcblock_inside_struct);
1696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(numwords < 2) asar_throw_error(0, error_type_block, error_id_spcblock_too_few_args);
1697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(numwords > 4) asar_throw_error(0, error_type_block, error_id_spcblock_too_many_args);
1698
1699
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 spcblock.destination = getnum(par);
1700 12 spcblock.type = spcblock_nspc;
1701
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 spcblock.macro_name = "";
1702
1703
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (spcblock.destination&~0xFFFF) asar_throw_error(0, error_type_block, error_id_snes_address_out_of_bounds, hex(spcblock.destination, 6).data());
1704
1705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(numwords == 3)
1706 {
1707 if(!stricmp(word[2], "nspc")) spcblock.type = spcblock_nspc;
1708 else if(!stricmp(word[2], "custom")) asar_throw_error(0, error_type_block, error_id_custom_spcblock_missing_macro);
1709 else asar_throw_error(0, error_type_block, error_id_unknown_spcblock_type);
1710 }
1711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 else if(numwords == 4)
1712 {
1713 if(!stricmp(word[2], "custom")) spcblock.type = spcblock_custom;
1714 else asar_throw_error(0, error_type_block, error_id_extra_spcblock_arg_for_type);
1715
1716 if(macros.exists(word[3]))
1717 {
1718 macrodata *macro = macros.find(word[3]);
1719 if(!macro->variadic) asar_throw_error(0, error_type_block, error_id_spcblock_macro_must_be_varadic);
1720 if(macro->numargs != 3) asar_throw_error(0, error_type_block, error_id_spcblock_macro_invalid_static_args);
1721 spcblock.macro_name = word[3];
1722 }
1723 else asar_throw_error(0, error_type_block, error_id_spcblock_macro_doesnt_exist);
1724 }
1725
1726
3/5
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 switch(spcblock.type)
1727 {
1728 12 case spcblock_nspc:
1729 12 spcblock.size_address=realsnespos;
1730
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 write2(0x0000);
1731
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 write2(spcblock.destination);
1732 12 snespos=(int)spcblock.destination;
1733 12 startpos=(int)spcblock.destination;
1734
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 add_addr_to_line(addrToLinePos);
1735 12 break;
1736 case spcblock_custom:
1737 //this is a todo that probably won't be ready for 1.9
1738 //mostly so we can leverage some cleanups we make in 2.0 for practicality
1739 asar_throw_error(0, error_type_block, error_id_spcblock_custom_types_incomplete);
1740 push_pc();
1741 spcblock.old_mapper = mapper;
1742 mapper = norom;
1743 break;
1744 default:
1745 asar_throw_error(0, error_type_fatal, error_id_internal_error, "invalid spcblock type");
1746 }
1747
1748
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 ns_backup = ns;
1749
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 ns = STR":SPCBLOCK:_" + ns_backup;
1750 12 in_spcblock = true;
1751 }
1752
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8447 times.
8459 else if(is("endspcblock"))
1753 {
1754
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if(!in_spcblock) asar_throw_error(0, error_type_block, error_id_endspcblock_without_spcblock);
1755
1756
3/5
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 switch(spcblock.type)
1757 {
1758 12 case spcblock_nspc:
1759
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (pass==2)
1760 {
1761 4 int pcpos=snestopc(spcblock.size_address&0xFFFFFF);
1762
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if (pcpos<0) asar_throw_error(2, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex((unsigned int)realsnespos, 6).data());
1763 4 int num=snespos-startpos;
1764
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 writeromdata_byte(pcpos, (unsigned char)num);
1765
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 writeromdata_byte(pcpos+1, (unsigned char)(num >> 8));
1766 }
1767
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (numwords == 3)
1768 {
1769
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if (strcmp(par, "execute")) asar_throw_error(0, error_type_null, error_id_invalid_endspcblock_arg, par);
1770 else
1771 {
1772
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(0x0000);
1773
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 write2(pass == 2 ? (unsigned int)getnum(word[2]) : 0);
1774 }
1775 }
1776
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 else if (numwords != 1)
1777 {
1778 asar_throw_error(0, error_type_null, error_id_unknown_endspcblock_format);
1779 }
1780 12 break;
1781 case spcblock_custom:
1782 mapper = spcblock.old_mapper;
1783 pop_pc();
1784 break;
1785 default:
1786 asar_throw_error(0, error_type_fatal, error_id_internal_error, "invalid spcblock type");
1787 }
1788
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 ns = ns_backup;
1789 12 in_spcblock = false;
1790 }
1791
6/6
✓ Branch 0 taken 7886 times.
✓ Branch 1 taken 561 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 7790 times.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 8351 times.
8447 else if (is1("base"))
1792 {
1793
4/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 66 times.
96 if (!stricmp(par, "off"))
1794 {
1795 30 snespos=realsnespos;
1796 30 startpos=realstartpos;
1797 30 snespos_valid = realsnespos >= 0;
1798 30 return;
1799 }
1800
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 unsigned int num=getnum(par);
1801
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
66 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_base_label_invalid);
1802
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
66 if (num&~0xFFFFFF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex((unsigned int)num).data());
1803 66 snespos=(int)num;
1804 66 startpos=(int)num;
1805 66 optimizeforbank=-1;
1806 66 snespos_valid = realsnespos >= 0;
1807 }
1808
6/6
✓ Branch 0 taken 7790 times.
✓ Branch 1 taken 561 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 7778 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 8339 times.
8351 else if (is1("dpbase"))
1809 {
1810
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 unsigned int num=(int)getnum(par);
1811
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_base_label_invalid);
1812
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (num&~0xFF00) asar_throw_error(1, error_type_block, error_id_bad_dp_base, hex((unsigned int)num, 6).data());
1813 12 dp_base = (int)num;
1814 }
1815
6/6
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 8183 times.
✓ Branch 2 taken 102 times.
✓ Branch 3 taken 54 times.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 8237 times.
8339 else if (is2("optimize"))
1816 {
1817
4/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 60 times.
102 if (!stricmp(par, "dp"))
1818 {
1819
4/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 18 times.
42 if (!stricmp(word[2], "none"))
1820 {
1821 24 optimize_dp = optimize_dp_flag::NONE;
1822 24 return;
1823 }
1824
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12 times.
18 if (!stricmp(word[2], "ram"))
1825 {
1826 6 optimize_dp = optimize_dp_flag::RAM;
1827 6 return;
1828 }
1829
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 if (!stricmp(word[2], "always"))
1830 {
1831 12 optimize_dp = optimize_dp_flag::ALWAYS;
1832 12 return;
1833 }
1834 asar_throw_error(1, error_type_block, error_id_bad_dp_optimize, word[2]);
1835 }
1836
3/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
60 if (!stricmp(par, "address"))
1837 {
1838
4/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 36 times.
60 if (!stricmp(word[2], "default"))
1839 {
1840 24 optimize_address = optimize_address_flag::DEFAULT;
1841 24 return;
1842 }
1843
4/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 18 times.
36 if (!stricmp(word[2], "ram"))
1844 {
1845 18 optimize_address = optimize_address_flag::RAM;
1846 18 return;
1847 }
1848
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 if (!stricmp(word[2], "mirrors"))
1849 {
1850 18 optimize_address = optimize_address_flag::MIRRORS;
1851 18 return;
1852 }
1853 asar_throw_error(1, error_type_block, error_id_bad_address_optimize, word[2]);
1854 }
1855 asar_throw_error(1, error_type_block, error_id_bad_optimize, par);
1856 }
1857
6/6
✓ Branch 0 taken 7778 times.
✓ Branch 1 taken 459 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 7760 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 8219 times.
8237 else if (is1("bank"))
1858 {
1859
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12 times.
18 if (!stricmp(par, "auto"))
1860 {
1861 6 optimizeforbank=-1;
1862 6 return;
1863 }
1864
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
12 if (!stricmp(par, "noassume"))
1865 {
1866 6 optimizeforbank=0x140;
1867 6 return;
1868 }
1869
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 unsigned int num=getnum(par);
1870 //if (forwardlabel) error(0, "bank Label is not valid");
1871 //if (foundlabel) num>>=16;
1872
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (num&~0x0000FF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex((unsigned int)num, 6).data());
1873 6 optimizeforbank=(int)num;
1874 }
1875
10/10
✓ Branch 0 taken 8213 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 7091 times.
✓ Branch 3 taken 1122 times.
✓ Branch 4 taken 6755 times.
✓ Branch 5 taken 336 times.
✓ Branch 6 taken 102 times.
✓ Branch 7 taken 6653 times.
✓ Branch 8 taken 1566 times.
✓ Branch 9 taken 6653 times.
8219 else if (is("freespace") || is("freecode") || is("freedata") || is("segment"))
1876 {
1877
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1566 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 783 times.
1566 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1878
1879
1/2
✓ Branch 0 taken 1566 times.
✗ Branch 1 not taken.
1566 freespace_data this_fs_settings = default_freespace_settings;
1880
2/2
✓ Branch 0 taken 1122 times.
✓ Branch 1 taken 444 times.
1566 if (is("freecode")) this_fs_settings.bank = -2;
1881
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 1230 times.
1566 if (is("freedata")) this_fs_settings.bank = -1;
1882
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 1464 times.
1566 if (is("segment")) this_fs_settings.write_rats = false;
1883
1884 1566 string parstr;
1885
3/4
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 1356 times.
✓ Branch 2 taken 210 times.
✗ Branch 3 not taken.
1566 if (numwords==1) parstr="";
1886
2/4
✓ Branch 0 taken 1356 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1356 times.
✗ Branch 3 not taken.
1356 else if (numwords==2) parstr=word[1];
1887 else asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1888
1/2
✓ Branch 0 taken 1566 times.
✗ Branch 1 not taken.
1566 parse_freespace_arguments(this_fs_settings, parstr);
1889
1890
5/6
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 1500 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
1566 if(this_fs_settings.bank == -3 && !this_fs_settings.write_rats) this_fs_settings.bank = -1;
1891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1566 times.
1566 if(this_fs_settings.bank == -3) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1892 // no point specifying anything about cleaning when not writing a rats tag
1893
4/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 1515 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 732 times.
1566 if(!this_fs_settings.write_rats &&
1894
6/8
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 51 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 51 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 51 times.
102 (this_fs_settings.flag_cleaned || this_fs_settings.is_static))
1895 asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1896
4/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 1515 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 732 times.
1566 if(!this_fs_settings.write_rats) this_fs_settings.flag_cleaned = true;
1897
1/2
✓ Branch 0 taken 1566 times.
✗ Branch 1 not taken.
1566 freespaceend();
1898 1566 freespaceid = freespaceidnext++;
1899
1/2
✓ Branch 0 taken 1566 times.
✗ Branch 1 not taken.
1566 freespace_data& thisfs = freespaces[freespaceid];
1900
1901
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 1044 times.
1566 if (pass==0) {
1902
1/2
✓ Branch 0 taken 522 times.
✗ Branch 1 not taken.
522 thisfs = this_fs_settings;
1903 522 thisfs.pos = -1;
1904 522 thisfs.leaked = true;
1905 522 thisfs.orgpos = -2;
1906 522 thisfs.orglen = -1;
1907 522 snespos=0;
1908 }
1909
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 1044 times.
1566 if (pass==1)
1910 {
1911
5/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 520 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
522 if (thisfs.is_static && thisfs.orgpos == -2)
1912 {
1913 thisfs.pos = 0;
1914 thisfs.leaked = false;//mute some other errors
1915 asar_throw_error(1, error_type_block, error_id_static_freespace_autoclean);
1916 }
1917 522 snespos = 0;
1918 }
1919
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 1044 times.
1566 if (pass==2)
1920 {
1921
5/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 520 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
522 if (thisfs.is_static && thisfs.orgpos == -2) return;//to kill some errors (supposedly????)
1922 522 snespos=thisfs.pos;
1923
6/10
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 228 times.
✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 228 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 228 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
522 if (thisfs.leaked && !thisfs.flag_cleaned) asar_throw_warning(2, warning_id_freespace_leaked);
1924
4/4
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 278 times.
✓ Branch 2 taken 244 times.
✓ Branch 3 taken 17 times.
522 freespaceuse += (thisfs.write_rats ? 8 : 0) + thisfs.len;
1925
1926 // add a mapping for the start of the rats tag
1927
5/6
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 278 times.
✓ Branch 2 taken 488 times.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 244 times.
✗ Branch 5 not taken.
522 if (thisfs.write_rats) add_addr_to_line(snespos-8);
1928 }
1929
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1566 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1566 if (snespos < 0 && mapper == sa1rom) asar_throw_error(pass, error_type_fatal, error_id_no_freespace_in_mapped_banks, dec(thisfs.len).data());
1930
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1566 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1566 if (snespos < 0) asar_throw_error(pass, error_type_fatal, error_id_no_freespace, dec(thisfs.len).data());
1931
4/4
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 834 times.
✓ Branch 2 taken 732 times.
✓ Branch 3 taken 51 times.
1566 bytes+=thisfs.write_rats ? 8 : 0;
1932 1566 freespacestart=snespos;
1933 1566 startpos=snespos;
1934 1566 realstartpos=snespos;
1935 1566 realsnespos=snespos;
1936 1566 optimizeforbank=-1;
1937
4/4
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 834 times.
✓ Branch 2 taken 732 times.
✓ Branch 3 taken 51 times.
1566 ratsmetastate=thisfs.write_rats ? ratsmeta_allow : ratsmeta_ban;
1938 1566 snespos_valid = true;
1939 // check this at the very end so that snespos gets set properly, to
1940 // prevent spurious errors later
1941 //...i guess this can still cause bankcross errors if the old freespace
1942 //happened to be very close to the end of a bank or something, but
1943 //whatever
1944
9/10
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 1044 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 520 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 260 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1566 if (pass == 2 && thisfs.is_static && thisfs.orgpos > 0 && thisfs.len > thisfs.orglen)
1945 2 asar_throw_error(2, error_type_block, error_id_static_freespace_growing);
1946
2/4
✓ Branch 0 taken 1564 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1564 times.
✗ Branch 3 not taken.
1568 }
1947
6/6
✓ Branch 0 taken 6404 times.
✓ Branch 1 taken 249 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6398 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6647 times.
6653 else if (is1("freespace_settings"))
1948 {
1949
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 string arg = word[1];
1950
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 parse_freespace_arguments(default_freespace_settings, arg);
1951 6 }
1952
6/6
✓ Branch 0 taken 6398 times.
✓ Branch 1 taken 249 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 6356 times.
✓ Branch 4 taken 42 times.
✓ Branch 5 taken 6605 times.
6647 else if (is1("prot"))
1953 {
1954
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
42 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1955
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
42 if (!ratsmetastate) asar_throw_error(2, error_type_block, error_id_prot_not_at_freespace_start);
1956
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 15 times.
42 if (ratsmetastate==ratsmeta_used) step(-5);
1957 21 int num;
1958
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 autoptr<char**> pars=qpsplit(par, ',', &num);
1959
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 verify_paren(pars);
1960
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('P');
1961
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('R');
1962
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('O');
1963
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('T');
1964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (num * 3 > 255) asar_throw_error(0, error_type_block, error_id_prot_too_many_entries);
1965
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1((unsigned int)(num*3));
1966
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 42 times.
96 for (int i=0;i<num;i++)
1967 {
1968 //int num=getnum(pars[i]);
1969 54 const char * labeltest=pars[i];
1970
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 string testlabel = labeltest;
1971
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 snes_label lblval = labelval(&labeltest);
1972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (*labeltest) asar_throw_error(0, error_type_block, error_id_label_not_found, testlabel.data());
1973
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 write3(lblval.pos);
1974
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
54 if (pass==1) freespaces[lblval.freespace_id].leaked = false;
1975 54 }
1976
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('S');
1977
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('T');
1978
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('O');
1979
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1('P');
1980
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 write1(0);
1981 42 ratsmetastate=ratsmeta_used;
1982
1983
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 add_addr_to_line(addrToLinePos);
1984 42 }
1985
9/10
✓ Branch 0 taken 6356 times.
✓ Branch 1 taken 249 times.
✓ Branch 2 taken 6356 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
✓ Branch 5 taken 6551 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 36 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 6587 times.
6605 else if (is1("autoclean") || is2("autoclean"))
1986 {
1987
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
18 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1988
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (numwords==3)
1989 {
1990 18 const char * labeltest = word[2];
1991
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 string testlabel = labeltest;
1992
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(!stricmpwithlower(word[1], "dl")) {
1993
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 handle_autoclean(testlabel, -1, snespos);
1994
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
18 write3(pass==2 ? getnum(testlabel.data()) : 0);
1995
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 add_addr_to_line(addrToLinePos);
1996 } else {
1997 // other ones are handled in arch-65816
1998 asar_throw_error(0, error_type_block, error_id_broken_autoclean);
1999 }
2000 18 }
2001 else if (pass==0) removerats((int)getnum(word[1]), freespacebyte);
2002 }
2003
6/6
✓ Branch 0 taken 6356 times.
✓ Branch 1 taken 231 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6350 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6581 times.
6587 else if (is1("freespacebyte"))
2004 {
2005
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 freespacebyte = getnum(word[1]);
2006
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2007 }
2008
6/6
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 6428 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 147 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6575 times.
6581 else if (is0("pushpc"))
2009 {
2010
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 verifysnespos();
2011
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].arch=arch;
2012
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snespos=snespos;
2013
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snesstart=startpos;
2014
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snesposreal=realsnespos;
2015
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snesstartreal=realstartpos;
2016
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].freeid=freespaceid;
2017
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].freest=freespacestart;
2018 6 pushpcnum++;
2019 6 snespos=(int)0xFFFFFFFF;
2020 6 startpos= (int)0xFFFFFFFF;
2021 6 realsnespos= (int)0xFFFFFFFF;
2022 6 realstartpos= (int)0xFFFFFFFF;
2023 6 snespos_valid = false;
2024 }
2025
6/6
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 6428 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 141 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6569 times.
6575 else if (is0("pullpc"))
2026 {
2027
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!pushpcnum) asar_throw_error(0, error_type_block, error_id_pullpc_without_pushpc);
2028 6 pushpcnum--;
2029
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 freespaceend();
2030
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (arch != pushpc[pushpcnum].arch) asar_throw_error(0, error_type_block, error_id_pullpc_different_arch);
2031
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 snespos=pushpc[pushpcnum].snespos;
2032
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 startpos=pushpc[pushpcnum].snesstart;
2033
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 realsnespos=pushpc[pushpcnum].snesposreal;
2034
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 realstartpos=pushpc[pushpcnum].snesstartreal;
2035
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 freespaceid=pushpc[pushpcnum].freeid;
2036
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 freespacestart=pushpc[pushpcnum].freest;
2037 6 snespos_valid = true;
2038 }
2039
6/6
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 6428 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 135 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6563 times.
6569 else if (is0("pushbase"))
2040 {
2041
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 basestack[basestacknum] = snespos;
2042 6 basestacknum++;
2043 }
2044
6/6
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 6428 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 129 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6557 times.
6563 else if (is0("pullbase"))
2045 {
2046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!basestacknum) asar_throw_error(0, error_type_block, error_id_pullbase_without_pushbase);
2047 6 basestacknum--;
2048
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 snespos = basestack[basestacknum];
2049
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 startpos = basestack[basestacknum];
2050
2051
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (snespos != realstartpos)
2052 {
2053 6 optimizeforbank = -1;
2054 }
2055 }
2056
6/6
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 6428 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 117 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 6545 times.
6557 else if (is0("pushns"))
2057 {
2058
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2059
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 pushns[pushnsnum].ns = ns;
2060
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for(int i = 0; i < namespace_list.count; i++)
2061 {
2062
3/6
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 pushns[pushnsnum].namespace_list.append(namespace_list[i]);
2063 }
2064
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 pushns[pushnsnum].nested_namespaces = nested_namespaces;
2065 12 pushnsnum++;
2066
2067 12 namespace_list.reset();
2068
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 ns = "";
2069 12 nested_namespaces = false;
2070 }
2071
6/6
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 6428 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 105 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 6533 times.
6545 else if (is0("pullns"))
2072 {
2073
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!pushnsnum) asar_throw_error(0, error_type_block, error_id_pullns_without_pushns);
2075 12 pushnsnum--;
2076
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 ns = pushns[pushnsnum].ns;
2077
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 nested_namespaces = pushns[pushnsnum].nested_namespaces;
2078 12 namespace_list.reset();
2079
3/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 12 times.
36 for(int i = 0; i < pushns[pushnsnum].namespace_list.count; i++)
2080 {
2081
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 namespace_list.append(pushns[pushnsnum].namespace_list[i]);
2082 }
2083 }
2084
9/10
✓ Branch 0 taken 6350 times.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 6221 times.
✓ Branch 3 taken 129 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 6368 times.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 165 times.
✓ Branch 9 taken 6368 times.
6533 else if (is1("namespace") || is2("namespace"))
2085 {
2086
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
165 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2087 165 bool leave = false;
2088
1/2
✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
165 if (par)
2089 {
2090
4/4
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 117 times.
165 if (!stricmp(par, "off"))
2091 {
2092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2093 48 leave = true;
2094 }
2095
4/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 81 times.
117 else if (!stricmp(par, "nested"))
2096 {
2097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (!word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2098
4/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 18 times.
36 else if (!stricmp(word[2], "on")) nested_namespaces = true;
2099
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 else if (!stricmp(word[2], "off")) nested_namespaces = false;
2100 }
2101 else
2102 {
2103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
81 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2104
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 const char * tmpstr= safedequote(par);
2105
3/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
81 if (!confirmname(tmpstr)) asar_throw_error(0, error_type_block, error_id_invalid_namespace_name);
2106
4/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 24 times.
81 if (!nested_namespaces)
2107 {
2108 33 namespace_list.reset();
2109 }
2110
2/4
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✗ Branch 3 not taken.
81 namespace_list.append(tmpstr);
2111 }
2112 }
2113 else
2114 {
2115 leave = true;
2116 }
2117
2118
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 117 times.
165 if (leave)
2119 {
2120
4/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 6 times.
48 if (nested_namespaces)
2121 {
2122 36 namespace_list.remove(namespace_list.count - 1);
2123 }
2124 else
2125 {
2126 12 namespace_list.reset();
2127 }
2128 }
2129
2130 // recompute ns
2131
1/2
✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
165 ns = "";
2132
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 165 times.
360 for (int i = 0; i < namespace_list.count; i++)
2133 {
2134
2/4
✓ Branch 0 taken 195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 195 times.
✗ Branch 3 not taken.
195 ns += namespace_list[i];
2135
1/2
✓ Branch 0 taken 195 times.
✗ Branch 1 not taken.
195 ns += "_";
2136 }
2137 }
2138
6/6
✓ Branch 0 taken 6221 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 4997 times.
✓ Branch 3 taken 1224 times.
✓ Branch 4 taken 4997 times.
✓ Branch 5 taken 1371 times.
6368 else if (is1("incsrc"))
2139 {
2140 4997 string name;
2141 // RPG Hacker: Should this also throw on absolute paths?
2142 // E.g., on something starting with C:/ or whatever.
2143
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4994 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1669 times.
4997 if (strchr(par, '\\'))
2144 {
2145 6 asar_throw_error(0, error_type_block, error_id_platform_paths);
2146 }
2147
2/4
✓ Branch 0 taken 4991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4991 times.
✗ Branch 3 not taken.
4991 name=safedequote(par);
2148
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 4826 times.
4991 assemblefile(name);
2149 4997 }
2150
6/6
✓ Branch 0 taken 1224 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 1152 times.
✓ Branch 4 taken 72 times.
✓ Branch 5 taken 1299 times.
1371 else if (is1("incbin"))
2151 {
2152 36 int len;
2153 72 int start=0;
2154 72 int end=0;
2155
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 30 times.
72 if (strqchr(par, ':'))
2156 {
2157 42 char * lengths=strqchr(par, ':');
2158 42 *lengths=0;
2159 42 lengths++;
2160
2161
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 char* split = strqpstr(lengths, "..");
2162
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
42 if(!split) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2163
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 string start_str(lengths, split-lengths);
2164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(start_str == "") asar_throw_error(0, error_type_block, error_id_broken_incbin);
2165
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 start = getnum(start_str);
2166
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
36 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2167
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 string end_str(split+2);
2168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if(end_str == "") asar_throw_error(0, error_type_block, error_id_broken_incbin);
2169
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 end = getnum(end_str);
2170
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
30 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2171 42 }
2172
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 const char* current_file = get_current_file_name();
2173 54 string name;
2174 // RPG Hacker: Should this also throw on absolute paths?
2175 // E.g., on something starting with C:/ or whatever.
2176
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 24 times.
54 if (strchr(par, '\\'))
2177 {
2178 6 asar_throw_error(0, error_type_block, error_id_platform_paths);
2179 }
2180
2/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 name = safedequote(par);
2181 24 char * data;//I couldn't find a way to get this into an autoptr
2182
7/12
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
48 if (!readfile(name, current_file, &data, &len)) asar_throw_error(0, error_type_block, vfile_error_to_error_id(asar_get_last_io_error()), name.data());
2183 36 autoptr<char*> datacopy=data;
2184
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 if (!end) end=len;
2185
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if(start < 0) asar_throw_error(0, error_type_block, error_id_file_offset_out_of_bounds, dec(start).data(), name.data());
2186
3/8
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
36 if (end < start || end > len || end < 0) asar_throw_error(0, error_type_block, error_id_file_offset_out_of_bounds, dec(end).data(), name.data());
2187
2188
3/4
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 36 times.
102 for (int i=start;i<end;i++) write1((unsigned int)data[i]);
2189
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 add_addr_to_line(addrToLinePos);
2190 54 }
2191
6/6
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 588 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 639 times.
✓ Branch 4 taken 660 times.
✓ Branch 5 taken 639 times.
1299 else if (is("skip") || is("fill"))
2192 {
2193
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 654 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
660 if(numwords != 2 && numwords != 3 && numwords != 5) asar_throw_error(0, error_type_block, error_id_unknown_command);
2194
6/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 654 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 330 times.
660 if(numwords > 2 && stricmp(word[1], "align")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2195
6/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 654 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 330 times.
660 if(numwords == 5 && stricmp(word[3], "offset")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2196 int amount;
2197
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 654 times.
660 if(numwords > 2)
2198 {
2199
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int alignment = getnum(word[2]);
2200
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2201 6 int offset = 0;
2202
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(numwords==5)
2203 {
2204
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 offset = getnum(word[4]);
2205
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2206 }
2207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(alignment > 0x800000) asar_throw_error(0, error_type_block, error_id_alignment_too_big);
2208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(alignment < 1) asar_throw_error(0, error_type_block, error_id_alignment_too_small);
2209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(alignment & (alignment-1)) asar_throw_error(0, error_type_block, error_id_invalid_alignment);
2210 // i just guessed this formula but it seems to work
2211 6 amount = (alignment - ((snespos - offset) & (alignment-1))) & (alignment-1);
2212 }
2213 else
2214 {
2215
1/2
✓ Branch 0 taken 654 times.
✗ Branch 1 not taken.
654 amount = (int)getnum(par);
2216
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 648 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 324 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
654 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2217 }
2218
2/2
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 66 times.
654 if(is("skip")) step(amount);
2219 else
2220 {
2221
3/4
✓ Branch 0 taken 407070 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 407070 times.
✓ Branch 3 taken 66 times.
407136 for(int i=0; i < amount; i++) write1(fillbyte[i%12]);
2222
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 add_addr_to_line(addrToLinePos);
2223 }
2224
2225 }
2226
6/6
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 534 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 99 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 633 times.
639 else if (is0("cleartable"))
2227 {
2228
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 cleartable();
2229 }
2230
6/6
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 534 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 93 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 627 times.
633 else if (is0("pushtable"))
2231 {
2232
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 tablestack.append(thetable);
2233 }
2234
6/6
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 534 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 87 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 621 times.
627 else if (is0("pulltable"))
2235 {
2236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (tablestack.count <= 0) asar_throw_error(0, error_type_block, error_id_pulltable_without_table);
2237
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 thetable=tablestack[tablestack.count-1];
2238
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 tablestack.remove(tablestack.count-1);
2239 }
2240
5/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 585 times.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 585 times.
621 else if (is("function") && numwords >= 3)
2241 {
2242
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
36 if (stricmp(word[2], "=")) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2243
2/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
36 if (!confirmqpar(word[1])) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2244
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 string line=word[1];
2245
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 line.qnormalize();
2246 36 char * startpar=strqchr(line.data(), '(');
2247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2248 36 *startpar=0;
2249 36 startpar++;
2250
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
36 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_invalid_function_name);
2251 36 char * endpar=strqchr(startpar, ')');
2252 //confirmqpar requires that all parentheses are matched, and a starting one exists, therefore it is harmless to not check for nulls
2253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (endpar[1]) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2254 36 *endpar=0;
2255
2256 36 string pars;
2257
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
72 for(int i = 3; i < numwords; i++){
2258
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if(i > 3) pars += " ";
2259
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 pars += word[i];
2260 }
2261
2262
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 createuserfunc(line, startpar, pars.data());
2263 36 }
2264
6/6
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 318 times.
✓ Branch 3 taken 180 times.
✓ Branch 4 taken 318 times.
✓ Branch 5 taken 267 times.
585 else if (is1("print"))
2265 {
2266
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 8 times.
318 string out = handle_print(par);
2267
3/4
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 212 times.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
310 if (pass==2) print(out);
2268 310 }
2269
6/6
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 174 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 261 times.
267 else if (is1("reset"))
2270 {
2271 if(0);
2272
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 else if (!stricmp(par, "bytes")) bytes=0;
2273 else if (!stricmp(par, "freespaceuse")) freespaceuse=0;
2274 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
2275 }
2276
15/18
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 156 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 156 times.
✓ Branch 5 taken 87 times.
✓ Branch 6 taken 156 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 156 times.
✓ Branch 9 taken 87 times.
✓ Branch 10 taken 156 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 156 times.
✓ Branch 13 taken 87 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 156 times.
✓ Branch 16 taken 18 times.
✓ Branch 17 taken 243 times.
261 else if (is1("padbyte") || is1("padword") || is1("padlong") || is1("paddword"))
2277 {
2278 18 int len = 0;
2279
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (is("padbyte")) len=1;
2280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("padword")) len=2;
2281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("padlong")) len=3;
2282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("paddword")) len=4;
2283
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 unsigned int val=getnum(par);
2284
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
18 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2285
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 12 times.
156 for (int i=0;i<12;i+=len)
2286 {
2287 144 unsigned int tmpval=val;
2288
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 144 times.
288 for (int j=0;j<len;j++)
2289 {
2290 144 padbyte[i+j]=(unsigned char)tmpval;
2291 144 tmpval>>=8;
2292 }
2293 }
2294 }
2295
6/6
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 138 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 225 times.
243 else if (is1("pad"))
2296 {
2297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (freespaceid > 0) asar_throw_error(0, error_type_block, error_id_pad_in_freespace);
2298
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 int num=(int)getnum(par);
2299
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
18 if ((unsigned int)num & 0xFF000000) asar_throw_error(0, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex((unsigned int)num, 6).data());
2300
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (num>realsnespos)
2301 {
2302 12 int end=snestopc(num);
2303 12 int start=snestopc(realsnespos);
2304 12 int len=end-start;
2305
3/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 12 times.
72 for (int i=0;i<len;i++) write1(padbyte[i%12]);
2306
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 add_addr_to_line(addrToLinePos);
2307 }
2308 }
2309
18/18
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 108 times.
✓ Branch 5 taken 87 times.
✓ Branch 6 taken 102 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 102 times.
✓ Branch 9 taken 87 times.
✓ Branch 10 taken 96 times.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 96 times.
✓ Branch 13 taken 87 times.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 90 times.
✓ Branch 16 taken 48 times.
✓ Branch 17 taken 177 times.
225 else if (is1("fillbyte") || is1("fillword") || is1("filllong") || is1("filldword"))
2310 {
2311 48 int len = 0;
2312
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 18 times.
48 if (is("fillbyte")) len=1;
2313
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 42 times.
48 if (is("fillword")) len=2;
2314
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 42 times.
48 if (is("filllong")) len=3;
2315
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 42 times.
48 if (is("filldword")) len=4;
2316
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 unsigned int val= getnum(par);
2317
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
48 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2318
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 42 times.
408 for (int i=0;i<12;i+=len)
2319 {
2320 366 unsigned int tmpval=val;
2321
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 366 times.
870 for (int j=0;j<len;j++)
2322 {
2323 504 fillbyte[i+j]=(unsigned char)tmpval;
2324 504 tmpval>>=8;
2325 }
2326 }
2327 }
2328
5/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 90 times.
✓ Branch 5 taken 87 times.
177 else if (is1("arch"))
2329 {
2330
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45 times.
90 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2331
4/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 66 times.
90 if (!stricmp(par, "65816")) { arch=arch_65816; return; }
2332
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 24 times.
66 if (!stricmp(par, "spc700")) { arch=arch_spc700; return; }
2333
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 if (!stricmp(par, "superfx")) { arch=arch_superfx; return; }
2334 asar_throw_error(0, error_type_block, error_id_broken_command, "arch", "Invalid architecture, expected one of 65816, spc700, superfx");
2335 }
2336
8/10
✓ Branch 0 taken 87 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 51 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 15 times.
✓ Branch 8 taken 15 times.
✓ Branch 9 taken 72 times.
87 else if (is0("{") || is0("}")) {}
2337 else
2338 {
2339 15 asar_throw_error(1, error_type_block, error_id_unknown_command);
2340 }
2341
2342
6/6
✓ Branch 0 taken 20809 times.
✓ Branch 1 taken 25885 times.
✓ Branch 2 taken 20809 times.
✓ Branch 3 taken 25885 times.
✓ Branch 4 taken 20809 times.
✓ Branch 5 taken 25885 times.
113962 }
2343
2344 13473 bool assemblemapper(char** word, int numwords)
2345 {
2346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5973 times.
13473 auto previous_mapper = mapper;
2347 if(0);
2348
6/6
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 808 times.
✓ Branch 4 taken 99 times.
✓ Branch 5 taken 13374 times.
13473 else if (is0("lorom"))
2349 {
2350 //this also makes xkas set snespos to $008000 for some reason
2351 99 mapper=lorom;
2352 }
2353
6/6
✓ Branch 0 taken 808 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 762 times.
✓ Branch 4 taken 46 times.
✓ Branch 5 taken 13328 times.
13374 else if (is0("hirom"))
2354 {
2355 //xkas makes this point to $C00000
2356 46 mapper=hirom;
2357 }
2358
6/6
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 753 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 13319 times.
13328 else if (is0("exlorom"))
2359 {
2360 9 mapper = exlorom;
2361 }
2362
6/6
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 744 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 13310 times.
13319 else if (is0("exhirom"))
2363 {
2364 9 mapper=exhirom;
2365 }
2366
6/6
✓ Branch 0 taken 744 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 729 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 13295 times.
13310 else if (is0("sfxrom"))
2367 {
2368 15 mapper=sfxrom;
2369 }
2370
6/6
✓ Branch 0 taken 729 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 684 times.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 13250 times.
13295 else if (is0("norom"))
2371 {
2372 //$000000 would be the best snespos for this, but I don't care
2373 45 mapper=norom;
2374
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 21 times.
45 if(!force_checksum_fix)
2375 6 checksum_fix_enabled = false;//we don't know where the header is, so don't set the checksum
2376 }
2377
6/6
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 12566 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 675 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 13241 times.
13250 else if (is0("fullsa1rom"))
2378 {
2379 9 mapper=bigsa1rom;
2380 }
2381
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 13214 times.
13241 else if (is("sa1rom"))
2382 {
2383
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 6 times.
27 if (par)
2384 {
2385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2386
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
42 if (!is_digit(par[0]) || par[1]!=',' ||
2387
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 !is_digit(par[2]) || par[3]!=',' ||
2388
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 !is_digit(par[4]) || par[5]!=',' ||
2389
4/8
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 21 times.
42 !is_digit(par[6]) || par[7]) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2390 12 int len;
2391
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 autoptr<char**> pars=qpsplit(par, ',', &len);
2392
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 verify_paren(pars);
2393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (len!=4) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
21 sa1banks[0]=(par[0]-'0')<<20;
2395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
21 sa1banks[1]=(par[2]-'0')<<20;
2396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
21 sa1banks[4]=(par[4]-'0')<<20;
2397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
21 sa1banks[5]=(par[6]-'0')<<20;
2398 21 }
2399 else
2400 {
2401 6 sa1banks[0]=0<<20;
2402 6 sa1banks[1]=1<<20;
2403 6 sa1banks[4]=2<<20;
2404 6 sa1banks[5]=3<<20;
2405 }
2406 27 mapper=sa1rom;
2407 }
2408 13214 else return false;
2409
2410
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 146 times.
259 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2411
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 191 times.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45 times.
259 if(!mapper_set){
2412 169 mapper_set = true;
2413
4/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
90 }else if(previous_mapper != mapper){
2414 78 asar_throw_warning(1, warning_id_mapper_already_set);
2415 }
2416 259 return true;
2417 }
2418