asar coverage - build #262


src/asar/
File: src/asar/assembleblock.cpp
Date: 2025-02-27 19:01:43
Lines:
1323/1428
92.6%
Functions:
39/40
97.5%
Branches:
1921/2748
69.9%

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