asar coverage - build #188


src/asar/
File: src/asar/assembleblock.cpp
Date: 2024-01-30 04:24:34
Lines:
1342/1442
93.1%
Functions:
42/42
100.0%
Branches:
1981/2830
70.0%

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