asar coverage - build #69


src/asar/
File: src/asar/assembleblock.cpp
Date: 2024-01-17 04:38:17
Lines:
1332/1474
90.4%
Functions:
40/41
97.6%
Branches:
2035/3314
61.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 195 int snestopc_pick(int addr)
70 {
71 350 return snestopc(addr);
72 }
73
74 435992 inline void verifysnespos()
75 {
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 435992 times.
435992 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 435992 }
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 435662 inline void step(int num)
150 {
151
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 435386 times.
435662 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 435386 snespos += num;
167 435386 realsnespos += num;
168 }
169 435662 bytes+=num;
170 435662 }
171
172 435074 inline void write1_65816(unsigned int num)
173 {
174 435074 verifysnespos();
175
2/2
✓ Branch 0 taken 144994 times.
✓ Branch 1 taken 290080 times.
435074 if (pass==2)
176 {
177 144994 int pcpos=snestopc(realsnespos&0xFFFFFF);
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144994 times.
144994 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 144994 writeromdata_byte(pcpos, (unsigned char)num);
184
2/2
✓ Branch 0 taken 8592 times.
✓ Branch 1 taken 136402 times.
144994 if (pcpos>=romlen) romlen=pcpos+1;
185 }
186
4/4
✓ Branch 0 taken 145034 times.
✓ Branch 1 taken 290040 times.
✓ Branch 2 taken 8838 times.
✓ Branch 3 taken 136196 times.
435074 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 435074 step(1);
192 435074 ratsmetastate=ratsmeta_ban;
193 435074 }
194
195 int recent_opcode_num = 0;
196
197 227746 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.
227962 write1_65816(num);
200 421324 }
201
202 23411 static bool asblock_pick(char** word, int numwords)
203 {
204 23411 recent_opcode_num = 1;
205
206
2/2
✓ Branch 0 taken 17387 times.
✓ Branch 1 taken 6024 times.
23411 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 };
334 static autoarray<freespace_data> freespaces;
335
336 // id of the next unused freespace.
337 static int freespaceidnext;
338 // id of the current freespace, or 0 if not in freespace.
339 int freespaceid;
340 // start address of the current freespace, used for computing the length of the
341 // current freespace.
342 static int freespacestart;
343
344
345 2446 bool confirmname(const char * name)
346 {
347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2446 times.
2446 if (!name[0]) return false;
348
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 1834 times.
2446 if (is_digit(name[0])) return false;
349
2/2
✓ Branch 0 taken 15318 times.
✓ Branch 1 taken 1828 times.
17146 for (int i=0;name[i];i++)
350 {
351
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15312 times.
15318 if (!is_ualnum(name[i])) return false;
352 }
353 914 return true;
354 }
355
356 48993 string posneglabelname(const char ** input, bool define)
357 {
358 48993 const char* label = *input;
359
360 48993 string output;
361
362 25602 int depth = 0;
363 25602 bool ismacro = false;
364
365
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 48947 times.
48993 if (label[0] == '?')
366 {
367 23 ismacro = true;
368 46 label++;
369 }
370
4/4
✓ Branch 0 taken 25602 times.
✓ Branch 1 taken 23391 times.
✓ Branch 2 taken 192 times.
✓ Branch 3 taken 48749 times.
48993 if (label[0] == '-' || label[0] == '+')
371 {
372 122 char first = label[0];
373
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++;
374
375
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 16 times.
244 if (!ismacro)
376 {
377
2/2
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 44 times.
228 if (first == '+')
378 {
379 184 *input = label;
380
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]);
381
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]++;
382 }
383 else
384 {
385 44 *input = label;
386
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]++;
387
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]);
388 }
389 }
390 else
391 {
392
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)
393 {
394 if (!macrorecursion) asar_throw_error(0, error_type_block, error_id_macro_label_outside_of_macro);
395 }
396 else
397 {
398
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (first == '+')
399 {
400 8 *input = label;
401
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]);
402
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]++;
403 }
404 else
405 {
406 8 *input = label;
407
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]++;
408
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]);
409 }
410 }
411 }
412 }
413
414 48993 return output;
415 }
416
417 2032 static string labelname(const char ** rawname, bool define=false)
418 {
419 #define deref_rawname (*rawname)
420 1016 autoarray<string>* sublabellist = &sublabels;
421
422 2032 bool ismacro = (deref_rawname[0] == '?');
423 1016 bool issublabel = false;
424
425
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2008 times.
2032 if (ismacro)
426 {
427 24 deref_rawname++;
428 24 sublabellist = macrosublabels;
429 }
430
431 2032 string name;
432 1016 int i=-1;
433
434
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2032 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2032 if (is_digit(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
435
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 1964 times.
2032 if (*deref_rawname ==':')
436 {
437 68 deref_rawname++;
438
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 name=":";
439 }
440
4/4
✓ Branch 0 taken 982 times.
✓ Branch 1 taken 982 times.
✓ Branch 2 taken 883 times.
✓ Branch 3 taken 883 times.
1964 else if (!in_struct && !in_sub_struct)
441 {
442
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 1742 times.
1836 for (i=0;(*deref_rawname =='.');i++) deref_rawname++;
443
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1742 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1742 if (!is_ualnum(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
444
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 1654 times.
1742 if (i)
445 {
446
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);
447
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]+"_";
448 44 issublabel = true;
449 }
450 }
451
452
4/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2012 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 4 times.
2032 if (ismacro && !issublabel)
453 {
454 // RPG Hacker: Don't add the prefix for sublabels, because they already inherit it from
455 // their parents' names.
456
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);
457
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;
458 }
459
460
461
4/4
✓ Branch 0 taken 1828 times.
✓ Branch 1 taken 198 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 1804 times.
2026 if (in_struct || in_sub_struct)
462 {
463
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 198 times.
222 if(in_sub_struct)
464 {
465
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
24 name += struct_parent + ".";
466 }
467
1/2
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
222 name += struct_name;
468
1/2
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
222 name += '.';
469
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!!!
470 216 deref_rawname++;
471 }
472
473
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2020 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2020 if (!is_ualnum(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
474
475
6/6
✓ Branch 0 taken 8270 times.
✓ Branch 1 taken 8270 times.
✓ Branch 2 taken 162 times.
✓ Branch 3 taken 2020 times.
✓ Branch 4 taken 7260 times.
✓ Branch 5 taken 1010 times.
16540 while (is_ualnum(*deref_rawname) || *deref_rawname == '.')
476 {
477
1/2
✓ Branch 0 taken 7260 times.
✗ Branch 1 not taken.
14520 name+=*(deref_rawname++);
478 }
479
480
4/4
✓ Branch 0 taken 1010 times.
✓ Branch 1 taken 1010 times.
✓ Branch 2 taken 611 times.
✓ Branch 3 taken 611 times.
2020 if(!define && *deref_rawname == '[')
481 {
482
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++;
483
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);
484 56 deref_rawname++;
485
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);
486 }
487
488
6/6
✓ Branch 0 taken 1150 times.
✓ Branch 1 taken 1150 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 2020 times.
✓ Branch 4 taken 140 times.
✓ Branch 5 taken 1010 times.
2300 while (is_ualnum(*deref_rawname) || *deref_rawname == '.')
489 {
490
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
280 name+=*(deref_rawname++);
491 }
492
493
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1996 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
2020 if(*deref_rawname == '[') asar_throw_error(2, error_type_block, error_id_invalid_subscript);
494
495
4/4
✓ Branch 0 taken 669 times.
✓ Branch 1 taken 1327 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 105 times.
1996 if (define && i>=0)
496 {
497
1/2
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
564 (*sublabellist).reset(i);
498
2/4
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 282 times.
✗ Branch 3 not taken.
282 (*sublabellist)[i]=name;
499 }
500 1996 return name;
501 #undef deref_rawname
502 36 }
503
504 1198 inline bool labelvalcore(const char ** rawname, snes_label * rval, bool define, bool shouldthrow)
505 {
506
1/2
✓ Branch 0 taken 599 times.
✗ Branch 1 not taken.
1198 string name=labelname(rawname, define);
507
14/20
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 569 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 1152 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 569 times.
✓ Branch 12 taken 16 times.
✓ Branch 13 taken 583 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.
1244 if (ns && labels.exists(ns+name)) {*rval = labels.find(ns+name);}
508
5/6
✓ Branch 0 taken 1094 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 511 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 511 times.
✗ Branch 5 not taken.
1166 else if (labels.exists(name)) {*rval = labels.find(name);}
509 else
510 {
511
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)
512 {
513
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());
514 }
515 142 rval->pos = (unsigned int)-1;
516 142 rval->freespace_id = 0;
517 142 rval->is_static = false;
518 142 return false;
519 }
520 527 return true;
521 1198 }
522
523 596 snes_label labelval(const char ** rawname, bool define)
524 {
525 596 snes_label rval;
526 596 labelvalcore(rawname, &rval, define, true);
527 594 return rval;
528 }
529
530 28 snes_label labelval(string name, bool define)
531 {
532 28 const char * rawname=name;
533 28 snes_label rval;
534
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
28 labelvalcore(&rawname, &rval, define, true);
535 42 return rval;
536 }
537
538 518 bool labelval(const char ** rawname, snes_label * rval, bool define)
539 {
540 518 return labelvalcore(rawname, rval, define, false);
541 }
542
543 56 bool labelval(string name, snes_label * rval, bool define)
544 {
545 56 const char * str=name;
546
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
84 return labelvalcore(&str, rval, define, false);
547 }
548
549 1076 static void setlabel(string name, int loc=-1, bool is_static=false, int freespace_id = -1)
550 {
551
2/2
✓ Branch 0 taken 912 times.
✓ Branch 1 taken 164 times.
1076 if (loc==-1)
552 {
553
1/2
✓ Branch 0 taken 456 times.
✗ Branch 1 not taken.
912 verifysnespos();
554 912 loc=snespos;
555 }
556
557 1076 snes_label label_data;
558 1076 label_data.pos = (unsigned int)loc;
559 1076 label_data.is_static = is_static;
560
2/2
✓ Branch 0 taken 1074 times.
✓ Branch 1 taken 2 times.
1076 label_data.freespace_id = freespace_id == -1 ? freespaceid : freespace_id;
561
562 unsigned int labelpos;
563
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 716 times.
1076 if (pass==0)
564 {
565
4/4
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 179 times.
360 if (labels.exists(name))
566 {
567 2 movinglabelspossible=true;
568
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());
569 }
570
1/2
✓ Branch 0 taken 179 times.
✗ Branch 1 not taken.
358 labels.create(name) = label_data;
571 }
572
2/2
✓ Branch 0 taken 358 times.
✓ Branch 1 taken 358 times.
716 else if (pass==1)
573 {
574
1/2
✓ Branch 0 taken 179 times.
✗ Branch 1 not taken.
358 labels.create(name) = label_data;
575 }
576
1/2
✓ Branch 0 taken 358 times.
✗ Branch 1 not taken.
358 else if (pass==2)
577 {
578 //all label locations are known at this point, add a sanity check
579
3/6
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 179 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 179 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
358 if (!labels.exists(name)) asar_throw_error(2, error_type_block, error_id_label_on_third_pass);
580
1/2
✓ Branch 0 taken 179 times.
✗ Branch 1 not taken.
358 labelpos = labels.find(name).pos;
581
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 354 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
358 if ((int)labelpos != loc && !movinglabelspossible)
582 {
583
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());
584
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());
585
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else if(errored) return;
586 else asar_throw_error(2, error_type_block, error_id_label_moving);
587 }
588 }
589 }
590
591 table thetable;
592 static autoarray<table> tablestack;
593
594 676 static void cleartable()
595 {
596
2/4
✓ Branch 0 taken 676 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 338 times.
✗ Branch 3 not taken.
676 thetable = table();
597 676 }
598
599 struct pushable {
600 int arch;
601 int snespos;
602 int snesstart;
603 int snesposreal;
604 int snesstartreal;
605 int freeid;
606 int freest;
607 int arch1;
608 int arch2;
609 int arch3;
610 int arch4;
611 };
612 static autoarray<pushable> pushpc;
613 static int pushpcnum;
614
615 static autoarray<int> basestack;
616 static int basestacknum;
617
618 struct ns_pushable {
619 string ns;
620 autoarray<string> namespace_list;
621 bool nested_namespaces;
622 };
623
624 static autoarray<ns_pushable> pushns;
625 static int pushnsnum;
626
627
628 static unsigned char fillbyte[12];
629 static unsigned char padbyte[12];
630
631 static bool nested_namespaces = false;
632
633 1374 static int getfreespaceid()
634 {
635 /*static const int max_num_freespaces = 125;
636 if (freespaceidnext > max_num_freespaces) asar_throw_error(pass, error_type_fatal, error_id_freespace_limit_reached, max_num_freespaces);*/
637 1374 int newid = freespaceidnext++;
638
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 916 times.
1374 if(newid >= freespaces.count) {
639 458 freespaces[newid].leaked = true;
640 458 freespaces[newid].orgpos = -2;
641 458 freespaces[newid].orglen = -1;
642 458 freespaces[newid].cleanbyte = 0x00;
643 }
644 1374 return newid;
645 }
646
647 43536 void checkbankcross()
648 {
649
2/2
✓ Branch 0 taken 21768 times.
✓ Branch 1 taken 21768 times.
43536 if (!snespos_valid) return;
650
2/2
✓ Branch 0 taken 17672 times.
✓ Branch 1 taken 17672 times.
35344 if (disable_bank_cross_errors) return;
651
2/2
✓ Branch 0 taken 17483 times.
✓ Branch 1 taken 17483 times.
34966 unsigned int mask = 0x7FFF0000 | (check_half_banks_crossed ? 0x8000 : 0);
652
4/4
✓ Branch 0 taken 454 times.
✓ Branch 1 taken 34512 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 450 times.
34966 if (((snespos^startpos) & mask) && (((snespos - 1) ^ startpos) & mask))
653 {
654 4 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, snespos);
655 }
656 // don't verify realsnespos when using norom. this allows making custom mappers where the file layout doesn't follow bank borders
657
5/6
✓ Branch 0 taken 34680 times.
✓ Branch 1 taken 282 times.
✓ Branch 2 taken 450 times.
✓ Branch 3 taken 34230 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 450 times.
34962 else if (mapper != norom && ((realsnespos^realstartpos) & mask) && (((realsnespos - 1) ^ realstartpos) & mask))
658 {
659 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, realsnespos);
660 }
661 }
662
663 2820 static void freespaceend()
664 {
665
2/2
✓ Branch 0 taken 1374 times.
✓ Branch 1 taken 1446 times.
2820 if (freespaceid > 0)
666 {
667 1374 freespaces[freespaceid].len = snespos-freespacestart;
668 1374 snespos=(int)0xFFFFFFFF;
669 1374 snespos_valid = false;
670 }
671 2820 freespaceid = 0;
672 2820 }
673
674 int numopcodes;
675
676
1/2
✓ Branch 0 taken 4355 times.
✗ Branch 1 not taken.
8710 static void adddefine(const string & key, string & value)
677 {
678
1/2
✓ Branch 0 taken 8710 times.
✗ Branch 1 not taken.
8710 if (!defines.exists(key)) defines.create(key) = value;
679 8710 }
680
681 670 void initstuff()
682 {
683
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 440 times.
670 if (pass==0)
684 {
685 230 freespaces.reset();
686 230 movinglabelspossible = false;
687 }
688 670 arch=arch_65816;
689 670 mapper=lorom;
690 670 mapper_set = false;
691 670 calledmacros = 0;
692 670 reallycalledmacros = 0;
693 670 macrorecursion = 0;
694 670 defines.reset();
695 670 builtindefines.each(adddefine);
696 670 clidefines.each(adddefine);
697 335 ns="";
698 670 namespace_list.reset();
699 670 sublabels.reset();
700 670 poslabels.reset();
701 670 neglabels.reset();
702 670 macroposlabels = nullptr;
703 670 macroneglabels = nullptr;
704 670 macrosublabels = nullptr;
705 670 cleartable();
706 670 pushpc.reset();
707 670 pushpcnum=0;
708 670 pushns.reset();
709 670 pushnsnum = 0;
710 670 bytes=0;
711 670 freespaceuse=0;
712 670 memset(fillbyte, 0, sizeof(fillbyte));
713 670 memset(padbyte, 0, sizeof(padbyte));
714 670 snespos_valid = false;
715 670 snespos=(int)0xFFFFFFFF;
716 670 realsnespos= (int)0xFFFFFFFF;
717 670 startpos= (int)0xFFFFFFFF;
718 670 realstartpos= (int)0xFFFFFFFF;
719 //fastrom=false;
720 670 freespaceidnext=1;
721 670 freespaceid=0;
722 670 numopcodes=0;
723 670 incsrcdepth = 0;
724
725 670 optimizeforbank = -1;
726 670 optimize_dp = optimize_dp_flag::NONE;
727 670 dp_base = 0;
728 670 optimize_address = optimize_address_flag::DEFAULT;
729
730 670 in_struct = false;
731 670 in_sub_struct = false;
732 670 in_spcblock = false;
733
734
1/2
✓ Branch 0 taken 670 times.
✗ Branch 1 not taken.
670 if (arch==arch_65816) asinit_65816();
735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 670 times.
670 if (arch==arch_spc700) asinit_spc700();
736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 670 times.
670 if (arch==arch_superfx) asinit_superfx();
737
738 670 disable_bank_cross_errors = false;
739 670 check_half_banks_crossed = false;
740 670 nested_namespaces = false;
741
742 670 includeonce.reset();
743
744 extern AddressToLineMapping addressToLineMapping;
745 670 addressToLineMapping.reset();
746
747 670 push_warnings(false);
748
749 670 initmathcore();
750
751 670 callstack.reset();
752 #if defined(_WIN32) || !defined(NO_USE_THREADS)
753 335 init_stack_use_check();
754 #endif
755 670 }
756
757 int get_freespace_pin_target(int target_id) {
758 // union-find algorithm
759 while(freespaces[target_id].pin_target_id != target_id) {
760 // i love programming
761 freespaces[target_id].pin_target_id =
762 freespaces[freespaces[target_id].pin_target_id].pin_target_id;
763 target_id = freespaces[target_id].pin_target_id;
764 }
765 return target_id;
766 }
767
768 220 void resolve_pinned_freespaces() {
769
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 220 times.
718 for(int i = 0; i < freespaces.count; i++)
770 // default to everyone being in a separate component
771 498 freespaces[i].pin_target_id = i;
772
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 220 times.
718 for(int i = 0; i < freespaces.count; i++) {
773
1/2
✓ Branch 0 taken 249 times.
✗ Branch 1 not taken.
249 freespace_data& fs = freespaces[i];
774
1/2
✓ Branch 0 taken 498 times.
✗ Branch 1 not taken.
498 if(fs.pin_target == "") continue;
775 snes_label value;
776 if(fs.pin_target_ns && labels.exists(fs.pin_target_ns + fs.pin_target))
777 value = labels.find(fs.pin_target_ns + fs.pin_target);
778 else if(labels.exists(fs.pin_target))
779 value = labels.find(fs.pin_target);
780 else continue; // the error for this is thrown in the freespace command during pass 2
781 fs.pin_target_id = get_freespace_pin_target(value.freespace_id);
782 fs.len = 0;
783 }
784 220 }
785
786 220 void allocate_freespaces() {
787
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 220 times.
718 for(int i = 0; i < freespaces.count; i++) {
788 249 freespace_data& fs = freespaces[i];
789
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 496 times.
498 if(fs.dont_find) continue;
790
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 492 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
496 if(fs.is_static && fs.orgpos > 0) {
791 2 fs.pos = fs.orgpos;
792 2 continue;
793 }
794 // TODO:
795 // * fs.pin_target_id
796 // * fs.search_start
797 // and possibly fancier align
798 494 fs.pos = getsnesfreespace(fs.len, fs.bank, true, true, fs.flag_align, fs.cleanbyte, fs.write_rats);
799 }
800 // relocate all labels that were in freespace to point them to their real location
801 220 labels.each([](const char * key, snes_label & val) {
802
6/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 304 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 153 times.
385 if(val.freespace_id != 0 && !freespaces[val.freespace_id].dont_find) {
803 52 val.pos += freespaces[val.freespace_id].pos;
804 }
805 358 });
806 220 }
807
808 //void nerf(const string& left, string& right){puts(S left+" = "+right);}
809
810 660 void finishpass()
811 {
812 660 verify_warnings();
813 660 pull_warnings(false);
814
815 //defines.traverse(nerf);
816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
660 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_missing_endspcblock);
817
2/4
✓ Branch 0 taken 660 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 660 times.
660 if (in_struct || in_sub_struct) asar_throw_error(pass, error_type_null, error_id_struct_without_endstruct);
818
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
660 else if (pushpcnum && pass == 0) asar_throw_error(pass, error_type_null, error_id_pushpc_without_pullpc);
819
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
660 else if (pushnsnum && pass == 0) asar_throw_error(pass, error_type_null, error_id_pushns_without_pullns);
820 660 freespaceend();
821
2/2
✓ Branch 0 taken 618 times.
✓ Branch 1 taken 42 times.
660 if (arch==arch_65816) asend_65816();
822
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 630 times.
660 if (arch==arch_spc700) asend_spc700();
823
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 648 times.
660 if (arch==arch_superfx) asend_superfx();
824
825 660 deinitmathcore();
826
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 440 times.
660 if(pass == 0) {
827 220 resolve_pinned_freespaces();
828
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 220 times.
440 } else if(pass == 1) {
829 220 allocate_freespaces();
830 220 handle_cleared_rats_tags();
831 }
832 #if defined(_WIN32) || !defined(NO_USE_THREADS)
833 330 deinit_stack_use_check();
834 #endif
835 660 }
836
837 43639 static bool addlabel(const char * label, int pos=-1, bool global_label = false)
838 {
839
4/4
✓ Branch 0 taken 28949 times.
✓ Branch 1 taken 14690 times.
✓ Branch 2 taken 13369 times.
✓ Branch 3 taken 15580 times.
43639 if (!label[0] || label[0]==':') return false;//colons are reserved for special labels
840
841 28949 const char* posneglabel = label;
842
1/2
✓ Branch 0 taken 15580 times.
✗ Branch 1 not taken.
28949 string posnegname = posneglabelname(&posneglabel, true);
843
844
4/4
✓ Branch 0 taken 15640 times.
✓ Branch 1 taken 13309 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 15520 times.
28949 if (posnegname.length() > 0)
845 {
846
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 60 times.
120 if (global_label) return false;
847
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);
848
2/4
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
120 setlabel(posnegname, pos);
849 120 return true;
850 }
851
7/8
✓ Branch 0 taken 28043 times.
✓ Branch 1 taken 786 times.
✓ Branch 2 taken 27983 times.
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 27977 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 27977 times.
28829 if (label[strlen(label)-1]==':' || label[0]=='.' || label[0]=='?' || label[0] == '#')
852 {
853
2/2
✓ Branch 0 taken 426 times.
✓ Branch 1 taken 426 times.
852 if (!label[1]) return false;
854
6/8
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 798 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.
840 if(global_label && (in_struct || in_sub_struct || label[0]=='?')) return false;
855
856 417 bool define = true;
857
858
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 810 times.
834 if (label[0] == '#')
859 {
860 12 define = false;
861 24 label++;
862 }
863
864 // RPG Hacker: Also checking label[1] now, since it might be a macro sublabel.
865 // Also, apparently this here doesn't account for main labels. I guess because
866 // we don't even get here in the first place if they don't include a colon?
867
7/8
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 534 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 528 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 264 times.
834 bool requirecolon = (label[0] != '.' && label[1] != '.') && (in_struct || in_sub_struct);
868
2/2
✓ Branch 0 taken 798 times.
✓ Branch 1 taken 36 times.
834 string name=labelname(&label, define);
869
2/2
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 42 times.
798 if (label[0]==':') label++;
870
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);
871
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
42 else if (global_label) return false;
872
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 792 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
792 if (label[0]) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
873
10/12
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 342 times.
✓ Branch 2 taken 102 times.
✓ Branch 3 taken 348 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 48 times.
✓ Branch 7 taken 348 times.
✓ Branch 8 taken 48 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 48 times.
✗ Branch 11 not taken.
840 if (ns && !global_label) name=ns+name;
874
9/10
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 186 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 582 times.
✓ Branch 4 taken 469 times.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 396 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 394 times.
✓ Branch 9 taken 2 times.
794 setlabel(name, pos, ((in_struct || in_sub_struct) && static_struct));
875 788 return true;
876 798 }
877 15094 return false;
878 28949 }
879
880 14790 static void add_addr_to_line(int pos)
881 {
882
2/2
✓ Branch 0 taken 5224 times.
✓ Branch 1 taken 9566 times.
14790 if (pass == 2)
883 5224 addressToLineMapping.includeMapping(get_current_file_name(), get_current_line() + 1, pos);
884 14790 }
885
886 static autoarray<bool> elsestatus;
887 int numtrue=0;//if 1 -> increase both
888 int numif = 0; //if 0 or inside if 0 -> increase only numif
889
890 autoarray<whiletracker> whilestatus;
891 int single_line_for_tracker;
892
893
894 90 static void push_pc()
895 {
896 90 pushpc[pushpcnum].arch=arch;
897 90 pushpc[pushpcnum].snespos=snespos;
898 90 pushpc[pushpcnum].snesstart=startpos;
899 90 pushpc[pushpcnum].snesposreal=realsnespos;
900 90 pushpc[pushpcnum].snesstartreal=realstartpos;
901 90 pushpc[pushpcnum].freeid=freespaceid;
902 90 pushpc[pushpcnum].freest=freespacestart;
903 90 pushpcnum++;
904 90 }
905
906 90 static void pop_pc()
907 {
908 90 pushpcnum--;
909 90 snespos=pushpc[pushpcnum].snespos;
910 90 startpos=pushpc[pushpcnum].snesstart;
911 90 realsnespos=pushpc[pushpcnum].snesposreal;
912 90 realstartpos=pushpc[pushpcnum].snesstartreal;
913 90 freespaceid=pushpc[pushpcnum].freeid;
914 90 freespacestart=pushpc[pushpcnum].freest;
915 90 }
916
917
918 312 string handle_print(char* input)
919 {
920 312 string out;
921
1/2
✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
312 autoptr<char**> pars = qpsplit(input, ',');
922
1/2
✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
312 verify_paren(pars);
923
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 306 times.
834 for (int i = 0; pars[i]; i++)
924 {
925 if (0);
926
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]);
927
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);
928
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);
929
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);
930
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
174 else if (!strncasecmp(pars[i], "bin(", strlen("bin(")) ||
931
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(")) ||
932
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(")) ||
933
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(")))
934 {
935 120 char * arg1pos = strchr(pars[i], '(') + 1;
936 60 char * endpos = strchr(arg1pos, '\0');
937
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--;
938
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);
939
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
120 string paramstr = string(arg1pos, (int)(endpos - arg1pos));
940
941 int numargs;
942
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 autoptr<char**> params = qpsplit(paramstr.temp_raw(), ',', &numargs);
943
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 verify_paren(params);
944
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);
945 60 int precision = 0;
946 120 bool hasprec = numargs == 2;
947
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 60 times.
120 if (hasprec)
948 {
949
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 precision = getnum(params[1]);
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
78 if (precision < 0) precision = 0;
951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if (precision > 64) precision = 64;
952 }
953 120 *(arg1pos - 1) = '\0'; // allows more convenient comparsion functions
954
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"))
955 {
956 // sadly printf doesn't have binary, so let's roll our own
957
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 int64_t value = getnum(params[0]);
958 char buffer[65];
959
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
30 if (value < 0) {
960
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 out += '-';
961 6 value = -value;
962 // decrement precision because we've output one char already
963 6 precision -= 1;
964
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (precision<0) precision = 0;
965 }
966
2/2
✓ Branch 0 taken 1920 times.
✓ Branch 1 taken 30 times.
1950 for (int j = 0; j < 64; j++) {
967 1920 buffer[63 - j] = '0' + ((value & (1ull << j)) >> j);
968 }
969 30 buffer[64] = 0;
970 15 int startidx = 0;
971
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++;
972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (startidx == 64) startidx--; // always want to print at least one digit
973
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
30 out += buffer + startidx;
974 }
975
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"))
976 {
977
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 int64_t value = getnum(params[0]);
978 char buffer[65];
979
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 snprintf(buffer, 65, "%0*" PRId64, precision, value);
980
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 out += buffer;
981 }
982
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"))
983 {
984
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 int64_t value = getnum(params[0]);
985 char buffer[65];
986
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 snprintf(buffer, 65, "%0*" PRIX64, precision, value);
987
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 out += buffer;
988 }
989
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"))
990 {
991
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 6 times.
42 if (!hasprec) precision = 5;
992
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);
993 }
994 120 }
995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
996 }
997 459 return out;
998 318 }
999
1000 // single_line_for_tracker is:
1001 // 0 if not in first block of line, not in (single-line) for loop
1002 // 1 if first block of line
1003 // 2 if in single-line for loop
1004 // 3 if after endfor (of a single-line loop)
1005 47047 void assembleblock(const char * block, int& single_line_for_tracker)
1006 {
1007 #define is(test) (!stricmpwithlower(word[0], test))
1008 #define is0(test) (numwords==1 && !stricmpwithlower(word[0], test))
1009 #define is1(test) (numwords==2 && !stricmpwithlower(word[0], test))
1010 #define is2(test) (numwords==3 && !stricmpwithlower(word[0], test))
1011 #define is3(test) (numwords==4 && !stricmpwithlower(word[0], test))
1012 #define par word[1]
1013
1014
1/2
✓ Branch 0 taken 24629 times.
✗ Branch 1 not taken.
47047 callstack_push cs_push(callstack_entry_type::BLOCK, block);
1015
1016 int numwords;
1017
1/2
✓ Branch 0 taken 24629 times.
✗ Branch 1 not taken.
47047 string splitblock = block;
1018
1/2
✓ Branch 0 taken 47047 times.
✗ Branch 1 not taken.
47047 char ** word = qsplit(splitblock.temp_raw(), ' ', &numwords);
1019 24629 autoptr<char **> scope_word = word;
1020 // when writing out the data for the addrToLine mapping,
1021 // we want to write out the snespos we had before writing opcodes
1022 47047 int addrToLinePos = realsnespos & 0xFFFFFF;
1023
1024
14/14
✓ Branch 0 taken 44763 times.
✓ Branch 1 taken 3162 times.
✓ Branch 2 taken 44077 times.
✓ Branch 3 taken 686 times.
✓ Branch 4 taken 23831 times.
✓ Branch 5 taken 20246 times.
✓ Branch 6 taken 23351 times.
✓ Branch 7 taken 480 times.
✓ Branch 8 taken 43557 times.
✓ Branch 9 taken 40 times.
✓ Branch 10 taken 878 times.
✓ Branch 11 taken 42679 times.
✓ Branch 12 taken 439 times.
✓ Branch 13 taken 24609 times.
47925 while (numif==numtrue && word[0] && (!word[1] || strcmp(word[1], "=")) && addlabel(word[0]))
1025 {
1026 878 word++;
1027 878 numwords--;
1028 }
1029
4/4
✓ Branch 0 taken 46321 times.
✓ Branch 1 taken 686 times.
✓ Branch 2 taken 22055 times.
✓ Branch 3 taken 24266 times.
47007 if (!word[0] || !word[0][0]) return;
1030
12/12
✓ Branch 0 taken 30845 times.
✓ Branch 1 taken 558 times.
✓ Branch 2 taken 30515 times.
✓ Branch 3 taken 330 times.
✓ Branch 4 taken 30485 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 28559 times.
✓ Branch 7 taken 1926 times.
✓ Branch 8 taken 13174 times.
✓ Branch 9 taken 15385 times.
✓ Branch 10 taken 1596 times.
✓ Branch 11 taken 15211 times.
31403 if (is("if") || is("elseif") || is("assert") || is("while") || is("for"))
1031 {
1032 3192 string errmsg;
1033 3192 whiletracker wstatus;
1034
1/2
✓ Branch 0 taken 3192 times.
✗ Branch 1 not taken.
3192 wstatus.startline = get_current_line();
1035 3192 wstatus.iswhile = is("while");
1036 3192 wstatus.cond = false;
1037 3192 wstatus.is_for = false;
1038 3192 wstatus.for_start = wstatus.for_end = wstatus.for_cur = 0;
1039 3192 wstatus.for_has_var_backup = false;
1040
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 2844 times.
3192 if(is("for")) wstatus.is_for = true;
1041
1042 1596 bool is_for_cont = false;
1043 // if this is a for loop and a whilestatus entry already exists at this level,
1044 // and the for loop isn't finished, this is a continuation of the for loop
1045
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.
2117 if (is("for") && whilestatus.count > numif && whilestatus[numif].is_for
1046
9/10
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 2844 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 1473 times.
3532 && whilestatus[numif].for_cur < whilestatus[numif].for_end)
1047 123 is_for_cont = true;
1048
5/8
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 123 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1473 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1473 times.
✗ Branch 7 not taken.
3192 whiletracker& addedwstatus = is_for_cont ? whilestatus[numif] : (whilestatus[numif] = wstatus);
1049
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 3162 times.
3192 if (is("assert"))
1050 {
1051
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 autoptr<char**> tokens = qpsplit(word[numwords - 1], ',');
1052
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 verify_paren(tokens);
1053
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)
1054 {
1055 12 string rawerrmsg;
1056 6 size_t pos = 1;
1057
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 12 times.
54 while (tokens[pos])
1058 {
1059
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
42 rawerrmsg += tokens[pos];
1060
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 12 times.
42 if (tokens[pos + 1] != NULL)
1061 {
1062
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
30 rawerrmsg += ",";
1063 }
1064 21 pos++;
1065 }
1066
1067
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());
1068 12 }
1069 30 }
1070
1071 //handle nested if statements
1072
8/8
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 2856 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 1515 times.
3192 if (numtrue!=numif && !(is("elseif") && numtrue+1==numif))
1073 {
1074
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++;
1075 81 return;
1076 }
1077
8/8
✓ Branch 0 taken 2520 times.
✓ Branch 1 taken 510 times.
✓ Branch 2 taken 642 times.
✓ Branch 3 taken 1878 times.
✓ Branch 4 taken 330 times.
✓ Branch 5 taken 312 times.
✓ Branch 6 taken 1359 times.
✓ Branch 7 taken 156 times.
3030 if ((is("if") || is("while") || is("for"))) numif++;
1078
1079
2/2
✓ Branch 0 taken 5304 times.
✓ Branch 1 taken 3030 times.
8334 for(int i = 1; i < numwords - 1; i++)
1080 {
1081 5304 word[i][strlen(word[i])] = ' ';
1082 }
1083 3030 numwords = 2;
1084
1085 bool cond;
1086
2/2
✓ Branch 0 taken 2700 times.
✓ Branch 1 taken 330 times.
3030 if(!is("for"))
1087 {
1088
1/2
✓ Branch 0 taken 2700 times.
✗ Branch 1 not taken.
2700 cond = getnum(word[1]);
1089
8/10
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 2640 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 1350 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 15 times.
2700 if (foundlabel && !foundlabel_static && !is("assert")) asar_throw_error(1, error_type_block, error_id_label_in_conditional, word[0]);
1090 }
1091
1092
2/2
✓ Branch 0 taken 330 times.
✓ Branch 1 taken 2670 times.
3000 if (is("for"))
1093 {
1094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 330 times.
330 if(single_line_for_tracker != 1)
1095 {
1096 numif--;
1097 asar_throw_error(0, error_type_line, error_id_bad_single_line_for);
1098 }
1099
1100
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 246 times.
330 if(!is_for_cont)
1101 {
1102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
84 char* past_eq = strchr(word[1], '=');
1103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if(!past_eq)
1104 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "missing loop range");
1105
1106
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 string varname(word[1], past_eq - word[1]);
1107 84 past_eq += 1;
1108
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 strip_whitespace(varname);
1109
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 if(!validatedefinename(varname))
1110 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "invalid define name");
1111
1112
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 char* range_sep = strqpstr(past_eq, "..");
1113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if(!range_sep)
1114 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "invalid loop range");
1115
1116
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 string for_start(past_eq, range_sep - past_eq);
1117
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 strip_whitespace(for_start);
1118
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 string for_end(range_sep+2);
1119
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 strip_whitespace(for_end);
1120
1121
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_start = getnum(for_start);
1122
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
84 if(foundlabel && !foundlabel_static)
1123 asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1124
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_end = getnum(for_end);
1125
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
84 if(foundlabel && !foundlabel_static)
1126 asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1127
1128
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
84 addedwstatus.for_variable = varname;
1129 84 addedwstatus.for_cur = addedwstatus.for_start;
1130 84 }
1131 246 else addedwstatus.for_cur++;
1132
1133 330 addedwstatus.cond = addedwstatus.for_cur < addedwstatus.for_end;
1134 330 single_line_for_tracker = 2;
1135
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 84 times.
330 if(addedwstatus.cond)
1136 {
1137
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 27 times.
246 numtrue++;
1138
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))
1139 {
1140 192 addedwstatus.for_has_var_backup = true;
1141
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);
1142 }
1143
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);
1144 }
1145 }
1146
6/6
✓ Branch 0 taken 2190 times.
✓ Branch 1 taken 480 times.
✓ Branch 2 taken 1095 times.
✓ Branch 3 taken 1095 times.
✓ Branch 4 taken 1179 times.
✓ Branch 5 taken 156 times.
2670 else if (is("if") || is("while"))
1147 {
1148 if(0);
1149
2/2
✓ Branch 0 taken 1938 times.
✓ Branch 1 taken 420 times.
2358 else if (cond)
1150 {
1151 1938 numtrue++;
1152
1/2
✓ Branch 0 taken 969 times.
✗ Branch 1 not taken.
1938 elsestatus[numif]=true;
1153 }
1154
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
210 else if (!cond)
1155 {
1156
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
420 elsestatus[numif]=false;
1157 }
1158 2358 addedwstatus.cond = cond;
1159 }
1160
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 30 times.
312 else if (is("elseif"))
1161 {
1162
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);
1163
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);
1164
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 174 times.
282 if (numif==numtrue) numtrue--;
1165
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])
1166 {
1167 78 numtrue++;
1168
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
78 elsestatus[numif]=true;
1169 }
1170 }
1171 // otherwise, must be assert command
1172
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)
1173 {
1174
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());
1175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 else asar_throw_error(2, error_type_block, error_id_assertion_failed, ".");
1176 }
1177
4/4
✓ Branch 0 taken 1496 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 1496 times.
✓ Branch 3 taken 81 times.
3311 }
1178
14/14
✓ Branch 0 taken 6096 times.
✓ Branch 1 taken 22115 times.
✓ Branch 2 taken 5538 times.
✓ Branch 3 taken 558 times.
✓ Branch 4 taken 5538 times.
✓ Branch 5 taken 22115 times.
✓ Branch 6 taken 3612 times.
✓ Branch 7 taken 1926 times.
✓ Branch 8 taken 3612 times.
✓ Branch 9 taken 22115 times.
✓ Branch 10 taken 348 times.
✓ Branch 11 taken 3264 times.
✓ Branch 12 taken 1416 times.
✓ Branch 13 taken 13795 times.
28211 else if (is0("endif") || is0("endwhile") || is0("endfor"))
1179 {
1180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2832 times.
2832 if (!numif)
1181 asar_throw_error(1, error_type_block, error_id_misplaced_endif);
1182
1/2
✓ Branch 0 taken 1416 times.
✗ Branch 1 not taken.
2832 whiletracker& thisws = whilestatus[numif - 1];
1183
1184
3/4
✓ Branch 0 taken 558 times.
✓ Branch 1 taken 1926 times.
✓ Branch 2 taken 558 times.
✗ Branch 3 not taken.
2484 if((!thisws.is_for && !thisws.iswhile && !is("endif")) ||
1185
7/8
✓ Branch 0 taken 2484 times.
✓ Branch 1 taken 348 times.
✓ Branch 2 taken 1926 times.
✓ Branch 3 taken 906 times.
✓ Branch 4 taken 1926 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 174 times.
✓ Branch 7 taken 2658 times.
6732 (thisws.iswhile && !is("endwhile")) ||
1186
3/4
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1416 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 174 times.
1590 (thisws.is_for && !is("endfor")))
1187 asar_throw_error(1, error_type_block, error_id_misplaced_endif);
1188
1189
2/2
✓ Branch 0 taken 2076 times.
✓ Branch 1 taken 756 times.
2832 if (numif==numtrue) numtrue--;
1190 2832 numif--;
1191
1192
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 2484 times.
2832 if(thisws.is_for)
1193 {
1194
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 288 times.
348 if(single_line_for_tracker == 2) single_line_for_tracker = 3;
1195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
348 if(moreonline)
1196 {
1197 // sabotage the whilestatus to prevent the loop running again
1198 // and spamming more of the same error
1199 thisws.for_cur = thisws.for_end;
1200 thisws.cond = false;
1201 asar_throw_error(0, error_type_block, error_id_bad_single_line_for);
1202 }
1203
1204
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 102 times.
348 if(thisws.cond)
1205 {
1206
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 54 times.
246 if(thisws.for_has_var_backup)
1207
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;
1208 else
1209
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 defines.remove(thisws.for_variable);
1210 }
1211 }
1212 }
1213
6/6
✓ Branch 0 taken 3264 times.
✓ Branch 1 taken 22115 times.
✓ Branch 2 taken 1632 times.
✓ Branch 3 taken 1632 times.
✓ Branch 4 taken 138 times.
✓ Branch 5 taken 13657 times.
25379 else if (is0("else"))
1214 {
1215
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 276 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
276 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_else);
1216
5/12
✓ Branch 0 taken 276 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 276 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 138 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 138 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 138 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
276 if (whilestatus[numif - 1].iswhile || whilestatus[numif - 1].is_for) asar_throw_error(1, error_type_block, error_id_else_in_while_loop);
1217
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 150 times.
276 else if (numif==numtrue) numtrue--;
1218
8/8
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 24 times.
✓ Branch 7 taken 51 times.
219 else if (numif==numtrue+1 && !elsestatus[numif])
1219 {
1220 48 numtrue++;
1221
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
48 elsestatus[numif]=true;
1222 }
1223 }
1224
2/2
✓ Branch 0 taken 11446 times.
✓ Branch 1 taken 13657 times.
25103 else if (numif!=numtrue) return;
1225
4/4
✓ Branch 0 taken 23401 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 9656 times.
✓ Branch 3 taken 13745 times.
23411 else if (asblock_pick(word, numwords))
1226 {
1227
1/2
✓ Branch 0 taken 9656 times.
✗ Branch 1 not taken.
9656 add_addr_to_line(addrToLinePos);
1228 9656 numopcodes += recent_opcode_num;
1229 }
1230
12/12
✓ Branch 0 taken 12641 times.
✓ Branch 1 taken 1104 times.
✓ Branch 2 taken 8861 times.
✓ Branch 3 taken 3780 times.
✓ Branch 4 taken 8813 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 8213 times.
✓ Branch 7 taken 600 times.
✓ Branch 8 taken 96 times.
✓ Branch 9 taken 8117 times.
✓ Branch 10 taken 2262 times.
✓ Branch 11 taken 5716 times.
13745 else if (numwords > 1 && (is("db") || is("dw") || is("dl") || is("dd")))
1231 {
1232 4524 string line;
1233
2/2
✓ Branch 0 taken 4524 times.
✓ Branch 1 taken 4524 times.
9048 for(int i = 1; i < numwords; i++){
1234
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4524 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4524 if(i > 1) line += " ";
1235
1/2
✓ Branch 0 taken 2262 times.
✗ Branch 1 not taken.
4524 line += word[i];
1236 }
1237
1/2
✓ Branch 0 taken 4524 times.
✗ Branch 1 not taken.
4524 autoptr<char**> pars=qpsplit(line.temp_raw(), ',');
1238
1/2
✓ Branch 0 taken 4524 times.
✗ Branch 1 not taken.
4524 verify_paren(pars);
1239
1240 void (*do_write)(unsigned int);
1241 4524 char first = to_lower(word[0][1]);
1242
2/2
✓ Branch 0 taken 2262 times.
✓ Branch 1 taken 2262 times.
4524 if (first == 'b') do_write = &write1;
1243
2/2
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 372 times.
744 else if (first == 'w') do_write = &write2;
1244
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 348 times.
696 else if (first == 'l') do_write = &write3;
1245 48 else do_write = &write4;
1246
1247
2/2
✓ Branch 0 taken 5262 times.
✓ Branch 1 taken 4502 times.
9764 for (int i=0;pars[i];i++)
1248 {
1249
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 5046 times.
5262 if (pars[i][0]=='"')
1250 {
1251
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 char * str=const_cast<char*>(safedequote(pars[i]));
1252 216 int codepoint = 0u;
1253
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 str += utf8_val(&codepoint, str);
1254
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 )
1255 {
1256
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));
1257
1/2
✓ Branch 0 taken 882 times.
✗ Branch 1 not taken.
882 str += utf8_val(&codepoint, str);
1258 }
1259
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);
1260 }
1261 else
1262 {
1263
5/6
✓ Branch 0 taken 1680 times.
✓ Branch 1 taken 3366 times.
✓ Branch 2 taken 1658 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 5024 times.
✗ Branch 5 not taken.
5046 do_write((pass==2)?getnum(pars[i]):0);
1264 }
1265 }
1266
1/2
✓ Branch 0 taken 4502 times.
✗ Branch 1 not taken.
4502 add_addr_to_line(addrToLinePos);
1267 4546 }
1268
2/2
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 8699 times.
9221 else if(word[0][0]=='%')
1269 {
1270
2/2
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 12 times.
522 callmacro(strchr(block, '%')+1);
1271 }
1272
6/6
✓ Branch 0 taken 7231 times.
✓ Branch 1 taken 1468 times.
✓ Branch 2 taken 2510 times.
✓ Branch 3 taken 4721 times.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 5395 times.
8699 else if (is1("undef"))
1273 {
1274
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);
1275
1276
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))
1277 {
1278
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 defines.remove(def);
1279 }
1280 else
1281 {
1282
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());
1283 }
1284 120 }
1285
6/6
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 7991 times.
✓ Branch 2 taken 294 times.
✓ Branch 3 taken 294 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 5392 times.
8579 else if (is0("error"))
1286 {
1287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(0, error_type_block, error_id_error_command, ".");
1288 }
1289
6/6
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 7991 times.
✓ Branch 2 taken 291 times.
✓ Branch 3 taken 291 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 5389 times.
8573 else if (is0("warn"))
1290 {
1291
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(2, warning_id_warn_command, ".");
1292 }
1293
6/6
✓ Branch 0 taken 7111 times.
✓ Branch 1 taken 1456 times.
✓ Branch 2 taken 2450 times.
✓ Branch 3 taken 4661 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 5383 times.
8567 else if (is1("error"))
1294 {
1295
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 string out = handle_print(par);
1296 // RPG Hacker: This used to be on pass 0, which had its merits (you don't want to miss a potentially critical
1297 // user-generated error, just because a bazillion other errors are thrown in passes before it). However, I
1298 // don't see how to support print functions with this without moving it to pass 2. Suggestions are welcome.
1299
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());
1300 12 }
1301
6/6
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 1456 times.
✓ Branch 2 taken 2444 times.
✓ Branch 3 taken 4655 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 5377 times.
8555 else if (is1("warn"))
1302 {
1303
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 string out = handle_print(par);
1304
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());
1305 12 }
1306
6/6
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 1456 times.
✓ Branch 2 taken 2438 times.
✓ Branch 3 taken 4649 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 5353 times.
8543 else if (is1("warnings"))
1307 {
1308
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)
1309 {
1310
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 push_warnings();
1311 }
1312
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)
1313 {
1314
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 pull_warnings();
1315 }
1316 else
1317 {
1318 asar_throw_error(0, error_type_block, error_id_broken_command, "warnings", "Unknown parameter");
1319 }
1320 }
1321
6/6
✓ Branch 0 taken 808 times.
✓ Branch 1 taken 7687 times.
✓ Branch 2 taken 404 times.
✓ Branch 3 taken 404 times.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 5314 times.
8495 else if (is2("warnings"))
1322 {
1323
4/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 30 times.
78 if (stricmp(word[1], "enable") == 0)
1324 {
1325
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1326
1327
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (warnid != warning_id_end)
1328 {
1329
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 set_warning_enabled(warnid, true);
1330 }
1331 else
1332 {
1333
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");
1334 }
1335 }
1336
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
60 else if (stricmp(word[1], "disable") == 0)
1337 {
1338
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1339
1340
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 12 times.
60 if (warnid != warning_id_end)
1341 {
1342
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 set_warning_enabled(warnid, false);
1343 }
1344 else
1345 {
1346
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");
1347 }
1348 }
1349 else
1350 {
1351 asar_throw_error(0, error_type_block, error_id_broken_command, "warnings", "Unknown parameter");
1352 }
1353 }
1354
6/6
✓ Branch 0 taken 7039 times.
✓ Branch 1 taken 1378 times.
✓ Branch 2 taken 2414 times.
✓ Branch 3 taken 4625 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 5293 times.
8417 else if(is1("global"))
1355 {
1356
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))
1357 {
1358
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]);
1359 }
1360 }
1361
6/6
✓ Branch 0 taken 730 times.
✓ Branch 1 taken 7645 times.
✓ Branch 2 taken 365 times.
✓ Branch 3 taken 365 times.
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 5258 times.
8375 else if (is2("check"))
1362 {
1363
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)
1364 {
1365 // RPG Hacker: Removed trimming for now - I think requiring an exact match is probably
1366 // better here (not sure, though, it's worth discussing)
1367
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]);
1368 // randomdude999: this also removes leading spaces because itrim gets stuck in an endless
1369 // loop when multi is true and one argument is empty
1370 // in hirom the rom needs to be an entire bank for it to have a title, other modes only need 0x8000 bytes
1371
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
1372 {
1373 if (!ignoretitleerrors) // title errors shouldn't be ignored
1374 asar_throw_error(0, error_type_block, error_id_rom_too_short, expected_title.data());
1375 else // title errors should be ignored, throw a warning anyways
1376 asar_throw_warning(0, warning_id_rom_too_short, expected_title.data());
1377 }
1378 else {
1379 6 string actual_title;
1380 6 string actual_display_title;
1381
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 6 times.
132 for (int i = 0;i < 21;i++)
1382 {
1383 126 unsigned char c = romdata[snestopc(0x00FFC0 + i)];
1384
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
126 actual_title += (char)c;
1385 // the replacements are from interface-cli.cpp
1386
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
126 if (c == 7) c = 14;
1387
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
126 if (c == 8) c = 27;
1388
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
126 if (c == 9) c = 26;
1389
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
126 if (c == '\r') c = 17;
1390
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 63 times.
126 if (c == '\n') c = 25;
1391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == '\0') c = 155;
1392
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
126 actual_display_title += (char)c;
1393 }
1394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (strncmp(expected_title, actual_title, 21) != 0)
1395 {
1396 if (!ignoretitleerrors) // title errors shouldn't be ignored
1397 asar_throw_error(0, error_type_block, error_id_rom_title_incorrect, expected_title.data(), actual_display_title.data());
1398 else // title errors should be ignored, throw a warning anyways
1399 asar_throw_warning(0, warning_id_rom_title_incorrect, expected_title.data(), actual_display_title.data());
1400 }
1401 6 }
1402 6 }
1403
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)
1404 {
1405 if (0);
1406
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"))
1407 {
1408 30 disable_bank_cross_errors = true;
1409 }
1410
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"))
1411 {
1412 32 disable_bank_cross_errors = false;
1413 32 check_half_banks_crossed = true;
1414 }
1415
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"))
1416 {
1417 2 disable_bank_cross_errors = false;
1418 2 check_half_banks_crossed = false;
1419 }
1420 else asar_throw_error(0, error_type_block, error_id_invalid_check);
1421
1422 }
1423 else
1424 {
1425 asar_throw_error(0, error_type_block, error_id_invalid_check);
1426 }
1427 }
1428
9/10
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 7729 times.
✓ Branch 2 taken 576 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997 times.
✓ Branch 5 taken 1308 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 6961 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 5240 times.
8305 else if (is0("asar") || is1("asar"))
1429 {
1430
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);
1431
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
66 if (!par) return;
1432 18 int dots=0;
1433 18 int dig=0;
1434
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 36 times.
186 for (int i=0;par[i];i++)
1435 {
1436
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 108 times.
150 if (par[i]=='.')
1437 {
1438
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);
1439 21 dig=0;
1440 42 dots++;
1441 }
1442
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 else if (is_digit(par[i])) dig++;
1443 else asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1444 }
1445
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);
1446
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 autoptr<char**> vers=split(par, '.');
1447 36 int vermaj=atoi(vers[0]);
1448
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);
1449
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 6 times.
36 if (vermaj<asarver_maj) return;
1450
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (dots==1)
1451 {
1452 if (strlen(vers[1])!=2) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1453 //if (asarver_min<10 && asarver_bug<10 && strlen(vers[1])>2) error(0, "This version of Asar is too old for this patch.");
1454 int verminbug=atoi(vers[1]);
1455 int tmpver=asarver_bug;
1456 if (tmpver>9) tmpver=9;
1457 if (asarver_min*10+tmpver<verminbug) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1458 }
1459 else
1460 {
1461 6 int vermin=atoi(vers[1]);
1462
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);
1463 6 int verbug=atoi(vers[2]);
1464
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);
1465 }
1466
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
36 }
1467
10/10
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 7693 times.
✓ Branch 2 taken 574 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 6961 times.
✓ Branch 5 taken 1306 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 6955 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 5236 times.
8269 else if (is0("include") || is1("includefrom"))
1468 {
1469
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);
1470
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())
1471 {
1472
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());
1473
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, "");
1474 }
1475 }
1476
6/6
✓ Branch 0 taken 574 times.
✓ Branch 1 taken 7687 times.
✓ Branch 2 taken 287 times.
✓ Branch 3 taken 287 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 5221 times.
8261 else if (is0("includeonce"))
1477 {
1478
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 const char* current_file = get_current_file_name();
1479
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))
1480 {
1481
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);
1482 }
1483 }
1484
8/8
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 7571 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 4981 times.
8231 else if (numwords==3 && !stricmp(word[1], "="))
1485 {
1486
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])
1487 {
1488 int codepoint;
1489 402 const char* char_start = word[0]+1;
1490
1/2
✓ Branch 0 taken 402 times.
✗ Branch 1 not taken.
402 const char* after = char_start + utf8_val(&codepoint, char_start);
1491
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);
1492
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') {
1493
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]));
1494
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);
1495 396 return;
1496 } // todo: error checking here
1497 }
1498 // randomdude999: int cast b/c i'm too lazy to also mess with making setlabel()
1499 // unsigned, besides it wouldn't matter anyways.
1500
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 int num=(int)getnum(word[2]);
1501
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);
1502
1503 72 const char* newlabelname = word[0];
1504 36 bool ismacro = false;
1505
1506
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
72 if (newlabelname[0] == '?')
1507 {
1508 3 ismacro = true;
1509 6 newlabelname++;
1510 }
1511
1512
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)
1513 {
1514 asar_throw_error(0, error_type_block, error_id_macro_label_outside_of_macro);
1515 }
1516
1517
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);
1518
1519 72 string completename;
1520
1521
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
72 if (ismacro)
1522 {
1523
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) + "_";
1524 }
1525
1526
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
72 completename += newlabelname;
1527
1528
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);
1529 72 }
1530
3/4
✓ Branch 0 taken 7751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7537 times.
✓ Branch 3 taken 214 times.
7751 else if (assemblemapper(word, numwords)) {}
1531
6/6
✓ Branch 0 taken 6937 times.
✓ Branch 1 taken 600 times.
✓ Branch 2 taken 2363 times.
✓ Branch 3 taken 4574 times.
✓ Branch 4 taken 393 times.
✓ Branch 5 taken 4481 times.
7537 else if (is1("org"))
1532 {
1533
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);
1534
1/2
✓ Branch 0 taken 393 times.
✗ Branch 1 not taken.
786 freespaceend();
1535
1/2
✓ Branch 0 taken 786 times.
✗ Branch 1 not taken.
786 unsigned int num=getnum(par);
1536
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);
1537
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());
1538
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);
1539 //if (fastrom) num|=0x800000;
1540 786 snespos=(int)num;
1541 786 realsnespos=(int)num;
1542 786 startpos=(int)num;
1543 786 realstartpos=(int)num;
1544 786 snespos_valid = true;
1545 }
1546 #define ret_error(errid) { asar_throw_error(0, error_type_block, errid); return; }
1547 #define ret_error_params(errid, ...) { asar_throw_error(0, error_type_block, errid, __VA_ARGS__); return; }
1548
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 6661 times.
6751 else if (is("struct"))
1549 {
1550 //verifysnespos();
1551
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);
1552
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);
1553
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);
1554
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);
1555
1556
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]);
1557
1558 90 static_struct = false;
1559 90 old_snespos = snespos;
1560 90 old_startpos = startpos;
1561 90 old_optimizeforbank = optimizeforbank;
1562 90 old_snespos_valid = snespos_valid;
1563 45 unsigned int base = 0;
1564
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 60 times.
90 if (numwords == 3)
1565 {
1566 30 static_struct = true;
1567
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 base = getnum(word[2]);
1568
1569
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;
1570 }
1571
1572 90 bool old_in_struct = in_struct;
1573 90 bool old_in_sub_struct = in_sub_struct;
1574
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;
1575 90 in_sub_struct = numwords == 4;
1576
1577 #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; }
1578 #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; }
1579
1580
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 60 times.
90 if (numwords == 3)
1581 {
1582
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());
1583 30 snespos = (int)base;
1584 30 startpos = (int)base;
1585 }
1586
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 36 times.
60 else if (numwords == 4)
1587 {
1588
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);
1589
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);
1590
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 string tmp_struct_parent = word[3];
1591
1592
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());
1593
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);
1594
1595 24 static_struct = structure.is_static;
1596
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 struct_parent = tmp_struct_parent;
1597 24 snespos = structure.base_end;
1598 24 startpos = structure.base_end;
1599
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 }
1600
1601
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
90 push_pc();
1602
1603 90 optimizeforbank = -1;
1604
1605
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
90 struct_name = word[1];
1606 90 struct_base = snespos;
1607 90 realsnespos = 0;
1608 90 realstartpos = 0;
1609 90 snespos_valid = true;
1610
1611
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);
1612
1613 #undef ret_error_cleanup
1614 #undef ret_error_params_cleanup
1615 }
1616
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 6571 times.
6661 else if (is("endstruct"))
1617 {
1618
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);
1619
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);
1620
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);
1621
1622
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;
1623
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);
1624
1625 45 snes_struct structure;
1626 90 structure.base_end = snespos;
1627 90 structure.struct_size = alignment * ((snespos - struct_base + alignment - 1) / alignment);
1628 90 structure.object_size = structure.struct_size;
1629 90 structure.is_static = static_struct;
1630
1631
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 24 times.
90 if (in_struct)
1632 {
1633
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;
1634 }
1635
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 else if (in_sub_struct)
1636 {
1637 12 snes_struct parent;
1638
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);
1639
1640
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (parent.object_size < parent.struct_size + structure.struct_size) {
1641 24 parent.object_size = parent.struct_size + structure.struct_size;
1642 }
1643
1644
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;
1645
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;
1646 12 }
1647
1648
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
90 pop_pc();
1649 90 in_struct = false;
1650 90 in_sub_struct = false;
1651 90 snespos = old_snespos;
1652 90 startpos = old_startpos;
1653 90 optimizeforbank = old_optimizeforbank;
1654 90 snespos_valid = old_snespos_valid;
1655 90 static_struct = false;
1656 45 }
1657 #undef ret_error
1658
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6565 times.
6571 else if(is("spcblock"))
1659 {
1660 //banned features when active: org, freespace(and variants), arch, mapper,namespace,pushns
1661
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);
1662
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);
1663
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);
1664
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);
1665
1666
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 spcblock.destination = getnum(par);
1667 6 spcblock.type = spcblock_nspc;
1668
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 spcblock.macro_name = "";
1669
1670
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());
1671
1672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(numwords == 3)
1673 {
1674 if(!stricmp(word[2], "nspc")) spcblock.type = spcblock_nspc;
1675 else if(!stricmp(word[2], "custom")) asar_throw_error(0, error_type_block, error_id_custom_spcblock_missing_macro);
1676 else asar_throw_error(0, error_type_block, error_id_unknown_spcblock_type);
1677 }
1678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 else if(numwords == 4)
1679 {
1680 if(!stricmp(word[2], "custom")) spcblock.type = spcblock_custom;
1681 else asar_throw_error(0, error_type_block, error_id_extra_spcblock_arg_for_type);
1682
1683 if(macros.exists(word[3]))
1684 {
1685 macrodata *macro = macros.find(word[3]);
1686 if(!macro->variadic) asar_throw_error(0, error_type_block, error_id_spcblock_macro_must_be_varadic);
1687 if(macro->numargs != 3) asar_throw_error(0, error_type_block, error_id_spcblock_macro_invalid_static_args);
1688 spcblock.macro_name = word[3];
1689 }
1690 else asar_throw_error(0, error_type_block, error_id_spcblock_macro_doesnt_exist);
1691 }
1692
1693
1/3
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 switch(spcblock.type)
1694 {
1695 6 case spcblock_nspc:
1696 6 spcblock.size_address=realsnespos;
1697
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(0x0000);
1698
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(spcblock.destination);
1699 6 snespos=(int)spcblock.destination;
1700 6 startpos=(int)spcblock.destination;
1701 6 spcblock.execute_address = -1u;
1702
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 add_addr_to_line(addrToLinePos);
1703 3 break;
1704 case spcblock_custom:
1705 //this is a todo that probably won't be ready for 1.9
1706 //mostly so we can leverage some cleanups we make in 2.0 for practicality
1707 asar_throw_error(0, error_type_block, error_id_spcblock_custom_types_incomplete);
1708 push_pc();
1709 spcblock.old_mapper = mapper;
1710 mapper = norom;
1711 break;
1712 default:
1713 asar_throw_error(0, error_type_fatal, error_id_internal_error, "invalid spcblock type");
1714 }
1715
1716
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 ns_backup = ns;
1717
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;
1718 6 in_spcblock = true;
1719 }
1720
6/6
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 6301 times.
✓ Branch 2 taken 132 times.
✓ Branch 3 taken 132 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4385 times.
6565 else if(is0("endspcblock"))
1721 {
1722
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);
1723
1724
1/3
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 switch(spcblock.type)
1725 {
1726 6 case spcblock_nspc:
1727
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==2)
1728 {
1729 2 int pcpos=snestopc(spcblock.size_address&0xFFFFFF);
1730
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());
1731 2 int num=snespos-startpos;
1732
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata_byte(pcpos, (unsigned char)num);
1733
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata_byte(pcpos+1, (unsigned char)(num >> 8));
1734 }
1735
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(spcblock.execute_address != -1u)
1736 {
1737
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(0x0000);
1738
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2((unsigned int)spcblock.execute_address);
1739 }
1740 3 break;
1741 case spcblock_custom:
1742 mapper = spcblock.old_mapper;
1743 pop_pc();
1744 break;
1745 default:
1746 asar_throw_error(0, error_type_fatal, error_id_internal_error, "invalid spcblock type");
1747 }
1748
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 ns = ns_backup;
1749 6 in_spcblock = false;
1750 }
1751
6/6
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 450 times.
✓ Branch 2 taken 1949 times.
✓ Branch 3 taken 4160 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4382 times.
6559 else if (is1("startpos"))
1752 {
1753
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);
1754
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 spcblock.execute_address=getnum(par);
1755 }
1756
6/6
✓ Branch 0 taken 6103 times.
✓ Branch 1 taken 450 times.
✓ Branch 2 taken 1946 times.
✓ Branch 3 taken 4157 times.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 4337 times.
6553 else if (is1("base"))
1757 {
1758
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"))
1759 {
1760 30 snespos=realsnespos;
1761 30 startpos=realstartpos;
1762 30 snespos_valid = realsnespos >= 0;
1763 30 return;
1764 }
1765
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 unsigned int num=getnum(par);
1766
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);
1767
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());
1768 60 snespos=(int)num;
1769 60 startpos=(int)num;
1770 60 optimizeforbank=-1;
1771 60 snespos_valid = realsnespos >= 0;
1772 }
1773
6/6
✓ Branch 0 taken 6013 times.
✓ Branch 1 taken 450 times.
✓ Branch 2 taken 1901 times.
✓ Branch 3 taken 4112 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 4331 times.
6463 else if (is1("dpbase"))
1774 {
1775
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 unsigned int num=(int)getnum(par);
1776
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);
1777
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());
1778 12 dp_base = (int)num;
1779 }
1780
6/6
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 6307 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 4313 times.
6451 else if (is2("optimize"))
1781 {
1782
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"))
1783 {
1784
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"))
1785 {
1786 6 optimize_dp = optimize_dp_flag::NONE;
1787 6 return;
1788 }
1789
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"))
1790 {
1791 6 optimize_dp = optimize_dp_flag::RAM;
1792 6 return;
1793 }
1794
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"))
1795 {
1796 12 optimize_dp = optimize_dp_flag::ALWAYS;
1797 12 return;
1798 }
1799 asar_throw_error(1, error_type_block, error_id_bad_dp_optimize, word[2]);
1800 }
1801
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"))
1802 {
1803
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"))
1804 {
1805 optimize_address = optimize_address_flag::DEFAULT;
1806 return;
1807 }
1808
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"))
1809 {
1810 6 optimize_address = optimize_address_flag::RAM;
1811 6 return;
1812 }
1813
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"))
1814 {
1815 6 optimize_address = optimize_address_flag::MIRRORS;
1816 6 return;
1817 }
1818 asar_throw_error(1, error_type_block, error_id_bad_address_optimize, word[2]);
1819 }
1820 asar_throw_error(1, error_type_block, error_id_bad_optimize, par);
1821 }
1822
6/6
✓ Branch 0 taken 6001 times.
✓ Branch 1 taken 414 times.
✓ Branch 2 taken 1895 times.
✓ Branch 3 taken 4106 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 4304 times.
6415 else if (is1("bank"))
1823 {
1824
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"))
1825 {
1826 6 optimizeforbank=-1;
1827 6 return;
1828 }
1829
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"))
1830 {
1831 6 optimizeforbank=0x100;
1832 6 return;
1833 }
1834
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 unsigned int num=getnum(par);
1835 //if (forwardlabel) error(0, "bank Label is not valid");
1836 //if (foundlabel) num>>=16;
1837
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());
1838 6 optimizeforbank=(int)num;
1839 }
1840
9/10
✓ Branch 0 taken 6397 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5341 times.
✓ Branch 3 taken 1056 times.
✓ Branch 4 taken 5059 times.
✓ Branch 5 taken 282 times.
✓ Branch 6 taken 1424 times.
✓ Branch 7 taken 3635 times.
✓ Branch 8 taken 684 times.
✓ Branch 9 taken 3620 times.
6397 else if (is("freespace") || is("freecode") || is("freedata") || is("segment"))
1841 {
1842
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1368 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1368 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1843 1368 string parstr;
1844
3/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 1260 times.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
1368 if (numwords==1) parstr="\n";//crappy hack: impossible character to cut out extra commas
1845
2/4
✓ Branch 0 taken 1260 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 630 times.
✗ Branch 3 not taken.
1260 else if (numwords==2) parstr=word[1];
1846 else asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1847
5/8
✓ Branch 0 taken 1056 times.
✓ Branch 1 taken 312 times.
✓ Branch 2 taken 528 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 528 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 528 times.
✗ Branch 7 not taken.
1896 if (is("freecode")) parstr=STR"ram,"+parstr;
1848
5/8
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 141 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 141 times.
✗ Branch 7 not taken.
1509 if (is("freedata")) parstr=STR"noram,"+parstr;
1849
5/8
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 1338 times.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
1383 if (is("segment")) parstr = STR "norats," + parstr;
1850
1/2
✓ Branch 0 taken 1368 times.
✗ Branch 1 not taken.
1368 autoptr<char**> pars=split(parstr.temp_raw(), ',');
1851 684 unsigned char fsbyte = 0x00;
1852 684 bool fixedpos=false;
1853 684 bool align=false;
1854 684 bool leakwarn=true;
1855 684 bool write_rats=true;
1856 684 int target_bank = -3;
1857
1/2
✓ Branch 0 taken 684 times.
✗ Branch 1 not taken.
1368 string pin_to_freespace = "";
1858 684 int search_start_pos = -1;
1859
1860
2/2
✓ Branch 0 taken 2736 times.
✓ Branch 1 taken 1368 times.
4104 for (int i=0;pars[i];i++)
1861 {
1862
2/2
✓ Branch 0 taken 2628 times.
✓ Branch 1 taken 108 times.
2736 if (pars[i][0]=='\n') {}
1863
4/4
✓ Branch 0 taken 1842 times.
✓ Branch 1 taken 786 times.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 786 times.
2628 else if (!stricmp(pars[i], "ram"))
1864 {
1865
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1056 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1056 if (target_bank!=-3) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1866 528 target_bank = -2;
1867 }
1868
4/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 645 times.
✓ Branch 2 taken 141 times.
✓ Branch 3 taken 645 times.
1572 else if (!stricmp(pars[i], "noram"))
1869 {
1870
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
282 if (target_bank!=-3) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1871 141 target_bank = -1;
1872 }
1873
4/4
✓ Branch 0 taken 651 times.
✓ Branch 1 taken 639 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 639 times.
1290 else if (!stricmp(pars[i], "static"))
1874 {
1875
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);
1876 6 fixedpos=true;
1877 }
1878
4/4
✓ Branch 0 taken 645 times.
✓ Branch 1 taken 633 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 633 times.
1278 else if (!stricmp(pars[i], "align"))
1879 {
1880
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);
1881 6 align=true;
1882 }
1883
4/4
✓ Branch 0 taken 1242 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 609 times.
✓ Branch 3 taken 24 times.
1266 else if (!stricmp(pars[i], "cleaned"))
1884 {
1885
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1218 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1218 if (!leakwarn) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1886 609 leakwarn=false;
1887 }
1888
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 9 times.
48 else if (!stricmp(pars[i], "norats"))
1889 {
1890 15 write_rats=false;
1891 }
1892
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 else if (stribegin(pars[i], "bank="))
1893 {
1894
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
18 if(target_bank != -3) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1895
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 target_bank = getnum(pars[i] + 5);
1896
2/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
18 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
1897 }
1898 else if (stribegin(pars[i], "start="))
1899 {
1900 search_start_pos = getnum(pars[i] + 6);
1901 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
1902 }
1903 else if (stribegin(pars[i], "pin="))
1904 {
1905 // TODO: should we handle posneg labels here too?
1906 string pin_to = pars[i] + 4;
1907 const char* pin_to_c = pin_to.data();
1908 pin_to_freespace = labelname(&pin_to_c);
1909 if(*pin_to_c) asar_throw_error(0, error_type_block, error_id_invalid_label_name);
1910 // this is to throw an "undefined label" error with the proper callstack
1911 if(pass) labelval(pin_to);
1912 }
1913 else if (stribegin(pars[i], "cleanbyte="))
1914 {
1915 fsbyte = getnum(pars[i] + strlen("cleanbyte="));
1916 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
1917 }
1918 else
1919 {
1920 // for backwards compat i guess
1921 fsbyte = (unsigned char)getnum(pars[i]);
1922 }
1923 }
1924
3/4
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 684 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
1368 if(target_bank == -3 && !write_rats) target_bank = -1;
1925
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1362 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1362 if(target_bank == -3) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1926 // no point specifying anything about cleaning when not writing a rats tag
1927
4/8
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 1338 times.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1368 if(!write_rats && (!leakwarn || fixedpos)) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1928
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 669 times.
684 if(!write_rats) leakwarn = false;
1929
1/2
✓ Branch 0 taken 684 times.
✗ Branch 1 not taken.
1368 freespaceend();
1930
1/2
✓ Branch 0 taken 684 times.
✗ Branch 1 not taken.
1368 freespaceid=getfreespaceid();
1931
1/2
✓ Branch 0 taken 684 times.
✗ Branch 1 not taken.
684 freespace_data& thisfs = freespaces[freespaceid];
1932 1368 thisfs.cleanbyte = fsbyte;
1933
1934
1/2
✓ Branch 0 taken 684 times.
✗ Branch 1 not taken.
1368 thisfs.pin_target = pin_to_freespace;
1935
3/6
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 684 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 684 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1368 if(pin_to_freespace) thisfs.pin_target_ns = ns;
1936 1368 thisfs.write_rats = write_rats;
1937 1368 thisfs.search_start = search_start_pos;
1938 1368 thisfs.bank = target_bank;
1939 1368 thisfs.flag_align = align;
1940
1941
2/2
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 912 times.
1368 if (pass==0) snespos=0;
1942
2/2
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 912 times.
1368 if (pass==1)
1943 {
1944
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 452 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
456 if (fixedpos && thisfs.orgpos<0)
1945 {
1946 thisfs.pos = 0;
1947 thisfs.leaked = false;//mute some other errors
1948 asar_throw_error(1, error_type_block, error_id_static_freespace_autoclean);
1949 }
1950 456 snespos = 0;
1951 }
1952
2/2
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 912 times.
1368 if (pass==2)
1953 {
1954
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 452 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
456 if (fixedpos && thisfs.orgpos == -1) return;//to kill some errors
1955 456 snespos=thisfs.pos;
1956
3/6
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 414 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
456 if (thisfs.leaked && leakwarn) asar_throw_warning(2, warning_id_freespace_leaked);
1957
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 228 times.
456 freespaceuse += (write_rats ? 8 : 0) + thisfs.len;
1958
1959 // add a mapping for the start of the rats tag
1960
3/4
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 446 times.
✗ Branch 3 not taken.
456 if (write_rats) add_addr_to_line(snespos-8);
1961 }
1962 1368 thisfs.is_static = fixedpos;
1963
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1368 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.
1368 if (snespos < 0 && mapper == sa1rom) asar_throw_error(pass, error_type_fatal, error_id_no_freespace_in_mapped_banks, dec(thisfs.len).data());
1964
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1368 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1368 if (snespos < 0) asar_throw_error(pass, error_type_fatal, error_id_no_freespace, dec(thisfs.len).data());
1965
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 684 times.
1368 bytes+=write_rats ? 8 : 0;
1966 1368 freespacestart=snespos;
1967 1368 startpos=snespos;
1968 1368 realstartpos=snespos;
1969 1368 realsnespos=snespos;
1970 1368 optimizeforbank=-1;
1971
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 684 times.
1368 ratsmetastate=write_rats ? ratsmeta_allow : ratsmeta_ban;
1972 1368 snespos_valid = true;
1973 // check this at the very end so that snespos gets set properly, to
1974 // prevent spurious errors later
1975 //...i guess this can still cause bankcross errors if the old freespace
1976 //happened to be very close to the end of a bank or something, but
1977 //whatever
1978
7/8
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 912 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 452 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
1368 if (pass == 2 && fixedpos && thisfs.orgpos > 0 && thisfs.len > thisfs.orglen)
1979
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 asar_throw_error(2, error_type_block, error_id_static_freespace_growing);
1980
3/6
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 683 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 683 times.
✗ Branch 5 not taken.
1372 }
1981
6/6
✓ Branch 0 taken 4723 times.
✓ Branch 1 taken 306 times.
✓ Branch 2 taken 1256 times.
✓ Branch 3 taken 3467 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 3596 times.
5029 else if (is1("prot"))
1982 {
1983
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);
1984
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);
1985
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 36 times.
48 if (ratsmetastate==ratsmeta_used) step(-5);
1986 int num;
1987
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 autoptr<char**> pars=qpsplit(par, ',', &num);
1988
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 verify_paren(pars);
1989
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('P');
1990
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('R');
1991
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('O');
1992
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('T');
1993
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);
1994
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 write1((unsigned int)(num*3));
1995
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 48 times.
108 for (int i=0;i<num;i++)
1996 {
1997 //int num=getnum(pars[i]);
1998 60 const char * labeltest=pars[i];
1999
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
60 string testlabel = labeltest;
2000
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 snes_label lblval = labelval(&labeltest);
2001
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());
2002
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 write3(lblval.pos);
2003
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;
2004 60 }
2005
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('S');
2006
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('T');
2007
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('O');
2008
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1('P');
2009
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 write1(0);
2010 48 ratsmetastate=ratsmeta_used;
2011
2012
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 add_addr_to_line(addrToLinePos);
2013 48 }
2014
9/10
✓ Branch 0 taken 4675 times.
✓ Branch 1 taken 306 times.
✓ Branch 2 taken 4675 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 108 times.
✓ Branch 5 taken 4873 times.
✓ Branch 6 taken 72 times.
✓ Branch 7 taken 36 times.
✓ Branch 8 taken 36 times.
✓ Branch 9 taken 3560 times.
4981 else if (is1("autoclean") || is2("autoclean"))
2015 {
2016
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);
2017
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if (numwords==3)
2018 {
2019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if(freespaceid > 0)
2020 asar_throw_error(0, error_type_block, error_id_autoclean_in_freespace);
2021 72 const char * labeltest = word[2];
2022
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
72 string testlabel = labeltest;
2023
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 snes_label lblval = labelval(&labeltest);
2024
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());
2025 72 int targetid= lblval.freespace_id;
2026
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;
2027 72 int num = lblval.pos;
2028
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;
2029
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"))
2030 {
2031 66 int orgpos=read3(snespos+1);
2032
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
66 int ratsloc=freespaces[targetid].orgpos;
2033
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);
2034 66 int pcpos=snestopc(snespos);
2035
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)
2036 {
2037
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 ratsloc=ratsstart(orgpos)+8;
2038
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 freespaces[targetid].orglen=read2(ratsloc-4)+1;
2039
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);
2040 }
2041
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 14 times.
42 else if (ratsloc<0) ratsloc=0;
2042
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 write1((unsigned int)firstbyte);
2043
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 write3((unsigned int)num);
2044
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 44 times.
66 if (pass==2)
2045 {
2046
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 int start=ratsstart(num);
2047
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)
2048 {
2049 asar_throw_error(2, error_type_block, error_id_autoclean_label_at_freespace_end);
2050 }
2051
2052
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 add_addr_to_line(addrToLinePos);
2053 }
2054 //freespaceorglen[targetid]=read2(ratsloc-4)+1;
2055
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
66 freespaces[targetid].orgpos = ratsloc;
2056 33 }
2057
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"))
2058 {
2059 6 int orgpos=read3(snespos);
2060
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 int ratsloc=freespaces[targetid].orgpos;
2061
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int start=ratsstart(num);
2062
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)
2063 {
2064
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ratsloc=ratsstart(orgpos)+8;
2065
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);
2066 }
2067
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 else if (!ratsloc) ratsloc=0;
2068
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)
2069 asar_throw_error(2, error_type_block, error_id_autoclean_label_at_freespace_end);
2070
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write3((unsigned int)num);
2071
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 freespaces[targetid].orgpos = ratsloc;
2072
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 freespaces[targetid].orglen = read2(ratsloc-4)+1;
2073
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 add_addr_to_line(addrToLinePos);
2074 }
2075 else asar_throw_error(0, error_type_block, error_id_broken_autoclean);
2076 72 }
2077 // weird gotcha: we don't know the freespace id here, so we don't know what clean_byte to use
2078 else if (pass==0) removerats((int)getnum(word[1]), 0x00);
2079 }
2080
6/6
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 4759 times.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 75 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3557 times.
4909 else if (is0("pushpc"))
2081 {
2082
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 verifysnespos();
2083
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].arch=arch;
2084
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snespos=snespos;
2085
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snesstart=startpos;
2086
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snesposreal=realsnespos;
2087
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].snesstartreal=realstartpos;
2088
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].freeid=freespaceid;
2089
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 pushpc[pushpcnum].freest=freespacestart;
2090 6 pushpcnum++;
2091 6 snespos=(int)0xFFFFFFFF;
2092 6 startpos= (int)0xFFFFFFFF;
2093 6 realsnespos= (int)0xFFFFFFFF;
2094 6 realstartpos= (int)0xFFFFFFFF;
2095 6 snespos_valid = false;
2096 }
2097
6/6
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 4759 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3554 times.
4903 else if (is0("pullpc"))
2098 {
2099
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);
2100 6 pushpcnum--;
2101
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 freespaceend();
2102
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);
2103
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 snespos=pushpc[pushpcnum].snespos;
2104
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 startpos=pushpc[pushpcnum].snesstart;
2105
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 realsnespos=pushpc[pushpcnum].snesposreal;
2106
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 realstartpos=pushpc[pushpcnum].snesstartreal;
2107
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 freespaceid=pushpc[pushpcnum].freeid;
2108
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 freespacestart=pushpc[pushpcnum].freest;
2109 6 snespos_valid = true;
2110 }
2111
6/6
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 4759 times.
✓ Branch 2 taken 69 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3551 times.
4897 else if (is0("pushbase"))
2112 {
2113
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 basestack[basestacknum] = snespos;
2114 6 basestacknum++;
2115 }
2116
6/6
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 4759 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 66 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3548 times.
4891 else if (is0("pullbase"))
2117 {
2118
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);
2119 6 basestacknum--;
2120
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 snespos = basestack[basestacknum];
2121
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 startpos = basestack[basestacknum];
2122
2123
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (snespos != realstartpos)
2124 {
2125 6 optimizeforbank = -1;
2126 }
2127 }
2128
6/6
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 4759 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 63 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3542 times.
4885 else if (is0("pushns"))
2129 {
2130
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);
2131
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;
2132
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for(int i = 0; i < namespace_list.count; i++)
2133 {
2134
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]);
2135 }
2136
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 pushns[pushnsnum].nested_namespaces = nested_namespaces;
2137 12 pushnsnum++;
2138
2139
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 namespace_list.reset();
2140
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 ns = "";
2141 12 nested_namespaces = false;
2142 }
2143
6/6
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 4759 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3536 times.
4873 else if (is0("pullns"))
2144 {
2145
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);
2146
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);
2147 12 pushnsnum--;
2148
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;
2149
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 nested_namespaces = pushns[pushnsnum].nested_namespaces;
2150
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 namespace_list.reset();
2151
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++)
2152 {
2153
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]);
2154 }
2155 }
2156
9/10
✓ Branch 0 taken 4675 times.
✓ Branch 1 taken 186 times.
✓ Branch 2 taken 4549 times.
✓ Branch 3 taken 126 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 4699 times.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 81 times.
✓ Branch 9 taken 3455 times.
4861 else if (is1("namespace") || is2("namespace"))
2157 {
2158
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);
2159 81 bool leave = false;
2160
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 if (par)
2161 {
2162
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"))
2163 {
2164
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);
2165 24 leave = true;
2166 }
2167
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"))
2168 {
2169
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);
2170
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;
2171
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;
2172 }
2173 else
2174 {
2175
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);
2176
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 const char * tmpstr= safedequote(par);
2177
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);
2178
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 48 times.
78 if (!nested_namespaces)
2179 {
2180
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
30 namespace_list.reset();
2181 }
2182
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);
2183 }
2184 }
2185 else
2186 {
2187 leave = true;
2188 }
2189
2190
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 57 times.
81 if (leave)
2191 {
2192
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 12 times.
48 if (nested_namespaces)
2193 {
2194
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
36 namespace_list.remove(namespace_list.count - 1);
2195 }
2196 else
2197 {
2198
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 namespace_list.reset();
2199 }
2200 }
2201
2202 // recompute ns
2203
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 ns = "";
2204
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 162 times.
354 for (int i = 0; i < namespace_list.count; i++)
2205 {
2206
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];
2207
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
192 ns += "_";
2208 }
2209 }
2210
6/6
✓ Branch 0 taken 4549 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 1169 times.
✓ Branch 3 taken 3380 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 3443 times.
4699 else if (is1("warnpc"))
2211 {
2212
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 unsigned int maxpos=getnum(par);
2213
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);
2214
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);
2215
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());
2216 }
2217 #ifdef SANDBOX
2218 else if (is("incsrc") || is("incbin") || is("table"))
2219 {
2220 asar_throw_error(0, error_type_block, error_id_command_disabled);
2221 }
2222 #endif
2223
6/6
✓ Branch 0 taken 4525 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 3368 times.
✓ Branch 3 taken 1157 times.
✓ Branch 4 taken 2789 times.
✓ Branch 5 taken 654 times.
4675 else if (is1("incsrc"))
2224 {
2225
1/2
✓ Branch 0 taken 3367 times.
✗ Branch 1 not taken.
3367 const char* current_file = get_current_file_name();
2226 3367 string name;
2227 // RPG Hacker: Should this also throw on absolute paths?
2228 // E.g., on something starting with C:/ or whatever.
2229
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3361 times.
3367 if (strchr(par, '\\'))
2230 {
2231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(0, error_type_block, error_id_platform_paths);
2232 }
2233
2/4
✓ Branch 0 taken 3361 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2786 times.
✗ Branch 3 not taken.
3361 name=safedequote(par);
2234
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 3211 times.
3361 assemblefile(name);
2235 3367 }
2236
10/10
✓ Branch 0 taken 1158 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 1086 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 42 times.
✓ Branch 5 taken 1194 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 36 times.
✓ Branch 8 taken 39 times.
✓ Branch 9 taken 615 times.
1308 else if (is1("incbin") || is3("incbin"))
2237 {
2238
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);
2239 int len;
2240 39 int start=0;
2241 39 int end=0;
2242
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 36 times.
78 if (strqchr(par, ':'))
2243 {
2244 21 char * lengths=strqchr(par, ':');
2245 42 *lengths=0;
2246 42 lengths++;
2247
2248
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 char* split = strqpstr(lengths, "..");
2249
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);
2250
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
36 string start_str(lengths, split-lengths);
2251
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);
2252
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 start = getnum(start_str);
2253
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);
2254
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
30 string end_str(split+2);
2255
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);
2256
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 end = getnum(end_str);
2257
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);
2258 42 }
2259
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 const char* current_file = get_current_file_name();
2260 60 string name;
2261 // RPG Hacker: Should this also throw on absolute paths?
2262 // E.g., on something starting with C:/ or whatever.
2263
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 54 times.
60 if (strchr(par, '\\'))
2264 {
2265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(0, error_type_block, error_id_platform_paths);
2266 }
2267
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
54 name = safedequote(par);
2268 char * data;//I couldn't find a way to get this into an autoptr
2269
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());
2270
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
42 autoptr<char*> datacopy=data;
2271
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 24 times.
42 if (!end) end=len;
2272
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());
2273
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());
2274
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
42 if (numwords==4)
2275 {
2276
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");
2277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!confirmname(word[3]))
2278 {
2279 int pos=(int)getnum(word[3]);
2280 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2281 int offset=snestopc(pos);
2282 if (offset + end - start > 0xFFFFFF) asar_throw_error(0, error_type_block, error_id_16mb_rom_limit);
2283 if (offset+end-start>romlen) romlen=offset+end-start;
2284 if (pass==2)
2285 {
2286 writeromdata(offset, data+start, end-start);
2287 add_addr_to_line(pos);
2288 }
2289 else if(pass == 1) addromwrite(offset, end-start);
2290 }
2291 else
2292 {
2293 int pos;
2294
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==0)
2295 {
2296 // TODO: this shouldn't allocate in pass 0 actually
2297 // and needs an addromwrite probably......
2298 // actually it should just use the freespace finder at the end of pass 1
2299
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);
2300
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 pos=getpcfreespace(end-start, -1, true, false);
2301
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());
2302
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 int foundfreespaceid=getfreespaceid();
2303
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 freespaces[foundfreespaceid].dont_find = true;
2304
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 freespaces[foundfreespaceid].pos = pctosnes(pos);
2305
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);
2306 // is this necessary?
2307
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata_bytes(pos, 0xFF, end-start);
2308 }
2309
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==1)
2310 {
2311
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 getfreespaceid();//nothing to do here, but we want to tick the counter
2312 }
2313
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==2)
2314 {
2315
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 int foundfreespaceid =getfreespaceid();
2316
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);
2317
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);
2318
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);
2319 2 freespaceuse+=8+end-start;
2320 }
2321 }
2322 }
2323 else
2324 {
2325
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]);
2326
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 add_addr_to_line(addrToLinePos);
2327 }
2328 60 }
2329
6/6
✓ Branch 0 taken 654 times.
✓ Branch 1 taken 576 times.
✓ Branch 2 taken 327 times.
✓ Branch 3 taken 327 times.
✓ Branch 4 taken 318 times.
✓ Branch 5 taken 297 times.
1230 else if (is("skip") || is("fill"))
2330 {
2331
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 630 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.
636 if(numwords != 2 && numwords != 3 && numwords != 5) asar_throw_error(0, error_type_block, error_id_unknown_command);
2332
6/10
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 630 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 318 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
636 if(numwords > 2 && stricmp(word[1], "align")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2333
6/10
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 630 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 318 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
636 if(numwords == 5 && stricmp(word[3], "offset")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2334 int amount;
2335
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 630 times.
636 if(numwords > 2)
2336 {
2337
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int alignment = getnum(word[2]);
2338
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);
2339 3 int offset = 0;
2340
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(numwords==5)
2341 {
2342
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 offset = getnum(word[4]);
2343
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);
2344 }
2345
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);
2346
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);
2347
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);
2348 // i just guessed this formula but it seems to work
2349 6 amount = (alignment - ((snespos - offset) & (alignment-1))) & (alignment-1);
2350 }
2351 else
2352 {
2353
1/2
✓ Branch 0 taken 630 times.
✗ Branch 1 not taken.
630 amount = (int)getnum(par);
2354
5/6
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
630 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2355 }
2356
2/2
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 54 times.
630 if(is("skip")) step(amount);
2357 else
2358 {
2359
3/4
✓ Branch 0 taken 406902 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 406902 times.
✓ Branch 3 taken 54 times.
406956 for(int i=0; i < amount; i++) write1(fillbyte[i%12]);
2360
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 add_addr_to_line(addrToLinePos);
2361 }
2362
2363 }
2364
6/6
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 492 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 294 times.
594 else if (is0("cleartable"))
2365 {
2366
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 cleartable();
2367 }
2368
6/6
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 492 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 291 times.
588 else if (is0("pushtable"))
2369 {
2370
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 tablestack.append(thetable);
2371 }
2372
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 492 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 288 times.
582 else if (is0("pulltable"))
2373 {
2374
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);
2375
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];
2376
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 tablestack.remove(tablestack.count-1);
2377 }
2378
6/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 540 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 270 times.
576 else if (is("function") && numwords >= 3)
2379 {
2380
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);
2381
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);
2382
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
36 string line=word[1];
2383
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 line.qnormalize();
2384 36 char * startpar=strqchr(line.data(), '(');
2385
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);
2386 36 *startpar=0;
2387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
36 startpar++;
2388
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);
2389 36 char * endpar=strqchr(startpar, ')');
2390 //confirmqpar requires that all parentheses are matched, and a starting one exists, therefore it is harmless to not check for nulls
2391
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);
2392 36 *endpar=0;
2393
2394 36 string pars;
2395
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 36 times.
72 for(int i = 3; i < numwords; i++){
2396
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if(i > 3) pars += " ";
2397
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
36 pars += word[i];
2398 }
2399
2400
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 createuserfunc(line, startpar, pars.data());
2401 36 }
2402
6/6
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 228 times.
✓ Branch 3 taken 228 times.
✓ Branch 4 taken 138 times.
✓ Branch 5 taken 132 times.
540 else if (is1("print"))
2403 {
2404
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 6 times.
276 string out = handle_print(par);
2405
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);
2406 270 }
2407
6/6
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 90 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 129 times.
264 else if (is1("reset"))
2408 {
2409 if(0);
2410
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;
2411 else if (!stricmp(par, "freespaceuse")) freespaceuse=0;
2412 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
2413 }
2414
15/18
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 156 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 156 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 156 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 156 times.
✓ Branch 9 taken 84 times.
✓ Branch 10 taken 156 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 156 times.
✓ Branch 13 taken 84 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 156 times.
✓ Branch 16 taken 9 times.
✓ Branch 17 taken 120 times.
258 else if (is1("padbyte") || is1("padword") || is1("padlong") || is1("paddword"))
2415 {
2416 9 int len = 0;
2417
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (is("padbyte")) len=1;
2418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("padword")) len=2;
2419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("padlong")) len=3;
2420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("paddword")) len=4;
2421
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 unsigned int val=getnum(par);
2422
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);
2423
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 12 times.
156 for (int i=0;i<12;i+=len)
2424 {
2425 72 unsigned int tmpval=val;
2426
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 144 times.
288 for (int j=0;j<len;j++)
2427 {
2428 144 padbyte[i+j]=(unsigned char)tmpval;
2429 144 tmpval>>=8;
2430 }
2431 }
2432 }
2433
6/6
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 78 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 111 times.
240 else if (is1("pad"))
2434 {
2435
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);
2436
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 int num=(int)getnum(par);
2437
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());
2438
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (num>realsnespos)
2439 {
2440 6 int end=snestopc(num);
2441 6 int start=snestopc(realsnespos);
2442 12 int len=end-start;
2443
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]);
2444
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 add_addr_to_line(addrToLinePos);
2445 }
2446 }
2447
18/18
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 24 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 21 times.
✓ Branch 17 taken 90 times.
222 else if (is1("fillbyte") || is1("fillword") || is1("filllong") || is1("filldword"))
2448 {
2449 21 int len = 0;
2450
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
42 if (is("fillbyte")) len=1;
2451
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
42 if (is("fillword")) len=2;
2452
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
42 if (is("filllong")) len=3;
2453
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 36 times.
42 if (is("filldword")) len=4;
2454
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 unsigned int val= getnum(par);
2455
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
42 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2456
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 36 times.
330 for (int i=0;i<12;i+=len)
2457 {
2458 147 unsigned int tmpval=val;
2459
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 294 times.
726 for (int j=0;j<len;j++)
2460 {
2461 432 fillbyte[i+j]=(unsigned char)tmpval;
2462 432 tmpval>>=8;
2463 }
2464 }
2465 }
2466
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"))
2467 {
2468
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);
2469
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; }
2470
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; }
2471
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; }
2472 }
2473
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("}")) {}
2474 else
2475 {
2476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 asar_throw_error(1, error_type_block, error_id_unknown_command);
2477 }
2478
2479
6/6
✓ Branch 0 taken 12739 times.
✓ Branch 1 taken 9029 times.
✓ Branch 2 taken 12739 times.
✓ Branch 3 taken 9029 times.
✓ Branch 4 taken 12739 times.
✓ Branch 5 taken 9029 times.
72127 }
2480
2481 11405 bool assemblemapper(char** word, int numwords)
2482 {
2483 11405 auto previous_mapper = mapper;
2484 if(0);
2485
6/6
✓ Branch 0 taken 754 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 658 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 6760 times.
11405 else if (is0("lorom"))
2486 {
2487 //this also makes xkas set snespos to $008000 for some reason
2488 96 mapper=lorom;
2489 }
2490
6/6
✓ Branch 0 taken 658 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 329 times.
✓ Branch 3 taken 329 times.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 6743 times.
11309 else if (is0("hirom"))
2491 {
2492 //xkas makes this point to $C00000
2493 34 mapper=hirom;
2494 }
2495
6/6
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 312 times.
✓ Branch 3 taken 312 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 6740 times.
11275 else if (is0("exlorom"))
2496 {
2497 6 mapper = exlorom;
2498 }
2499
6/6
✓ Branch 0 taken 618 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 309 times.
✓ Branch 3 taken 309 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 6737 times.
11269 else if (is0("exhirom"))
2500 {
2501 6 mapper=exhirom;
2502 }
2503
6/6
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 306 times.
✓ Branch 3 taken 306 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6731 times.
11263 else if (is0("sfxrom"))
2504 {
2505 12 mapper=sfxrom;
2506 //fastrom=false;
2507 }
2508
6/6
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 300 times.
✓ Branch 3 taken 300 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 6716 times.
11251 else if (is0("norom"))
2509 {
2510 //$000000 would be the best snespos for this, but I don't care
2511 30 mapper=norom;
2512 //fastrom=false;
2513
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if(!force_checksum_fix)
2514 30 checksum_fix_enabled = false;//we don't know where the header is, so don't set the checksum
2515 }
2516
6/6
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 10651 times.
✓ Branch 2 taken 285 times.
✓ Branch 3 taken 285 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 6713 times.
11221 else if (is0("fullsa1rom"))
2517 {
2518 6 mapper=bigsa1rom;
2519 //fastrom=false;
2520 }
2521
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 11191 times.
11215 else if (is("sa1rom"))
2522 {
2523 //fastrom=false;
2524
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 if (par)
2525 {
2526
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);
2527
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
27 if (!is_digit(par[0]) || par[1]!=',' ||
2528
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]!=',' ||
2529
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]!=',' ||
2530
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);
2531 int len;
2532
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 autoptr<char**> pars=qpsplit(par, ',', &len);
2533
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 verify_paren(pars);
2534
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);
2535 18 sa1banks[0]=(par[0]-'0')<<20;
2536 18 sa1banks[1]=(par[2]-'0')<<20;
2537 18 sa1banks[4]=(par[4]-'0')<<20;
2538 18 sa1banks[5]=(par[6]-'0')<<20;
2539 18 }
2540 else
2541 {
2542 6 sa1banks[0]=0<<20;
2543 6 sa1banks[1]=1<<20;
2544 6 sa1banks[4]=2<<20;
2545 6 sa1banks[5]=3<<20;
2546 }
2547 24 mapper=sa1rom;
2548 }
2549 6701 else return false;
2550
2551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 214 times.
214 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2552
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 84 times.
214 if(!mapper_set){
2553 130 mapper_set = true;
2554
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 42 times.
84 }else if(previous_mapper != mapper){
2555 72 asar_throw_warning(1, warning_id_mapper_already_set);
2556 }
2557 107 return true;
2558 }
2559