asar coverage - build #76


src/asar/
File: src/asar/assembleblock.cpp
Date: 2024-01-18 11:25:05
Lines:
1224/1456
84.1%
Functions:
36/39
92.3%
Branches:
1416/2670
53.0%

Line Branch Exec Source
1 #include "addr2line.h"
2 #include "asar.h"
3 #include "libstr.h"
4 #include "libsmw.h"
5 #include "assocarr.h"
6 #include "autoarray.h"
7 #include "warnings.h"
8 #include "assembleblock.h"
9 #include "asar_math.h"
10 #include "macro.h"
11 #include "platform/file-helpers.h"
12 #include <cinttypes>
13
14 #include "interface-shared.h"
15 #include "arch-shared.h"
16
17 int arch=arch_65816;
18
19 int snespos;
20 int realsnespos;
21 int startpos;
22 int realstartpos;
23
24 bool emulatexkas;
25 bool mapper_set = false;
26 bool warn_endwhile = true;
27 static bool specifiedasarver = false;
28
29 static int old_snespos;
30 static int old_startpos;
31 static int old_optimizeforbank;
32 static int struct_base;
33 static string struct_name;
34 static string struct_parent;
35 static bool in_struct = false;
36 static bool in_sub_struct = false;
37 static bool static_struct = false;
38 static bool in_spcblock = false;
39
40 assocarr<snes_struct> structs;
41
42 static bool movinglabelspossible = false;
43
44 static bool disable_bank_cross_errors = false;
45 static bool check_half_banks_crossed = false;
46
47 int bytes;
48
49 static enum {
50 ratsmeta_ban,
51 ratsmeta_allow,
52 ratsmeta_used,
53 } ratsmetastate=ratsmeta_ban;
54
55 enum spcblock_type{
56 spcblock_nspc,
57 spcblock_custom
58 };
59
60 struct spcblock_data{
61 unsigned int destination;
62 spcblock_type type;
63 string macro_name;
64
65 unsigned int execute_address;
66 unsigned int size_address;
67 mapper_t old_mapper;
68 }spcblock;
69
70 21 int snestopc_pick(int addr)
71 {
72 155 return snestopc(addr);
73 }
74
75 119045 inline void verifysnespos()
76 {
77
3/4
✓ Branch 0 taken 119033 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 119033 times.
119045 if (snespos<0 || realsnespos<0)
78 {
79 12 asar_throw_warning(0, warning_id_missing_org);
80 12 snespos=0x008000;
81 12 realsnespos=0x008000;
82 12 startpos=0x008000;
83 12 realstartpos=0x008000;
84 }
85 119045 }
86
87 480 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 186 times.
✓ Branch 1 taken 294 times.
480 if (mapper == lorom) {
94
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 174 times.
186 if ((inaddr&0xFFFF)+step > 0xFFFF) {
95 // bank crossed
96 12 return inaddr+step+0x8000;
97 }
98 174 return inaddr+step;
99 } 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 } else if (mapper == exlorom) {
108 // exlorom has no mirroring so this should work fine
109 return pctosnes(snestopc(inaddr)+step);
110 } 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 } 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 } 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 } else if (mapper == bigsa1rom) {
141 // no mirrors here, so this should work
142 return pctosnes(snestopc(inaddr)+step);
143 } else if (mapper == norom) {
144 294 return inaddr+step;
145 }
146 return -1;
147 }
148
149 118721 inline void step(int num)
150 {
151
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 118481 times.
118721 if (disable_bank_cross_errors)
152 {
153 240 snespos = fixsnespos(snespos, num);
154 240 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 240 startpos = snespos;
162 240 realstartpos = realsnespos;
163 }
164 else
165 {
166 118481 snespos += num;
167 118481 realsnespos += num;
168 }
169 118721 bytes+=num;
170 118721 }
171
172 118625 inline void write1_65816(unsigned int num)
173 {
174 118625 verifysnespos();
175
2/2
✓ Branch 0 taken 39536 times.
✓ Branch 1 taken 79089 times.
118625 if (pass==2)
176 {
177 39536 int pcpos=snestopc(realsnespos&0xFFFFFF);
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39536 times.
39536 if (pcpos<0)
179 {
180 movinglabelspossible=true;
181 asar_throw_error(2, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex6((unsigned int)realsnespos).data());
182 }
183 39536 writeromdata_byte(pcpos, (unsigned char)num);
184
2/2
✓ Branch 0 taken 4131 times.
✓ Branch 1 taken 35405 times.
39536 if (pcpos>=romlen) romlen=pcpos+1;
185 }
186 118625 step(1);
187 118625 ratsmetastate=ratsmeta_ban;
188 118625 }
189
190 int recent_opcode_num = 0;
191
192 7598 void write1_pick(unsigned int num)
193 {
194
10/20
✓ Branch 0 taken 106852 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 27 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27 times.
✗ Branch 19 not taken.
114693 write1_65816(num);
195 107614 }
196
197 113788 static bool asblock_pick(char** word, int numwords)
198 {
199 113788 recent_opcode_num = 1;
200
201
2/2
✓ Branch 0 taken 110776 times.
✓ Branch 1 taken 3012 times.
113788 if (arch==arch_65816) return asblock_65816(word, numwords);
202
2/2
✓ Branch 0 taken 1179 times.
✓ Branch 1 taken 1833 times.
3012 if (arch==arch_spc700) return asblock_spc700(word, numwords);
203
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1827 times.
1833 if (arch==arch_spc700_inline) return asblock_spc700(word, numwords);
204
1/2
✓ Branch 0 taken 1827 times.
✗ Branch 1 not taken.
1827 if (arch==arch_superfx) return asblock_superfx(word, numwords);
205 return true;
206 }
207
208 #define write1 write1_pick
209 #define snestopc snestopc_pick
210
211 754 const char * safedequote(char * str)
212 {
213 754 const char * tmp=dequote(str);
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 754 times.
754 if (!tmp) asar_throw_error(0, error_type_block, error_id_garbage_near_quoted_string);
215 754 return tmp;
216 }
217
218 extern char romtitle[30];
219 extern bool stdlib;
220
221 853 void write2(unsigned int num)
222 {
223 write1(num);
224 853 write1(num/256);
225 853 }
226
227 509 void write3(unsigned int num)
228 {
229 write1(num);
230 509 write1(num/256);
231 509 write1(num/65536);
232 509 }
233
234 45 void write4(unsigned int num)
235 {
236 write1(num);
237 45 write1(num/256);
238 45 write1(num/65536);
239 45 write1(num/16777216);
240 45 }
241
242 //these are NOT used by the math parser - see math.cpp for that
243 int read1(int insnespos)
244 {
245 int addr=snestopc(insnespos);
246 if (addr<0 || addr+1>romlen_r) return -1;
247 return
248 romdata_r[addr ] ;
249 }
250
251 9 int read2(int insnespos)
252 {
253 int addr=snestopc(insnespos);
254
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 if (addr<0 || addr+2>romlen_r) return -1;
255 return
256 9 romdata_r[addr ] |
257 9 (romdata_r[addr+1]<< 8);
258 }
259
260 27 int read3(int insnespos)
261 {
262 int addr=snestopc(insnespos);
263
2/4
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
27 if (addr<0 || addr+3>romlen_r) return -1;
264 return
265 27 romdata_r[addr ] |
266 27 (romdata_r[addr+1]<< 8)|
267 27 (romdata_r[addr+2]<<16);
268 }
269
270 708 int getlenfromchar(char c)
271 {
272 708 c=(char)to_lower(c);
273
2/2
✓ Branch 0 taken 378 times.
✓ Branch 1 taken 330 times.
708 if (c=='b') return 1;
274
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 330 times.
378 if (c=='w') return 2;
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (c=='l') return 3;
276 if (c=='d')
277 {
278 asar_throw_warning(1, warning_id_feature_deprecated, ".d opcode suffix", "this doesn't even make sense");
279 return 4;
280 }
281 asar_throw_error(0, error_type_block, error_id_invalid_opcode_length);
282 return -1;
283 }
284
285 assocarr<snes_label> labels;
286 static autoarray<int> poslabels;
287 static autoarray<int> neglabels;
288
289 autoarray<int>* macroposlabels;
290 autoarray<int>* macroneglabels;
291
292 autoarray<string> sublabels;
293 autoarray<string>* macrosublabels;
294
295 // randomdude999: ns is still the string to prefix to all labels, it's calculated whenever namespace_list is changed
296 string ns;
297 string ns_backup;
298 autoarray<string> namespace_list;
299
300 //bool fastrom=false;
301
302 autoarray<string> includeonce;
303
304 442 bool confirmname(const char * name)
305 {
306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 442 times.
442 if (!name[0]) return false;
307
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 367 times.
442 if (is_digit(name[0])) return false;
308
2/2
✓ Branch 0 taken 2586 times.
✓ Branch 1 taken 364 times.
2950 for (int i=0;name[i];i++)
309 {
310
4/4
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 2454 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 129 times.
2586 if (!is_alnum(name[i]) && name[i]!='_') return false;
311 }
312 return true;
313 }
314
315 1140857 string posneglabelname(const char ** input, bool define)
316 {
317 1140857 const char* label = *input;
318
319 1140857 string output;
320
321 int depth = 0;
322 bool ismacro = false;
323
324
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1140832 times.
1140857 if (label[0] == '?')
325 {
326 ismacro = true;
327 25 label++;
328 }
329
4/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1140816 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 1140708 times.
1140857 if (label[0] == '-' || label[0] == '+')
330 {
331 char first = label[0];
332
4/4
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 106 times.
✓ Branch 2 taken 149 times.
✓ Branch 3 taken 43 times.
298 for (depth = 0; label[0] && label[0] == first; depth++) label++;
333
334
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 10 times.
149 if (!ismacro)
335 {
336
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 36 times.
139 if (first == '+')
337 {
338 103 *input = label;
339 206 output = STR":pos_" + dec(depth) + "_" + dec(poslabels[depth]);
340
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 52 times.
154 if (define) poslabels[depth]++;
341 }
342 else
343 {
344 36 *input = label;
345
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
39 if (define) neglabels[depth]++;
346 72 output = STR":neg_" + dec(depth) + "_" + dec(neglabels[depth]);
347 }
348 }
349 else
350 {
351
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 if (macrorecursion == 0 || macroposlabels == nullptr || macroneglabels == nullptr)
352 {
353 if (!macrorecursion) asar_throw_error(0, error_type_block, error_id_macro_label_outside_of_macro);
354 }
355 else
356 {
357
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (first == '+')
358 {
359 5 *input = label;
360 10 output = STR":macro_" + dec(calledmacros) + STR"_pos_" + dec(depth) + "_" + dec((*macroposlabels)[depth]);
361
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (define) (*macroposlabels)[depth]++;
362 }
363 else
364 {
365 5 *input = label;
366
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
8 if (define) (*macroneglabels)[depth]++;
367 10 output = STR":macro_" + dec(calledmacros) + STR"_neg_" + dec(depth) + "_" + dec((*macroneglabels)[depth]);
368 }
369 }
370 }
371 }
372
373 1140857 return output;
374 }
375
376 1164 static string labelname(const char ** rawname, bool define=false)
377 {
378 #define deref_rawname (*rawname)
379 1164 bool ismacro = (deref_rawname[0] == '?');
380
381
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1152 times.
1164 if (ismacro)
382 {
383 12 deref_rawname++;
384 }
385
386 bool issublabel = false;
387
388 1164 string name;
389 int i=-1;
390
391 autoarray<string>* sublabellist = &sublabels;
392
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1152 times.
1164 if (ismacro)
393 {
394 12 sublabellist = macrosublabels;
395 }
396
397
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1164 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1164 if (is_digit(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
398
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1116 times.
1164 if (*deref_rawname ==':')
399 {
400 48 deref_rawname++;
401 name=":";
402 }
403
4/4
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 1032 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1020 times.
1116 else if (!in_struct && !in_sub_struct)
404 {
405
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 1020 times.
1054 for (i=0;(*deref_rawname =='.');i++) deref_rawname++;
406
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1020 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1020 if (!is_ualnum(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
407
3/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1012 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1020 if (emulatexkas && i>1) asar_throw_warning(1, warning_id_convert_to_asar);
408
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 989 times.
1020 if (i)
409 {
410
2/6
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
31 if (!sublabellist || !(*sublabellist)[i - 1]) asar_throw_error(1, error_type_block, error_id_label_missing_parent);
411 62 name+=STR(*sublabellist)[i-1]+"_";
412 issublabel = true;
413 }
414 }
415
416
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1157 times.
1164 if (ismacro && !issublabel)
417 {
418 // RPG Hacker: Don't add the prefix for sublabels, because they already inherit it from
419 // their parents' names.
420
2/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7 if (!macrorecursion || macrosublabels == nullptr) asar_throw_error(1, error_type_block, error_id_macro_label_outside_of_macro);
421 14 name = STR":macro_" + dec(calledmacros) + "_" + name;
422 }
423
424
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1152 times.
1164 if(in_sub_struct)
425 {
426 12 name += struct_parent + ".";
427 }
428
429
4/4
✓ Branch 0 taken 1080 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 1068 times.
1164 if (in_struct || in_sub_struct)
430 {
431 96 name += struct_name;
432 96 name += '.';
433
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
96 if(*deref_rawname != '.') asar_throw_error(1, error_type_block, error_id_invalid_label_name); //probably should be a better error. TODO!!!
434 96 deref_rawname++;
435 }
436
437
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1164 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1164 if (!is_ualnum(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
438
439
6/6
✓ Branch 0 taken 9133 times.
✓ Branch 1 taken 1321 times.
✓ Branch 2 taken 118 times.
✓ Branch 3 taken 1203 times.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 1164 times.
10454 while (is_ualnum(*deref_rawname) || *deref_rawname == '.' || *deref_rawname == '[')
440 {
441
6/6
✓ Branch 0 taken 8720 times.
✓ Branch 1 taken 570 times.
✓ Branch 2 taken 8684 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 8645 times.
9290 if(!in_struct && !in_sub_struct && *deref_rawname == '[')
442 {
443 bool invalid = true;
444
1/2
✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
117 while (isprint(*deref_rawname))
445 {
446
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 39 times.
117 if (*(deref_rawname++) == ']')
447 {
448 invalid = false;
449 break;
450 }
451 }
452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (invalid)
453 {
454 asar_throw_error(1, error_type_block, error_id_invalid_label_missing_closer);
455 }
456 }
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251 times.
9251 else if (*deref_rawname == '{')
458 {
459 asar_throw_error(1, error_type_block, error_id_array_invalid_inside_structs);
460 }
461
462 9290 name+=*(deref_rawname++);
463 }
464
2/2
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 909 times.
1164 if (define && i>=0)
465 {
466 255 (*sublabellist).reset(i);
467 (*sublabellist)[i]=name;
468 }
469 1164 return name;
470 #undef deref_rawname
471 }
472
473 801 inline bool labelvalcore(const char ** rawname, snes_label * rval, bool define, bool shouldthrow)
474 {
475 801 string name=labelname(rawname, define);
476 snes_label rval_;
477
8/8
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 756 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 756 times.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 756 times.
✓ Branch 6 taken 27 times.
✓ Branch 7 taken 774 times.
873 if (ns && labels.exists(STR ns+name)) {rval_ = labels.find(STR ns+name);}
478
2/2
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 63 times.
774 else if (labels.exists(name)) {rval_ = labels.find(name);}
479 else
480 {
481
3/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
63 if (shouldthrow && pass)
482 {
483 asar_throw_error(1, error_type_block, error_id_label_not_found, name.data());
484 }
485
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 if (rval) { rval->pos = (unsigned int)-1; rval->is_static = false; }
486 63 return false;
487 }
488
1/2
✓ Branch 0 taken 738 times.
✗ Branch 1 not taken.
738 if (rval)
489 {
490 738 *rval=rval_;
491 //if (fastrom && (rval_&0x700000)!=0x700000) *rval|=0x800000;
492 }
493 return true;
494 801 }
495
496 506 snes_label labelval(const char ** rawname, bool define)
497 {
498 snes_label rval;
499 506 labelvalcore(rawname, &rval, define, true);
500 506 return rval;
501 }
502
503 snes_label labelval(char ** rawname, bool define)
504 {
505 snes_label rval;
506 labelvalcore(const_cast<const char**>(rawname), &rval, define, true);
507 return rval;
508 }
509
510 28 snes_label labelval(string name, bool define)
511 {
512 28 const char * rawname=name;
513 snes_label rval;
514 28 labelvalcore(&rawname, &rval, define, true);
515 28 return rval;
516 }
517
518 239 bool labelval(const char ** rawname, snes_label * rval, bool define)
519 {
520 239 return labelvalcore(rawname, rval, define, false);
521 }
522
523 bool labelval(char ** rawname, snes_label * rval, bool define)
524 {
525 return labelvalcore(const_cast<const char**>(rawname), rval, define, false);
526 }
527
528 28 bool labelval(string name, snes_label * rval, bool define)
529 {
530 28 const char * str=name;
531 28 return labelvalcore(&str, rval, define, false);
532 }
533
534 454 static void setlabel(string name, int loc=-1, bool is_static=false)
535 {
536
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 34 times.
454 if (loc==-1)
537 {
538 420 verifysnespos();
539 420 loc=snespos;
540 }
541
542 snes_label label_data;
543 454 label_data.pos = (unsigned int)loc;
544 454 label_data.is_static = is_static;
545
546 unsigned int labelpos;
547
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 302 times.
454 if (pass==0)
548 {
549
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 151 times.
152 if (labels.exists(name))
550 {
551 1 movinglabelspossible=true;
552 1 asar_throw_error(0, error_type_block, error_id_label_redefined, name.data());
553 }
554 151 labels.create(name) = label_data;
555 }
556
2/2
✓ Branch 0 taken 151 times.
✓ Branch 1 taken 151 times.
302 else if (pass==1)
557 {
558 151 labels.create(name) = label_data;
559 }
560
1/2
✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
151 else if (pass==2)
561 {
562 //all label locations are known at this point, add a sanity check
563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
151 if (!labels.exists(name)) asar_throw_error(2, error_type_block, error_id_label_on_third_pass);
564 151 labelpos = labels.find(name).pos;
565
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
151 if ((int)labelpos != loc && !movinglabelspossible)
566 {
567 if((unsigned int)loc < labelpos && (unsigned int)loc>>16 != labelpos>>16) asar_throw_error(2, error_type_block, error_id_label_ambiguous, name.raw());
568 else if((unsigned int)loc < labelpos && labelpos == (dp_base + 0xFFu)) asar_throw_error(2, error_type_block, error_id_label_ambiguous, name.raw());
569 else if(errored) return;
570 else asar_throw_error(2, error_type_block, error_id_label_moving);
571 }
572 }
573 }
574
575
576 chartabledata table;
577 static autoarray<chartabledata> tablestack;
578
579 static int freespacepos[256];
580 static int freespacelen[256];
581 static int freespaceidnext;
582 static int freespaceid;
583 static int freespacestart;
584 int freespaceextra;
585
586 static bool freespaceleak[256];
587 static string freespacefile[256];
588
589 static int freespaceorgpos[256];
590 static int freespaceorglen[256];
591 static bool freespacestatic[256];
592 static unsigned char freespacebyte[256];
593
594 281 static void cleartable()
595 {
596
2/2
✓ Branch 0 taken 71936 times.
✓ Branch 1 taken 281 times.
72217 for (unsigned int i=0;i<256;i++) table.table[i]=i;
597 281 }
598
599 struct pushable {
600 int arch;
601 int snespos;
602 int snesstart;
603 int snesposreal;
604 int snesstartreal;
605 int freeid;
606 int freeex;
607 int freest;
608 int arch1;
609 int arch2;
610 int arch3;
611 int arch4;
612 };
613 static autoarray<pushable> pushpc;
614 static int pushpcnum;
615
616 static autoarray<int> basestack;
617 static int basestacknum;
618
619 struct ns_pushable {
620 string ns;
621 autoarray<string> namespace_list;
622 bool nested_namespaces;
623 };
624
625 static autoarray<ns_pushable> pushns;
626 static int pushnsnum;
627
628
629 static unsigned char fillbyte[12];
630 static unsigned char padbyte[12];
631
632 static bool nested_namespaces = false;
633
634 441 static int getfreespaceid()
635 {
636 static const int max_num_freespaces = 125;
637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 441 times.
441 if (freespaceidnext > max_num_freespaces) asar_throw_error(pass, error_type_fatal, error_id_freespace_limit_reached, max_num_freespaces);
638 441 return freespaceidnext++;
639 }
640
641 436663 void checkbankcross()
642 {
643
5/8
✓ Branch 0 taken 3321 times.
✓ Branch 1 taken 433342 times.
✓ Branch 2 taken 3321 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3321 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3321 times.
436663 if (snespos<0 && realsnespos<0 && startpos<0 && realstartpos<0) return;
644
2/2
✓ Branch 0 taken 433009 times.
✓ Branch 1 taken 333 times.
433342 if (disable_bank_cross_errors) return;
645
2/2
✓ Branch 0 taken 433007 times.
✓ Branch 1 taken 2 times.
433009 unsigned int mask = 0x7FFF0000 | (check_half_banks_crossed ? 0x8000 : 0);
646
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 432990 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 18 times.
433009 if (((snespos^ startpos) & mask) && (((snespos - 1) ^ startpos) & mask))
647 {
648 1 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, snespos);
649 }
650
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 432990 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
433008 else if (((realsnespos^realstartpos) & mask) && (((realsnespos - 1) ^ realstartpos) & mask))
651 {
652 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, realsnespos);
653 }
654 }
655
656 1066 static void freespaceend()
657 {
658
4/4
✓ Branch 0 taken 709 times.
✓ Branch 1 taken 357 times.
✓ Branch 2 taken 438 times.
✓ Branch 3 taken 271 times.
1066 if ((snespos&0x7F000000) && ((unsigned int)snespos&0x80000000)==0)
659 {
660 438 freespacelen[freespaceid]=snespos-freespacestart+freespaceextra;
661 438 snespos=(int)0xFFFFFFFF;
662 }
663 1066 freespaceextra=0;
664 1066 }
665
666 int numopcodes;
667
668 bool warnxkas;
669
670
1/2
✓ Branch 0 taken 2810 times.
✗ Branch 1 not taken.
2810 static void adddefine(const string & key, string & value)
671 {
672
1/2
✓ Branch 0 taken 2810 times.
✗ Branch 1 not taken.
2810 if (!defines.exists(key)) defines.create(key) = value;
673 2810 }
674
675 281 void initstuff()
676 {
677
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 186 times.
281 if (pass==0)
678 {
679
2/2
✓ Branch 0 taken 24320 times.
✓ Branch 1 taken 95 times.
24415 for (int i=0;i<256;i++)
680 {
681 24320 freespaceleak[i]=true;
682 24320 freespaceorgpos[i]=-2;
683 24320 freespaceorglen[i]=-1;
684 24320 freespacebyte[i] = 0x00;
685 }
686 }
687 281 arch=arch_65816;
688 281 mapper=lorom;
689 281 mapper_set = false;
690 281 reallycalledmacros=0;
691 281 calledmacros=0;
692 281 macrorecursion=0;
693 281 repeatnext=1;
694 281 defines.reset();
695 281 builtindefines.each(adddefine);
696 281 clidefines.each(adddefine);
697 ns="";
698 281 namespace_list.reset();
699 281 sublabels.reset();
700 281 poslabels.reset();
701 281 neglabels.reset();
702 281 macroposlabels = nullptr;
703 281 macroneglabels = nullptr;
704 281 macrosublabels = nullptr;
705 281 cleartable();
706 281 pushpc.reset();
707 281 pushpcnum=0;
708 281 pushns.reset();
709 281 pushnsnum = 0;
710 281 bytes=0;
711 281 memset(fillbyte, 0, sizeof(fillbyte));
712 281 memset(padbyte, 0, sizeof(padbyte));
713 281 snespos=(int)0xFFFFFFFF;
714 281 realsnespos= (int)0xFFFFFFFF;
715 281 startpos= (int)0xFFFFFFFF;
716 281 realstartpos= (int)0xFFFFFFFF;
717 //fastrom=false;
718 281 freespaceidnext=1;
719 281 freespaceid=1;
720 281 freespaceextra=0;
721 281 numopcodes=0;
722 281 specifiedasarver = false;
723 281 incsrcdepth = 0;
724
725 281 optimizeforbank = -1;
726 281 optimize_dp = optimize_dp_flag::NONE;
727 281 dp_base = 0;
728 281 optimize_address = optimize_address_flag::DEFAULT;
729
730 281 in_struct = false;
731 281 in_sub_struct = false;
732 281 in_spcblock = false;
733
734 281 math_pri=false;
735 281 math_round=true;
736
737
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
281 if (arch==arch_65816) asinit_65816();
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
281 if (arch==arch_spc700) asinit_spc700();
739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
281 if (arch==arch_spc700_inline) asinit_spc700();
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
281 if (arch==arch_superfx) asinit_superfx();
741
742 281 warnxkas=false;
743 281 emulatexkas=false;
744 281 disable_bank_cross_errors = false;
745 281 check_half_banks_crossed = false;
746 281 nested_namespaces = false;
747
748 thisfilename = "";
749
750 281 includeonce.reset();
751
752 extern AddressToLineMapping addressToLineMapping;
753 281 addressToLineMapping.reset();
754
755 281 push_warnings(false);
756
757 281 initmathcore();
758 281 }
759
760
761 //void nerf(const string& left, string& right){puts(S left+" = "+right);}
762
763 279 void finishpass()
764 {
765 279 verify_warnings();
766 279 pull_warnings(false);
767
768 //defines.traverse(nerf);
769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_missing_endspcblock);
770
2/4
✓ Branch 0 taken 279 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 279 times.
279 if (in_struct || in_sub_struct) asar_throw_error(pass, error_type_null, error_id_struct_without_endstruct);
771
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
279 else if (pushpcnum && pass == 0) asar_throw_error(pass, error_type_null, error_id_pushpc_without_pullpc);
772
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
279 else if (pushnsnum && pass == 0) asar_throw_error(pass, error_type_null, error_id_pushns_without_pullns);
773 279 freespaceend();
774
2/2
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 24 times.
279 if (arch==arch_65816) asend_65816();
775
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 264 times.
279 if (arch==arch_spc700) asend_spc700();
776
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 276 times.
279 if (arch==arch_spc700_inline) asend_spc700();
777
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 273 times.
279 if (arch==arch_superfx) asend_superfx();
778
779 279 deinitmathcore();
780 279 }
781
782 436203 static bool addlabel(const char * label, int pos=-1, bool global_label = false)
783 {
784
3/4
✓ Branch 0 taken 325720 times.
✓ Branch 1 taken 110483 times.
✓ Branch 2 taken 325720 times.
✗ Branch 3 not taken.
436203 if (!label[0] || label[0]==':') return false;//colons are reserved for special labels
785
786 325720 const char* posneglabel = label;
787 325720 string posnegname = posneglabelname(&posneglabel, true);
788
789
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 325660 times.
325720 if (posnegname.length() > 0)
790 {
791
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if (global_label) return false;
792
3/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
60 if (*posneglabel != '\0' && *posneglabel != ':') asar_throw_error(0, error_type_block, error_id_broken_label_definition);
793
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 setlabel(posnegname, pos);
794 60 return true;
795 }
796
7/8
✓ Branch 0 taken 325318 times.
✓ Branch 1 taken 342 times.
✓ Branch 2 taken 325291 times.
✓ Branch 3 taken 27 times.
✓ Branch 4 taken 325288 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 325288 times.
325660 if (label[strlen(label)-1]==':' || label[0]=='.' || label[0]=='?' || label[0] == '#')
797 {
798
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 6 times.
372 if (!label[1]) return false;
799
6/8
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 345 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 3 times.
366 if(global_label && (in_struct || in_sub_struct || label[0]=='?')) return false;
800
801 bool define = true;
802
803
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 351 times.
363 if (label[0] == '#')
804 {
805 define = false;
806 12 label++;
807 }
808
809 // RPG Hacker: Also checking label[1] now, since it might be a macro sublabel.
810 // Also, apparently this here doesn't account for main labels. I guess because
811 // we don't even get here in the first place if they don't include a colon?
812
5/6
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
363 bool requirecolon = (label[0] != '.' && label[1] != '.') && (in_struct || in_sub_struct);
813
1/2
✓ Branch 0 taken 363 times.
✗ Branch 1 not taken.
363 string name=labelname(&label, define);
814
2/2
✓ Branch 0 taken 342 times.
✓ Branch 1 taken 21 times.
363 if (label[0]==':') label++;
815
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21 else if (requirecolon) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
816
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
21 else if (global_label) return false;
817
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 360 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
360 if (label[0]) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
818
4/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 306 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 6 times.
408 if (ns && !global_label) name=STR ns+name;
819
6/6
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 264 times.
✓ Branch 4 taken 359 times.
✓ Branch 5 taken 1 times.
360 setlabel(name, pos, ((in_struct || in_sub_struct) && static_struct));
820 359 return true;
821 363 }
822 return false;
823 325720 }
824
825 static autoarray<bool> elsestatus;
826 int numtrue=0;//if 1 -> increase both
827 int numif = 0; //if 0 or inside if 0 -> increase only numif
828
829 autoarray<whiletracker> whilestatus;
830 int single_line_for_tracker;
831
832 static int freespaceuse=0;
833
834
835 36 static void push_pc()
836 {
837 36 pushpc[pushpcnum].arch=arch;
838 36 pushpc[pushpcnum].snespos=snespos;
839 36 pushpc[pushpcnum].snesstart=startpos;
840 36 pushpc[pushpcnum].snesposreal=realsnespos;
841 36 pushpc[pushpcnum].snesstartreal=realstartpos;
842 36 pushpc[pushpcnum].freeid=freespaceid;
843 36 pushpc[pushpcnum].freeex=freespaceextra;
844 36 pushpc[pushpcnum].freest=freespacestart;
845 36 pushpcnum++;
846 36 }
847
848 36 static void pop_pc()
849 {
850 36 pushpcnum--;
851 36 snespos=pushpc[pushpcnum].snespos;
852 36 startpos=pushpc[pushpcnum].snesstart;
853 36 realsnespos=pushpc[pushpcnum].snesposreal;
854 36 realstartpos=pushpc[pushpcnum].snesstartreal;
855 36 freespaceid=pushpc[pushpcnum].freeid;
856 36 freespaceextra=pushpc[pushpcnum].freeex;
857 36 freespacestart=pushpc[pushpcnum].freest;
858 36 }
859
860
861 66 string handle_print(char* input)
862 {
863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (!confirmqpar(input)) asar_throw_error(0, error_type_block, error_id_mismatched_parentheses);
864 66 string out;
865
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 autoptr<char**> pars = qpsplit(input, ",");
866
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 66 times.
228 for (int i = 0; pars[i]; i++)
867 {
868 if (0);
869
3/4
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 105 times.
✗ Branch 3 not taken.
162 else if (pars[i][0] == '"') out += safedequote(pars[i]);
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 else if (!stricmp(pars[i], "bytes")) out += dec(bytes);
871
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 else if (!stricmp(pars[i], "freespaceuse")) out += dec(freespaceuse);
872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 else if (!stricmp(pars[i], "pc")) out += hex6((unsigned int)(snespos & 0xFFFFFF));
873 102 else if (!strncasecmp(pars[i], "bin(", strlen("bin(")) ||
874
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 12 times.
45 !strncasecmp(pars[i], "dec(", strlen("dec(")) ||
875
4/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 12 times.
90 !strncasecmp(pars[i], "hex(", strlen("hex(")) ||
876
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 !strncasecmp(pars[i], "double(", strlen("double(")))
877 {
878 57 char * arg1pos = strchr(pars[i], '(') + 1;
879 char * endpos = strchr(arg1pos, '\0');
880
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 57 times.
114 while (*endpos == ' ' || *endpos == '\0') endpos--;
881
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57 if (*endpos != ')') asar_throw_error(0, error_type_block, error_id_invalid_print_function_syntax);
882 57 string paramstr = string(arg1pos, (int)(endpos - arg1pos));
883
884 int numargs;
885
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 autoptr<char**> params = qpsplit(paramstr.temp_raw(), ",", &numargs);
886
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57 if (numargs > 2) asar_throw_error(0, error_type_block, error_id_wrong_num_parameters);
887 int precision = 0;
888 57 bool hasprec = numargs == 2;
889
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 39 times.
57 if (hasprec)
890 {
891
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 precision = getnum64(params[1]);
892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (precision < 0) precision = 0;
893 39 if (precision > 64) precision = 64;
894 }
895 57 *(arg1pos - 1) = '\0'; // allows more convenient comparsion functions
896
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 45 times.
57 if (!stricmp(pars[i], "bin"))
897 {
898 // sadly printf doesn't have binary, so let's roll our own
899
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 int64_t value = getnum64(params[0]);
900 char buffer[65];
901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (value < 0) {
902 out += '-';
903 value = -value;
904 // decrement precision because we've output one char already
905 precision -= 1;
906 if (precision<0) precision = 0;
907 }
908
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 12 times.
780 for (int j = 0; j < 64; j++) {
909 768 buffer[63 - j] = '0' + ((value & (1ull << j)) >> j);
910 }
911 12 buffer[64] = 0;
912 int startidx = 0;
913
3/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 672 times.
✗ Branch 3 not taken.
684 while (startidx < 64 - precision && buffer[startidx] == '0') startidx++;
914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (startidx == 64) startidx--; // always want to print at least one digit
915 12 out += buffer + startidx;
916 }
917
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 33 times.
45 else if (!stricmp(pars[i], "dec"))
918 {
919
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 int64_t value = getnum64(params[0]);
920 char buffer[65];
921 12 snprintf(buffer, 65, "%0*" PRId64, precision, value);
922 12 out += buffer;
923 }
924
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 21 times.
33 else if (!stricmp(pars[i], "hex"))
925 {
926
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 int64_t value = getnum64(params[0]);
927 char buffer[65];
928 12 snprintf(buffer, 65, "%0*" PRIX64, precision, value);
929 12 out += buffer;
930 }
931
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 else if (!stricmp(pars[i], "double"))
932 {
933
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 3 times.
21 if (!hasprec) precision = 5;
934
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 out += ftostrvar(getnumdouble(params[0]), precision);
935 }
936 57 }
937 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
938 }
939 66 return out;
940 66 }
941
942
943 436992 void assembleblock(const char * block, bool isspecialline)
944 {
945 436992 string tmp=block;
946 int numwords;
947
1/2
✓ Branch 0 taken 436992 times.
✗ Branch 1 not taken.
436992 char ** word = qsplit(tmp.temp_raw(), " ", &numwords);
948 436992 string resolved;
949 // when writing out the data for the addrToLine mapping,
950 // we want to write out the snespos we had before writing opcodes
951 436992 int addrToLinePos = realsnespos & 0xFFFFFF;
952
953 #define is(test) (!stricmpwithlower(word[0], test))
954 #define is0(test) (numwords==1 && !stricmpwithlower(word[0], test))
955 #define is1(test) (numwords==2 && !stricmpwithlower(word[0], test))
956 #define is2(test) (numwords==3 && !stricmpwithlower(word[0], test))
957 #define is3(test) (numwords==4 && !stricmpwithlower(word[0], test))
958 #define par word[1]
959
960
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 436992 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
436992 if(!moreonlinecond && !(is("elseif") || is("else"))){
961 return;
962 }
963
964 // RPG Hacker: Hack to fix the bug where defines in elseifs would never get resolved
965 // This really seems like the only possible place for the fix
966
4/4
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 436923 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 33 times.
436992 if (is("elseif") && numtrue+1==numif)
967 {
968
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 resolvedefines(resolved, block);
969
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 free(word);
970
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 word = qsplit(resolved.temp_raw(), " ", &numwords);
971 }
972
973 autoptr<char**> wordcopy=word;
974
6/6
✓ Branch 0 taken 436227 times.
✓ Branch 1 taken 765 times.
✓ Branch 2 taken 323626 times.
✓ Branch 3 taken 112601 times.
✓ Branch 4 taken 112580 times.
✓ Branch 5 taken 21 times.
436992 if (numif==numtrue && is1("global")) {
975
3/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 15 times.
21 if (!addlabel(word[1], -1, true)) {
976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(1, error_type_block, error_id_invalid_global_label, word[1]);
977 }
978 15 return;
979 }
980
12/12
✓ Branch 0 taken 436610 times.
✓ Branch 1 taken 765 times.
✓ Branch 2 taken 436293 times.
✓ Branch 3 taken 317 times.
✓ Branch 4 taken 218754 times.
✓ Branch 5 taken 217539 times.
✓ Branch 6 taken 218643 times.
✓ Branch 7 taken 111 times.
✓ Branch 8 taken 436181 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 435777 times.
✓ Branch 11 taken 404 times.
437375 while (numif==numtrue && word[0] && (!word[1] || strcmp(word[1], "=")) && addlabel(word[0]))
981 {
982 404 word++;
983 404 numwords--;
984 }
985
4/4
✓ Branch 0 taken 436653 times.
✓ Branch 1 taken 317 times.
✓ Branch 2 taken 326146 times.
✓ Branch 3 taken 110507 times.
436970 if (!word[0] || !word[0][0]) return;
986
4/4
✓ Branch 0 taken 325405 times.
✓ Branch 1 taken 741 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 325297 times.
326146 if (numif==numtrue && word[0][0]=='%')
987 {
988
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 3 times.
108 if (!macrorecursion)
989 {
990 callerfilename=thisfilename;
991 105 callerline=thisline;
992 }
993 108 int fakeendif_prev = fakeendif;
994 108 int moreonlinecond_prev = moreonlinecond;
995 108 int calledmacros_prev = calledmacros;
996
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 6 times.
108 int single_line_for_tracker_prev = single_line_for_tracker;
997
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 6 times.
108 callmacro(strchr(block, '%')+1);
998 102 fakeendif = fakeendif_prev;
999 102 moreonlinecond = moreonlinecond_prev;
1000 102 calledmacros = calledmacros_prev;
1001 102 single_line_for_tracker = single_line_for_tracker_prev;
1002
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 3 times.
102 if (!macrorecursion)
1003 {
1004 callerfilename="";
1005 99 callerline=-1;
1006 }
1007 102 return;
1008 }
1009
10/10
✓ Branch 0 taken 325876 times.
✓ Branch 1 taken 162 times.
✓ Branch 2 taken 325807 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 325792 times.
✓ Branch 5 taken 15 times.
✓ Branch 6 taken 220300 times.
✓ Branch 7 taken 105492 times.
✓ Branch 8 taken 220126 times.
✓ Branch 9 taken 174 times.
326038 if (is("if") || is("elseif") || is("assert") || is("while") || is("for"))
1010 {
1011
4/4
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 105750 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 159 times.
105912 if(is("if") && moreonline) fakeendif++;
1012
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 105912 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
105912 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
1013 105912 string errmsg;
1014 105912 whiletracker wstatus;
1015 105912 wstatus.startline = thisline;
1016 105912 wstatus.iswhile = false;
1017 105912 wstatus.cond = false;
1018 105912 wstatus.is_for = false;
1019 105912 wstatus.for_start = wstatus.for_end = wstatus.for_cur = 0;
1020 105912 wstatus.for_has_var_backup = false;
1021
2/2
✓ Branch 0 taken 105492 times.
✓ Branch 1 taken 420 times.
105912 if (is("while")) wstatus.iswhile = true;
1022
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 105738 times.
105912 if (is("for")) wstatus.is_for = true;
1023 // if we are a for loop and:
1024 // 1) whilestatus has an entry at this level already
1025 // 2) said entry represents an incomplete for loop
1026 // then this loop must be meant "for us".
1027 // check number 2 is necessary because otherwise, 2 for loops back-to-back (not nested) would try to use the same whilestatus entry
1028 bool is_for_cont = false;
1029
8/8
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 105738 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 166 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 43 times.
✓ Branch 7 taken 123 times.
106085 if (is("for") && whilestatus.count > numif && whilestatus[numif].is_for && whilestatus[numif].for_cur < whilestatus[numif].for_end)
1030 {
1031 // continuation of a for loop
1032 is_for_cont = true;
1033 }
1034 105912 whiletracker& addedwstatus = is_for_cont ? whilestatus[numif] : (whilestatus[numif] = wstatus);
1035
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 105897 times.
105912 if (is("assert"))
1036 {
1037
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 autoptr<char**> tokens = qpsplit(word[numwords - 1], ",");
1038
3/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 9 times.
15 if (tokens[0] != NULL && tokens[1] != NULL)
1039 {
1040 6 string rawerrmsg;
1041 size_t pos = 1;
1042
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 6 times.
27 while (tokens[pos])
1043 {
1044 21 rawerrmsg += tokens[pos];
1045
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 6 times.
21 if (tokens[pos + 1] != NULL)
1046 {
1047 15 rawerrmsg += ",";
1048 }
1049 pos++;
1050 }
1051
1052
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 errmsg = handle_print(rawerrmsg.raw());
1053 6 }
1054 15 }
1055
5/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 105858 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
105912 if (numtrue!=numif && !(is("elseif") && numtrue+1==numif))
1056 {
1057
4/6
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
18 if ((is("if") || is("while") || is("for"))) numif++;
1058 return;
1059 }
1060
6/6
✓ Branch 0 taken 105732 times.
✓ Branch 1 taken 162 times.
✓ Branch 2 taken 249 times.
✓ Branch 3 taken 105483 times.
✓ Branch 4 taken 165 times.
✓ Branch 5 taken 84 times.
105894 if ((is("if") || is("while") || is("for"))) numif++;
1061 bool cond;
1062
1063 105894 bool isassert = is("assert");
1064
1065 105894 char ** nextword=word+1;
1066 char * condstr= nullptr;
1067
2/2
✓ Branch 0 taken 105729 times.
✓ Branch 1 taken 165 times.
105894 if(!is("for")) {
1068 while (true)
1069 {
1070
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 105732 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
105732 if (!nextword[0]) asar_throw_error(0, error_type_block, error_id_broken_conditional, word[0]);
1071 bool thiscond = false;
1072
4/6
✓ Branch 0 taken 105555 times.
✓ Branch 1 taken 177 times.
✓ Branch 2 taken 105555 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 105555 times.
105732 if (!nextword[1] || !strcmp(nextword[1], "&&") || !strcmp(nextword[1], "||"))
1073 {
1074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177 times.
177 if (nextword[0][0] == '!')
1075 {
1076 asar_throw_warning(0, warning_id_feature_deprecated, "old style conditional negation (if !condition) ", "the not function");
1077 double val = getnumdouble(nextword[0]+1);
1078 if (foundlabel && !foundlabel_static && !isassert) asar_throw_error(0, error_type_block, error_id_label_in_conditional, word[0]);
1079 thiscond = !(val > 0);
1080 }
1081 else
1082 {
1083
1/2
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
177 double val = getnumdouble(nextword[0]);
1084
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 177 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.
177 if (foundlabel && !foundlabel_static && !isassert) asar_throw_error(0, error_type_block, error_id_label_in_conditional, word[0]);
1085 177 thiscond = (val > 0);
1086 }
1087
1088
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 177 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
177 if (condstr && nextword[1])
1089 {
1090 if (strcmp(condstr, nextword[1])) asar_throw_error(1, error_type_block, error_id_invalid_condition);
1091 }
1092 177 else condstr=nextword[1];
1093 177 nextword+=2;
1094 177 }
1095 else
1096 {
1097
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 105555 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
105555 if (!nextword[2]) asar_throw_error(0, error_type_block, error_id_broken_conditional, word[0]);
1098
1/2
✓ Branch 0 taken 105555 times.
✗ Branch 1 not taken.
105555 double par1=getnumdouble(nextword[0]);
1099
6/8
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 105525 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 15 times.
105555 if (foundlabel && !foundlabel_static && !isassert) asar_throw_error(0, error_type_block, error_id_label_in_conditional, word[0]);
1100
1/2
✓ Branch 0 taken 105540 times.
✗ Branch 1 not taken.
105540 double par2=getnumdouble(nextword[2]);
1101
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 105540 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.
105540 if (foundlabel && !foundlabel_static && !isassert) asar_throw_error(0, error_type_block, error_id_label_in_conditional, word[0]);
1102 if(0);
1103
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 105480 times.
105540 else if (!strcmp(nextword[1], ">")) thiscond=(par1>par2);
1104
2/2
✓ Branch 0 taken 105429 times.
✓ Branch 1 taken 51 times.
105480 else if (!strcmp(nextword[1], "<")) thiscond=(par1<par2);
1105
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 48 times.
51 else if (!strcmp(nextword[1], ">=")) thiscond=(par1>=par2);
1106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 else if (!strcmp(nextword[1], "<=")) thiscond=(par1<=par2);
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 else if (!strcmp(nextword[1], "="))
1108 {
1109 asar_throw_warning(0, warning_id_feature_deprecated, "if a = b", "use \"if a == b\" instead");
1110 thiscond=(par1==par2);
1111 }
1112
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 else if (!strcmp(nextword[1], "==")) thiscond=(par1==par2);
1113 else if (!strcmp(nextword[1], "!=")) thiscond=(par1!=par2);
1114 //else if (!strcmp(nextword[1], "<>")) thiscond=(par1!=par2);
1115 else asar_throw_error(0, error_type_block, error_id_broken_conditional, word[0]);
1116
1117
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 105537 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
105540 if (condstr && nextword[3])
1118 {
1119 if (strcmp(condstr, nextword[3])) asar_throw_error(1, error_type_block, error_id_invalid_condition);
1120 }
1121 105540 else condstr=nextword[3];
1122 105540 nextword+=4;
1123 }
1124
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 105708 times.
105717 if (condstr)
1125 {
1126
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 6 times.
9 if (!strcmp(condstr, "&&")) { if(thiscond) continue; }
1127 else if (!strcmp(condstr, "||")) { if(!thiscond) continue; }
1128 else asar_throw_error(0, error_type_block, error_id_broken_conditional, word[0]);
1129 }
1130 cond=thiscond;
1131 break;
1132 }
1133 }
1134
1135
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 105714 times.
105879 if (is("for"))
1136 {
1137 // for loops as anything except the first block cause weirdness
1138 // (while loops do too, but let's not talk about it)
1139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
165 if(single_line_for_tracker != 1) {
1140 numif--;
1141 asar_throw_error(0, error_type_line, error_id_bad_single_line_for);
1142 }
1143 // TODO: these errors could probably be a bit more descriptive
1144
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 123 times.
165 if(!is_for_cont)
1145 {
1146 // "for i = 0..16"
1147
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
42 if(numwords != 4) asar_throw_error(0, error_type_block, error_id_broken_for_loop);
1148
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
42 if(strcmp(word[2], "=") != 0) asar_throw_error(0, error_type_block, error_id_broken_for_loop);
1149
1150
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 char* range_sep = strqpstr(word[3], "..");
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if(!range_sep)
1152 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "invalid loop range");
1153
1154 42 string for_start(word[3], range_sep - word[3]);
1155 42 string for_end(range_sep+2);
1156
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 addedwstatus.for_start = getnum(for_start);
1157
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(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1158
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 addedwstatus.for_end = getnum(for_end);
1159
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(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1160 42 string varname = word[1];
1161
2/6
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
42 if(!validatedefinename(varname)) asar_throw_error(0, error_type_block, error_id_broken_for_loop);
1162 42 addedwstatus.for_variable = varname;
1163 42 addedwstatus.for_cur = addedwstatus.for_start;
1164 42 }
1165 else
1166 {
1167 123 addedwstatus.for_cur++;
1168 }
1169 // this cond is actually also used to tell assemblefile whether to jump back to the beginning of the loop, so keep it updated
1170 165 addedwstatus.cond = addedwstatus.for_cur < addedwstatus.for_end;
1171 165 single_line_for_tracker = 2;
1172
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 42 times.
165 if(addedwstatus.cond)
1173 {
1174
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 27 times.
123 numtrue++;
1175
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 27 times.
123 if(defines.exists(addedwstatus.for_variable)) {
1176 96 addedwstatus.for_has_var_backup = true;
1177 96 addedwstatus.for_var_backup = defines.find(addedwstatus.for_variable);
1178 }
1179
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 defines.create(addedwstatus.for_variable) = ftostr(addedwstatus.for_cur);
1180 }
1181 }
1182
4/4
✓ Branch 0 taken 105567 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 105483 times.
105714 else if (is("if") || is("while"))
1183 {
1184 if(0);
1185
2/2
✓ Branch 0 taken 105522 times.
✓ Branch 1 taken 108 times.
105630 else if (cond)
1186 {
1187 105522 numtrue++;
1188 105522 elsestatus[numif]=true;
1189 }
1190 else if (!cond)
1191 {
1192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(moreonline) moreonlinecond=false;
1193 108 elsestatus[numif]=false;
1194 }
1195 105630 addedwstatus.cond = cond;
1196 }
1197
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 15 times.
84 else if (is("elseif"))
1198 {
1199
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
69 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_elseif);
1200
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
69 if (whilestatus[numif - 1].iswhile) asar_throw_error(1, error_type_block, error_id_elseif_in_while);
1201
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 36 times.
69 if (numif==numtrue) numtrue--;
1202
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 15 times.
102 if (cond && !elsestatus[numif])
1203 {
1204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if(moreonline) moreonlinecond = true;
1205 18 numtrue++;
1206 18 elsestatus[numif]=true;
1207 }
1208 }
1209 // otherwise, must be assert command
1210
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 times.
15 else if (pass == 2 && !cond)
1211 {
1212
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
8 if (errmsg) asar_throw_error(2, error_type_block, error_id_assertion_failed, (string(": ") + errmsg).data());
1213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 else asar_throw_error(2, error_type_block, error_id_assertion_failed, ".");
1214 }
1215 105931 }
1216
6/6
✓ Branch 0 taken 219541 times.
✓ Branch 1 taken 585 times.
✓ Branch 2 taken 114472 times.
✓ Branch 3 taken 105069 times.
✓ Branch 4 taken 114298 times.
✓ Branch 5 taken 174 times.
220126 else if (is("endif") || is("endwhile") || is("endfor"))
1217 {
1218
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 105825 times.
105828 if(fakeendif) fakeendif--;
1219
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 105828 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
105828 if (numwords != 1) asar_throw_error(1, error_type_block, error_id_unknown_command);
1220
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 105828 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
105828 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_endif);
1221
2/2
✓ Branch 0 taken 105597 times.
✓ Branch 1 taken 231 times.
105828 if (numif==numtrue) numtrue--;
1222 105828 numif--;
1223
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 105654 times.
105828 if(whilestatus[numif].is_for) {
1224
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 144 times.
174 if(single_line_for_tracker == 2) single_line_for_tracker = 3;
1225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
174 if(moreonline) {
1226 // sabotage the whilestatus to prevent the loop running again
1227 // and spamming more of the same error
1228 whilestatus[numif].for_cur = whilestatus[numif].for_end;
1229 whilestatus[numif].cond = false;
1230 asar_throw_error(0, error_type_block, error_id_bad_single_line_for);
1231 }
1232
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 51 times.
174 if(whilestatus[numif].cond) {
1233
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 27 times.
123 if(whilestatus[numif].for_has_var_backup)
1234
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 defines.create(whilestatus[numif].for_variable) = whilestatus[numif].for_var_backup;
1235
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 else defines.remove(whilestatus[numif].for_variable);
1236 }
1237 }
1238
2/2
✓ Branch 0 taken 105403 times.
✓ Branch 1 taken 425 times.
105828 if(warn_endwhile) {
1239
2/2
✓ Branch 0 taken 105070 times.
✓ Branch 1 taken 333 times.
105403 if(whilestatus[numif].iswhile) {
1240
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 105069 times.
105070 if(!is("endwhile")) {
1241 1 warn_endwhile = false;
1242
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 asar_throw_warning(0, warning_id_feature_deprecated, "mismatched terminators", "use endwhile to terminate a while statement");
1243 }
1244 }
1245
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 159 times.
333 else if(whilestatus[numif].is_for) {
1246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
174 if(!is("endfor")) {
1247 warn_endwhile = false;
1248 asar_throw_warning(0, warning_id_feature_deprecated, "mismatched terminators", "use endfor to terminate a for statement");
1249 }
1250 }
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 159 times.
159 else if(!is("endif")) {
1252 warn_endwhile = false;
1253 asar_throw_warning(0, warning_id_feature_deprecated, "mismatched terminators", "use endif to terminate an if statement");
1254 }
1255 }
1256 }
1257
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 114190 times.
114298 else if (is("else"))
1258 {
1259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!moreonlinecond) moreonlinecond = true;
1260
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108 if (numwords != 1) asar_throw_error(1, error_type_block, error_id_unknown_command);
1261
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_else);
1262
2/6
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
108 if (whilestatus[numif - 1].iswhile || whilestatus[numif - 1].is_for) asar_throw_error(1, error_type_block, error_id_else_in_while_loop);
1263
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 54 times.
108 else if (numif==numtrue) numtrue--;
1264
3/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 33 times.
108 else if (numif==numtrue+1 && !elsestatus[numif])
1265 {
1266 21 numtrue++;
1267 21 elsestatus[numif]=true;
1268 }
1269 }
1270
2/2
✓ Branch 0 taken 113788 times.
✓ Branch 1 taken 402 times.
114190 else if (numif!=numtrue) return;
1271
4/4
✓ Branch 0 taken 113787 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4775 times.
✓ Branch 3 taken 109012 times.
113788 else if (asblock_pick(word, numwords))
1272 {
1273
2/2
✓ Branch 0 taken 1591 times.
✓ Branch 1 taken 3184 times.
4775 if (pass == 2)
1274 {
1275 // RPG Hacker: This makes a pretty big assumption to calculate the size of opcodes.
1276 // However, this should currently only really be used for pseudo opcodes, where it should always be good enough.
1277
2/2
✓ Branch 0 taken 1590 times.
✓ Branch 1 taken 1 times.
1591 if (recent_opcode_num > 0)
1278 {
1279 1590 int opcode_size = ((0xFFFFFF & realsnespos) - addrToLinePos) / recent_opcode_num;
1280
2/2
✓ Branch 0 taken 1607 times.
✓ Branch 1 taken 1590 times.
3197 for (int i = 0; i < recent_opcode_num; ++i)
1281 {
1282 extern AddressToLineMapping addressToLineMapping;
1283
1/2
✓ Branch 0 taken 1607 times.
✗ Branch 1 not taken.
1607 addressToLineMapping.includeMapping(thisfilename.data(), thisline + 1, addrToLinePos + (i * opcode_size));
1284 }
1285 }
1286 }
1287 4775 numopcodes += recent_opcode_num;
1288 }
1289
4/4
✓ Branch 0 taken 108470 times.
✓ Branch 1 taken 542 times.
✓ Branch 2 taken 108467 times.
✓ Branch 3 taken 3 times.
109012 else if (is1("undef"))
1290 {
1291 3 string def;
1292 // RPG Hacker: Not sure if we should allow this?
1293 // Currently, the manual states that we should not include the
1294 // exclamation mark, and I believe that this is for the better
1295 // because I can see this leading to ambiguities or causing
1296 // problems. If we add this back in, we should definitely
1297 // also added it to the defined() function for consistency, though.
1298 // Well, actually I just check and we can't support this in
1299 // defined() (the defined is already replaced at that point), so
1300 // I think we should not support it here, either.
1301 /*if (*par == '!') def = S safedequote(par) + 1;
1302
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 else*/ def = STR safedequote(par);
1303
1304
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (defines.exists(def))
1305 {
1306
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 defines.remove(def);
1307 }
1308 else
1309 {
1310 asar_throw_error(0, error_type_block, error_id_define_not_found, def.data());
1311 }
1312 3 }
1313
4/4
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 108753 times.
✓ Branch 2 taken 253 times.
✓ Branch 3 taken 3 times.
109009 else if (is0("error"))
1314 {
1315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 asar_throw_error(0, error_type_block, error_id_error_command, ".");
1316 }
1317
4/4
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 108753 times.
✓ Branch 2 taken 250 times.
✓ Branch 3 taken 3 times.
109006 else if (is0("warn"))
1318 {
1319
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(2, warning_id_warn_command, ".");
1320 }
1321
4/4
✓ Branch 0 taken 108467 times.
✓ Branch 1 taken 536 times.
✓ Branch 2 taken 108461 times.
✓ Branch 3 taken 6 times.
109003 else if (is1("error"))
1322 {
1323
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 string out = handle_print(par);
1324 // RPG Hacker: This used to be on pass 0, which had its merits (you don't want to miss a potentially critical
1325 // user-generated error, just because a bazillion other errors are thrown in passes before it). However, I
1326 // don't see how to support print functions with this without moving it to pass 2. Suggestions are welcome.
1327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
18 asar_throw_error(2, error_type_block, error_id_error_command, (string(": ") + out).data());
1328 6 }
1329
4/4
✓ Branch 0 taken 108461 times.
✓ Branch 1 taken 536 times.
✓ Branch 2 taken 108455 times.
✓ Branch 3 taken 6 times.
108997 else if (is1("warn"))
1330 {
1331
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 string out = handle_print(par);
1332
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 asar_throw_warning(2, warning_id_warn_command, (string(": ") + out).data());
1333 6 }
1334
4/4
✓ Branch 0 taken 108455 times.
✓ Branch 1 taken 536 times.
✓ Branch 2 taken 108437 times.
✓ Branch 3 taken 18 times.
108991 else if (is1("warnings"))
1335 {
1336
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (stricmp(word[1], "push") == 0)
1337 {
1338
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 push_warnings();
1339 }
1340
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 else if (stricmp(word[1], "pull") == 0)
1341 {
1342
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 pull_warnings();
1343 }
1344 }
1345
4/4
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 108717 times.
✓ Branch 2 taken 220 times.
✓ Branch 3 taken 36 times.
108973 else if (is2("warnings"))
1346 {
1347
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 if (stricmp(word[1], "enable") == 0)
1348 {
1349
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1350
1351
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (warnid != warning_id_end)
1352 {
1353
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 set_warning_enabled(warnid, true);
1354 }
1355 else
1356 {
1357 asar_throw_error(0, error_type_null, error_id_invalid_warning_id, "warnings enable", (int)(warning_id_start + 1), (int)(warning_id_end - 1));
1358 }
1359 }
1360
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 else if (stricmp(word[1], "disable") == 0)
1361 {
1362
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1363
1364
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (warnid != warning_id_end)
1365 {
1366
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 set_warning_enabled(warnid, false);
1367 }
1368 else
1369 {
1370 asar_throw_error(0, error_type_null, error_id_invalid_warning_id, "warnings disable", (int)(warning_id_start + 1), (int)(warning_id_end - 1));
1371 }
1372 }
1373 }
1374
4/4
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 108717 times.
✓ Branch 2 taken 186 times.
✓ Branch 3 taken 34 times.
108937 else if (is2("check"))
1375 {
1376
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 31 times.
34 if (stricmp(word[1], "title") == 0)
1377 {
1378 // RPG Hacker: Removed trimming for now - I think requiring an exact match is probably
1379 // better here (not sure, though, it's worth discussing)
1380
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 string expected_title = safedequote(word[2]);
1381 // randomdude999: this also removes leading spaces because itrim gets stuck in an endless
1382 // loop when multi is true and one argument is empty
1383 //expected_title = itrim(expected_title.data(), " ", " ", true); // remove trailing spaces
1384 // in hirom the rom needs to be an entire bank for it to have a title, other modes only need 0x8000 bytes
1385
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 if (romlen < ((mapper == hirom || mapper == exhirom) ? 0x10000 : 0x8000)) // too short
1386 {
1387 if (!ignoretitleerrors) // title errors shouldn't be ignored
1388 asar_throw_error(0, error_type_block, error_id_rom_too_short, expected_title.data());
1389 else // title errors should be ignored, throw a warning anyways
1390 asar_throw_warning(0, warning_id_rom_too_short, expected_title.data());
1391 }
1392 else {
1393 3 string actual_title;
1394 3 string actual_display_title;
1395
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 3 times.
66 for (int i = 0;i < 21;i++)
1396 {
1397 63 unsigned char c = romdata[snestopc(0x00FFC0 + i)];
1398 63 actual_title += (char)c;
1399 // the replacements are from interface-cli.cpp
1400
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 if (c == 7) c = 14;
1401
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 if (c == 8) c = 27;
1402
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 if (c == 9) c = 26;
1403
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 if (c == '\r') c = 17;
1404
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
63 if (c == '\n') c = 25;
1405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
63 if (c == '\0') c = 155;
1406 63 actual_display_title += (char)c;
1407 }
1408 //actual_display_title = itrim(actual_display_title.data(), " ", " ", true); // remove trailing spaces
1409 //actual_title = itrim(actual_title.data(), " ", " ", true); // remove trailing spaces
1410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (strncmp(expected_title, actual_title, 21) != 0)
1411 {
1412 if (!ignoretitleerrors) // title errors shouldn't be ignored
1413 asar_throw_error(0, error_type_block, error_id_rom_title_incorrect, expected_title.data(), actual_display_title.data());
1414 else // title errors should be ignored, throw a warning anyways
1415 asar_throw_warning(0, warning_id_rom_title_incorrect, expected_title.data(), actual_display_title.data());
1416 }
1417 3 }
1418 3 }
1419
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 else if (stricmp(word[1], "bankcross") == 0)
1420 {
1421 if (0);
1422
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 16 times.
31 else if (!stricmp(word[2], "on"))
1423 {
1424
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 asar_throw_warning(0, warning_id_feature_deprecated, "bankcheck on", "bankcheck full or bankcheck half");
1425 }
1426
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
16 else if (!stricmp(word[2], "off"))
1427 {
1428 15 disable_bank_cross_errors = true;
1429 }
1430
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if (!stricmp(word[2], "half"))
1431 {
1432 1 disable_bank_cross_errors = false;
1433 1 check_half_banks_crossed = true;
1434 }
1435 else if (!stricmp(word[2], "full"))
1436 {
1437 disable_bank_cross_errors = false;
1438 check_half_banks_crossed = false;
1439 }
1440 else asar_throw_error(0, error_type_block, error_id_invalid_check);
1441
1442 }
1443 else
1444 {
1445 asar_throw_error(0, error_type_block, error_id_invalid_check);
1446 }
1447 }
1448
7/8
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 108653 times.
✓ Branch 2 taken 250 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 108437 times.
✓ Branch 5 taken 466 times.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 108422 times.
108903 else if (is0("asar") || is1("asar"))
1449 {
1450
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1451
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (!par) return;
1452
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (emulatexkas) asar_throw_error(0, error_type_block, error_id_xkas_asar_conflict);
1453 int dots=0;
1454 int dig=0;
1455
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 15 times.
75 for (int i=0;par[i];i++)
1456 {
1457
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 45 times.
60 if (par[i]=='.')
1458 {
1459
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (!dig) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1460 dig=0;
1461 15 dots++;
1462 }
1463
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 else if (is_digit(par[i])) dig++;
1464 else asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1465 }
1466
2/6
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15 if (!dig || !dots || dots>2) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1467
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 autoptr<char**> vers=split(par, ".");
1468 15 int vermaj=atoi(vers[0]);
1469
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (vermaj > asarver_maj) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (vermaj<asarver_maj) return;
1471
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (dots==1)
1472 {
1473
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (strlen(vers[1])!=2) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1474 //if (asarver_min<10 && asarver_bug<10 && strlen(vers[1])>2) error(0, "This version of Asar is too old for this patch.");
1475 15 int verminbug=atoi(vers[1]);
1476 15 int tmpver=asarver_bug;
1477 15 if (tmpver>9) tmpver=9;
1478
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (asarver_min*10+tmpver<verminbug) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1479
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 12 times.
15 if(vermaj == 1 && verminbug >= 90) { default_math_pri = true; default_math_round_off = true; }
1480 }
1481 else
1482 {
1483 int vermin=atoi(vers[1]);
1484 if (vermin>asarver_min) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1485 int verbug=atoi(vers[2]);
1486 if (vermin==asarver_min && verbug>asarver_bug) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1487 if(vermaj == 1 && vermin >= 9) { default_math_pri = true; default_math_round_off = true; }
1488 }
1489 15 specifiedasarver = true;
1490 15 }
1491
4/4
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 108638 times.
✓ Branch 2 taken 244 times.
✓ Branch 3 taken 6 times.
108888 else if (is0("xkas"))
1492 {
1493
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(0, warning_id_feature_deprecated, "xkas compatibility mode", "UPGRADE YOUR PATCH ITS 2021!!!");
1494
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1495
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
6 if (incsrcdepth != 1 && !emulatexkas) asar_throw_error(0, error_type_block, error_id_command_in_non_root_file);
1496
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (specifiedasarver) asar_throw_error(0, error_type_block, error_id_xkas_asar_conflict);
1497 3 emulatexkas=true;
1498 3 optimizeforbank=0x100;
1499
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(!force_checksum_fix)
1500 3 checksum_fix_enabled = false;
1501 sublabels[0]=":xkasdefault:";
1502 }
1503
6/8
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 108638 times.
✓ Branch 2 taken 244 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 108422 times.
✓ Branch 5 taken 460 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 108422 times.
108882 else if (is0("include") || is1("includefrom"))
1504 {
1505 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1506 if (istoplevel)
1507 {
1508 if (par) asar_throw_error(pass, error_type_fatal, error_id_cant_be_main_file, (string(" The main file is '") + STR par + STR "'.").data());
1509 else asar_throw_error(pass, error_type_fatal, error_id_cant_be_main_file, "");
1510 }
1511 }
1512
4/4
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 108638 times.
✓ Branch 2 taken 229 times.
✓ Branch 3 taken 15 times.
108882 else if (is0("includeonce"))
1513 {
1514
2/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
15 if (!file_included_once(thisfilename))
1515 {
1516 15 includeonce.append(thisfilename);
1517 }
1518 }
1519
16/16
✓ Branch 0 taken 108422 times.
✓ Branch 1 taken 445 times.
✓ Branch 2 taken 1847 times.
✓ Branch 3 taken 106575 times.
✓ Branch 4 taken 1847 times.
✓ Branch 5 taken 445 times.
✓ Branch 6 taken 1831 times.
✓ Branch 7 taken 16 times.
✓ Branch 8 taken 1831 times.
✓ Branch 9 taken 445 times.
✓ Branch 10 taken 1540 times.
✓ Branch 11 taken 291 times.
✓ Branch 12 taken 1540 times.
✓ Branch 13 taken 445 times.
✓ Branch 14 taken 36 times.
✓ Branch 15 taken 1504 times.
108867 else if (is1("db") || is1("dw") || is1("dl") || is1("dd"))
1520 {
1521 int len = 0;
1522
2/6
✓ Branch 0 taken 106918 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 106918 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
106918 if (!confirmqpar(par)) asar_throw_error(0, error_type_block, error_id_mismatched_parentheses);
1523
3/4
✓ Branch 0 taken 106918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343 times.
✓ Branch 3 taken 106575 times.
106918 if (is1("db")) len=1;
1524
3/4
✓ Branch 0 taken 106918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106902 times.
✓ Branch 3 taken 16 times.
106918 if (is1("dw")) len=2;
1525
3/4
✓ Branch 0 taken 106918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106627 times.
✓ Branch 3 taken 291 times.
106918 if (is1("dl")) len=3;
1526
3/4
✓ Branch 0 taken 106918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106882 times.
✓ Branch 3 taken 36 times.
106918 if (is1("dd")) len=4;
1527
1/2
✓ Branch 0 taken 106918 times.
✗ Branch 1 not taken.
106918 autoptr<char**> pars=qpsplit(par, ",");
1528
2/2
✓ Branch 0 taken 107275 times.
✓ Branch 1 taken 106913 times.
214188 for (int i=0;pars[i];i++)
1529 {
1530
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 107191 times.
107275 if (pars[i][0]=='"')
1531 {
1532
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
84 if (!strcmp(pars[i],"\"STAR\"") && !emulatexkas)
1533 asar_throw_warning(0, warning_id_xkas_patch);
1534
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 309 times.
✓ Branch 3 taken 84 times.
393 for (char * str=const_cast<char*>(safedequote(pars[i]));*str;str++)
1535 {
1536
3/4
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 273 times.
✗ Branch 3 not taken.
309 if (len==1) write1(table.table[(size_t)(unsigned char) *str]);
1537
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 297 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
309 if (len==2) write2(table.table[(size_t)(unsigned char) *str]);
1538
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 297 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
309 if (len==3) write3(table.table[(size_t)(unsigned char) *str]);
1539
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 297 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
309 if (len==4) write4(table.table[(size_t)(unsigned char) *str]);
1540 }
1541 }
1542 else
1543 {
1544 const char * math=pars[i];
1545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107191 times.
107191 if (math[0]=='#') math++;
1546
4/4
✓ Branch 0 taken 35730 times.
✓ Branch 1 taken 71461 times.
✓ Branch 2 taken 35725 times.
✓ Branch 3 taken 5 times.
107191 unsigned int num=(pass==2)?getnum(math):0;
1547
2/2
✓ Branch 0 taken 106852 times.
✓ Branch 1 taken 334 times.
107186 if (len == 1) write1(num);
1548
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 107173 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
107186 if (len == 2) write2(num);
1549
3/4
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 106898 times.
✓ Branch 2 taken 288 times.
✗ Branch 3 not taken.
107186 if (len == 3) write3(num);
1550
3/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 107153 times.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
107186 if (len == 4) write4(num);
1551 }
1552 }
1553 106918 }
1554
4/4
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 1763 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 75 times.
1949 else if (numwords==3 && !stricmp(word[1], "="))
1555 {
1556
5/8
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 75 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 75 times.
✗ Branch 7 not taken.
111 if (word[0][0]=='\'' && word[0][1] && word[0][2]=='\'' && word[0][3]=='\0')
1557 {
1558
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 table.table[(unsigned char)word[0][1]]=getnum(word[2]);
1559
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
75 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
1560 75 return;
1561 }
1562 // randomdude999: int cast b/c i'm too lazy to also mess with making setlabel()
1563 // unsigned, besides it wouldn't matter anyways.
1564
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 int num=(int)getnum(word[2]);
1565
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
36 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_cross_assignment);
1566
1567 33 const char* newlabelname = word[0];
1568 bool ismacro = false;
1569
1570
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 30 times.
33 if (newlabelname[0] == '?')
1571 {
1572 ismacro = true;
1573 3 newlabelname++;
1574 }
1575
1576
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ismacro && macrorecursion == 0)
1577 {
1578 asar_throw_error(0, error_type_block, error_id_macro_label_outside_of_macro);
1579 }
1580
1581
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
33 if (!confirmname(newlabelname)) asar_throw_error(0, error_type_block, error_id_invalid_label_name);
1582
1583 33 string completename;
1584
1585
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 30 times.
33 if (ismacro)
1586 {
1587 6 completename += STR":macro_" + dec(calledmacros) + "_";
1588 }
1589
1590 33 completename += newlabelname;
1591
1592
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 setlabel(ns + completename, num, true);
1593 33 }
1594
3/4
✓ Branch 0 taken 1838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1759 times.
✓ Branch 3 taken 79 times.
1838 else if (assemblemapper(word, numwords)) {}
1595
4/4
✓ Branch 0 taken 1495 times.
✓ Branch 1 taken 264 times.
✓ Branch 2 taken 1149 times.
✓ Branch 3 taken 346 times.
1759 else if (is1("org"))
1596 {
1597
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
346 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1598 346 freespaceend();
1599
1/2
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
346 unsigned int num=getnum(par);
1600
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
346 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_org_label_forward);
1601
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 346 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
346 if (num&~0xFFFFFF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex6(num).data());
1602
5/10
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 213 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 130 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 216 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
346 if ((mapper==lorom || mapper==exlorom) && (num&0x408000)==0x400000 && (num&0x700000)!=0x700000) asar_throw_warning(0, warning_id_set_middle_byte);
1603 //if (fastrom) num|=0x800000;
1604 346 snespos=(int)num;
1605 346 realsnespos=(int)num;
1606 346 startpos=(int)num;
1607 346 realstartpos=(int)num;
1608 }
1609 #define ret_error(errid) { asar_throw_error(0, error_type_block, errid); return; }
1610 #define ret_error_params(errid, ...) { asar_throw_error(0, error_type_block, errid, __VA_ARGS__); return; }
1611
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1377 times.
1413 else if (is("struct"))
1612 {
1613 //verifysnespos();
1614
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 (in_struct || in_sub_struct) ret_error(error_id_nested_struct);
1615
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if (numwords < 2) ret_error(error_id_missing_struct_params);
1616
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if (numwords > 4) ret_error(error_id_too_many_struct_params);
1617
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if (!confirmname(word[1])) ret_error(error_id_invalid_struct_name);
1618
1619
3/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
36 if (structs.exists(word[1]) && pass == 0) ret_error_params(error_id_struct_redefined, word[1]);
1620
1621 36 static_struct = false;
1622 36 old_snespos = snespos;
1623 36 old_startpos = startpos;
1624 36 old_optimizeforbank = optimizeforbank;
1625 unsigned int base = 0;
1626
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 if (numwords == 3)
1627 {
1628 12 static_struct = true;
1629
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 base = getnum(word[2]);
1630
1631
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (foundlabel && !foundlabel_static) static_struct = false;
1632 }
1633
1634 36 bool old_in_struct = in_struct;
1635 36 bool old_in_sub_struct = in_sub_struct;
1636 36 in_struct = numwords == 2 || numwords == 3;
1637 36 in_sub_struct = numwords == 4;
1638
1639 #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; }
1640 #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; }
1641
1642
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 if (numwords == 3)
1643 {
1644
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (base&~0xFFFFFF) ret_error_params_cleanup(error_id_snes_address_out_of_bounds, hex6((unsigned int)base).data());
1645 12 snespos = (int)base;
1646 12 startpos = (int)base;
1647 }
1648
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 else if (numwords == 4)
1649 {
1650
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (strcasecmp(word[2], "extends")) ret_error_cleanup(error_id_missing_extends);
1651
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (!confirmname(word[3])) ret_error_cleanup(error_id_struct_invalid_parent_name);
1652 12 string tmp_struct_parent = word[3];
1653
1654
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (!structs.exists(tmp_struct_parent)) ret_error_params_cleanup(error_id_struct_not_found, tmp_struct_parent.data());
1655 12 snes_struct structure = structs.find(tmp_struct_parent);
1656
1657 12 static_struct = structure.is_static;
1658 struct_parent = tmp_struct_parent;
1659 12 snespos = structure.base_end;
1660 12 startpos = structure.base_end;
1661 12 }
1662
1663 36 push_pc();
1664
1665 36 optimizeforbank = -1;
1666
1667 36 struct_name = word[1];
1668 36 struct_base = snespos;
1669 36 realsnespos = 0;
1670 36 realstartpos = 0;
1671 #undef ret_error_cleanup
1672 #undef ret_error_params_cleanup
1673 }
1674
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1341 times.
1377 else if (is("endstruct"))
1675 {
1676
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
36 if (numwords != 1 && numwords != 3) ret_error(error_id_invalid_endstruct_count);
1677
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
36 if (numwords == 3 && strcasecmp(word[1], "align")) ret_error(error_id_expected_align);
1678
3/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
36 if (!in_struct && !in_sub_struct) ret_error(error_id_endstruct_without_struct);
1679
1680
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
36 int alignment = numwords == 3 ? (int)getnum(word[2]) : 1;
1681
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (alignment < 1) ret_error(error_id_alignment_too_small);
1682
1683 snes_struct structure;
1684 36 structure.base_end = snespos;
1685 36 structure.struct_size = alignment * ((snespos - struct_base + alignment - 1) / alignment);
1686 36 structure.object_size = structure.struct_size;
1687 36 structure.is_static = static_struct;
1688
1689
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 if (in_struct)
1690 {
1691
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 structs.create(struct_name) = structure;
1692 }
1693
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 else if (in_sub_struct)
1694 {
1695 snes_struct parent;
1696 12 parent = structs.find(struct_parent);
1697
1698
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (parent.object_size < parent.struct_size + structure.struct_size) {
1699 12 parent.object_size = parent.struct_size + structure.struct_size;
1700 }
1701
1702
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 structs.create(struct_parent + "." + struct_name) = structure;
1703
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 structs.create(struct_parent) = parent;
1704 }
1705
1706 36 pop_pc();
1707 36 in_struct = false;
1708 36 in_sub_struct = false;
1709 36 snespos = old_snespos;
1710 36 startpos = old_startpos;
1711 36 optimizeforbank = old_optimizeforbank;
1712 36 static_struct = false;
1713 }
1714 #undef ret_error
1715
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1338 times.
1341 else if(is("spcblock"))
1716 {
1717 //banned features when active: org, freespace(and variants), arch, mapper,namespace,pushns
1718
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(arch != arch_spc700) asar_throw_error(0, error_type_block, error_id_spcblock_bad_arch);
1719
2/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if(in_struct || in_sub_struct) asar_throw_error(0, error_type_block, error_id_spcblock_inside_struct);
1720
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(numwords < 2) asar_throw_error(0, error_type_block, error_id_spcblock_too_few_args);
1721
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(numwords > 4) asar_throw_error(0, error_type_block, error_id_spcblock_too_many_args);
1722
1723
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 spcblock.destination = getnum(par);
1724 3 spcblock.type = spcblock_nspc;
1725 spcblock.macro_name = "";
1726
1727
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (spcblock.destination&~0xFFFF) asar_throw_error(0, error_type_block, error_id_snes_address_out_of_bounds, hex6(spcblock.destination).data());
1728
1729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(numwords == 3)
1730 {
1731 if(!stricmp(word[2], "nspc")) spcblock.type = spcblock_nspc;
1732 else if(!stricmp(word[2], "custom")) asar_throw_error(0, error_type_block, error_id_custom_spcblock_missing_macro);
1733 else asar_throw_error(0, error_type_block, error_id_unknown_spcblock_type);
1734 }
1735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 else if(numwords == 4)
1736 {
1737 if(!stricmp(word[2], "custom")) spcblock.type = spcblock_custom;
1738 else asar_throw_error(0, error_type_block, error_id_extra_spcblock_arg_for_type);
1739
1740 if(macros.exists(word[3]))
1741 {
1742 macrodata *macro = macros.find(word[3]);
1743 if(!macro->variadic) asar_throw_error(0, error_type_block, error_id_spcblock_macro_must_be_varadic);
1744 if(macro->numargs != 3) asar_throw_error(0, error_type_block, error_id_spcblock_macro_invalid_static_args);
1745 spcblock.macro_name = word[3];
1746 }
1747 else asar_throw_error(0, error_type_block, error_id_spcblock_macro_doesnt_exist);
1748 }
1749
1750
1/3
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
3 switch(spcblock.type)
1751 {
1752 3 case spcblock_nspc:
1753 3 spcblock.size_address=realsnespos;
1754
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 write2(0x0000);
1755
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 write2(spcblock.destination);
1756 3 snespos=(int)spcblock.destination;
1757 3 startpos=(int)spcblock.destination;
1758 3 spcblock.execute_address = -1u;
1759 3 break;
1760 case spcblock_custom:
1761 //this is a todo that probably won't be ready for 1.9
1762 //mostly so we can leverage some cleanups we make in 2.0 for practicality
1763 asar_throw_error(0, error_type_block, error_id_spcblock_custom_types_incomplete);
1764 push_pc();
1765 spcblock.old_mapper = mapper;
1766 mapper = norom;
1767 break;
1768 default:
1769 asar_throw_error(0, error_type_fatal, error_id_internal_error, "invalid spcblock type");
1770 }
1771
1772 ns_backup = ns;
1773 6 ns = STR":SPCBLOCK:_" + ns_backup;
1774 3 in_spcblock = true;
1775 }
1776
4/4
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 1212 times.
✓ Branch 2 taken 123 times.
✓ Branch 3 taken 3 times.
1338 else if(is0("endspcblock"))
1777 {
1778
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(!in_spcblock) asar_throw_error(0, error_type_block, error_id_endspcblock_without_spcblock);
1779
1780
1/3
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
3 switch(spcblock.type)
1781 {
1782 3 case spcblock_nspc:
1783
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (pass==2)
1784 {
1785 1 int pcpos=snestopc(spcblock.size_address&0xFFFFFF);
1786
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (pcpos<0) asar_throw_error(2, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex6((unsigned int)realsnespos).data());
1787 1 int num=snespos-startpos;
1788
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 writeromdata_byte(pcpos, (unsigned char)num);
1789
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 writeromdata_byte(pcpos+1, (unsigned char)(num >> 8));
1790 }
1791
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(spcblock.execute_address != -1u)
1792 {
1793
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 write2(0x0000);
1794
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 write2((unsigned int)spcblock.execute_address);
1795 }
1796 break;
1797 case spcblock_custom:
1798 mapper = spcblock.old_mapper;
1799 pop_pc();
1800 break;
1801 default:
1802 asar_throw_error(0, error_type_fatal, error_id_internal_error, "invalid spcblock type");
1803 }
1804 ns = ns_backup;
1805 3 in_spcblock = false;
1806 }
1807
4/4
✓ Branch 0 taken 1134 times.
✓ Branch 1 taken 201 times.
✓ Branch 2 taken 1131 times.
✓ Branch 3 taken 3 times.
1335 else if (is1("startpos"))
1808 {
1809
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(!in_spcblock) asar_throw_error(0, error_type_block, error_id_startpos_without_spcblock);
1810
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 spcblock.execute_address=getnum64(par);
1811 }
1812
4/4
✓ Branch 0 taken 1131 times.
✓ Branch 1 taken 201 times.
✓ Branch 2 taken 1089 times.
✓ Branch 3 taken 42 times.
1332 else if (is1("base"))
1813 {
1814
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 27 times.
42 if (!stricmp(par, "off"))
1815 {
1816 15 snespos=realsnespos;
1817 15 startpos=realstartpos;
1818 15 return;
1819 }
1820
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 unsigned int num=getnum(par);
1821
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_base_label_invalid);
1822
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if (num&~0xFFFFFF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex6((unsigned int)num).data());
1823 27 snespos=(int)num;
1824 27 startpos=(int)num;
1825 27 optimizeforbank=-1;
1826 }
1827
4/4
✓ Branch 0 taken 1089 times.
✓ Branch 1 taken 201 times.
✓ Branch 2 taken 1083 times.
✓ Branch 3 taken 6 times.
1290 else if (is1("dpbase"))
1828 {
1829
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 unsigned int num=(int)getnum(par);
1830
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_base_label_invalid);
1831
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (num&~0xFF00) asar_throw_error(1, error_type_block, error_id_bad_dp_base, hex6((unsigned int)num).data());
1832 6 dp_base = (int)num;
1833 }
1834
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 1224 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 15 times.
1284 else if (is2("optimize"))
1835 {
1836
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 6 times.
15 if (!stricmp(par, "dp"))
1837 {
1838
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
9 if (!stricmp(word[2], "none"))
1839 {
1840 3 optimize_dp = optimize_dp_flag::NONE;
1841 3 return;
1842 }
1843
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (!stricmp(word[2], "ram"))
1844 {
1845 3 optimize_dp = optimize_dp_flag::RAM;
1846 3 return;
1847 }
1848
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!stricmp(word[2], "always"))
1849 {
1850 3 optimize_dp = optimize_dp_flag::ALWAYS;
1851 3 return;
1852 }
1853 asar_throw_error(1, error_type_block, error_id_bad_dp_optimize, word[2]);
1854 }
1855
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (!stricmp(par, "address"))
1856 {
1857
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!stricmp(word[2], "default"))
1858 {
1859 optimize_address = optimize_address_flag::DEFAULT;
1860 return;
1861 }
1862
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (!stricmp(word[2], "ram"))
1863 {
1864 3 optimize_address = optimize_address_flag::RAM;
1865 3 return;
1866 }
1867
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!stricmp(word[2], "mirrors"))
1868 {
1869 3 optimize_address = optimize_address_flag::MIRRORS;
1870 3 return;
1871 }
1872 asar_throw_error(1, error_type_block, error_id_bad_address_optimize, word[2]);
1873 }
1874 asar_throw_error(1, error_type_block, error_id_bad_optimize, par);
1875 }
1876
3/4
✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 186 times.
✓ Branch 2 taken 1083 times.
✗ Branch 3 not taken.
1269 else if (is1("bank"))
1877 {
1878 if (!stricmp(par, "auto"))
1879 {
1880 optimizeforbank=-1;
1881 return;
1882 }
1883 if (!stricmp(par, "noassume"))
1884 {
1885 optimizeforbank=0x100;
1886 return;
1887 }
1888 unsigned int num=getnum(par);
1889 //if (forwardlabel) error(0, "bank Label is not valid");
1890 //if (foundlabel) num>>=16;
1891 if (num&~0x0000FF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex6((unsigned int)num).data());
1892 optimizeforbank=(int)num;
1893 }
1894
5/6
✓ Branch 0 taken 1269 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 870 times.
✓ Branch 3 taken 399 times.
✓ Branch 4 taken 831 times.
✓ Branch 5 taken 39 times.
1269 else if (is("freespace") || is("freecode") || is("freedata"))
1895 {
1896
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
438 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1897
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
438 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
1898 438 string parstr;
1899
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 390 times.
438 if (numwords==1) parstr="\n";//crappy hack: impossible character to cut out extra commas
1900
1/2
✓ Branch 0 taken 390 times.
✗ Branch 1 not taken.
390 else if (numwords==2) parstr=word[1];
1901 else asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1902
2/2
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 39 times.
837 if (is("freecode")) parstr=STR"ram,"+parstr;
1903
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 399 times.
477 if (is("freedata")) parstr=STR"noram,"+parstr;
1904
1/2
✓ Branch 0 taken 438 times.
✗ Branch 1 not taken.
438 autoptr<char**> pars=split(parstr.temp_raw(), ",");
1905 unsigned char fsbyte = 0x00;
1906 int useram=-1;
1907 bool fixedpos=false;
1908 bool align=false;
1909 bool leakwarn=true;
1910
2/2
✓ Branch 0 taken 876 times.
✓ Branch 1 taken 438 times.
1314 for (int i=0;pars[i];i++)
1911 {
1912
2/2
✓ Branch 0 taken 828 times.
✓ Branch 1 taken 48 times.
876 if (pars[i][0]=='\n') {}
1913
2/2
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 429 times.
828 else if (!stricmp(pars[i], "ram"))
1914 {
1915
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 399 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
399 if (useram!=-1) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1916 useram=1;
1917 }
1918
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 390 times.
429 else if (!stricmp(pars[i], "noram"))
1919 {
1920
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 if (useram!=-1) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1921 useram=0;
1922 }
1923
2/4
✓ Branch 0 taken 390 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 390 times.
✗ Branch 3 not taken.
390 else if (!stricmp(pars[i], "static") || !stricmp(pars[i], "fixed"))
1924 {
1925 if (!stricmp(pars[i], "fixed")) asar_throw_warning(0, warning_id_feature_deprecated, "freespace/code/data fixed", "freespace/code/data static");
1926 if (fixedpos) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1927 fixedpos=true;
1928 }
1929
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 387 times.
390 else if (!stricmp(pars[i], "align"))
1930 {
1931
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (align) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1932 align=true;
1933 }
1934
1/2
✓ Branch 0 taken 387 times.
✗ Branch 1 not taken.
387 else if (!stricmp(pars[i], "cleaned"))
1935 {
1936
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 387 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
387 if (!leakwarn) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1937 leakwarn=false;
1938 }
1939 else
1940 {
1941 fsbyte = (unsigned char)getnum(pars[i]);
1942 }
1943 }
1944
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
438 if (useram==-1) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1945
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
438 if (mapper == norom) asar_throw_error(0, error_type_block, error_id_no_freespace_norom);
1946 438 freespaceend();
1947
1/2
✓ Branch 0 taken 438 times.
✗ Branch 1 not taken.
438 freespaceid=getfreespaceid();
1948 438 freespacebyte[freespaceid] = fsbyte;
1949
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 292 times.
438 if (pass==0) snespos=(freespaceid<<24)|0x8000;
1950
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 292 times.
438 if (pass==1)
1951 {
1952
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
146 if (fixedpos && freespaceorgpos[freespaceid]<0)
1953 {
1954 freespacepos[freespaceid]=0x008000;
1955 freespaceleak[freespaceid]=false;//mute some other errors
1956 asar_throw_error(1, error_type_block, error_id_static_freespace_autoclean);
1957 }
1958 if (fixedpos && freespaceorgpos[freespaceid]) freespacepos[freespaceid]=snespos=(freespaceid<<24)|freespaceorgpos[freespaceid];
1959
1/2
✓ Branch 0 taken 146 times.
✗ Branch 1 not taken.
146 else freespacepos[freespaceid]=snespos=(freespaceid<<24)|getsnesfreespace(freespacelen[freespaceid], (useram != 0), true, true, align, freespacebyte[freespaceid]);
1960 }
1961
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 292 times.
438 if (pass==2)
1962 {
1963
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
146 if (fixedpos && freespaceorgpos[freespaceid]==-1) return;//to kill some errors
1964 146 snespos=(freespaceid<<24)|freespacepos[freespaceid];
1965
1/2
✓ Branch 0 taken 146 times.
✗ Branch 1 not taken.
146 resizerats(snespos&0xFFFFFF, freespacelen[freespaceid]);
1966
3/6
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 127 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
146 if (freespaceleak[freespaceid] && leakwarn) asar_throw_warning(2, warning_id_freespace_leaked);
1967
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
146 if (fixedpos && freespaceorgpos[freespaceid]>0 && freespacelen[freespaceid]>freespaceorglen[freespaceid])
1968 asar_throw_error(2, error_type_block, error_id_static_freespace_growing);
1969 146 freespaceuse+=8+freespacelen[freespaceid];
1970 }
1971 438 freespacestatic[freespaceid]=fixedpos;
1972
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
438 if (snespos < 0 && mapper == sa1rom) asar_throw_error(pass, error_type_fatal, error_id_no_freespace_in_mapped_banks, dec(freespacelen[freespaceid]).data());
1973
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 438 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
438 if (snespos < 0) asar_throw_error(pass, error_type_fatal, error_id_no_freespace, dec(freespacelen[freespaceid]).data());
1974 438 bytes+=8;
1975 438 freespacestart=snespos;
1976 438 startpos=snespos;
1977 438 realstartpos=snespos;
1978 438 realsnespos=snespos;
1979 438 optimizeforbank=-1;
1980 438 ratsmetastate=ratsmeta_allow;
1981 438 }
1982
4/4
✓ Branch 0 taken 693 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 666 times.
✓ Branch 3 taken 27 times.
831 else if (is1("prot"))
1983 {
1984
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1985
2/6
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
27 if (!confirmqpar(par)) asar_throw_error(0, error_type_block, error_id_mismatched_parentheses);
1986
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if (!ratsmetastate) asar_throw_error(2, error_type_block, error_id_prot_not_at_freespace_start);
1987
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 21 times.
27 if (ratsmetastate==ratsmeta_used) step(-5);
1988 int num;
1989
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 autoptr<char**> pars=qpsplit(par, ",", &num);
1990 write1('P');
1991 write1('R');
1992 write1('O');
1993 write1('T');
1994
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if (num * 3 > 255) asar_throw_error(0, error_type_block, error_id_prot_too_many_entries);
1995
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 write1((unsigned int)(num*3));
1996
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 27 times.
60 for (int i=0;i<num;i++)
1997 {
1998 //int num=getnum(pars[i]);
1999 33 const char * labeltest=pars[i];
2000 33 string testlabel = labeltest;
2001
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 int labelnum=(int)labelval(&labeltest).pos;
2002
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
33 if (*labeltest) asar_throw_error(0, error_type_block, error_id_label_not_found, testlabel.data());
2003
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 write3((unsigned int)labelnum);
2004
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 22 times.
33 if (pass==1) freespaceleak[labelnum >>24]=false;
2005 33 }
2006 write1('S');
2007 write1('T');
2008 write1('O');
2009 write1('P');
2010 write1(0);
2011 27 ratsmetastate=ratsmeta_used;
2012 27 }
2013
13/16
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 666 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 45 times.
✓ Branch 5 taken 759 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 27 times.
✓ Branch 8 taken 666 times.
✓ Branch 9 taken 111 times.
✓ Branch 10 taken 666 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 18 times.
✓ Branch 13 taken 759 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 18 times.
804 else if (is1("autoclean") || is2("autoclean") || is1("autoclear") || is2("autoclear"))
2014 {
2015
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2016
3/10
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
27 if (is1("autoclear") || is2("autoclear")) asar_throw_warning(0, warning_id_autoclear_deprecated);
2017
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 if (numwords==3)
2018 {
2019
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if ((unsigned int)snespos & 0xFF000000) asar_throw_error(0, error_type_block, error_id_autoclean_in_freespace);
2020 27 const char * labeltest = word[2];
2021 27 string testlabel = labeltest;
2022
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 int num=(int)labelval(&labeltest).pos;
2023
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if (*labeltest) asar_throw_error(0, error_type_block, error_id_label_not_found, testlabel.data());
2024 unsigned char targetid=(unsigned char)(num>>24);
2025
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 18 times.
27 if (pass==1) freespaceleak[targetid]=false;
2026 27 num&=0xFFFFFF;
2027
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
27 if (strlen(par)>3 && !stricmp(par+3, ".l")) par[3]=0;
2028
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
27 if (!stricmp(par, "JSL") || !stricmp(par, "JML"))
2029 {
2030 27 int orgpos=read3(snespos+1);
2031 27 int ratsloc=freespaceorgpos[targetid];
2032
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 15 times.
27 int firstbyte = ((!stricmp(par, "JSL")) ? 0x22 : 0x5C);
2033 int pcpos=snestopc(snespos);
2034
4/6
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 18 times.
27 if (/*pass==1 && */pcpos>=0 && pcpos<romlen_r && romdata_r[pcpos]==firstbyte)
2035 {
2036
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 ratsloc=ratsstart(orgpos)+8;
2037 9 freespaceorglen[targetid]=read2(ratsloc-4)+1;
2038
4/6
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 if (!freespacestatic[targetid] && pass==1) removerats(orgpos, freespacebyte[targetid]);
2039 }
2040 18 else if (ratsloc<0) ratsloc=0;
2041
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 write1((unsigned int)firstbyte);
2042
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 write3((unsigned int)num);
2043
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 18 times.
27 if (pass==2)
2044 {
2045
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 int start=ratsstart(num);
2046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (start>=num || start<0)
2047 {
2048 asar_throw_error(2, error_type_block, error_id_autoclean_label_at_freespace_end);
2049 }
2050
2051 extern AddressToLineMapping addressToLineMapping;
2052
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 addressToLineMapping.includeMapping(thisfilename.data(), thisline + 1, addrToLinePos);
2053 }
2054 //freespaceorglen[targetid]=read2(ratsloc-4)+1;
2055 27 freespaceorgpos[targetid]=ratsloc;
2056 27 }
2057 else if (!stricmp(par, "dl"))
2058 {
2059 int orgpos=read3(snespos);
2060 int ratsloc=freespaceorgpos[targetid];
2061 int start=ratsstart(num);
2062 if (pass==1 && num>=0)
2063 {
2064 ratsloc=ratsstart(orgpos)+8;
2065 if (!freespacestatic[targetid]) removerats(orgpos, freespacebyte[targetid]);
2066 }
2067 else if (!ratsloc) ratsloc=0;
2068 if ((start==num || start<0) && pass==2)
2069 asar_throw_error(2, error_type_block, error_id_autoclean_label_at_freespace_end);
2070 write3((unsigned int)num);
2071 freespaceorgpos[targetid]=ratsloc;
2072 freespaceorglen[targetid]=read2(ratsloc-4)+1;
2073 }
2074 else asar_throw_error(0, error_type_block, error_id_broken_autoclean);
2075 27 }
2076 else if (pass==0) removerats((int)getnum(word[1]), 0x00);
2077 }
2078
4/4
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 702 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 3 times.
777 else if (is0("pushpc"))
2079 {
2080
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
2081 3 pushpc[pushpcnum].arch=arch;
2082 3 pushpc[pushpcnum].snespos=snespos;
2083 3 pushpc[pushpcnum].snesstart=startpos;
2084 3 pushpc[pushpcnum].snesposreal=realsnespos;
2085 3 pushpc[pushpcnum].snesstartreal=realstartpos;
2086 3 pushpc[pushpcnum].freeid=freespaceid;
2087 3 pushpc[pushpcnum].freeex=freespaceextra;
2088 3 pushpc[pushpcnum].freest=freespacestart;
2089 3 pushpcnum++;
2090 3 snespos=(int)0xFFFFFFFF;
2091 3 startpos= (int)0xFFFFFFFF;
2092 3 realsnespos= (int)0xFFFFFFFF;
2093 3 realstartpos= (int)0xFFFFFFFF;
2094 }
2095
4/4
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 702 times.
✓ Branch 2 taken 69 times.
✓ Branch 3 taken 3 times.
774 else if (is0("pullpc"))
2096 {
2097
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (!pushpcnum) asar_throw_error(0, error_type_block, error_id_pullpc_without_pushpc);
2098 3 pushpcnum--;
2099 3 freespaceend();
2100
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (arch != pushpc[pushpcnum].arch) asar_throw_error(0, error_type_block, error_id_pullpc_different_arch);
2101 3 snespos=pushpc[pushpcnum].snespos;
2102 3 startpos=pushpc[pushpcnum].snesstart;
2103 3 realsnespos=pushpc[pushpcnum].snesposreal;
2104 3 realstartpos=pushpc[pushpcnum].snesstartreal;
2105 3 freespaceid=pushpc[pushpcnum].freeid;
2106 3 freespaceextra=pushpc[pushpcnum].freeex;
2107 3 freespacestart=pushpc[pushpcnum].freest;
2108 }
2109
4/4
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 702 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 3 times.
771 else if (is0("pushbase"))
2110 {
2111
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
2112 3 basestack[basestacknum] = snespos;
2113 3 basestacknum++;
2114 }
2115
4/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 702 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 3 times.
768 else if (is0("pullbase"))
2116 {
2117
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (!basestacknum) asar_throw_error(0, error_type_block, error_id_pullbase_without_pushbase);
2118 3 basestacknum--;
2119 3 snespos = basestack[basestacknum];
2120 3 startpos = basestack[basestacknum];
2121
2122
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (snespos != realstartpos)
2123 {
2124 3 optimizeforbank = -1;
2125 }
2126 }
2127
4/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 702 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 6 times.
765 else if (is0("pushns"))
2128 {
2129
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_feature_unavaliable_in_spcblock);
2130 6 pushns[pushnsnum].ns = ns;
2131
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for(int i = 0; i < namespace_list.count; i++)
2132 {
2133 6 pushns[pushnsnum].namespace_list.append(namespace_list[i]);
2134 }
2135 6 pushns[pushnsnum].nested_namespaces = nested_namespaces;
2136 6 pushnsnum++;
2137
2138 6 namespace_list.reset();
2139 ns = "";
2140 6 nested_namespaces = false;
2141 }
2142
4/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 702 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 6 times.
759 else if (is0("pullns"))
2143 {
2144
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_feature_unavaliable_in_spcblock);
2145
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (!pushnsnum) asar_throw_error(0, error_type_block, error_id_pullns_without_pushns);
2146 6 pushnsnum--;
2147 6 ns = pushns[pushnsnum].ns;
2148 6 nested_namespaces = pushns[pushnsnum].nested_namespaces;
2149 6 namespace_list.reset();
2150
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for(int i = 0; i < pushns[pushnsnum].namespace_list.count; i++)
2151 {
2152 12 namespace_list.append(pushns[pushnsnum].namespace_list[i]);
2153 }
2154 }
2155
7/8
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 603 times.
✓ Branch 3 taken 63 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 672 times.
✓ Branch 6 taken 18 times.
✗ Branch 7 not taken.
753 else if (is1("namespace") || is2("namespace"))
2156 {
2157
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
81 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2158 bool leave = false;
2159
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 if (par)
2160 {
2161
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 57 times.
81 if (!stricmp(par, "off"))
2162 {
2163
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2164 leave = true;
2165 }
2166
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 39 times.
57 else if (!stricmp(par, "nested"))
2167 {
2168
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_namespace_use);
2169
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 else if (!stricmp(word[2], "on")) nested_namespaces = true;
2170
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 else if (!stricmp(word[2], "off")) nested_namespaces = false;
2171 }
2172 else
2173 {
2174
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2175
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 const char * tmpstr= safedequote(par);
2176
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 if (!confirmname(tmpstr)) asar_throw_error(0, error_type_block, error_id_invalid_namespace_name);
2177
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 24 times.
39 if (!nested_namespaces)
2178 {
2179 15 namespace_list.reset();
2180 }
2181 39 namespace_list.append(STR tmpstr);
2182 }
2183 }
2184 else
2185 {
2186 leave = true;
2187 }
2188
2189 if (leave)
2190 {
2191
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 if (nested_namespaces)
2192 {
2193 18 namespace_list.remove(namespace_list.count - 1);
2194 }
2195 else
2196 {
2197 6 namespace_list.reset();
2198 }
2199 }
2200
2201 // recompute ns
2202 ns = "";
2203
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 81 times.
177 for (int i = 0; i < namespace_list.count; i++)
2204 {
2205 96 ns += namespace_list[i];
2206 96 ns += STR"_";
2207 }
2208 }
2209
4/4
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 600 times.
✓ Branch 3 taken 3 times.
672 else if (is1("warnpc"))
2210 {
2211
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 unsigned int maxpos=getnum(par);
2212
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ((unsigned int)snespos & 0xFF000000) asar_throw_error(0, error_type_block, error_id_warnpc_in_freespace);
2213
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ((unsigned int)maxpos & 0xFF000000) asar_throw_error(0, error_type_block, error_id_warnpc_broken_param);
2214
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ((unsigned int)snespos > maxpos) asar_throw_error(0, error_type_block, error_id_warnpc_failed, hex6((unsigned int)snespos).data(), hex6((unsigned int)maxpos).data());
2215
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if (warnxkas && (unsigned int)snespos == maxpos) asar_throw_warning(0, warning_id_xkas_warnpc_relaxed);
2216
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if (emulatexkas && (unsigned int)snespos==maxpos) asar_throw_error(0, error_type_block, error_id_warnpc_failed_equal, hex6((unsigned int)snespos).data(), hex6((unsigned int)maxpos).data());
2217 }
2218
4/4
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 585 times.
✓ Branch 3 taken 15 times.
669 else if (is1("rep"))
2219 {
2220
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
15 int rep = (int)getnum64(par);
2221
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (foundlabel) asar_throw_error(0, error_type_block, error_id_rep_label);
2222
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (rep<=1)
2223 {
2224
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
9 if(rep < 0){
2225
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(0, warning_id_feature_deprecated, "rep condition < 0", "You probably want conditionals");
2226 }
2227
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (emulatexkas)
2228 {
2229
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 asar_throw_warning(0, warning_id_feature_deprecated, "rep <= 1 xkas behaviour", "You probably want conditionals");
2230
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (rep==0) rep=1;
2231
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rep<0) rep=0;
2232 9 repeatnext=rep;
2233 9 return;
2234 }
2235 }
2236
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(0, warning_id_feature_deprecated, "rep X : {command}", "Use while loops, unrolled loops, pseudo opcodes or for loops");
2237 3 repeatnext=rep;
2238 }
2239 #ifdef SANDBOX
2240 else if (is("incsrc") || is("incbin") || is("table"))
2241 {
2242 asar_throw_error(0, error_type_block, error_id_command_disabled);
2243 }
2244 #endif
2245
4/4
✓ Branch 0 taken 585 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 276 times.
✓ Branch 3 taken 309 times.
654 else if (is1("incsrc"))
2246 {
2247 309 string name;
2248
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 309 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
309 if (warnxkas && (strchr(thisfilename, '/') || strchr(thisfilename, '\\')))
2249 asar_throw_warning(0, warning_id_xkas_incsrc_relative);
2250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 309 times.
309 if (strchr(par, '\\'))
2251 {
2252 if (emulatexkas)
2253 {
2254 asar_throw_warning(0, warning_id_feature_deprecated, "xkas style paths", "convert paths to crossplatform style");
2255 for (int i=0;par[i];i++)
2256 {
2257 if (par[i]=='\\') par[i]='/';//let's just hope nobody finds I could just enable this for everything.
2258 }
2259 }
2260 #ifdef _WIN32
2261 else asar_throw_warning(0, warning_id_feature_deprecated, "windows specific paths", "convert paths to crossplatform style");
2262 #endif
2263 }
2264
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 309 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
309 if (emulatexkas) name= safedequote(par);
2265
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 else name=STR safedequote(par);
2266
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 249 times.
309 assemblefile(name, false);
2267 309 }
2268
8/8
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 243 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 294 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 15 times.
345 else if (is1("incbin") || is3("incbin"))
2269 {
2270
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
36 if (numwords == 4 && strcmp(word[2], "->")) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2271 int len;
2272 int start=0;
2273 int end=0;
2274
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 15 times.
36 if (strqchr(par, ':'))
2275 {
2276 21 char * lengths=strqchr(par, ':');
2277 21 *lengths=0;
2278 21 lengths++;
2279
3/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 3 times.
21 if(strqpstr(lengths, ".."))
2280 {
2281 // new style ranges
2282
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 char* split = strqpstr(lengths, "..");
2283 18 string start_str(lengths, split-lengths);
2284
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 start = getnum(start_str);
2285
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
18 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2286 15 string end_str(split+2);
2287
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 end = getnum(end_str);
2288
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
15 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2289 21 }
2290 else
2291 {
2292
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(0, warning_id_feature_deprecated, "old style incbin ranges", "use the :start..end syntax instead");
2293
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (strchr(lengths, '"')) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2294
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(*lengths=='(') {
2295
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 char* tmp = strqpchr(lengths, '-');
2296
2/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if(!tmp || (*(tmp-1)!=')')) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 start = (int)getnum64(string(lengths+1, tmp-1-lengths-1));
2298 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2299 lengths = tmp;
2300 } else {
2301 start=(int)strtoul(lengths, &lengths, 16);
2302 }
2303 if (*lengths!='-') asar_throw_error(0, error_type_block, error_id_broken_incbin);
2304 lengths++;
2305 if(*lengths=='(') {
2306 char* tmp = strchr(lengths, '\0');
2307 if(*(tmp-1)!=')') asar_throw_error(0, error_type_block, error_id_broken_incbin);
2308 end = (int)getnum64(string(lengths+1, tmp-1-lengths-1));
2309 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2310 // no need to check end-of-string here
2311 } else {
2312 end=(int)strtoul(lengths, &lengths, 16);
2313 if (*lengths) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2314 }
2315 }
2316 }
2317 27 string name;
2318
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
27 if (warnxkas && (strchr(thisfilename, '/') || strchr(thisfilename, '\\')))
2319 asar_throw_warning(0, warning_id_xkas_incsrc_relative);
2320
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 24 times.
27 if (strchr(par, '\\'))
2321 {
2322
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (emulatexkas)
2323 {
2324
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(0, warning_id_feature_deprecated, "xkas style paths", "convert paths to crossplatform style");
2325
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 3 times.
60 for (int i=0;par[i];i++)
2326 {
2327
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 51 times.
57 if (par[i]=='\\') par[i]='/';//let's just hope nobody finds I could just enable this for everything.
2328 }
2329 }
2330 #ifdef _WIN32
2331 else asar_throw_warning(0, warning_id_feature_deprecated, "windows specific paths", "convert paths to crossplatform style");
2332 #endif
2333 }
2334
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
27 if (emulatexkas) name= safedequote(par);
2335
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 else name=STR safedequote(par);
2336 char * data;//I couldn't find a way to get this into an autoptr
2337
6/10
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
27 if (!readfile(name, thisfilename, &data, &len)) asar_throw_error(0, error_type_block, vfile_error_to_error_id(asar_get_last_io_error()), name.data());
2338
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 autoptr<char*> datacopy=data;
2339
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (!end) end=len;
2340
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if(start < 0) asar_throw_error(0, error_type_block, error_id_file_offset_out_of_bounds, dec(start).data(), name.data());
2341
3/8
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 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());
2342
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 21 times.
24 if (numwords==4)
2343 {
2344
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(0, warning_id_feature_deprecated, "incbin with target location", "put an org before the incbin");
2345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!confirmname(word[3]))
2346 {
2347 int pos=(int)getnum(word[3]);
2348 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2349 int offset=snestopc(pos);
2350 if (offset + end - start > 0xFFFFFF) asar_throw_error(0, error_type_block, error_id_16mb_rom_limit);
2351 if (offset+end-start>romlen) romlen=offset+end-start;
2352 if (pass==2) writeromdata(offset, data+start, end-start);
2353 }
2354 else
2355 {
2356 int pos;
2357
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (pass==0)
2358 {
2359
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (end - start > 65536) asar_throw_error(0, error_type_block, error_id_incbin_64kb_limit);
2360
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 pos=getpcfreespace(end-start, false, true, false);
2361
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (pos < 0) asar_throw_error(0, error_type_block, error_id_no_freespace, dec(end - start).data());
2362
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 int foundfreespaceid=getfreespaceid();
2363 1 freespacepos[foundfreespaceid]=pctosnes(pos)|(/*fastrom?0x800000:*/0x000000)|(foundfreespaceid <<24);
2364
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 setlabel(word[3], freespacepos[foundfreespaceid]);
2365
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 writeromdata_bytes(pos, 0xFF, end-start);
2366 }
2367
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (pass==1)
2368 {
2369
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 getfreespaceid();//nothing to do here, but we want to tick the counter
2370 }
2371
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (pass==2)
2372 {
2373
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 int foundfreespaceid =getfreespaceid();
2374
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (freespaceleak[foundfreespaceid]) asar_throw_warning(2, warning_id_freespace_leaked);
2375
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 writeromdata(snestopc(freespacepos[foundfreespaceid]&0xFFFFFF), data+start, end-start);
2376 1 freespaceuse+=8+end-start;
2377 }
2378 }
2379 }
2380 else
2381 {
2382
3/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 21 times.
54 for (int i=start;i<end;i++) write1((unsigned int)data[i]);
2383 }
2384 27 }
2385
4/4
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 201 times.
✓ Branch 3 taken 18 times.
309 else if (is("skip") || is("fill"))
2386 {
2387
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
108 if(numwords != 2 && numwords != 3 && numwords != 5) asar_throw_error(0, error_type_block, error_id_unknown_command);
2388
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
108 if(numwords > 2 && stricmp(word[1], "align")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2389
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
108 if(numwords == 5 && stricmp(word[3], "offset")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2390 int amount;
2391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(numwords > 2)
2392 {
2393 int alignment = getnum64(word[2]);
2394 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2395 int offset = 0;
2396 if(numwords==5)
2397 {
2398 offset = getnum64(word[4]);
2399 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2400 }
2401 if(alignment > 0x800000) asar_throw_error(0, error_type_block, error_id_alignment_too_big);
2402 if(alignment < 1) asar_throw_error(0, error_type_block, error_id_alignment_too_small);
2403 if(alignment & (alignment-1)) asar_throw_error(0, error_type_block, error_id_invalid_alignment);
2404 // i just guessed this formula but it seems to work
2405 amount = (alignment - ((snespos - offset) & (alignment-1))) & (alignment-1);
2406 }
2407 else
2408 {
2409
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 amount = (int)getnum64(par);
2410
5/6
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
108 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2411 }
2412
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 15 times.
105 if(is("skip")) step(amount);
2413
3/4
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 129 times.
✓ Branch 3 taken 15 times.
144 else for(int i=0; i < amount; i++) write1(fillbyte[i%12]);
2414
2415 }
2416
3/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
201 else if (is0("cleartable"))
2417 {
2418 cleartable();
2419 }
2420
4/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 3 times.
201 else if (is0("pushtable"))
2421 {
2422 3 tablestack.append(table);
2423 }
2424
4/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 3 times.
198 else if (is0("pulltable"))
2425 {
2426
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if (tablestack.count <= 0) asar_throw_error(0, error_type_block, error_id_pulltable_without_table);
2427 3 table=tablestack[tablestack.count-1];
2428 3 tablestack.remove(tablestack.count-1);
2429 }
2430
3/4
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 135 times.
✗ Branch 3 not taken.
195 else if (is1("table"))
2431 {
2432 asar_throw_warning(0, warning_id_feature_deprecated, "table command", "Use direct character assignments. For example: 'a' = $61");
2433 bool fliporder=false;
2434 if(0);
2435 else if (striend(par, ",ltr")) { itrim(par, "", ",ltr"); }
2436 else if (striend(par, ",rtl")) { itrim(par, "", ",rtl"); fliporder=true; }
2437 string name=STR safedequote(par);
2438 autoptr<char*> tablecontents=readfile(name, thisfilename);
2439 if (!tablecontents) asar_throw_error(0, error_type_block, vfile_error_to_error_id(asar_get_last_io_error()), name.data());
2440 autoptr<char**> tablelines=split(tablecontents, "\n");
2441 for (int i=0;i<256;i++) table.table[i]=(unsigned int)(((numopcodes+read2(0x00FFDE)+i)*0x26594131)|0x40028020);
2442 //garbage value so people will notice they're doing it wrong (for bonus points: figure out what 0x26594131 is)
2443 for (int i=0;tablelines[i];i++)
2444 {
2445 string tableline=tablelines[i];
2446 if (!*tableline) continue;
2447 if (strlen(tableline) < 4 || strlen(tableline) & 1 || strlen(tableline) > 10) asar_throw_error(0, error_type_block, error_id_invalid_table_file, i+1);
2448 if (!fliporder)
2449 {
2450 if (tableline[3]=='x' || tableline[3]=='X') asar_throw_error(0, error_type_block, error_id_invalid_table_file, i+1);
2451 char * end;
2452 table.table[(unsigned char)tableline[0]]=(unsigned int)strtol(tableline.data()+2, &end, 16);
2453 if (*end) asar_throw_error(0, error_type_block, error_id_invalid_table_file, i+1);
2454 }
2455 else
2456 {
2457 if (tableline[1]=='x' || tableline[1]=='X') asar_throw_error(0, error_type_block, error_id_invalid_table_file, i+1);
2458 char * eq;
2459 unsigned int val=(unsigned int)strtol(tableline, &eq, 16);
2460 if (eq[0]!='=' || eq[2]) asar_throw_error(0, error_type_block, error_id_invalid_table_file, i+1);
2461 table.table[(unsigned char)eq[1]]=val;
2462 }
2463 }
2464 }
2465
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 180 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
195 else if (is3("function"))
2466 {
2467 //if (!pass)
2468 //{
2469
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (stricmp(word[2], "=")) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2470
2/6
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15 if (!confirmqpar(word[1])) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2471 15 string line=word[1];
2472
4/8
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
15 clean(line);
2473 15 char * startpar=strqchr(line.data(), '(');
2474
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2475 15 *startpar=0;
2476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 startpar++;
2477
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_invalid_function_name);
2478 15 char * endpar=strqchr(startpar, ')');
2479 //confirmqpar requires that all parentheses are matched, and a starting one exists, therefore it is harmless to not check for nulls
2480
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 if (endpar[1]) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2481 15 *endpar=0;
2482
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 createuserfunc(line, startpar, word[3]);
2483 //}
2484 15 }
2485
4/4
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 87 times.
✓ Branch 3 taken 48 times.
180 else if (is1("print"))
2486 {
2487
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 string out = handle_print(par);
2488
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 if (pass!=2) return;
2489
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 print(out);
2490 48 }
2491
3/4
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 87 times.
✗ Branch 3 not taken.
132 else if (is1("reset"))
2492 {
2493 if(0);
2494 else if (!stricmp(par, "bytes")) bytes=0;
2495 else if (!stricmp(par, "freespaceuse")) freespaceuse=0;
2496 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
2497 }
2498
13/16
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 78 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 78 times.
✓ Branch 9 taken 45 times.
✓ Branch 10 taken 78 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 78 times.
✓ Branch 13 taken 45 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 78 times.
132 else if (is1("padbyte") || is1("padword") || is1("padlong") || is1("paddword"))
2499 {
2500 int len = 0;
2501
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (is("padbyte")) len=1;
2502
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (is("padword")) len=2;
2503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (is("padlong")) len=3;
2504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (is("paddword")) len=4;
2505
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 unsigned int val=getnum(par);
2506
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 if(foundlabel && !foundlabel_static) asar_throw_warning(1, warning_id_feature_deprecated, "labels in padbyte", "just... don't.");
2507
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 9 times.
117 for (int i=0;i<12;i+=len)
2508 {
2509 unsigned int tmpval=val;
2510
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 108 times.
216 for (int j=0;j<len;j++)
2511 {
2512 108 padbyte[i+j]=(unsigned char)tmpval;
2513 108 tmpval>>=8;
2514 }
2515 }
2516 }
2517
4/4
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 69 times.
✓ Branch 3 taken 9 times.
123 else if (is1("pad"))
2518 {
2519
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9 if ((unsigned int)realsnespos & 0xFF000000) asar_throw_error(0, error_type_block, error_id_pad_in_freespace);
2520
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 int num=(int)getnum(par);
2521
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9 if ((unsigned int)num & 0xFF000000) asar_throw_error(0, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex6((unsigned int)num).data());
2522
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 if (num>realsnespos)
2523 {
2524 int end=snestopc(num);
2525 int start=snestopc(realsnespos);
2526 6 int len=end-start;
2527
3/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 6 times.
36 for (int i=0;i<len;i++) write1(padbyte[i%12]);
2528 }
2529 }
2530
16/16
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 57 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 57 times.
✓ Branch 9 taken 45 times.
✓ Branch 10 taken 54 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 54 times.
✓ Branch 13 taken 45 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 51 times.
114 else if (is1("fillbyte") || is1("fillword") || is1("filllong") || is1("filldword"))
2531 {
2532 int len = 0;
2533
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (is("fillbyte")) len=1;
2534
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
18 if (is("fillword")) len=2;
2535
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
18 if (is("filllong")) len=3;
2536
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
18 if (is("filldword")) len=4;
2537
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 unsigned int val= getnum(par);
2538
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
18 if(foundlabel && !foundlabel_static) asar_throw_warning(1, warning_id_feature_deprecated, "labels in fillbyte", "just... don't");
2539
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 18 times.
165 for (int i=0;i<12;i+=len)
2540 {
2541 unsigned int tmpval=val;
2542
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 147 times.
363 for (int j=0;j<len;j++)
2543 {
2544 216 fillbyte[i+j]=(unsigned char)tmpval;
2545 216 tmpval>>=8;
2546 }
2547 }
2548 }
2549
3/4
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51 times.
96 else if (is1("arch"))
2550 {
2551
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
51 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2552
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
51 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
2553
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 39 times.
51 if (!stricmp(par, "65816")) { arch=arch_65816; return; }
2554
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 21 times.
39 if (!stricmp(par, "spc700")) { arch=arch_spc700; return; }
2555
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
21 if (!stricmp(par, "spc700-inline")) { asar_throw_warning(1, warning_id_feature_deprecated, "spc700-inline", " Use spcblock and endspcblock"); arch=arch_spc700_inline; return; }
2556
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
18 if (!stricmp(par, "spc700-raw")) {
2557
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(1, warning_id_feature_deprecated, "spc700-raw", " Use arch spc700 with norom");
2558 6 arch=arch_spc700;
2559 6 mapper=norom;
2560 6 mapper_set = false;
2561
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(!force_checksum_fix)
2562 6 checksum_fix_enabled = false;
2563 6 return;
2564 }
2565
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (!stricmp(par, "superfx")) { arch=arch_superfx; return; }
2566 }
2567
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 else if (is2("math"))
2568 {
2569 bool val = false;
2570 if(0);
2571 else if (!stricmp(word[2], "on")) val=true;
2572 else if (!stricmp(word[2], "off")) val=false;
2573 else asar_throw_error(0, error_type_block, error_id_invalid_math);
2574 if(0);
2575 else if (!stricmp(word[1], "pri")){ math_pri=val; asar_throw_warning(2, warning_id_feature_deprecated, "math pri", "Rewrite your math statements using parentheses where needed and put \"asar 1.9\" in your patch to enable the future behavior of always enforcing math prioritization rules"); }
2576 else if (!stricmp(word[1], "round")){ math_round=val; asar_throw_warning(2, warning_id_feature_deprecated, "math round", "Put \"asar 1.9\" in your patch to enable the future behavior of never rounding intermediate results. Call the round(), floor() or ceil() functions in places where intermediate rounding is required"); }
2577 else asar_throw_error(0, error_type_block, error_id_invalid_math);
2578 }
2579
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 else if (is2("warn"))
2580 {
2581 bool val = false;
2582 if(0);
2583 else if (!stricmp(word[2], "on")) val=true;
2584 else if (!stricmp(word[2], "off")) val=false;
2585 else asar_throw_error(0, error_type_block, error_id_invalid_warn);
2586 if(0);
2587 else if (!stricmp(word[1], "xkas")) {
2588 asar_throw_warning(0, warning_id_feature_deprecated, "xkas compatibility warning", "If you worry about xkas I worry about you. Just stop.");
2589 warnxkas=val;
2590 }
2591 else asar_throw_error(0, error_type_block, error_id_invalid_warn);
2592 }
2593
3/4
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 3 times.
45 else if (is0("fastrom"))
2594 {
2595
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 asar_throw_warning(0, warning_id_feature_deprecated, "fastrom", "This feature has been disabled for years and is a lie. Sorry.");
2596 //removed due to causing more trouble than it's worth.
2597 //if (emulatexkas) warn0("Convert the patch to native Asar format instead of making an Asar-only xkas patch.");
2598 //if (mapper==lorom || mapper==hirom) fastrom=true;
2599 //else error(0, "Can't use fastrom in this mapper.");
2600 }
2601
6/8
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 18 times.
42 else if (is0("{") || is0("}")) {}
2602 else
2603 {
2604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (isspecialline)
2605 {
2606 asar_throw_warning(0, warning_id_unrecognized_special_command);
2607 }
2608 else
2609 {
2610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(1, error_type_block, error_id_unknown_command);
2611 }
2612 }
2613
2614 437650 }
2615
2616 3665 bool assemblemapper(char** word, int numwords)
2617 {
2618 3665 auto previous_mapper = mapper;
2619 if(0);
2620
4/4
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 298 times.
3665 else if (is0("lorom"))
2621 {
2622 //this also makes xkas set snespos to $008000 for some reason
2623 36 mapper=lorom;
2624 }
2625
4/4
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 291 times.
✓ Branch 3 taken 7 times.
3629 else if (is0("hirom"))
2626 {
2627 //xkas makes this point to $C00000
2628 7 mapper=hirom;
2629 }
2630
4/4
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 288 times.
✓ Branch 3 taken 3 times.
3622 else if (is0("exlorom"))
2631 {
2632 3 mapper = exlorom;
2633 }
2634
4/4
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 285 times.
✓ Branch 3 taken 3 times.
3619 else if (is0("exhirom"))
2635 {
2636 3 mapper=exhirom;
2637 }
2638
4/4
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 279 times.
✓ Branch 3 taken 6 times.
3616 else if (is0("sfxrom"))
2639 {
2640 6 mapper=sfxrom;
2641 //fastrom=false;
2642 }
2643
4/4
✓ Branch 0 taken 279 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 270 times.
✓ Branch 3 taken 9 times.
3610 else if (is0("norom"))
2644 {
2645 //$000000 would be the best snespos for this, but I don't care
2646 9 mapper=norom;
2647 //fastrom=false;
2648
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(!force_checksum_fix)
2649 9 checksum_fix_enabled = false;//we don't know where the header is, so don't set the checksum
2650 }
2651
4/4
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 3331 times.
✓ Branch 2 taken 267 times.
✓ Branch 3 taken 3 times.
3601 else if (is0("fullsa1rom"))
2652 {
2653 3 mapper=bigsa1rom;
2654 //fastrom=false;
2655 }
2656
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3586 times.
3598 else if (is("sa1rom"))
2657 {
2658 //fastrom=false;
2659
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (par)
2660 {
2661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2662
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (!is_digit(par[0]) || par[1]!=',' ||
2663
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 !is_digit(par[2]) || par[3]!=',' ||
2664
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 !is_digit(par[4]) || par[5]!=',' ||
2665
3/6
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
18 !is_digit(par[6]) || par[7]) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2666 int len;
2667 9 autoptr<char**> pars=qpsplit(par, ",", &len);
2668
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9 if (len!=4) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2669 9 sa1banks[0]=(par[0]-'0')<<20;
2670 9 sa1banks[1]=(par[2]-'0')<<20;
2671 9 sa1banks[4]=(par[4]-'0')<<20;
2672 9 sa1banks[5]=(par[6]-'0')<<20;
2673 9 }
2674 else
2675 {
2676 3 sa1banks[0]=0<<20;
2677 3 sa1banks[1]=1<<20;
2678 3 sa1banks[4]=2<<20;
2679 3 sa1banks[5]=3<<20;
2680 }
2681 12 mapper=sa1rom;
2682 }
2683
3/4
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 3322 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 264 times.
3586 else if (is0("header"))
2684 {
2685 //headers are detected elsewhere; ignoring for familiarity
2686 asar_throw_warning(0, warning_id_feature_deprecated, "header", "Remove command, unnecessary.");
2687 }
2688 else return false;
2689
2690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
79 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2691
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 33 times.
79 if(!mapper_set){
2692 46 mapper_set = true;
2693
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 27 times.
33 }else if(previous_mapper != mapper){
2694 27 asar_throw_warning(1, warning_id_mapper_already_set);
2695 }
2696 return true;
2697 }
2698