asar coverage - build #87


src/asar/
File: src/asar/assembleblock.cpp
Date: 2024-01-19 13:47:25
Lines:
1227/1462
83.9%
Functions:
36/39
92.3%
Branches:
1504/2820
53.3%

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 42 int snestopc_pick(int addr)
71 {
72 310 return snestopc(addr);
73 }
74
75 238090 inline void verifysnespos()
76 {
77
3/4
✓ Branch 0 taken 238066 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 238066 times.
238090 if (snespos<0 || realsnespos<0)
78 {
79 24 asar_throw_warning(0, warning_id_missing_org);
80 24 snespos=0x008000;
81 24 realsnespos=0x008000;
82 24 startpos=0x008000;
83 24 realstartpos=0x008000;
84 }
85 238090 }
86
87 960 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 372 times.
✓ Branch 1 taken 588 times.
960 if (mapper == lorom) {
94
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 348 times.
372 if ((inaddr&0xFFFF)+step > 0xFFFF) {
95 // bank crossed
96 24 return inaddr+step+0x8000;
97 }
98 348 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 588 return inaddr+step;
145 }
146 return -1;
147 }
148
149 237442 inline void step(int num)
150 {
151
2/2
✓ Branch 0 taken 480 times.
✓ Branch 1 taken 236962 times.
237442 if (disable_bank_cross_errors)
152 {
153 480 snespos = fixsnespos(snespos, num);
154 480 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 480 startpos = snespos;
162 480 realstartpos = realsnespos;
163 }
164 else
165 {
166 236962 snespos += num;
167 236962 realsnespos += num;
168 }
169 237442 bytes+=num;
170 237442 }
171
172 237250 inline void write1_65816(unsigned int num)
173 {
174 237250 verifysnespos();
175
2/2
✓ Branch 0 taken 79072 times.
✓ Branch 1 taken 158178 times.
237250 if (pass==2)
176 {
177 79072 int pcpos=snestopc(realsnespos&0xFFFFFF);
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 79072 times.
79072 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 79072 writeromdata_byte(pcpos, (unsigned char)num);
184
2/2
✓ Branch 0 taken 8262 times.
✓ Branch 1 taken 70810 times.
79072 if (pcpos>=romlen) romlen=pcpos+1;
185 }
186 237250 step(1);
187 237250 ratsmetastate=ratsmeta_ban;
188 237250 }
189
190 int recent_opcode_num = 0;
191
192 15196 void write1_pick(unsigned int num)
193 {
194
10/20
✓ Branch 0 taken 213704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 54 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 54 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 54 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 54 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 54 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 54 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 54 times.
✗ Branch 19 not taken.
229386 write1_65816(num);
195 215228 }
196
197 227576 static bool asblock_pick(char** word, int numwords)
198 {
199 227576 recent_opcode_num = 1;
200
201
2/2
✓ Branch 0 taken 221552 times.
✓ Branch 1 taken 6024 times.
227576 if (arch==arch_65816) return asblock_65816(word, numwords);
202
2/2
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 3666 times.
6024 if (arch==arch_spc700) return asblock_spc700(word, numwords);
203
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3654 times.
3666 if (arch==arch_spc700_inline) return asblock_spc700(word, numwords);
204
1/2
✓ Branch 0 taken 3654 times.
✗ Branch 1 not taken.
3654 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 1508 const char * safedequote(char * str)
212 {
213 1508 const char * tmp=dequote(str);
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1508 times.
1508 if (!tmp) asar_throw_error(0, error_type_block, error_id_garbage_near_quoted_string);
215 1508 return tmp;
216 }
217
218 extern char romtitle[30];
219 extern bool stdlib;
220
221 1706 void write2(unsigned int num)
222 {
223 write1(num);
224 1706 write1(num/256);
225 1706 }
226
227 1018 void write3(unsigned int num)
228 {
229 write1(num);
230 1018 write1(num/256);
231 1018 write1(num/65536);
232 1018 }
233
234 90 void write4(unsigned int num)
235 {
236 write1(num);
237 90 write1(num/256);
238 90 write1(num/65536);
239 90 write1(num/16777216);
240 90 }
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 18 int read2(int insnespos)
252 {
253 int addr=snestopc(insnespos);
254
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 if (addr<0 || addr+2>romlen_r) return -1;
255 return
256 18 romdata_r[addr ] |
257 18 (romdata_r[addr+1]<< 8);
258 }
259
260 54 int read3(int insnespos)
261 {
262 int addr=snestopc(insnespos);
263
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
54 if (addr<0 || addr+3>romlen_r) return -1;
264 return
265 54 romdata_r[addr ] |
266 54 (romdata_r[addr+1]<< 8)|
267 54 (romdata_r[addr+2]<<16);
268 }
269
270 1416 int getlenfromchar(char c)
271 {
272 1416 c=(char)to_lower(c);
273
2/2
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 660 times.
1416 if (c=='b') return 1;
274
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 660 times.
756 if (c=='w') return 2;
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 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 884 bool confirmname(const char * name)
305 {
306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 884 times.
884 if (!name[0]) return false;
307
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 734 times.
884 if (is_digit(name[0])) return false;
308
2/2
✓ Branch 0 taken 5172 times.
✓ Branch 1 taken 728 times.
5900 for (int i=0;name[i];i++)
309 {
310
4/4
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 4908 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 258 times.
5172 if (!is_alnum(name[i]) && name[i]!='_') return false;
311 }
312 return true;
313 }
314
315 2281714 string posneglabelname(const char ** input, bool define)
316 {
317 2281714 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 50 times.
✓ Branch 1 taken 2281664 times.
2281714 if (label[0] == '?')
325 {
326 ismacro = true;
327 50 label++;
328 }
329
4/4
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 2281632 times.
✓ Branch 2 taken 216 times.
✓ Branch 3 taken 2281416 times.
2281714 if (label[0] == '-' || label[0] == '+')
330 {
331 char first = label[0];
332
4/4
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 212 times.
✓ Branch 2 taken 298 times.
✓ Branch 3 taken 86 times.
596 for (depth = 0; label[0] && label[0] == first; depth++) label++;
333
334
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 20 times.
298 if (!ismacro)
335 {
336
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 72 times.
278 if (first == '+')
337 {
338 206 *input = label;
339 412 output = STR":pos_" + dec(depth) + "_" + dec(poslabels[depth]);
340
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 104 times.
308 if (define) poslabels[depth]++;
341 }
342 else
343 {
344 72 *input = label;
345
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
78 if (define) neglabels[depth]++;
346 144 output = STR":neg_" + dec(depth) + "_" + dec(neglabels[depth]);
347 }
348 }
349 else
350 {
351
3/6
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
20 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 10 times.
✓ Branch 1 taken 10 times.
20 if (first == '+')
358 {
359 10 *input = label;
360 25 output = STR":macro_" + dec(calledmacros) + STR"_pos_" + dec(depth) + "_" + dec((*macroposlabels)[depth]);
361
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 if (define) (*macroposlabels)[depth]++;
362 }
363 else
364 {
365 10 *input = label;
366
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
16 if (define) (*macroneglabels)[depth]++;
367 25 output = STR":macro_" + dec(calledmacros) + STR"_neg_" + dec(depth) + "_" + dec((*macroneglabels)[depth]);
368 }
369 }
370 }
371 }
372
373 2281714 return output;
374 }
375
376 2328 static string labelname(const char ** rawname, bool define=false)
377 {
378 #define deref_rawname (*rawname)
379 2328 bool ismacro = (deref_rawname[0] == '?');
380
381
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2304 times.
2328 if (ismacro)
382 {
383 24 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 24 times.
✓ Branch 1 taken 2304 times.
2328 if (ismacro)
393 {
394 24 sublabellist = macrosublabels;
395 }
396
397
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2328 if (is_digit(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
398
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 2232 times.
2328 if (*deref_rawname ==':')
399 {
400 96 deref_rawname++;
401 name=":";
402 }
403
4/4
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 2064 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 2040 times.
2232 else if (!in_struct && !in_sub_struct)
404 {
405
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 2040 times.
2108 for (i=0;(*deref_rawname =='.');i++) deref_rawname++;
406
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2040 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2040 if (!is_ualnum(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
407
3/6
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2024 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2040 if (emulatexkas && i>1) asar_throw_warning(1, warning_id_convert_to_asar);
408
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 1978 times.
2040 if (i)
409 {
410
2/6
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 62 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
62 if (!sublabellist || !(*sublabellist)[i - 1]) asar_throw_error(1, error_type_block, error_id_label_missing_parent);
411 124 name+=STR(*sublabellist)[i-1]+"_";
412 issublabel = true;
413 }
414 }
415
416
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2314 times.
2328 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 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
14 if (!macrorecursion || macrosublabels == nullptr) asar_throw_error(1, error_type_block, error_id_macro_label_outside_of_macro);
421 28 name = STR":macro_" + dec(calledmacros) + "_" + name;
422 }
423
424
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 2304 times.
2328 if(in_sub_struct)
425 {
426 24 name += struct_parent + ".";
427 }
428
429
4/4
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 2136 times.
2328 if (in_struct || in_sub_struct)
430 {
431 192 name += struct_name;
432 192 name += '.';
433
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
192 if(*deref_rawname != '.') asar_throw_error(1, error_type_block, error_id_invalid_label_name); //probably should be a better error. TODO!!!
434 192 deref_rawname++;
435 }
436
437
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2328 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2328 if (!is_ualnum(*deref_rawname)) asar_throw_error(1, error_type_block, error_id_invalid_label_name);
438
439
6/6
✓ Branch 0 taken 18266 times.
✓ Branch 1 taken 2642 times.
✓ Branch 2 taken 236 times.
✓ Branch 3 taken 2406 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 2328 times.
20908 while (is_ualnum(*deref_rawname) || *deref_rawname == '.' || *deref_rawname == '[')
440 {
441
6/6
✓ Branch 0 taken 17440 times.
✓ Branch 1 taken 1140 times.
✓ Branch 2 taken 17368 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 17290 times.
18580 if(!in_struct && !in_sub_struct && *deref_rawname == '[')
442 {
443 bool invalid = true;
444
1/2
✓ Branch 0 taken 234 times.
✗ Branch 1 not taken.
234 while (isprint(*deref_rawname))
445 {
446
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 78 times.
234 if (*(deref_rawname++) == ']')
447 {
448 invalid = false;
449 break;
450 }
451 }
452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
78 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 18502 times.
18502 else if (*deref_rawname == '{')
458 {
459 asar_throw_error(1, error_type_block, error_id_array_invalid_inside_structs);
460 }
461
462 18580 name+=*(deref_rawname++);
463 }
464
2/2
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 1818 times.
2328 if (define && i>=0)
465 {
466 510 (*sublabellist).reset(i);
467 (*sublabellist)[i]=name;
468 }
469 2328 return name;
470 #undef deref_rawname
471 }
472
473 1602 inline bool labelvalcore(const char ** rawname, snes_label * rval, bool define, bool shouldthrow)
474 {
475 1602 string name=labelname(rawname, define);
476 snes_label rval_;
477
8/8
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 1512 times.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 1512 times.
✓ Branch 4 taken 90 times.
✓ Branch 5 taken 1512 times.
✓ Branch 6 taken 54 times.
✓ Branch 7 taken 1548 times.
1746 if (ns && labels.exists(STR ns+name)) {rval_ = labels.find(STR ns+name);}
478
2/2
✓ Branch 0 taken 1422 times.
✓ Branch 1 taken 126 times.
1548 else if (labels.exists(name)) {rval_ = labels.find(name);}
479 else
480 {
481
3/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42 times.
126 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 126 times.
✗ Branch 1 not taken.
126 if (rval) { rval->pos = (unsigned int)-1; rval->is_static = false; }
486 126 return false;
487 }
488
1/2
✓ Branch 0 taken 1476 times.
✗ Branch 1 not taken.
1476 if (rval)
489 {
490 1476 *rval=rval_;
491 //if (fastrom && (rval_&0x700000)!=0x700000) *rval|=0x800000;
492 }
493 return true;
494 1602 }
495
496 1012 snes_label labelval(const char ** rawname, bool define)
497 {
498 snes_label rval;
499 1012 labelvalcore(rawname, &rval, define, true);
500 1012 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 56 snes_label labelval(string name, bool define)
511 {
512 56 const char * rawname=name;
513 snes_label rval;
514 56 labelvalcore(&rawname, &rval, define, true);
515 56 return rval;
516 }
517
518 478 bool labelval(const char ** rawname, snes_label * rval, bool define)
519 {
520 478 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 56 bool labelval(string name, snes_label * rval, bool define)
529 {
530 56 const char * str=name;
531 56 return labelvalcore(&str, rval, define, false);
532 }
533
534 908 static void setlabel(string name, int loc=-1, bool is_static=false)
535 {
536
2/2
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 68 times.
908 if (loc==-1)
537 {
538 840 verifysnespos();
539 840 loc=snespos;
540 }
541
542 snes_label label_data;
543 908 label_data.pos = (unsigned int)loc;
544 908 label_data.is_static = is_static;
545
546 unsigned int labelpos;
547
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 604 times.
908 if (pass==0)
548 {
549
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 302 times.
304 if (labels.exists(name))
550 {
551 2 movinglabelspossible=true;
552 2 asar_throw_error(0, error_type_block, error_id_label_redefined, name.data());
553 }
554 302 labels.create(name) = label_data;
555 }
556
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 302 times.
604 else if (pass==1)
557 {
558 302 labels.create(name) = label_data;
559 }
560
1/2
✓ Branch 0 taken 302 times.
✗ Branch 1 not taken.
302 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 302 times.
302 if (!labels.exists(name)) asar_throw_error(2, error_type_block, error_id_label_on_third_pass);
564 302 labelpos = labels.find(name).pos;
565
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 302 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
302 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 562 static void cleartable()
595 {
596
2/2
✓ Branch 0 taken 143872 times.
✓ Branch 1 taken 562 times.
144434 for (unsigned int i=0;i<256;i++) table.table[i]=i;
597 562 }
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 98 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 882 static int getfreespaceid()
635 {
636 static const int max_num_freespaces = 125;
637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 882 times.
882 if (freespaceidnext > max_num_freespaces) asar_throw_error(pass, error_type_fatal, error_id_freespace_limit_reached, max_num_freespaces);
638 882 return freespaceidnext++;
639 }
640
641 873326 void checkbankcross()
642 {
643
5/8
✓ Branch 0 taken 6642 times.
✓ Branch 1 taken 866684 times.
✓ Branch 2 taken 6642 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6642 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6642 times.
873326 if (snespos<0 && realsnespos<0 && startpos<0 && realstartpos<0) return;
644
2/2
✓ Branch 0 taken 866018 times.
✓ Branch 1 taken 666 times.
866684 if (disable_bank_cross_errors) return;
645
2/2
✓ Branch 0 taken 866014 times.
✓ Branch 1 taken 4 times.
866018 unsigned int mask = 0x7FFF0000 | (check_half_banks_crossed ? 0x8000 : 0);
646
4/4
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 865980 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 36 times.
866018 if (((snespos^ startpos) & mask) && (((snespos - 1) ^ startpos) & mask))
647 {
648 2 asar_throw_error(pass, error_type_fatal, error_id_bank_border_crossed, snespos);
649 }
650
3/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 865980 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
866016 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 2132 static void freespaceend()
657 {
658
4/4
✓ Branch 0 taken 1418 times.
✓ Branch 1 taken 714 times.
✓ Branch 2 taken 876 times.
✓ Branch 3 taken 542 times.
2132 if ((snespos&0x7F000000) && ((unsigned int)snespos&0x80000000)==0)
659 {
660 876 freespacelen[freespaceid]=snespos-freespacestart+freespaceextra;
661 876 snespos=(int)0xFFFFFFFF;
662 }
663 2132 freespaceextra=0;
664 2132 }
665
666 int numopcodes;
667
668 bool warnxkas;
669
670
1/2
✓ Branch 0 taken 5620 times.
✗ Branch 1 not taken.
5620 static void adddefine(const string & key, string & value)
671 {
672
1/2
✓ Branch 0 taken 5620 times.
✗ Branch 1 not taken.
5620 if (!defines.exists(key)) defines.create(key) = value;
673 5620 }
674
675 562 void initstuff()
676 {
677
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 372 times.
562 if (pass==0)
678 {
679
2/2
✓ Branch 0 taken 48640 times.
✓ Branch 1 taken 190 times.
48830 for (int i=0;i<256;i++)
680 {
681 48640 freespaceleak[i]=true;
682 48640 freespaceorgpos[i]=-2;
683 48640 freespaceorglen[i]=-1;
684 48640 freespacebyte[i] = 0x00;
685 }
686 }
687 562 arch=arch_65816;
688 562 mapper=lorom;
689 562 mapper_set = false;
690 562 reallycalledmacros=0;
691 562 calledmacros=0;
692 562 macrorecursion=0;
693 562 repeatnext=1;
694 562 defines.reset();
695 562 builtindefines.each(adddefine);
696 562 clidefines.each(adddefine);
697 ns="";
698 562 namespace_list.reset();
699 562 sublabels.reset();
700 562 poslabels.reset();
701 562 neglabels.reset();
702 562 macroposlabels = nullptr;
703 562 macroneglabels = nullptr;
704 562 macrosublabels = nullptr;
705 562 cleartable();
706 562 pushpc.reset();
707 562 pushpcnum=0;
708 562 pushns.reset();
709 562 pushnsnum = 0;
710 562 bytes=0;
711 562 memset(fillbyte, 0, sizeof(fillbyte));
712 562 memset(padbyte, 0, sizeof(padbyte));
713 562 snespos=(int)0xFFFFFFFF;
714 562 realsnespos= (int)0xFFFFFFFF;
715 562 startpos= (int)0xFFFFFFFF;
716 562 realstartpos= (int)0xFFFFFFFF;
717 //fastrom=false;
718 562 freespaceidnext=1;
719 562 freespaceid=1;
720 562 freespaceextra=0;
721 562 numopcodes=0;
722 562 specifiedasarver = false;
723 562 incsrcdepth = 0;
724
725 562 optimizeforbank = -1;
726 562 optimize_dp = optimize_dp_flag::NONE;
727 562 dp_base = 0;
728 562 optimize_address = optimize_address_flag::DEFAULT;
729
730 562 in_struct = false;
731 562 in_sub_struct = false;
732 562 in_spcblock = false;
733
734 562 math_pri=false;
735 562 math_round=true;
736
737
1/2
✓ Branch 0 taken 562 times.
✗ Branch 1 not taken.
562 if (arch==arch_65816) asinit_65816();
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 562 times.
562 if (arch==arch_spc700) asinit_spc700();
739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 562 times.
562 if (arch==arch_spc700_inline) asinit_spc700();
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 562 times.
562 if (arch==arch_superfx) asinit_superfx();
741
742 562 warnxkas=false;
743 562 emulatexkas=false;
744 562 disable_bank_cross_errors = false;
745 562 check_half_banks_crossed = false;
746 562 nested_namespaces = false;
747
748 thisfilename = "";
749
750 562 includeonce.reset();
751
752 extern AddressToLineMapping addressToLineMapping;
753 562 addressToLineMapping.reset();
754
755 562 push_warnings(false);
756
757 562 initmathcore();
758 562 }
759
760
761 //void nerf(const string& left, string& right){puts(S left+" = "+right);}
762
763 558 void finishpass()
764 {
765 558 verify_warnings();
766 558 pull_warnings(false);
767
768 //defines.traverse(nerf);
769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 558 times.
558 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_missing_endspcblock);
770
2/4
✓ Branch 0 taken 558 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 558 times.
558 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 558 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
558 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 558 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
558 else if (pushnsnum && pass == 0) asar_throw_error(pass, error_type_null, error_id_pushns_without_pullns);
773 558 freespaceend();
774
2/2
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 48 times.
558 if (arch==arch_65816) asend_65816();
775
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 528 times.
558 if (arch==arch_spc700) asend_spc700();
776
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 552 times.
558 if (arch==arch_spc700_inline) asend_spc700();
777
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 546 times.
558 if (arch==arch_superfx) asend_superfx();
778
779 558 deinitmathcore();
780 558 }
781
782 872406 static bool addlabel(const char * label, int pos=-1, bool global_label = false)
783 {
784
3/4
✓ Branch 0 taken 651440 times.
✓ Branch 1 taken 220966 times.
✓ Branch 2 taken 651440 times.
✗ Branch 3 not taken.
872406 if (!label[0] || label[0]==':') return false;//colons are reserved for special labels
785
786 651440 const char* posneglabel = label;
787 651440 string posnegname = posneglabelname(&posneglabel, true);
788
789
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 651320 times.
651440 if (posnegname.length() > 0)
790 {
791
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 if (global_label) return false;
792
3/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
120 if (*posneglabel != '\0' && *posneglabel != ':') asar_throw_error(0, error_type_block, error_id_broken_label_definition);
793
1/2
✓ Branch 0 taken 120 times.
✗ Branch 1 not taken.
120 setlabel(posnegname, pos);
794 120 return true;
795 }
796
7/8
✓ Branch 0 taken 650636 times.
✓ Branch 1 taken 684 times.
✓ Branch 2 taken 650582 times.
✓ Branch 3 taken 54 times.
✓ Branch 4 taken 650576 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 650576 times.
651320 if (label[strlen(label)-1]==':' || label[0]=='.' || label[0]=='?' || label[0] == '#')
797 {
798
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 12 times.
744 if (!label[1]) return false;
799
6/8
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 690 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 6 times.
732 if(global_label && (in_struct || in_sub_struct || label[0]=='?')) return false;
800
801 bool define = true;
802
803
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 702 times.
726 if (label[0] == '#')
804 {
805 define = false;
806 24 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 486 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 480 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 480 times.
✗ Branch 5 not taken.
726 bool requirecolon = (label[0] != '.' && label[1] != '.') && (in_struct || in_sub_struct);
813
1/2
✓ Branch 0 taken 726 times.
✗ Branch 1 not taken.
726 string name=labelname(&label, define);
814
2/2
✓ Branch 0 taken 684 times.
✓ Branch 1 taken 42 times.
726 if (label[0]==':') label++;
815
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
42 else if (requirecolon) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
816
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 6 times.
42 else if (global_label) return false;
817
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 720 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
720 if (label[0]) asar_throw_error(0, error_type_block, error_id_broken_label_definition);
818
4/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 612 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 12 times.
816 if (ns && !global_label) name=STR ns+name;
819
6/6
✓ Branch 0 taken 552 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 528 times.
✓ Branch 4 taken 718 times.
✓ Branch 5 taken 2 times.
720 setlabel(name, pos, ((in_struct || in_sub_struct) && static_struct));
820 718 return true;
821 726 }
822 return false;
823 651440 }
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 72 static void push_pc()
836 {
837 72 pushpc[pushpcnum].arch=arch;
838 72 pushpc[pushpcnum].snespos=snespos;
839 72 pushpc[pushpcnum].snesstart=startpos;
840 72 pushpc[pushpcnum].snesposreal=realsnespos;
841 72 pushpc[pushpcnum].snesstartreal=realstartpos;
842 72 pushpc[pushpcnum].freeid=freespaceid;
843 72 pushpc[pushpcnum].freeex=freespaceextra;
844 72 pushpc[pushpcnum].freest=freespacestart;
845 72 pushpcnum++;
846 72 }
847
848 72 static void pop_pc()
849 {
850 72 pushpcnum--;
851 72 snespos=pushpc[pushpcnum].snespos;
852 72 startpos=pushpc[pushpcnum].snesstart;
853 72 realsnespos=pushpc[pushpcnum].snesposreal;
854 72 realstartpos=pushpc[pushpcnum].snesstartreal;
855 72 freespaceid=pushpc[pushpcnum].freeid;
856 72 freespaceextra=pushpc[pushpcnum].freeex;
857 72 freespacestart=pushpc[pushpcnum].freest;
858 72 }
859
860
861 132 string handle_print(char* input)
862 {
863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
132 if (!confirmqpar(input)) asar_throw_error(0, error_type_block, error_id_mismatched_parentheses);
864 66 string out;
865
1/2
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
132 autoptr<char**> pars = qpsplit(input, ",");
866
2/2
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 132 times.
456 for (int i = 0; pars[i]; i++)
867 {
868 if (0);
869
3/4
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 210 times.
✗ Branch 3 not taken.
324 else if (pars[i][0] == '"') out += safedequote(pars[i]);
870
3/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57 times.
114 else if (!stricmp(pars[i], "bytes")) out += dec(bytes);
871
3/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57 times.
114 else if (!stricmp(pars[i], "freespaceuse")) out += dec(freespaceuse);
872
3/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57 times.
114 else if (!stricmp(pars[i], "pc")) out += hex6((unsigned int)(snespos & 0xFFFFFF));
873
3/4
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 12 times.
204 else if (!strncasecmp(pars[i], "bin(", strlen("bin(")) ||
874
4/4
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 12 times.
123 !strncasecmp(pars[i], "dec(", strlen("dec(")) ||
875
5/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
201 !strncasecmp(pars[i], "hex(", strlen("hex(")) ||
876
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 !strncasecmp(pars[i], "double(", strlen("double(")))
877 {
878 114 char * arg1pos = strchr(pars[i], '(') + 1;
879 57 char * endpos = strchr(arg1pos, '\0');
880
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 228 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 114 times.
228 while (*endpos == ' ' || *endpos == '\0') endpos--;
881
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
114 if (*endpos != ')') asar_throw_error(0, error_type_block, error_id_invalid_print_function_syntax);
882 114 string paramstr = string(arg1pos, (int)(endpos - arg1pos));
883
884 int numargs;
885
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 autoptr<char**> params = qpsplit(paramstr.temp_raw(), ",", &numargs);
886
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
114 if (numargs > 2) asar_throw_error(0, error_type_block, error_id_wrong_num_parameters);
887 int precision = 0;
888 114 bool hasprec = numargs == 2;
889
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 78 times.
114 if (hasprec)
890 {
891
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 precision = getnum64(params[1]);
892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
78 if (precision < 0) precision = 0;
893 78 if (precision > 64) precision = 64;
894 }
895 114 *(arg1pos - 1) = '\0'; // allows more convenient comparsion functions
896
4/4
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 45 times.
114 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 24 times.
✗ Branch 1 not taken.
24 int64_t value = getnum64(params[0]);
900 char buffer[65];
901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 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 1536 times.
✓ Branch 1 taken 24 times.
1560 for (int j = 0; j < 64; j++) {
909 1536 buffer[63 - j] = '0' + ((value & (1ull << j)) >> j);
910 }
911 24 buffer[64] = 0;
912 int startidx = 0;
913
3/4
✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 1344 times.
✗ Branch 3 not taken.
1368 while (startidx < 64 - precision && buffer[startidx] == '0') startidx++;
914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (startidx == 64) startidx--; // always want to print at least one digit
915 24 out += buffer + startidx;
916 }
917
4/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 33 times.
90 else if (!stricmp(pars[i], "dec"))
918 {
919
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 int64_t value = getnum64(params[0]);
920 char buffer[65];
921
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 snprintf(buffer, 65, "%0*" PRId64, precision, value);
922 24 out += buffer;
923 }
924
4/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 21 times.
66 else if (!stricmp(pars[i], "hex"))
925 {
926
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 int64_t value = getnum64(params[0]);
927 char buffer[65];
928
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 snprintf(buffer, 65, "%0*" PRIX64, precision, value);
929 24 out += buffer;
930 }
931
2/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
42 else if (!stricmp(pars[i], "double"))
932 {
933
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 6 times.
42 if (!hasprec) precision = 5;
934
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 out += ftostrvar(getnumdouble(params[0]), precision);
935 }
936 114 }
937 else asar_throw_error(2, error_type_block, error_id_unknown_variable);
938 }
939 132 return out;
940 132 }
941
942
943 873984 void assembleblock(const char * block, bool isspecialline)
944 {
945 436992 string tmp=block;
946 int numwords;
947
1/2
✓ Branch 0 taken 873984 times.
✗ Branch 1 not taken.
873984 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 873984 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 873984 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
873984 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 138 times.
✓ Branch 1 taken 873846 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 66 times.
873984 if (is("elseif") && numtrue+1==numif)
967 {
968
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 resolvedefines(resolved, block);
969
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 free(word);
970
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 word = qsplit(resolved.temp_raw(), " ", &numwords);
971 }
972
973 autoptr<char**> wordcopy=word;
974
6/6
✓ Branch 0 taken 872454 times.
✓ Branch 1 taken 1530 times.
✓ Branch 2 taken 647252 times.
✓ Branch 3 taken 225202 times.
✓ Branch 4 taken 225160 times.
✓ Branch 5 taken 42 times.
873984 if (numif==numtrue && is1("global")) {
975
3/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 30 times.
42 if (!addlabel(word[1], -1, true)) {
976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 asar_throw_error(1, error_type_block, error_id_invalid_global_label, word[1]);
977 }
978 30 return;
979 }
980
12/12
✓ Branch 0 taken 873220 times.
✓ Branch 1 taken 1530 times.
✓ Branch 2 taken 872586 times.
✓ Branch 3 taken 634 times.
✓ Branch 4 taken 437508 times.
✓ Branch 5 taken 435078 times.
✓ Branch 6 taken 437286 times.
✓ Branch 7 taken 222 times.
✓ Branch 8 taken 872362 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 871554 times.
✓ Branch 11 taken 808 times.
874750 while (numif==numtrue && word[0] && (!word[1] || strcmp(word[1], "=")) && addlabel(word[0]))
981 {
982 808 word++;
983 808 numwords--;
984 }
985
4/4
✓ Branch 0 taken 873306 times.
✓ Branch 1 taken 634 times.
✓ Branch 2 taken 652292 times.
✓ Branch 3 taken 221014 times.
873940 if (!word[0] || !word[0][0]) return;
986
4/4
✓ Branch 0 taken 650810 times.
✓ Branch 1 taken 1482 times.
✓ Branch 2 taken 216 times.
✓ Branch 3 taken 650594 times.
652292 if (numif==numtrue && word[0][0]=='%')
987 {
988
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 6 times.
216 if (!macrorecursion)
989 {
990 callerfilename=thisfilename;
991 210 callerline=thisline;
992 }
993 216 int fakeendif_prev = fakeendif;
994 216 int moreonlinecond_prev = moreonlinecond;
995 216 int calledmacros_prev = calledmacros;
996
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 6 times.
216 int single_line_for_tracker_prev = single_line_for_tracker;
997
2/2
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 12 times.
216 callmacro(strchr(block, '%')+1);
998 204 fakeendif = fakeendif_prev;
999 204 moreonlinecond = moreonlinecond_prev;
1000 204 calledmacros = calledmacros_prev;
1001 204 single_line_for_tracker = single_line_for_tracker_prev;
1002
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 6 times.
204 if (!macrorecursion)
1003 {
1004 callerfilename="";
1005 198 callerline=-1;
1006 }
1007 204 return;
1008 }
1009
10/10
✓ Branch 0 taken 651752 times.
✓ Branch 1 taken 324 times.
✓ Branch 2 taken 651614 times.
✓ Branch 3 taken 138 times.
✓ Branch 4 taken 651584 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 440600 times.
✓ Branch 7 taken 210984 times.
✓ Branch 8 taken 440252 times.
✓ Branch 9 taken 348 times.
652076 if (is("if") || is("elseif") || is("assert") || is("while") || is("for"))
1010 {
1011
4/4
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 211500 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 318 times.
211824 if(is("if") && moreonline) fakeendif++;
1012
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 211824 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
211824 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
1013 105912 string errmsg;
1014 105912 whiletracker wstatus;
1015 211824 wstatus.startline = thisline;
1016 211824 wstatus.iswhile = false;
1017 211824 wstatus.cond = false;
1018 211824 wstatus.is_for = false;
1019 211824 wstatus.for_start = wstatus.for_end = wstatus.for_cur = 0;
1020 211824 wstatus.for_has_var_backup = false;
1021
2/2
✓ Branch 0 taken 210984 times.
✓ Branch 1 taken 840 times.
211824 if (is("while")) wstatus.iswhile = true;
1022
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 211476 times.
211824 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 348 times.
✓ Branch 1 taken 211476 times.
✓ Branch 2 taken 346 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 332 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 86 times.
✓ Branch 7 taken 246 times.
212170 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 211824 whiletracker& addedwstatus = is_for_cont ? whilestatus[numif] : (whilestatus[numif] = wstatus);
1035
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 211794 times.
211824 if (is("assert"))
1036 {
1037
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 autoptr<char**> tokens = qpsplit(word[numwords - 1], ",");
1038
3/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 18 times.
30 if (tokens[0] != NULL && tokens[1] != NULL)
1039 {
1040 6 string rawerrmsg;
1041 size_t pos = 1;
1042
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 12 times.
54 while (tokens[pos])
1043 {
1044 42 rawerrmsg += tokens[pos];
1045
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 12 times.
42 if (tokens[pos + 1] != NULL)
1046 {
1047 30 rawerrmsg += ",";
1048 }
1049 pos++;
1050 }
1051
1052
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 errmsg = handle_print(rawerrmsg.raw());
1053 12 }
1054 30 }
1055
5/6
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 211716 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
211824 if (numtrue!=numif && !(is("elseif") && numtrue+1==numif))
1056 {
1057
4/6
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
36 if ((is("if") || is("while") || is("for"))) numif++;
1058 return;
1059 }
1060
6/6
✓ Branch 0 taken 211464 times.
✓ Branch 1 taken 324 times.
✓ Branch 2 taken 498 times.
✓ Branch 3 taken 210966 times.
✓ Branch 4 taken 330 times.
✓ Branch 5 taken 168 times.
211788 if ((is("if") || is("while") || is("for"))) numif++;
1061 bool cond;
1062
1063 211788 bool isassert = is("assert");
1064
1065 211788 char ** nextword=word+1;
1066 char * condstr= nullptr;
1067
2/2
✓ Branch 0 taken 211458 times.
✓ Branch 1 taken 330 times.
211788 if(!is("for")) {
1068 while (true)
1069 {
1070
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 211464 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
211464 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 211110 times.
✓ Branch 1 taken 354 times.
✓ Branch 2 taken 211110 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 211110 times.
211464 if (!nextword[1] || !strcmp(nextword[1], "&&") || !strcmp(nextword[1], "||"))
1073 {
1074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 354 times.
354 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 354 times.
✗ Branch 1 not taken.
354 double val = getnumdouble(nextword[0]);
1084
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 354 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.
354 if (foundlabel && !foundlabel_static && !isassert) asar_throw_error(0, error_type_block, error_id_label_in_conditional, word[0]);
1085 354 thiscond = (val > 0);
1086 }
1087
1088
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 354 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
354 if (condstr && nextword[1])
1089 {
1090 if (strcmp(condstr, nextword[1])) asar_throw_error(1, error_type_block, error_id_invalid_condition);
1091 }
1092 354 else condstr=nextword[1];
1093 354 nextword+=2;
1094 354 }
1095 else
1096 {
1097
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 211110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
211110 if (!nextword[2]) asar_throw_error(0, error_type_block, error_id_broken_conditional, word[0]);
1098
1/2
✓ Branch 0 taken 211110 times.
✗ Branch 1 not taken.
211110 double par1=getnumdouble(nextword[0]);
1099
6/8
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 211050 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 30 times.
211110 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 211080 times.
✗ Branch 1 not taken.
211080 double par2=getnumdouble(nextword[2]);
1101
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 211080 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.
211080 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 120 times.
✓ Branch 1 taken 210960 times.
211080 else if (!strcmp(nextword[1], ">")) thiscond=(par1>par2);
1104
2/2
✓ Branch 0 taken 210858 times.
✓ Branch 1 taken 102 times.
210960 else if (!strcmp(nextword[1], "<")) thiscond=(par1<par2);
1105
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 96 times.
102 else if (!strcmp(nextword[1], ">=")) thiscond=(par1>=par2);
1106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 else if (!strcmp(nextword[1], "<=")) thiscond=(par1<=par2);
1107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 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 96 times.
✗ Branch 1 not taken.
96 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 6 times.
✓ Branch 1 taken 211074 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
211080 if (condstr && nextword[3])
1118 {
1119 if (strcmp(condstr, nextword[3])) asar_throw_error(1, error_type_block, error_id_invalid_condition);
1120 }
1121 211080 else condstr=nextword[3];
1122 211080 nextword+=4;
1123 }
1124
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 211416 times.
211434 if (condstr)
1125 {
1126
3/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12 times.
18 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 330 times.
✓ Branch 1 taken 211428 times.
211758 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 330 times.
330 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 84 times.
✓ Branch 1 taken 246 times.
330 if(!is_for_cont)
1145 {
1146 // "for i = 0..16"
1147
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
84 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 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
84 if(strcmp(word[2], "=") != 0) asar_throw_error(0, error_type_block, error_id_broken_for_loop);
1149
1150
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 char* range_sep = strqpstr(word[3], "..");
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if(!range_sep)
1152 asar_throw_error(0, error_type_block, error_id_broken_for_loop, "invalid loop range");
1153
1154 84 string for_start(word[3], range_sep - word[3]);
1155 84 string for_end(range_sep+2);
1156
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_start = getnum(for_start);
1157
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
84 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1158
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 addedwstatus.for_end = getnum(for_end);
1159
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
84 if(foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_in_conditional, "for");
1160 84 string varname = word[1];
1161
2/6
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
84 if(!validatedefinename(varname)) asar_throw_error(0, error_type_block, error_id_broken_for_loop);
1162 84 addedwstatus.for_variable = varname;
1163 84 addedwstatus.for_cur = addedwstatus.for_start;
1164 84 }
1165 else
1166 {
1167 246 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 330 addedwstatus.cond = addedwstatus.for_cur < addedwstatus.for_end;
1171 330 single_line_for_tracker = 2;
1172
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 84 times.
330 if(addedwstatus.cond)
1173 {
1174
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 54 times.
246 numtrue++;
1175
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 54 times.
246 if(defines.exists(addedwstatus.for_variable)) {
1176 192 addedwstatus.for_has_var_backup = true;
1177 192 addedwstatus.for_var_backup = defines.find(addedwstatus.for_variable);
1178 }
1179
1/2
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
246 defines.create(addedwstatus.for_variable) = ftostr(addedwstatus.for_cur);
1180 }
1181 }
1182
4/4
✓ Branch 0 taken 211134 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 210966 times.
211428 else if (is("if") || is("while"))
1183 {
1184 if(0);
1185
2/2
✓ Branch 0 taken 211044 times.
✓ Branch 1 taken 216 times.
211260 else if (cond)
1186 {
1187 211044 numtrue++;
1188 211044 elsestatus[numif]=true;
1189 }
1190 else if (!cond)
1191 {
1192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(moreonline) moreonlinecond=false;
1193 216 elsestatus[numif]=false;
1194 }
1195 211260 addedwstatus.cond = cond;
1196 }
1197
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 30 times.
168 else if (is("elseif"))
1198 {
1199
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 138 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
138 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_elseif);
1200
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 138 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
138 if (whilestatus[numif - 1].iswhile) asar_throw_error(1, error_type_block, error_id_elseif_in_while);
1201
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 72 times.
138 if (numif==numtrue) numtrue--;
1202
4/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 30 times.
204 if (cond && !elsestatus[numif])
1203 {
1204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(moreonline) moreonlinecond = true;
1205 36 numtrue++;
1206 36 elsestatus[numif]=true;
1207 }
1208 }
1209 // otherwise, must be assert command
1210
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 2 times.
30 else if (pass == 2 && !cond)
1211 {
1212
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
16 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 4 times.
4 else asar_throw_error(2, error_type_block, error_id_assertion_failed, ".");
1214 }
1215 211862 }
1216
6/6
✓ Branch 0 taken 439082 times.
✓ Branch 1 taken 1170 times.
✓ Branch 2 taken 228944 times.
✓ Branch 3 taken 210138 times.
✓ Branch 4 taken 228596 times.
✓ Branch 5 taken 348 times.
440252 else if (is("endif") || is("endwhile") || is("endfor"))
1217 {
1218
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 211650 times.
211656 if(fakeendif) fakeendif--;
1219
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 211656 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
211656 if (numwords != 1) asar_throw_error(1, error_type_block, error_id_unknown_command);
1220
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 211656 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
211656 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_endif);
1221
2/2
✓ Branch 0 taken 211194 times.
✓ Branch 1 taken 462 times.
211656 if (numif==numtrue) numtrue--;
1222 211656 numif--;
1223
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 211308 times.
211656 if(whilestatus[numif].is_for) {
1224
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 288 times.
348 if(single_line_for_tracker == 2) single_line_for_tracker = 3;
1225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
348 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 246 times.
✓ Branch 1 taken 102 times.
348 if(whilestatus[numif].cond) {
1233
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 54 times.
246 if(whilestatus[numif].for_has_var_backup)
1234
1/2
✓ Branch 0 taken 192 times.
✗ Branch 1 not taken.
192 defines.create(whilestatus[numif].for_variable) = whilestatus[numif].for_var_backup;
1235
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 else defines.remove(whilestatus[numif].for_variable);
1236 }
1237 }
1238
2/2
✓ Branch 0 taken 210806 times.
✓ Branch 1 taken 850 times.
211656 if(warn_endwhile) {
1239
2/2
✓ Branch 0 taken 210140 times.
✓ Branch 1 taken 666 times.
210806 if(whilestatus[numif].iswhile) {
1240
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 210138 times.
210140 if(!is("endwhile")) {
1241 2 warn_endwhile = false;
1242
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 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 348 times.
✓ Branch 1 taken 318 times.
666 else if(whilestatus[numif].is_for) {
1246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
348 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 318 times.
318 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 216 times.
✓ Branch 1 taken 228380 times.
228596 else if (is("else"))
1258 {
1259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(!moreonlinecond) moreonlinecond = true;
1260
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
216 if (numwords != 1) asar_throw_error(1, error_type_block, error_id_unknown_command);
1261
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
216 if (!numif) asar_throw_error(1, error_type_block, error_id_misplaced_else);
1262
2/6
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
216 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 108 times.
✓ Branch 1 taken 108 times.
216 else if (numif==numtrue) numtrue--;
1264
3/4
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 66 times.
216 else if (numif==numtrue+1 && !elsestatus[numif])
1265 {
1266 42 numtrue++;
1267 42 elsestatus[numif]=true;
1268 }
1269 }
1270
2/2
✓ Branch 0 taken 227576 times.
✓ Branch 1 taken 804 times.
228380 else if (numif!=numtrue) return;
1271
4/4
✓ Branch 0 taken 227574 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9550 times.
✓ Branch 3 taken 218024 times.
227576 else if (asblock_pick(word, numwords))
1272 {
1273
2/2
✓ Branch 0 taken 3182 times.
✓ Branch 1 taken 6368 times.
9550 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 3180 times.
✓ Branch 1 taken 2 times.
3182 if (recent_opcode_num > 0)
1278 {
1279 3180 int opcode_size = ((0xFFFFFF & realsnespos) - addrToLinePos) / recent_opcode_num;
1280
2/2
✓ Branch 0 taken 3214 times.
✓ Branch 1 taken 3180 times.
6394 for (int i = 0; i < recent_opcode_num; ++i)
1281 {
1282 extern AddressToLineMapping addressToLineMapping;
1283
1/2
✓ Branch 0 taken 3214 times.
✗ Branch 1 not taken.
3214 addressToLineMapping.includeMapping(thisfilename.data(), thisline + 1, addrToLinePos + (i * opcode_size));
1284 }
1285 }
1286 }
1287 9550 numopcodes += recent_opcode_num;
1288 }
1289
4/4
✓ Branch 0 taken 216940 times.
✓ Branch 1 taken 1084 times.
✓ Branch 2 taken 216934 times.
✓ Branch 3 taken 6 times.
218024 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 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
9 else*/ def = STR safedequote(par);
1303
1304
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (defines.exists(def))
1305 {
1306
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 defines.remove(def);
1307 }
1308 else
1309 {
1310 asar_throw_error(0, error_type_block, error_id_define_not_found, def.data());
1311 }
1312 6 }
1313
4/4
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 217506 times.
✓ Branch 2 taken 506 times.
✓ Branch 3 taken 6 times.
218018 else if (is0("error"))
1314 {
1315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(0, error_type_block, error_id_error_command, ".");
1316 }
1317
4/4
✓ Branch 0 taken 506 times.
✓ Branch 1 taken 217506 times.
✓ Branch 2 taken 500 times.
✓ Branch 3 taken 6 times.
218012 else if (is0("warn"))
1318 {
1319
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(2, warning_id_warn_command, ".");
1320 }
1321
4/4
✓ Branch 0 taken 216934 times.
✓ Branch 1 taken 1072 times.
✓ Branch 2 taken 216922 times.
✓ Branch 3 taken 12 times.
218006 else if (is1("error"))
1322 {
1323
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 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 12 times.
30 asar_throw_error(2, error_type_block, error_id_error_command, (string(": ") + out).data());
1328 12 }
1329
4/4
✓ Branch 0 taken 216922 times.
✓ Branch 1 taken 1072 times.
✓ Branch 2 taken 216910 times.
✓ Branch 3 taken 12 times.
217994 else if (is1("warn"))
1330 {
1331
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 string out = handle_print(par);
1332
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
18 asar_throw_warning(2, warning_id_warn_command, (string(": ") + out).data());
1333 12 }
1334
4/4
✓ Branch 0 taken 216910 times.
✓ Branch 1 taken 1072 times.
✓ Branch 2 taken 216874 times.
✓ Branch 3 taken 36 times.
217982 else if (is1("warnings"))
1335 {
1336
4/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
36 if (stricmp(word[1], "push") == 0)
1337 {
1338
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 push_warnings();
1339 }
1340
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
18 else if (stricmp(word[1], "pull") == 0)
1341 {
1342
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 pull_warnings();
1343 }
1344 }
1345
4/4
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 217434 times.
✓ Branch 2 taken 440 times.
✓ Branch 3 taken 72 times.
217946 else if (is2("warnings"))
1346 {
1347
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 30 times.
72 if (stricmp(word[1], "enable") == 0)
1348 {
1349
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1350
1351
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (warnid != warning_id_end)
1352 {
1353
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 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
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
60 else if (stricmp(word[1], "disable") == 0)
1361 {
1362
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 asar_warning_id warnid = parse_warning_id_from_string(word[2]);
1363
1364
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if (warnid != warning_id_end)
1365 {
1366
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 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 440 times.
✓ Branch 1 taken 217434 times.
✓ Branch 2 taken 372 times.
✓ Branch 3 taken 68 times.
217874 else if (is2("check"))
1375 {
1376
4/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 31 times.
68 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 6 times.
✗ Branch 1 not taken.
6 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 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 if (romlen < ((mapper == hirom || mapper == exhirom) ? 0x10000 : 0x8000)) // too short
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 126 times.
✓ Branch 1 taken 6 times.
132 for (int i = 0;i < 21;i++)
1396 {
1397 126 unsigned char c = romdata[snestopc(0x00FFC0 + i)];
1398 126 actual_title += (char)c;
1399 // the replacements are from interface-cli.cpp
1400
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if (c == 7) c = 14;
1401
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if (c == 8) c = 27;
1402
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if (c == 9) c = 26;
1403
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if (c == '\r') c = 17;
1404
1/2
✓ Branch 0 taken 126 times.
✗ Branch 1 not taken.
126 if (c == '\n') c = 25;
1405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (c == '\0') c = 155;
1406 126 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 6 times.
6 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 6 }
1418 6 }
1419
2/4
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
62 else if (stricmp(word[1], "bankcross") == 0)
1420 {
1421 if (0);
1422
4/4
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 16 times.
62 else if (!stricmp(word[2], "on"))
1423 {
1424
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 asar_throw_warning(0, warning_id_feature_deprecated, "bankcheck on", "bankcheck full or bankcheck half");
1425 }
1426
4/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1 times.
32 else if (!stricmp(word[2], "off"))
1427 {
1428 30 disable_bank_cross_errors = true;
1429 }
1430
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 else if (!stricmp(word[2], "half"))
1431 {
1432 2 disable_bank_cross_errors = false;
1433 2 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 500 times.
✓ Branch 1 taken 217306 times.
✓ Branch 2 taken 500 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216874 times.
✓ Branch 5 taken 932 times.
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 216844 times.
217806 else if (is0("asar") || is1("asar"))
1449 {
1450
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1451
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (!par) return;
1452
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 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 120 times.
✓ Branch 1 taken 30 times.
150 for (int i=0;par[i];i++)
1456 {
1457
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 90 times.
120 if (par[i]=='.')
1458 {
1459
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (!dig) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1460 dig=0;
1461 30 dots++;
1462 }
1463
1/2
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
90 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 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
30 if (!dig || !dots || dots>2) asar_throw_error(0, error_type_block, error_id_invalid_version_number);
1467
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 autoptr<char**> vers=split(par, ".");
1468 30 int vermaj=atoi(vers[0]);
1469
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 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 30 times.
30 if (vermaj<asarver_maj) return;
1471
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (dots==1)
1472 {
1473
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 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 30 int verminbug=atoi(vers[1]);
1476 30 int tmpver=asarver_bug;
1477 30 if (tmpver>9) tmpver=9;
1478
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (asarver_min*10+tmpver<verminbug) asar_throw_error(pass, error_type_fatal, error_id_asar_too_old);
1479
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
30 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 30 specifiedasarver = true;
1490 30 }
1491
4/4
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 217276 times.
✓ Branch 2 taken 488 times.
✓ Branch 3 taken 12 times.
217776 else if (is0("xkas"))
1492 {
1493
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 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 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (!asarverallowed) asar_throw_error(0, error_type_block, error_id_start_of_file);
1495
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
12 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (specifiedasarver) asar_throw_error(0, error_type_block, error_id_xkas_asar_conflict);
1497 6 emulatexkas=true;
1498 6 optimizeforbank=0x100;
1499
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(!force_checksum_fix)
1500 6 checksum_fix_enabled = false;
1501 sublabels[0]=":xkasdefault:";
1502 }
1503
6/8
✓ Branch 0 taken 488 times.
✓ Branch 1 taken 217276 times.
✓ Branch 2 taken 488 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216844 times.
✓ Branch 5 taken 920 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 216844 times.
217764 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 488 times.
✓ Branch 1 taken 217276 times.
✓ Branch 2 taken 458 times.
✓ Branch 3 taken 30 times.
217764 else if (is0("includeonce"))
1513 {
1514
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 if (!file_included_once(thisfilename))
1515 {
1516 30 includeonce.append(thisfilename);
1517 }
1518 }
1519
16/16
✓ Branch 0 taken 216844 times.
✓ Branch 1 taken 890 times.
✓ Branch 2 taken 3694 times.
✓ Branch 3 taken 213150 times.
✓ Branch 4 taken 3694 times.
✓ Branch 5 taken 890 times.
✓ Branch 6 taken 3662 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 3662 times.
✓ Branch 9 taken 890 times.
✓ Branch 10 taken 3080 times.
✓ Branch 11 taken 582 times.
✓ Branch 12 taken 3080 times.
✓ Branch 13 taken 890 times.
✓ Branch 14 taken 72 times.
✓ Branch 15 taken 3008 times.
217734 else if (is1("db") || is1("dw") || is1("dl") || is1("dd"))
1520 {
1521 int len = 0;
1522
2/6
✓ Branch 0 taken 213836 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 213836 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
213836 if (!confirmqpar(par)) asar_throw_error(0, error_type_block, error_id_mismatched_parentheses);
1523
3/4
✓ Branch 0 taken 213836 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 686 times.
✓ Branch 3 taken 213150 times.
213836 if (is1("db")) len=1;
1524
3/4
✓ Branch 0 taken 213836 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 213804 times.
✓ Branch 3 taken 32 times.
213836 if (is1("dw")) len=2;
1525
3/4
✓ Branch 0 taken 213836 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 213254 times.
✓ Branch 3 taken 582 times.
213836 if (is1("dl")) len=3;
1526
3/4
✓ Branch 0 taken 213836 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 213764 times.
✓ Branch 3 taken 72 times.
213836 if (is1("dd")) len=4;
1527
1/2
✓ Branch 0 taken 213836 times.
✗ Branch 1 not taken.
213836 autoptr<char**> pars=qpsplit(par, ",");
1528
2/2
✓ Branch 0 taken 214550 times.
✓ Branch 1 taken 213826 times.
428376 for (int i=0;pars[i];i++)
1529 {
1530
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 214382 times.
214550 if (pars[i][0]=='"')
1531 {
1532
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
168 if (!strcmp(pars[i],"\"STAR\"") && !emulatexkas)
1533 asar_throw_warning(0, warning_id_xkas_patch);
1534
3/4
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 618 times.
✓ Branch 3 taken 168 times.
786 for (char * str=const_cast<char*>(safedequote(pars[i]));*str;str++)
1535 {
1536
3/4
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 546 times.
✗ Branch 3 not taken.
618 if (len==1) write1(table.table[(size_t)(unsigned char) *str]);
1537
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 594 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
618 if (len==2) write2(table.table[(size_t)(unsigned char) *str]);
1538
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 594 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
618 if (len==3) write3(table.table[(size_t)(unsigned char) *str]);
1539
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 594 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
618 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 214382 times.
214382 if (math[0]=='#') math++;
1546
4/4
✓ Branch 0 taken 71460 times.
✓ Branch 1 taken 142922 times.
✓ Branch 2 taken 71450 times.
✓ Branch 3 taken 10 times.
214382 unsigned int num=(pass==2)?getnum(math):0;
1547
2/2
✓ Branch 0 taken 213704 times.
✓ Branch 1 taken 668 times.
214372 if (len == 1) write1(num);
1548
3/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 214346 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
214372 if (len == 2) write2(num);
1549
3/4
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 213796 times.
✓ Branch 2 taken 576 times.
✗ Branch 3 not taken.
214372 if (len == 3) write3(num);
1550
3/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 214306 times.
✓ Branch 2 taken 66 times.
✗ Branch 3 not taken.
214372 if (len == 4) write4(num);
1551 }
1552 }
1553 213836 }
1554
6/6
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 3526 times.
✓ Branch 2 taken 297 times.
✓ Branch 3 taken 75 times.
✓ Branch 4 taken 75 times.
✓ Branch 5 taken 111 times.
3898 else if (numwords==3 && !stricmp(word[1], "="))
1555 {
1556
5/8
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 150 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 150 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 150 times.
✗ Branch 7 not taken.
222 if (word[0][0]=='\'' && word[0][1] && word[0][2]=='\'' && word[0][3]=='\0')
1557 {
1558
1/2
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
150 table.table[(unsigned char)word[0][1]]=getnum(word[2]);
1559
3/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
150 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
1560 150 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 72 times.
✗ Branch 1 not taken.
72 int num=(int)getnum(word[2]);
1565
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
72 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_label_cross_assignment);
1566
1567 66 const char* newlabelname = word[0];
1568 bool ismacro = false;
1569
1570
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 60 times.
66 if (newlabelname[0] == '?')
1571 {
1572 ismacro = true;
1573 6 newlabelname++;
1574 }
1575
1576
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 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 66 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
66 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 6 times.
✓ Branch 1 taken 60 times.
66 if (ismacro)
1586 {
1587 12 completename += STR":macro_" + dec(calledmacros) + "_";
1588 }
1589
1590 66 completename += newlabelname;
1591
1592
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 setlabel(ns + completename, num, true);
1593 66 }
1594
3/4
✓ Branch 0 taken 3676 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3518 times.
✓ Branch 3 taken 158 times.
3676 else if (assemblemapper(word, numwords)) {}
1595
4/4
✓ Branch 0 taken 2990 times.
✓ Branch 1 taken 528 times.
✓ Branch 2 taken 2298 times.
✓ Branch 3 taken 692 times.
3518 else if (is1("org"))
1596 {
1597
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 692 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
692 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1598 692 freespaceend();
1599
1/2
✓ Branch 0 taken 692 times.
✗ Branch 1 not taken.
692 unsigned int num=getnum(par);
1600
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 692 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
692 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_org_label_forward);
1601
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 692 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
692 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 266 times.
✓ Branch 1 taken 426 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 260 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 432 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
692 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 692 snespos=(int)num;
1605 692 realsnespos=(int)num;
1606 692 startpos=(int)num;
1607 692 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 72 times.
✓ Branch 1 taken 2754 times.
2826 else if (is("struct"))
1612 {
1613 //verifysnespos();
1614
2/6
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
72 if (in_struct || in_sub_struct) ret_error(error_id_nested_struct);
1615
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
72 if (numwords < 2) ret_error(error_id_missing_struct_params);
1616
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
72 if (numwords > 4) ret_error(error_id_too_many_struct_params);
1617
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
72 if (!confirmname(word[1])) ret_error(error_id_invalid_struct_name);
1618
1619
3/6
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
72 if (structs.exists(word[1]) && pass == 0) ret_error_params(error_id_struct_redefined, word[1]);
1620
1621 72 static_struct = false;
1622 72 old_snespos = snespos;
1623 72 old_startpos = startpos;
1624 72 old_optimizeforbank = optimizeforbank;
1625 unsigned int base = 0;
1626
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 48 times.
72 if (numwords == 3)
1627 {
1628 24 static_struct = true;
1629
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 base = getnum(word[2]);
1630
1631
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if (foundlabel && !foundlabel_static) static_struct = false;
1632 }
1633
1634 72 bool old_in_struct = in_struct;
1635 72 bool old_in_sub_struct = in_sub_struct;
1636 72 in_struct = numwords == 2 || numwords == 3;
1637 72 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 24 times.
✓ Branch 1 taken 48 times.
72 if (numwords == 3)
1643 {
1644
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if (base&~0xFFFFFF) ret_error_params_cleanup(error_id_snes_address_out_of_bounds, hex6((unsigned int)base).data());
1645 24 snespos = (int)base;
1646 24 startpos = (int)base;
1647 }
1648
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 else if (numwords == 4)
1649 {
1650
3/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
24 if (strcasecmp(word[2], "extends")) ret_error_cleanup(error_id_missing_extends);
1651
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if (!confirmname(word[3])) ret_error_cleanup(error_id_struct_invalid_parent_name);
1652 12 string tmp_struct_parent = word[3];
1653
1654
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if (!structs.exists(tmp_struct_parent)) ret_error_params_cleanup(error_id_struct_not_found, tmp_struct_parent.data());
1655 24 snes_struct structure = structs.find(tmp_struct_parent);
1656
1657 24 static_struct = structure.is_static;
1658 struct_parent = tmp_struct_parent;
1659 24 snespos = structure.base_end;
1660 24 startpos = structure.base_end;
1661 24 }
1662
1663 72 push_pc();
1664
1665 72 optimizeforbank = -1;
1666
1667 72 struct_name = word[1];
1668 72 struct_base = snespos;
1669 72 realsnespos = 0;
1670 72 realstartpos = 0;
1671 #undef ret_error_cleanup
1672 #undef ret_error_params_cleanup
1673 }
1674
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 2682 times.
2754 else if (is("endstruct"))
1675 {
1676
3/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
72 if (numwords != 1 && numwords != 3) ret_error(error_id_invalid_endstruct_count);
1677
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
72 if (numwords == 3 && strcasecmp(word[1], "align")) ret_error(error_id_expected_align);
1678
3/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
72 if (!in_struct && !in_sub_struct) ret_error(error_id_endstruct_without_struct);
1679
1680
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
72 int alignment = numwords == 3 ? (int)getnum(word[2]) : 1;
1681
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (alignment < 1) ret_error(error_id_alignment_too_small);
1682
1683 snes_struct structure;
1684 72 structure.base_end = snespos;
1685 72 structure.struct_size = alignment * ((snespos - struct_base + alignment - 1) / alignment);
1686 72 structure.object_size = structure.struct_size;
1687 72 structure.is_static = static_struct;
1688
1689
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 if (in_struct)
1690 {
1691
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 structs.create(struct_name) = structure;
1692 }
1693
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 else if (in_sub_struct)
1694 {
1695 snes_struct parent;
1696 24 parent = structs.find(struct_parent);
1697
1698
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (parent.object_size < parent.struct_size + structure.struct_size) {
1699 24 parent.object_size = parent.struct_size + structure.struct_size;
1700 }
1701
1702
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 structs.create(struct_parent + "." + struct_name) = structure;
1703
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 structs.create(struct_parent) = parent;
1704 }
1705
1706 72 pop_pc();
1707 72 in_struct = false;
1708 72 in_sub_struct = false;
1709 72 snespos = old_snespos;
1710 72 startpos = old_startpos;
1711 72 optimizeforbank = old_optimizeforbank;
1712 72 static_struct = false;
1713 }
1714 #undef ret_error
1715
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2676 times.
2682 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(arch != arch_spc700) asar_throw_error(0, error_type_block, error_id_spcblock_bad_arch);
1719
2/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if(in_struct || in_sub_struct) asar_throw_error(0, error_type_block, error_id_spcblock_inside_struct);
1720
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(numwords < 2) asar_throw_error(0, error_type_block, error_id_spcblock_too_few_args);
1721
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(numwords > 4) asar_throw_error(0, error_type_block, error_id_spcblock_too_many_args);
1722
1723
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 spcblock.destination = getnum(par);
1724 6 spcblock.type = spcblock_nspc;
1725 spcblock.macro_name = "";
1726
1727
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 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 6 times.
6 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 6 times.
6 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 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 switch(spcblock.type)
1751 {
1752 6 case spcblock_nspc:
1753 6 spcblock.size_address=realsnespos;
1754
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(0x0000);
1755
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(spcblock.destination);
1756 6 snespos=(int)spcblock.destination;
1757 6 startpos=(int)spcblock.destination;
1758 6 spcblock.execute_address = -1u;
1759 6 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 9 ns = STR":SPCBLOCK:_" + ns_backup;
1774 6 in_spcblock = true;
1775 }
1776
4/4
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 2424 times.
✓ Branch 2 taken 246 times.
✓ Branch 3 taken 6 times.
2676 else if(is0("endspcblock"))
1777 {
1778
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(!in_spcblock) asar_throw_error(0, error_type_block, error_id_endspcblock_without_spcblock);
1779
1780
1/3
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 switch(spcblock.type)
1781 {
1782 6 case spcblock_nspc:
1783
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==2)
1784 {
1785 2 int pcpos=snestopc(spcblock.size_address&0xFFFFFF);
1786
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (pcpos<0) asar_throw_error(2, error_type_block, error_id_snes_address_doesnt_map_to_rom, hex6((unsigned int)realsnespos).data());
1787 2 int num=snespos-startpos;
1788
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata_byte(pcpos, (unsigned char)num);
1789
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata_byte(pcpos+1, (unsigned char)(num >> 8));
1790 }
1791
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(spcblock.execute_address != -1u)
1792 {
1793
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write2(0x0000);
1794
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 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 6 in_spcblock = false;
1806 }
1807
4/4
✓ Branch 0 taken 2268 times.
✓ Branch 1 taken 402 times.
✓ Branch 2 taken 2262 times.
✓ Branch 3 taken 6 times.
2670 else if (is1("startpos"))
1808 {
1809
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(!in_spcblock) asar_throw_error(0, error_type_block, error_id_startpos_without_spcblock);
1810
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 spcblock.execute_address=getnum64(par);
1811 }
1812
4/4
✓ Branch 0 taken 2262 times.
✓ Branch 1 taken 402 times.
✓ Branch 2 taken 2178 times.
✓ Branch 3 taken 84 times.
2664 else if (is1("base"))
1813 {
1814
4/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 27 times.
84 if (!stricmp(par, "off"))
1815 {
1816 30 snespos=realsnespos;
1817 30 startpos=realstartpos;
1818 30 return;
1819 }
1820
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 unsigned int num=getnum(par);
1821
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_base_label_invalid);
1822
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if (num&~0xFFFFFF) asar_throw_error(1, error_type_block, error_id_snes_address_out_of_bounds, hex6((unsigned int)num).data());
1823 54 snespos=(int)num;
1824 54 startpos=(int)num;
1825 54 optimizeforbank=-1;
1826 }
1827
4/4
✓ Branch 0 taken 2178 times.
✓ Branch 1 taken 402 times.
✓ Branch 2 taken 2166 times.
✓ Branch 3 taken 12 times.
2580 else if (is1("dpbase"))
1828 {
1829
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 unsigned int num=(int)getnum(par);
1830
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (forwardlabel) asar_throw_error(0, error_type_block, error_id_base_label_invalid);
1831
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (num&~0xFF00) asar_throw_error(1, error_type_block, error_id_bad_dp_base, hex6((unsigned int)num).data());
1832 12 dp_base = (int)num;
1833 }
1834
4/4
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 2448 times.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 30 times.
2568 else if (is2("optimize"))
1835 {
1836
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 6 times.
30 if (!stricmp(par, "dp"))
1837 {
1838
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 6 times.
18 if (!stricmp(word[2], "none"))
1839 {
1840 6 optimize_dp = optimize_dp_flag::NONE;
1841 6 return;
1842 }
1843
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
12 if (!stricmp(word[2], "ram"))
1844 {
1845 6 optimize_dp = optimize_dp_flag::RAM;
1846 6 return;
1847 }
1848
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 if (!stricmp(word[2], "always"))
1849 {
1850 6 optimize_dp = optimize_dp_flag::ALWAYS;
1851 6 return;
1852 }
1853 asar_throw_error(1, error_type_block, error_id_bad_dp_optimize, word[2]);
1854 }
1855
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 if (!stricmp(par, "address"))
1856 {
1857
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if (!stricmp(word[2], "default"))
1858 {
1859 optimize_address = optimize_address_flag::DEFAULT;
1860 return;
1861 }
1862
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
12 if (!stricmp(word[2], "ram"))
1863 {
1864 6 optimize_address = optimize_address_flag::RAM;
1865 6 return;
1866 }
1867
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 if (!stricmp(word[2], "mirrors"))
1868 {
1869 6 optimize_address = optimize_address_flag::MIRRORS;
1870 6 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 2166 times.
✓ Branch 1 taken 372 times.
✓ Branch 2 taken 2166 times.
✗ Branch 3 not taken.
2538 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 2538 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1740 times.
✓ Branch 3 taken 798 times.
✓ Branch 4 taken 1662 times.
✓ Branch 5 taken 78 times.
2538 else if (is("freespace") || is("freecode") || is("freedata"))
1895 {
1896
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 876 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
876 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 876 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
876 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
1898 438 string parstr;
1899
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 780 times.
876 if (numwords==1) parstr="\n";//crappy hack: impossible character to cut out extra commas
1900
1/2
✓ Branch 0 taken 780 times.
✗ Branch 1 not taken.
780 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 798 times.
✓ Branch 1 taken 78 times.
1674 if (is("freecode")) parstr=STR"ram,"+parstr;
1903
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 798 times.
954 if (is("freedata")) parstr=STR"noram,"+parstr;
1904
1/2
✓ Branch 0 taken 876 times.
✗ Branch 1 not taken.
876 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 1752 times.
✓ Branch 1 taken 876 times.
2628 for (int i=0;pars[i];i++)
1911 {
1912
2/2
✓ Branch 0 taken 1656 times.
✓ Branch 1 taken 96 times.
1752 if (pars[i][0]=='\n') {}
1913
4/4
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 429 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 429 times.
1656 else if (!stricmp(pars[i], "ram"))
1914 {
1915
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 798 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
798 if (useram!=-1) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1916 useram=1;
1917 }
1918
4/4
✓ Branch 0 taken 468 times.
✓ Branch 1 taken 390 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 390 times.
858 else if (!stricmp(pars[i], "noram"))
1919 {
1920
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
78 if (useram!=-1) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1921 useram=0;
1922 }
1923
4/8
✓ Branch 0 taken 780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 780 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 390 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 390 times.
✗ Branch 7 not taken.
780 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
4/4
✓ Branch 0 taken 393 times.
✓ Branch 1 taken 387 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 387 times.
780 else if (!stricmp(pars[i], "align"))
1930 {
1931
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (align) asar_throw_error(0, error_type_block, error_id_invalid_freespace_request);
1932 align=true;
1933 }
1934
2/4
✓ Branch 0 taken 774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 387 times.
✗ Branch 3 not taken.
774 else if (!stricmp(pars[i], "cleaned"))
1935 {
1936
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 774 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
774 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 876 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
876 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 876 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
876 if (mapper == norom) asar_throw_error(0, error_type_block, error_id_no_freespace_norom);
1946 876 freespaceend();
1947
1/2
✓ Branch 0 taken 876 times.
✗ Branch 1 not taken.
876 freespaceid=getfreespaceid();
1948 876 freespacebyte[freespaceid] = fsbyte;
1949
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 584 times.
876 if (pass==0) snespos=(freespaceid<<24)|0x8000;
1950
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 584 times.
876 if (pass==1)
1951 {
1952
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 292 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
292 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 292 times.
✗ Branch 1 not taken.
292 else freespacepos[freespaceid]=snespos=(freespaceid<<24)|getsnesfreespace(freespacelen[freespaceid], (useram != 0), true, true, align, freespacebyte[freespaceid]);
1960 }
1961
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 584 times.
876 if (pass==2)
1962 {
1963
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 292 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
292 if (fixedpos && freespaceorgpos[freespaceid]==-1) return;//to kill some errors
1964 292 snespos=(freespaceid<<24)|freespacepos[freespaceid];
1965
1/2
✓ Branch 0 taken 292 times.
✗ Branch 1 not taken.
292 resizerats(snespos&0xFFFFFF, freespacelen[freespaceid]);
1966
3/6
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
292 if (freespaceleak[freespaceid] && leakwarn) asar_throw_warning(2, warning_id_freespace_leaked);
1967
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 292 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
292 if (fixedpos && freespaceorgpos[freespaceid]>0 && freespacelen[freespaceid]>freespaceorglen[freespaceid])
1968 asar_throw_error(2, error_type_block, error_id_static_freespace_growing);
1969 292 freespaceuse+=8+freespacelen[freespaceid];
1970 }
1971 876 freespacestatic[freespaceid]=fixedpos;
1972
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 876 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
876 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 876 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
876 if (snespos < 0) asar_throw_error(pass, error_type_fatal, error_id_no_freespace, dec(freespacelen[freespaceid]).data());
1974 876 bytes+=8;
1975 876 freespacestart=snespos;
1976 876 startpos=snespos;
1977 876 realstartpos=snespos;
1978 876 realsnespos=snespos;
1979 876 optimizeforbank=-1;
1980 876 ratsmetastate=ratsmeta_allow;
1981 876 }
1982
4/4
✓ Branch 0 taken 1386 times.
✓ Branch 1 taken 276 times.
✓ Branch 2 taken 1332 times.
✓ Branch 3 taken 54 times.
1662 else if (is1("prot"))
1983 {
1984
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
1985
2/6
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
54 if (!confirmqpar(par)) asar_throw_error(0, error_type_block, error_id_mismatched_parentheses);
1986
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if (!ratsmetastate) asar_throw_error(2, error_type_block, error_id_prot_not_at_freespace_start);
1987
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 42 times.
54 if (ratsmetastate==ratsmeta_used) step(-5);
1988 int num;
1989
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 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 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if (num * 3 > 255) asar_throw_error(0, error_type_block, error_id_prot_too_many_entries);
1995
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 write1((unsigned int)(num*3));
1996
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 54 times.
120 for (int i=0;i<num;i++)
1997 {
1998 //int num=getnum(pars[i]);
1999 66 const char * labeltest=pars[i];
2000 33 string testlabel = labeltest;
2001
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 int labelnum=(int)labelval(&labeltest).pos;
2002
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
66 if (*labeltest) asar_throw_error(0, error_type_block, error_id_label_not_found, testlabel.data());
2003
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
66 write3((unsigned int)labelnum);
2004
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 44 times.
66 if (pass==1) freespaceleak[labelnum >>24]=false;
2005 66 }
2006 write1('S');
2007 write1('T');
2008 write1('O');
2009 write1('P');
2010 write1(0);
2011 54 ratsmetastate=ratsmeta_used;
2012 54 }
2013
13/16
✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 276 times.
✓ Branch 2 taken 1332 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 90 times.
✓ Branch 5 taken 1518 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 54 times.
✓ Branch 8 taken 1332 times.
✓ Branch 9 taken 222 times.
✓ Branch 10 taken 1332 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 36 times.
✓ Branch 13 taken 1518 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 36 times.
1608 else if (is1("autoclean") || is2("autoclean") || is1("autoclear") || is2("autoclear"))
2014 {
2015
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 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 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 54 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
54 if (is1("autoclear") || is2("autoclear")) asar_throw_warning(0, warning_id_autoclear_deprecated);
2017
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 if (numwords==3)
2018 {
2019
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if ((unsigned int)snespos & 0xFF000000) asar_throw_error(0, error_type_block, error_id_autoclean_in_freespace);
2020 54 const char * labeltest = word[2];
2021 27 string testlabel = labeltest;
2022
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 int num=(int)labelval(&labeltest).pos;
2023
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 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 18 times.
✓ Branch 1 taken 36 times.
54 if (pass==1) freespaceleak[targetid]=false;
2026 54 num&=0xFFFFFF;
2027
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
54 if (strlen(par)>3 && !stricmp(par+3, ".l")) par[3]=0;
2028
6/8
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12 times.
54 if (!stricmp(par, "JSL") || !stricmp(par, "JML"))
2029 {
2030 54 int orgpos=read3(snespos+1);
2031 54 int ratsloc=freespaceorgpos[targetid];
2032
4/4
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 15 times.
54 int firstbyte = ((!stricmp(par, "JSL")) ? 0x22 : 0x5C);
2033 27 int pcpos=snestopc(snespos);
2034
4/6
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 36 times.
54 if (/*pass==1 && */pcpos>=0 && pcpos<romlen_r && romdata_r[pcpos]==firstbyte)
2035 {
2036
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 ratsloc=ratsstart(orgpos)+8;
2037 18 freespaceorglen[targetid]=read2(ratsloc-4)+1;
2038
4/6
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
18 if (!freespacestatic[targetid] && pass==1) removerats(orgpos, freespacebyte[targetid]);
2039 }
2040 36 else if (ratsloc<0) ratsloc=0;
2041
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 write1((unsigned int)firstbyte);
2042
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 write3((unsigned int)num);
2043
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 36 times.
54 if (pass==2)
2044 {
2045
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 int start=ratsstart(num);
2046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 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 18 times.
✗ Branch 1 not taken.
18 addressToLineMapping.includeMapping(thisfilename.data(), thisline + 1, addrToLinePos);
2053 }
2054 //freespaceorglen[targetid]=read2(ratsloc-4)+1;
2055 54 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 54 }
2076 else if (pass==0) removerats((int)getnum(word[1]), 0x00);
2077 }
2078
4/4
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 6 times.
1554 else if (is0("pushpc"))
2079 {
2080
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
2081 6 pushpc[pushpcnum].arch=arch;
2082 6 pushpc[pushpcnum].snespos=snespos;
2083 6 pushpc[pushpcnum].snesstart=startpos;
2084 6 pushpc[pushpcnum].snesposreal=realsnespos;
2085 6 pushpc[pushpcnum].snesstartreal=realstartpos;
2086 6 pushpc[pushpcnum].freeid=freespaceid;
2087 6 pushpc[pushpcnum].freeex=freespaceextra;
2088 6 pushpc[pushpcnum].freest=freespacestart;
2089 6 pushpcnum++;
2090 6 snespos=(int)0xFFFFFFFF;
2091 6 startpos= (int)0xFFFFFFFF;
2092 6 realsnespos= (int)0xFFFFFFFF;
2093 6 realstartpos= (int)0xFFFFFFFF;
2094 }
2095
4/4
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 6 times.
1548 else if (is0("pullpc"))
2096 {
2097
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (!pushpcnum) asar_throw_error(0, error_type_block, error_id_pullpc_without_pushpc);
2098 6 pushpcnum--;
2099 6 freespaceend();
2100
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (arch != pushpc[pushpcnum].arch) asar_throw_error(0, error_type_block, error_id_pullpc_different_arch);
2101 6 snespos=pushpc[pushpcnum].snespos;
2102 6 startpos=pushpc[pushpcnum].snesstart;
2103 6 realsnespos=pushpc[pushpcnum].snesposreal;
2104 6 realstartpos=pushpc[pushpcnum].snesstartreal;
2105 6 freespaceid=pushpc[pushpcnum].freeid;
2106 6 freespaceextra=pushpc[pushpcnum].freeex;
2107 6 freespacestart=pushpc[pushpcnum].freest;
2108 }
2109
4/4
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 132 times.
✓ Branch 3 taken 6 times.
1542 else if (is0("pushbase"))
2110 {
2111
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
2112 6 basestack[basestacknum] = snespos;
2113 6 basestacknum++;
2114 }
2115
4/4
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 6 times.
1536 else if (is0("pullbase"))
2116 {
2117
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (!basestacknum) asar_throw_error(0, error_type_block, error_id_pullbase_without_pushbase);
2118 6 basestacknum--;
2119 6 snespos = basestack[basestacknum];
2120 6 startpos = basestack[basestacknum];
2121
2122
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (snespos != realstartpos)
2123 {
2124 6 optimizeforbank = -1;
2125 }
2126 }
2127
4/4
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 12 times.
1530 else if (is0("pushns"))
2128 {
2129
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2130 12 pushns[pushnsnum].ns = ns;
2131
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 for(int i = 0; i < namespace_list.count; i++)
2132 {
2133 12 pushns[pushnsnum].namespace_list.append(namespace_list[i]);
2134 }
2135 12 pushns[pushnsnum].nested_namespaces = nested_namespaces;
2136 12 pushnsnum++;
2137
2138 12 namespace_list.reset();
2139 ns = "";
2140 12 nested_namespaces = false;
2141 }
2142
4/4
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 1404 times.
✓ Branch 2 taken 102 times.
✓ Branch 3 taken 12 times.
1518 else if (is0("pullns"))
2143 {
2144
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2145
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (!pushnsnum) asar_throw_error(0, error_type_block, error_id_pullns_without_pushns);
2146 12 pushnsnum--;
2147 12 ns = pushns[pushnsnum].ns;
2148 12 nested_namespaces = pushns[pushnsnum].nested_namespaces;
2149 12 namespace_list.reset();
2150
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 for(int i = 0; i < pushns[pushnsnum].namespace_list.count; i++)
2151 {
2152 24 namespace_list.append(pushns[pushnsnum].namespace_list[i]);
2153 }
2154 }
2155
7/8
✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 174 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 126 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 1344 times.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
1506 else if (is1("namespace") || is2("namespace"))
2156 {
2157
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
162 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2158 bool leave = false;
2159
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 if (par)
2160 {
2161
4/4
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 57 times.
162 if (!stricmp(par, "off"))
2162 {
2163
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
48 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2164 leave = true;
2165 }
2166
4/4
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 39 times.
114 else if (!stricmp(par, "nested"))
2167 {
2168
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
36 if (!word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2169
4/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
36 else if (!stricmp(word[2], "on")) nested_namespaces = true;
2170
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
18 else if (!stricmp(word[2], "off")) nested_namespaces = false;
2171 }
2172 else
2173 {
2174
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
78 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_namespace_use);
2175
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 const char * tmpstr= safedequote(par);
2176
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
78 if (!confirmname(tmpstr)) asar_throw_error(0, error_type_block, error_id_invalid_namespace_name);
2177
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 48 times.
78 if (!nested_namespaces)
2178 {
2179 30 namespace_list.reset();
2180 }
2181 78 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 36 times.
✓ Branch 1 taken 12 times.
48 if (nested_namespaces)
2192 {
2193 36 namespace_list.remove(namespace_list.count - 1);
2194 }
2195 else
2196 {
2197 12 namespace_list.reset();
2198 }
2199 }
2200
2201 // recompute ns
2202 ns = "";
2203
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 162 times.
354 for (int i = 0; i < namespace_list.count; i++)
2204 {
2205 192 ns += namespace_list[i];
2206 192 ns += STR"_";
2207 }
2208 }
2209
4/4
✓ Branch 0 taken 1206 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 1200 times.
✓ Branch 3 taken 6 times.
1344 else if (is1("warnpc"))
2210 {
2211
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 unsigned int maxpos=getnum(par);
2212
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 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 1200 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 1170 times.
✓ Branch 3 taken 30 times.
1338 else if (is1("rep"))
2219 {
2220
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 int rep = (int)getnum64(par);
2221
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24 if (foundlabel) asar_throw_error(0, error_type_block, error_id_rep_label);
2222
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 if (rep<=1)
2223 {
2224
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
18 if(rep < 0){
2225
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(0, warning_id_feature_deprecated, "rep condition < 0", "You probably want conditionals");
2226 }
2227
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (emulatexkas)
2228 {
2229
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 asar_throw_warning(0, warning_id_feature_deprecated, "rep <= 1 xkas behaviour", "You probably want conditionals");
2230
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 if (rep==0) rep=1;
2231
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rep<0) rep=0;
2232 18 repeatnext=rep;
2233 18 return;
2234 }
2235 }
2236
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(0, warning_id_feature_deprecated, "rep X : {command}", "Use while loops, unrolled loops, pseudo opcodes or for loops");
2237 6 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 1170 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 552 times.
✓ Branch 3 taken 618 times.
1308 else if (is1("incsrc"))
2246 {
2247 309 string name;
2248
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 618 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
618 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 618 times.
618 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 618 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
618 if (emulatexkas) name= safedequote(par);
2265
1/2
✓ Branch 0 taken 618 times.
✗ Branch 1 not taken.
927 else name=STR safedequote(par);
2266
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 498 times.
618 assemblefile(name, false);
2267 618 }
2268
8/8
✓ Branch 0 taken 552 times.
✓ Branch 1 taken 138 times.
✓ Branch 2 taken 486 times.
✓ Branch 3 taken 66 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 588 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 30 times.
690 else if (is1("incbin") || is3("incbin"))
2269 {
2270
3/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
72 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 42 times.
✓ Branch 1 taken 30 times.
72 if (strqchr(par, ':'))
2275 {
2276 42 char * lengths=strqchr(par, ':');
2277 42 *lengths=0;
2278 42 lengths++;
2279
3/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 6 times.
42 if(strqpstr(lengths, ".."))
2280 {
2281 // new style ranges
2282
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 char* split = strqpstr(lengths, "..");
2283 36 string start_str(lengths, split-lengths);
2284
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 start = getnum(start_str);
2285
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
36 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2286 30 string end_str(split+2);
2287
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 end = getnum(end_str);
2288
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
30 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2289 42 }
2290 else
2291 {
2292
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 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 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (strchr(lengths, '"')) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2294
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(*lengths=='(') {
2295
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 char* tmp = strqpchr(lengths, '-');
2296
2/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if(!tmp || (*(tmp-1)!=')')) asar_throw_error(0, error_type_block, error_id_broken_incbin);
2297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 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 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
54 if (warnxkas && (strchr(thisfilename, '/') || strchr(thisfilename, '\\')))
2319 asar_throw_warning(0, warning_id_xkas_incsrc_relative);
2320
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 48 times.
54 if (strchr(par, '\\'))
2321 {
2322
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (emulatexkas)
2323 {
2324
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(0, warning_id_feature_deprecated, "xkas style paths", "convert paths to crossplatform style");
2325
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 6 times.
120 for (int i=0;par[i];i++)
2326 {
2327
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 102 times.
114 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 6 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
54 if (emulatexkas) name= safedequote(par);
2335
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
72 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 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
54 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 24 times.
✓ Branch 1 taken 24 times.
48 autoptr<char*> datacopy=data;
2339
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 if (!end) end=len;
2340
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
48 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 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
48 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 6 times.
✓ Branch 1 taken 42 times.
48 if (numwords==4)
2343 {
2344
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 asar_throw_warning(0, warning_id_feature_deprecated, "incbin with target location", "put an org before the incbin");
2345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 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 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==0)
2358 {
2359
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (end - start > 65536) asar_throw_error(0, error_type_block, error_id_incbin_64kb_limit);
2360
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 pos=getpcfreespace(end-start, false, true, false);
2361
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (pos < 0) asar_throw_error(0, error_type_block, error_id_no_freespace, dec(end - start).data());
2362
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 int foundfreespaceid=getfreespaceid();
2363 2 freespacepos[foundfreespaceid]=pctosnes(pos)|(/*fastrom?0x800000:*/0x000000)|(foundfreespaceid <<24);
2364
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 setlabel(word[3], freespacepos[foundfreespaceid]);
2365
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata_bytes(pos, 0xFF, end-start);
2366 }
2367
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==1)
2368 {
2369
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 getfreespaceid();//nothing to do here, but we want to tick the counter
2370 }
2371
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (pass==2)
2372 {
2373
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 int foundfreespaceid =getfreespaceid();
2374
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (freespaceleak[foundfreespaceid]) asar_throw_warning(2, warning_id_freespace_leaked);
2375
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 writeromdata(snestopc(freespacepos[foundfreespaceid]&0xFFFFFF), data+start, end-start);
2376 2 freespaceuse+=8+end-start;
2377 }
2378 }
2379 }
2380 else
2381 {
2382
3/4
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 42 times.
108 for (int i=start;i<end;i++) write1((unsigned int)data[i]);
2383 }
2384 54 }
2385
4/4
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 180 times.
✓ Branch 2 taken 402 times.
✓ Branch 3 taken 36 times.
618 else if (is("skip") || is("fill"))
2386 {
2387
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
216 if(numwords != 2 && numwords != 3 && numwords != 5) asar_throw_error(0, error_type_block, error_id_unknown_command);
2388
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 216 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.
216 if(numwords > 2 && stricmp(word[1], "align")) asar_throw_error(0, error_type_block, error_id_unknown_command);
2389
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 216 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.
216 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 216 times.
216 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 216 times.
✗ Branch 1 not taken.
216 amount = (int)getnum64(par);
2410
5/6
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
216 if (foundlabel && !foundlabel_static) asar_throw_error(0, error_type_block, error_id_no_labels_here);
2411 }
2412
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 30 times.
210 if(is("skip")) step(amount);
2413
3/4
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 258 times.
✓ Branch 3 taken 30 times.
288 else for(int i=0; i < amount; i++) write1(fillbyte[i%12]);
2414
2415 }
2416
3/4
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 102 times.
✗ Branch 3 not taken.
402 else if (is0("cleartable"))
2417 {
2418 cleartable();
2419 }
2420
4/4
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 6 times.
402 else if (is0("pushtable"))
2421 {
2422 6 tablestack.append(table);
2423 }
2424
4/4
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 6 times.
396 else if (is0("pulltable"))
2425 {
2426
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (tablestack.count <= 0) asar_throw_error(0, error_type_block, error_id_pulltable_without_table);
2427 6 table=tablestack[tablestack.count-1];
2428 6 tablestack.remove(tablestack.count-1);
2429 }
2430
3/4
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 270 times.
✗ Branch 3 not taken.
390 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 30 times.
✓ Branch 1 taken 360 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
390 else if (is3("function"))
2466 {
2467 //if (!pass)
2468 //{
2469
3/6
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
30 if (stricmp(word[2], "=")) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2470
2/6
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
30 if (!confirmqpar(word[1])) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2471 30 string line=word[1];
2472
4/8
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
30 clean(line);
2473 30 char * startpar=strqchr(line.data(), '(');
2474
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2475 30 *startpar=0;
2476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 startpar++;
2477
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_invalid_function_name);
2478 30 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 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (endpar[1]) asar_throw_error(0, error_type_block, error_id_broken_function_declaration);
2481 30 *endpar=0;
2482
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 createuserfunc(line, startpar, word[3]);
2483 //}
2484 30 }
2485
4/4
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 174 times.
✓ Branch 3 taken 96 times.
360 else if (is1("print"))
2486 {
2487
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 string out = handle_print(par);
2488
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 if (pass!=2) return;
2489
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 print(out);
2490 96 }
2491
3/4
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 174 times.
✗ Branch 3 not taken.
264 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 174 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 156 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 156 times.
✓ Branch 5 taken 90 times.
✓ Branch 6 taken 156 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 156 times.
✓ Branch 9 taken 90 times.
✓ Branch 10 taken 156 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 156 times.
✓ Branch 13 taken 90 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 156 times.
264 else if (is1("padbyte") || is1("padword") || is1("padlong") || is1("paddword"))
2499 {
2500 int len = 0;
2501
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (is("padbyte")) len=1;
2502
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("padword")) len=2;
2503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("padlong")) len=3;
2504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (is("paddword")) len=4;
2505
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 unsigned int val=getnum(par);
2506
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
18 if(foundlabel && !foundlabel_static) asar_throw_warning(1, warning_id_feature_deprecated, "labels in padbyte", "just... don't.");
2507
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 18 times.
234 for (int i=0;i<12;i+=len)
2508 {
2509 unsigned int tmpval=val;
2510
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 216 times.
432 for (int j=0;j<len;j++)
2511 {
2512 216 padbyte[i+j]=(unsigned char)tmpval;
2513 216 tmpval>>=8;
2514 }
2515 }
2516 }
2517
4/4
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 18 times.
246 else if (is1("pad"))
2518 {
2519
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
18 if ((unsigned int)realsnespos & 0xFF000000) asar_throw_error(0, error_type_block, error_id_pad_in_freespace);
2520
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 int num=(int)getnum(par);
2521
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
18 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 12 times.
✓ Branch 1 taken 6 times.
18 if (num>realsnespos)
2523 {
2524 int end=snestopc(num);
2525 int start=snestopc(realsnespos);
2526 12 int len=end-start;
2527
3/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 12 times.
72 for (int i=0;i<len;i++) write1(padbyte[i%12]);
2528 }
2529 }
2530
16/16
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 120 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 90 times.
✓ Branch 6 taken 114 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 114 times.
✓ Branch 9 taken 90 times.
✓ Branch 10 taken 108 times.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 108 times.
✓ Branch 13 taken 90 times.
✓ Branch 14 taken 6 times.
✓ Branch 15 taken 102 times.
228 else if (is1("fillbyte") || is1("fillword") || is1("filllong") || is1("filldword"))
2531 {
2532 int len = 0;
2533
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
36 if (is("fillbyte")) len=1;
2534
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 if (is("fillword")) len=2;
2535
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 if (is("filllong")) len=3;
2536
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 30 times.
36 if (is("filldword")) len=4;
2537
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 unsigned int val= getnum(par);
2538
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
36 if(foundlabel && !foundlabel_static) asar_throw_warning(1, warning_id_feature_deprecated, "labels in fillbyte", "just... don't");
2539
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 36 times.
330 for (int i=0;i<12;i+=len)
2540 {
2541 unsigned int tmpval=val;
2542
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 294 times.
726 for (int j=0;j<len;j++)
2543 {
2544 432 fillbyte[i+j]=(unsigned char)tmpval;
2545 432 tmpval>>=8;
2546 }
2547 }
2548 }
2549
3/4
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 102 times.
192 else if (is1("arch"))
2550 {
2551
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102 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 102 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102 if (emulatexkas) asar_throw_warning(0, warning_id_convert_to_asar);
2553
4/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 39 times.
102 if (!stricmp(par, "65816")) { arch=arch_65816; return; }
2554
4/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 21 times.
78 if (!stricmp(par, "spc700")) { arch=arch_spc700; return; }
2555
5/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
42 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
4/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 12 times.
36 if (!stricmp(par, "spc700-raw")) {
2557
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 asar_throw_warning(1, warning_id_feature_deprecated, "spc700-raw", " Use arch spc700 with norom");
2558 12 arch=arch_spc700;
2559 12 mapper=norom;
2560 12 mapper_set = false;
2561
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!force_checksum_fix)
2562 12 checksum_fix_enabled = false;
2563 12 return;
2564 }
2565
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
24 if (!stricmp(par, "superfx")) { arch=arch_superfx; return; }
2566 }
2567
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
90 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 90 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
90 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 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 6 times.
90 else if (is0("fastrom"))
2594 {
2595
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 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 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 36 times.
84 else if (is0("{") || is0("}")) {}
2602 else
2603 {
2604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 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 12 times.
12 asar_throw_error(1, error_type_block, error_id_unknown_command);
2611 }
2612 }
2613
2614 875300 }
2615
2616 7330 bool assemblemapper(char** word, int numwords)
2617 {
2618 7330 auto previous_mapper = mapper;
2619 if(0);
2620
4/4
✓ Branch 0 taken 668 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 596 times.
7330 else if (is0("lorom"))
2621 {
2622 //this also makes xkas set snespos to $008000 for some reason
2623 72 mapper=lorom;
2624 }
2625
4/4
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 582 times.
✓ Branch 3 taken 14 times.
7258 else if (is0("hirom"))
2626 {
2627 //xkas makes this point to $C00000
2628 14 mapper=hirom;
2629 }
2630
4/4
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 576 times.
✓ Branch 3 taken 6 times.
7244 else if (is0("exlorom"))
2631 {
2632 6 mapper = exlorom;
2633 }
2634
4/4
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 570 times.
✓ Branch 3 taken 6 times.
7238 else if (is0("exhirom"))
2635 {
2636 6 mapper=exhirom;
2637 }
2638
4/4
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 558 times.
✓ Branch 3 taken 12 times.
7232 else if (is0("sfxrom"))
2639 {
2640 12 mapper=sfxrom;
2641 //fastrom=false;
2642 }
2643
4/4
✓ Branch 0 taken 558 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 540 times.
✓ Branch 3 taken 18 times.
7220 else if (is0("norom"))
2644 {
2645 //$000000 would be the best snespos for this, but I don't care
2646 18 mapper=norom;
2647 //fastrom=false;
2648
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(!force_checksum_fix)
2649 18 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 540 times.
✓ Branch 1 taken 6662 times.
✓ Branch 2 taken 534 times.
✓ Branch 3 taken 6 times.
7202 else if (is0("fullsa1rom"))
2652 {
2653 6 mapper=bigsa1rom;
2654 //fastrom=false;
2655 }
2656
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 7172 times.
7196 else if (is("sa1rom"))
2657 {
2658 //fastrom=false;
2659
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 if (par)
2660 {
2661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (word[2]) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2662
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (!is_digit(par[0]) || par[1]!=',' ||
2663
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 !is_digit(par[2]) || par[3]!=',' ||
2664
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 !is_digit(par[4]) || par[5]!=',' ||
2665
3/6
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
36 !is_digit(par[6]) || par[7]) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2666 int len;
2667 18 autoptr<char**> pars=qpsplit(par, ",", &len);
2668
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
18 if (len!=4) asar_throw_error(0, error_type_block, error_id_invalid_mapper);
2669 18 sa1banks[0]=(par[0]-'0')<<20;
2670 18 sa1banks[1]=(par[2]-'0')<<20;
2671 18 sa1banks[4]=(par[4]-'0')<<20;
2672 18 sa1banks[5]=(par[6]-'0')<<20;
2673 18 }
2674 else
2675 {
2676 6 sa1banks[0]=0<<20;
2677 6 sa1banks[1]=1<<20;
2678 6 sa1banks[4]=2<<20;
2679 6 sa1banks[5]=3<<20;
2680 }
2681 24 mapper=sa1rom;
2682 }
2683
3/4
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 6644 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 528 times.
7172 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 158 times.
158 if(in_spcblock) asar_throw_error(0, error_type_block, error_id_feature_unavaliable_in_spcblock);
2691
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 66 times.
158 if(!mapper_set){
2692 92 mapper_set = true;
2693
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 54 times.
66 }else if(previous_mapper != mapper){
2694 54 asar_throw_warning(1, warning_id_mapper_already_set);
2695 }
2696 return true;
2697 }
2698