asar coverage - build #72


src/asar/
File: src/asar/assembleblock.cpp
Date: 2024-01-18 08:25:45
Lines:
1370/1491
91.9%
Functions:
41/41
100.0%
Branches:
2074/3326
62.4%

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