asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
603 of 695, 0 excluded
86.8%
Functions:
35 of 38, 0 excluded
92.1%
Branches:
1160 of 2232, 0 excluded
52.0%

main.cpp
Line Branch Exec Source
1 // "because satanism is best defeated by summoning a bigger satan"
2 // ~Alcaro, 2019 (discussing Asar)
3 #include "addr2line.h"
4 #include "asar.h"
5 #include "virtualfile.h"
6 #include "platform/file-helpers.h"
7 #include "assembleblock.h"
8 #include "asar_math.h"
9 #include "macro.h"
10 #include <algorithm>
11 #include <ctime>
12 // randomdude999: remember to also update the .rc files (in res/windows/) when changing this.
13 // Couldn't find a way to automate this without shoving the version somewhere in the CMake files
14 const int asarver_maj=2;
15 const int asarver_min=0;
16 const int asarver_bug=0;
17 const bool asarver_beta=true;
18
19 #ifdef _I_RELEASE
20 extern char blockbetareleases[(!asarver_beta)?1:-1];
21 #endif
22 #ifdef _I_DEBUG
23 extern char blockreleasedebug[(asarver_beta)?1:-1];
24 #endif
25
26 unsigned const char * romdata_r;
27 int romlen_r;
28
29 int pass;
30
31 int optimizeforbank=-1;
32 int optimize_dp = optimize_dp_flag::ALWAYS;
33 int dp_base = 0;
34 int optimize_address = optimize_address_flag::MIRRORS;
35
36 std::vector<callstack_entry> callstack;
37
38 bool errored=false;
39 bool ignoretitleerrors=false;
40
41 int recursioncount=0;
42
43 virtual_filesystem* filesystem = nullptr;
44
45 AddressToLineMapping addressToLineMapping;
46
47 290 int get_version_int()
48 {
49 290 return asarver_maj * 10000 + asarver_min * 100 + asarver_bug;
50 }
51
52 bool setmapper()
53 {
54 int maxscore=-99999;
55 mapper_t bestmap=lorom;
56 mapper_t maps[]={lorom, hirom, exlorom, exhirom};
57 for (size_t mapid=0;mapid<sizeof(maps)/sizeof(maps[0]);mapid++)
58 {
59 mapper=maps[mapid];
60 int score=0;
61 int highbits=0;
62 bool foundnull=false;
63 for (int i=0;i<21;i++)
64 {
65 unsigned char c=romdata[snestopc(0x00FFC0+i)];
66 if (foundnull && c) score-=4;//according to some documents, NUL terminated names are possible - but they shouldn't appear in the middle of the name
67 if (c>=128) highbits++;
68 else if (is_upper(c)) score+=3;
69 else if (c==' ') score+=2;
70 else if (is_digit(c)) score+=1;
71 else if (is_lower(c)) score+=1;
72 else if (c=='-') score+=1;
73 else if (!c) foundnull=true;
74 else score-=3;
75 }
76 if (highbits>0 && highbits<=14) score-=21;//high bits set on some, but not all, bytes = unlikely to be a ROM
77 if ((romdata[snestopc(0x00FFDE)]^romdata[snestopc(0x00FFDC)])!=0xFF ||
78 (romdata[snestopc(0x00FFDF)]^romdata[snestopc(0x00FFDD)])!=0xFF) score=-99999;//checksum doesn't match up to 0xFFFF? Not a ROM.
79 //too lazy to check the real checksum
80 if (score>maxscore)
81 {
82 maxscore=score;
83 bestmap=mapper;
84 }
85 }
86 mapper=bestmap;
87
88 //detect oddball mappers
89 int mapperbyte=romdata[snestopc(0x00FFD5)];
90 int romtypebyte=romdata[snestopc(0x00FFD6)];
91 if (mapper==lorom)
92 {
93 if (mapperbyte==0x23 && (romtypebyte==0x32 || romtypebyte==0x34 || romtypebyte==0x35)) mapper=sa1rom;
94 }
95 return (maxscore>=0);
96 }
97
98
99 bool simple_callstacks = true;
100
101 // Shortens target_path to a relative path, but only if it resides
102 // within base_path or a child directory of it.
103 10353 static string shorten_to_relative_path(const char* base_path, const char* target_path)
104 {
105
3/5
✓ Branch 3 → 4 taken 5351 times.
✗ Branch 3 → 5 not taken.
✓ Branch 3 → 8 taken 5002 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 176 times.
10353 if (stribegin(target_path, base_path)) target_path += strlen(base_path);
106 10353 return target_path;
107 }
108
109 10353 static string get_top_level_directory()
110 {
111 10353 string top_level_file_dir;
112
2/4
✓ Branch 13 → 4 taken 5175 times.
✗ Branch 13 → 14 not taken.
✓ Branch 19 → 4 taken 5178 times.
✗ Branch 19 → 20 not taken.
10353 for (size_t i = 0; i < callstack.size(); ++i)
113 {
114
2/4
✓ Branch 5 → 6 taken 5175 times.
✗ Branch 5 → 11 not taken.
✓ Branch 6 → 7 taken 5178 times.
✗ Branch 6 → 17 not taken.
10353 if (callstack[i].type == callstack_entry_type::FILE)
115 {
116
2/4
✓ Branch 7 → 8 taken 5175 times.
✗ Branch 7 → 16 not taken.
✓ Branch 11 → 12 taken 5178 times.
✗ Branch 11 → 22 not taken.
10353 top_level_file_dir = dir(callstack[i].content);
117 10353 break;
118 }
119 }
120 10353 return top_level_file_dir;
121 }
122
123 10311 static string generate_call_details_string(const char* current_block, const char* current_call, int indentation, bool add_lines)
124 {
125 10311 string e;
126
5/5
✓ Branch 3 → 4 taken 48 times.
✓ Branch 3 → 5 taken 10263 times.
✓ Branch 4 → 5 taken 42 times.
✓ Branch 4 → 42 taken 3 times.
✓ Branch 4 → 63 taken 3 times.
10311 if (current_block != nullptr || current_call != nullptr)
127 {
128 10305 string indent;
129
2/7
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 5151 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5154 times.
✗ Branch 7 → 74 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 105 not taken.
10305 if (add_lines) indent += "|";
130
6/8
✓ Branch 9 → 10 taken 512 times.
✗ Branch 9 → 74 not taken.
✓ Branch 10 → 11 taken 524 times.
✗ Branch 10 → 105 not taken.
✓ Branch 11 → 9 taken 512 times.
✓ Branch 11 → 12 taken 5151 times.
✓ Branch 12 → 10 taken 524 times.
✓ Branch 12 → 13 taken 5154 times.
11341 for (; indentation > 0; --indentation) indent += " ";
131
132
16/28
✓ Branch 12 → 13 taken 5130 times.
✓ Branch 12 → 26 taken 21 times.
✓ Branch 13 → 14 taken 5133 times.
✓ Branch 13 → 37 taken 21 times.
✓ Branch 14 → 15 taken 5130 times.
✗ Branch 14 → 54 not taken.
✓ Branch 15 → 16 taken 5130 times.
✗ Branch 15 → 52 not taken.
✓ Branch 16 → 17 taken 5130 times.
✗ Branch 16 → 50 not taken.
✓ Branch 17 → 18 taken 5130 times.
✗ Branch 17 → 48 not taken.
✓ Branch 18 → 19 taken 5130 times.
✗ Branch 18 → 46 not taken.
✓ Branch 19 → 20 taken 5130 times.
✗ Branch 19 → 44 not taken.
✓ Branch 20 → 21 taken 5133 times.
✗ Branch 20 → 75 not taken.
✓ Branch 21 → 22 taken 5133 times.
✗ Branch 21 → 73 not taken.
✓ Branch 22 → 23 taken 5133 times.
✗ Branch 22 → 71 not taken.
✓ Branch 23 → 24 taken 5133 times.
✗ Branch 23 → 69 not taken.
✓ Branch 24 → 25 taken 5133 times.
✗ Branch 24 → 67 not taken.
✓ Branch 26 → 27 taken 5133 times.
✗ Branch 26 → 65 not taken.
10305 if (current_block != nullptr) e += STR "\n"+indent+"in block: ["+current_block+"]";
133
16/28
✓ Branch 26 → 27 taken 21 times.
✓ Branch 26 → 40 taken 5130 times.
✓ Branch 28 → 29 taken 21 times.
✗ Branch 28 → 69 not taken.
✓ Branch 29 → 30 taken 21 times.
✗ Branch 29 → 67 not taken.
✓ Branch 30 → 31 taken 21 times.
✗ Branch 30 → 65 not taken.
✓ Branch 31 → 32 taken 21 times.
✗ Branch 31 → 63 not taken.
✓ Branch 32 → 33 taken 21 times.
✗ Branch 32 → 61 not taken.
✓ Branch 33 → 34 taken 21 times.
✗ Branch 33 → 59 not taken.
✓ Branch 37 → 38 taken 21 times.
✓ Branch 37 → 61 taken 5133 times.
✓ Branch 44 → 45 taken 21 times.
✗ Branch 44 → 95 not taken.
✓ Branch 45 → 46 taken 21 times.
✗ Branch 45 → 93 not taken.
✓ Branch 46 → 47 taken 21 times.
✗ Branch 46 → 91 not taken.
✓ Branch 47 → 48 taken 21 times.
✗ Branch 47 → 89 not taken.
✓ Branch 48 → 49 taken 21 times.
✗ Branch 48 → 87 not taken.
✓ Branch 50 → 51 taken 21 times.
✗ Branch 50 → 85 not taken.
10305 if (current_call != nullptr) e += STR "\n"+indent+"in macro call: [%"+current_call+"]";
134 10305 }
135 10311 return e;
136 }
137
138 10353 static string get_pretty_filename(const char* current_file)
139 {
140 // RPG Hacker: One could make an argument that we shouldn't shorten paths
141 // here, since some IDEs support jumping to files by double-clicking their
142 // paths. However, AFAIK, no IDE supports this for Asar yet, and if it's
143 // ever desired, we could just make it a command line option. Until then,
144 // I think it's more important to optimize for pretty command line display.
145
4/8
✓ Branch 2 → 3 taken 5175 times.
✗ Branch 2 → 11 not taken.
✓ Branch 3 → 4 taken 5178 times.
✗ Branch 3 → 14 not taken.
✓ Branch 4 → 5 taken 5175 times.
✗ Branch 4 → 9 not taken.
✓ Branch 7 → 8 taken 5178 times.
✗ Branch 7 → 12 not taken.
10353 return shorten_to_relative_path(get_top_level_directory(), current_file);
146 }
147
148 307 static string generate_filename_and_line(const char* current_file, int current_line_no)
149 {
150
2/4
✓ Branch 9 → 10 taken 152 times.
✗ Branch 9 → 22 not taken.
✓ Branch 15 → 16 taken 155 times.
✗ Branch 15 → 34 not taken.
614 return STR current_file
151
24/46
✓ Branch 2 → 3 taken 149 times.
✓ Branch 2 → 7 taken 3 times.
✓ Branch 3 → 4 taken 301 times.
✓ Branch 3 → 11 taken 3 times.
✗ Branch 3 → 25 not taken.
✓ Branch 5 → 6 taken 301 times.
✗ Branch 5 → 25 not taken.
✗ Branch 5 → 38 not taken.
✓ Branch 6 → 8 taken 149 times.
✗ Branch 6 → 25 not taken.
✓ Branch 7 → 8 taken 3 times.
✗ Branch 7 → 25 not taken.
✓ Branch 9 → 10 taken 152 times.
✗ Branch 9 → 38 not taken.
✓ Branch 10 → 11 taken 152 times.
✓ Branch 10 → 12 taken 152 times.
✗ Branch 10 → 20 not taken.
✗ Branch 10 → 38 not taken.
✓ Branch 11 → 12 taken 3 times.
✗ Branch 11 → 38 not taken.
✓ Branch 14 → 15 taken 149 times.
✓ Branch 14 → 16 taken 3 times.
✓ Branch 16 → 17 taken 149 times.
✓ Branch 16 → 18 taken 3 times.
✓ Branch 17 → 18 taken 155 times.
✗ Branch 17 → 32 not taken.
✓ Branch 22 → 23 taken 152 times.
✓ Branch 22 → 24 taken 3 times.
✓ Branch 24 → 25 taken 152 times.
✓ Branch 24 → 26 taken 3 times.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
✓ Branch 26 → 27 taken 152 times.
✓ Branch 26 → 28 taken 3 times.
✓ Branch 28 → 29 taken 152 times.
✓ Branch 28 → 30 taken 3 times.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 31 not taken.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 43 not taken.
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
921 + (current_line_no>=0?STR ":"+dec(current_line_no+1):"");
152 }
153
154 static string format_stack_line(const printable_callstack_entry& entry, int stack_frame_index)
155 {
156 string indent = "\n| ";
157 indent += dec(stack_frame_index);
158 indent += ": ";
159 // RPG Hacker: We'll probably never have a call stack in the
160 // hundreds even, so this very specific, lazy solution suffices.
161 if (stack_frame_index < 100) indent += " ";
162 if (stack_frame_index < 10) indent += " ";
163 return indent
164 + generate_filename_and_line(entry.prettypath, entry.lineno)
165 + entry.details;
166 }
167
168 10046 static void push_stack_line(autoarray<printable_callstack_entry>* out, const char* current_file, const char* current_block, const char* current_call, int current_line_no, int indentation, bool add_lines)
169 {
170 10046 printable_callstack_entry new_entry;
171
2/4
✓ Branch 3 → 4 taken 5023 times.
✗ Branch 3 → 15 not taken.
✓ Branch 4 → 5 taken 5023 times.
✗ Branch 4 → 26 not taken.
10046 new_entry.fullpath = current_file;
172
2/4
✓ Branch 4 → 5 taken 5023 times.
✗ Branch 4 → 13 not taken.
✓ Branch 6 → 7 taken 5023 times.
✗ Branch 6 → 22 not taken.
10046 new_entry.prettypath = get_pretty_filename(current_file);
173 10046 new_entry.lineno = current_line_no;
174
2/4
✓ Branch 7 → 8 taken 5023 times.
✗ Branch 7 → 14 not taken.
✓ Branch 12 → 13 taken 5023 times.
✗ Branch 12 → 24 not taken.
10046 new_entry.details = generate_call_details_string(current_block, current_call, indentation, add_lines);
175
2/4
✓ Branch 10 → 11 taken 5023 times.
✗ Branch 10 → 15 not taken.
✓ Branch 18 → 19 taken 5023 times.
✗ Branch 18 → 26 not taken.
10046 out->append(new_entry);
176 15069 }
177
178 270 void get_current_line_details(string* location, string* details, bool exclude_block)
179 {
180 270 const char* current_file = nullptr;
181 270 const char* current_block = nullptr;
182 270 const char* current_call = nullptr;
183 270 int current_line_no = -1;
184
4/4
✓ Branch 37 → 4 taken 361 times.
✓ Branch 37 → 38 taken 2 times.
✓ Branch 60 → 4 taken 370 times.
✓ Branch 60 → 61 taken 3 times.
736 for (int i = (int)callstack.size()-1; i >= 0 ; --i)
185 {
186
6/10
✓ Branch 5 → 6 taken 131 times.
✗ Branch 5 → 20 not taken.
✓ Branch 5 → 24 taken 128 times.
✓ Branch 5 → 32 taken 102 times.
✗ Branch 5 → 36 not taken.
✓ Branch 6 → 7 taken 134 times.
✗ Branch 6 → 35 not taken.
✓ Branch 6 → 41 taken 131 times.
✓ Branch 6 → 53 taken 105 times.
✗ Branch 6 → 59 not taken.
731 switch (callstack[i].type)
187 {
188 265 case callstack_entry_type::FILE:
189 265 current_file = callstack[i].content;
190
2/4
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 131 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 134 times.
265 if (exclude_block) current_block = nullptr;
191
4/8
✓ Branch 9 → 10 taken 131 times.
✗ Branch 9 → 43 not taken.
✓ Branch 11 → 12 taken 131 times.
✗ Branch 11 → 41 not taken.
✓ Branch 14 → 15 taken 134 times.
✗ Branch 14 → 68 not taken.
✓ Branch 17 → 18 taken 134 times.
✗ Branch 17 → 66 not taken.
265 *location = generate_filename_and_line(get_pretty_filename(current_file), current_line_no);
192 265 *location += ": ";
193
2/4
✓ Branch 16 → 17 taken 131 times.
✗ Branch 16 → 45 not taken.
✓ Branch 28 → 29 taken 134 times.
✗ Branch 28 → 72 not taken.
265 *details = generate_call_details_string(current_block, current_call, 4, false);
194 265 return;
195 case callstack_entry_type::MACRO_CALL:
196 if (current_call == nullptr) current_call = callstack[i].content;
197 break;
198 259 case callstack_entry_type::LINE:
199
6/8
✓ Branch 24 → 25 taken 26 times.
✓ Branch 24 → 28 taken 102 times.
✓ Branch 25 → 26 taken 26 times.
✗ Branch 25 → 28 not taken.
✓ Branch 41 → 42 taken 26 times.
✓ Branch 41 → 47 taken 105 times.
✓ Branch 42 → 43 taken 26 times.
✗ Branch 42 → 47 not taken.
259 if (current_block == nullptr && current_call == nullptr) current_block = callstack[i].content;
200
2/4
✓ Branch 28 → 29 taken 128 times.
✗ Branch 28 → 31 not taken.
✓ Branch 47 → 48 taken 131 times.
✗ Branch 47 → 52 not taken.
259 if (current_line_no == -1) current_line_no = callstack[i].lineno;
201 259 break;
202 207 case callstack_entry_type::BLOCK:
203
2/4
✓ Branch 32 → 33 taken 102 times.
✗ Branch 32 → 35 not taken.
✓ Branch 53 → 54 taken 105 times.
✗ Branch 53 → 58 not taken.
207 if (current_block == nullptr) current_block = callstack[i].content;
204 207 break;
205 }
206 }
207 5 *location = "";
208 5 *details = "";
209 }
210
211 270 void get_full_printable_callstack(autoarray<printable_callstack_entry>* out, int indentation, bool add_lines)
212 {
213 270 out->reset();
214 270 const char* current_file = nullptr;
215 270 const char* current_block = nullptr;
216 270 const char* current_call = nullptr;
217 270 int current_line_no = -1;
218
4/4
✓ Branch 19 → 4 taken 15451 times.
✓ Branch 19 → 20 taken 133 times.
✓ Branch 31 → 5 taken 15460 times.
✓ Branch 31 → 32 taken 137 times.
31181 for (size_t i = 0; i < callstack.size(); ++i)
219 {
220
8/10
✓ Branch 5 → 6 taken 5154 times.
✓ Branch 5 → 10 taken 21 times.
✓ Branch 5 → 12 taken 5151 times.
✓ Branch 5 → 15 taken 5125 times.
✗ Branch 5 → 17 not taken.
✓ Branch 7 → 8 taken 5157 times.
✓ Branch 7 → 14 taken 21 times.
✓ Branch 7 → 18 taken 5154 times.
✓ Branch 7 → 25 taken 5128 times.
✗ Branch 7 → 29 not taken.
30911 switch (callstack[i].type)
221 {
222 10311 case callstack_entry_type::FILE:
223
4/4
✓ Branch 6 → 7 taken 5023 times.
✓ Branch 6 → 8 taken 131 times.
✓ Branch 8 → 9 taken 5023 times.
✓ Branch 8 → 10 taken 134 times.
10311 if (current_file != nullptr)
224 {
225 10046 push_stack_line(out, current_file, current_block, current_call, current_line_no, indentation, add_lines);
226 }
227 10311 current_file = callstack[i].content;
228 10311 current_block = nullptr;
229 10311 current_call = nullptr;
230 10311 current_line_no = -1;
231 10311 break;
232 42 case callstack_entry_type::MACRO_CALL:
233 42 current_block = nullptr;
234 42 current_call = callstack[i].content;
235 42 break;
236 10305 case callstack_entry_type::LINE:
237 10305 current_line_no = callstack[i].lineno;
238 10305 current_block = callstack[i].content;
239 10305 break;
240 10253 case callstack_entry_type::BLOCK:
241 10253 current_block = callstack[i].content;
242 10253 break;
243 }
244 }
245 270 }
246
247 static string get_full_callstack()
248 {
249 autoarray<printable_callstack_entry> printable_stack;
250 get_full_printable_callstack(&printable_stack, 12, true);
251
252 string e;
253 if (printable_stack.count > 0)
254 {
255 e += "\nFull call stack:";
256 for (int i = printable_stack.count-1; i >= 0; --i)
257 {
258 e += format_stack_line(printable_stack[i], i);
259 }
260 }
261 return e;
262 }
263
264 // RPG Hacker: This function essetially replicates classic Asar behavior
265 // of only printing a single macro call below the current level.
266 270 static string get_simple_callstack()
267 {
268 int i;
269 270 const char* current_call = nullptr;
270
4/4
✓ Branch 9 → 4 taken 15388 times.
✓ Branch 9 → 10 taken 112 times.
✓ Branch 12 → 4 taken 15397 times.
✓ Branch 12 → 13 taken 116 times.
31013 for (i = (int)callstack.size()-1; i >= 0 ; --i)
271 {
272
4/4
✓ Branch 5 → 6 taken 21 times.
✓ Branch 5 → 8 taken 15367 times.
✓ Branch 6 → 7 taken 21 times.
✓ Branch 6 → 11 taken 15376 times.
30785 if (callstack[i].type == callstack_entry_type::MACRO_CALL)
273 {
274 42 current_call = callstack[i].content;
275 42 break;
276 }
277 }
278
279 270 const char* current_file = nullptr;
280 270 int current_line_no = -1;
281
4/4
✓ Branch 10 → 11 taken 21 times.
✓ Branch 10 → 32 taken 112 times.
✓ Branch 13 → 14 taken 21 times.
✓ Branch 13 → 40 taken 116 times.
270 if (current_call != nullptr)
282 {
283 42 bool stop = false;
284
2/4
✓ Branch 30 → 12 taken 63 times.
✗ Branch 30 → 31 not taken.
✓ Branch 38 → 15 taken 63 times.
✗ Branch 38 → 39 not taken.
126 for (int j = i-1; j >= 0 ; --j)
285 {
286
6/10
✓ Branch 13 → 14 taken 21 times.
✗ Branch 13 → 18 not taken.
✓ Branch 13 → 19 taken 21 times.
✓ Branch 13 → 23 taken 21 times.
✗ Branch 13 → 24 not taken.
✓ Branch 17 → 18 taken 21 times.
✗ Branch 17 → 24 not taken.
✓ Branch 17 → 25 taken 21 times.
✓ Branch 17 → 31 taken 21 times.
✗ Branch 17 → 32 not taken.
126 switch (callstack[j].type)
287 {
288 42 case callstack_entry_type::FILE:
289
2/4
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 21 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 21 times.
42 if (current_file != nullptr)
290 {
291 stop = true;
292 break;
293 }
294 42 current_file = callstack[j].content;
295 42 break;
296 case callstack_entry_type::MACRO_CALL:
297 stop = true;
298 break;
299 42 case callstack_entry_type::LINE:
300
2/4
✓ Branch 19 → 20 taken 21 times.
✗ Branch 19 → 22 not taken.
✓ Branch 25 → 26 taken 21 times.
✗ Branch 25 → 30 not taken.
42 if (current_line_no == -1) current_line_no = callstack[j].lineno;
301 42 break;
302 42 case callstack_entry_type::BLOCK:
303 42 break;
304 }
305
306
6/8
✓ Branch 24 → 25 taken 21 times.
✓ Branch 24 → 27 taken 42 times.
✓ Branch 25 → 26 taken 21 times.
✗ Branch 25 → 27 not taken.
✓ Branch 32 → 33 taken 21 times.
✓ Branch 32 → 35 taken 42 times.
✓ Branch 33 → 34 taken 21 times.
✗ Branch 33 → 35 not taken.
126 if (current_file != nullptr && current_line_no != -1) stop = true;
307
308
4/4
✓ Branch 27 → 28 taken 21 times.
✓ Branch 27 → 29 taken 42 times.
✓ Branch 35 → 36 taken 21 times.
✓ Branch 35 → 37 taken 42 times.
126 if (stop) break;
309 }
310 }
311
312 270 string e;
313
6/8
✓ Branch 33 → 34 taken 21 times.
✓ Branch 33 → 53 taken 112 times.
✓ Branch 34 → 35 taken 21 times.
✗ Branch 34 → 53 not taken.
✓ Branch 41 → 42 taken 21 times.
✓ Branch 41 → 77 taken 116 times.
✓ Branch 42 → 43 taken 21 times.
✗ Branch 42 → 77 not taken.
270 if (current_call != nullptr && current_file != nullptr)
314 {
315
8/16
✓ Branch 35 → 36 taken 21 times.
✗ Branch 35 → 70 not taken.
✓ Branch 37 → 38 taken 21 times.
✗ Branch 37 → 68 not taken.
✓ Branch 39 → 40 taken 21 times.
✗ Branch 39 → 65 not taken.
✓ Branch 40 → 41 taken 21 times.
✗ Branch 40 → 63 not taken.
✓ Branch 49 → 50 taken 21 times.
✗ Branch 49 → 95 not taken.
✓ Branch 52 → 53 taken 21 times.
✗ Branch 52 → 93 not taken.
✓ Branch 56 → 57 taken 21 times.
✗ Branch 56 → 89 not taken.
✓ Branch 57 → 58 taken 21 times.
✗ Branch 57 → 87 not taken.
84 e += STR "\n called from: " + generate_filename_and_line(get_pretty_filename(current_file), current_line_no)
316
8/16
✓ Branch 41 → 42 taken 21 times.
✗ Branch 41 → 61 not taken.
✓ Branch 42 → 43 taken 21 times.
✗ Branch 42 → 59 not taken.
✓ Branch 43 → 44 taken 21 times.
✗ Branch 43 → 57 not taken.
✓ Branch 44 → 45 taken 21 times.
✗ Branch 44 → 55 not taken.
✓ Branch 58 → 59 taken 21 times.
✗ Branch 58 → 85 not taken.
✓ Branch 59 → 60 taken 21 times.
✗ Branch 59 → 83 not taken.
✓ Branch 60 → 61 taken 21 times.
✗ Branch 60 → 81 not taken.
✓ Branch 62 → 63 taken 21 times.
✗ Branch 62 → 79 not taken.
105 + ": [%" + current_call + "]";
317 }
318 270 return e;
319 }
320
321 270 string get_callstack()
322 {
323
3/4
✓ Branch 2 → 3 taken 133 times.
✓ Branch 2 → 4 taken 137 times.
✓ Branch 4 → 5 taken 137 times.
✗ Branch 4 → 7 not taken.
270 if (simple_callstacks)
324 270 return get_simple_callstack();
325 else
326 return get_full_callstack();
327 }
328
329 18 void throw_vfile_error(int whichpass, virtual_file_error vfile_error, const char* filename)
330 {
331
2/5
✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 6 not taken.
✓ Branch 2 → 9 taken 12 times.
✗ Branch 2 → 12 not taken.
✗ Branch 2 → 15 not taken.
18 switch (vfile_error)
332 {
333 6 case vfe_doesnt_exist:
334 6 throw_err_block(whichpass, err_file_not_found, filename);
335 case vfe_access_denied:
336 throw_err_block(whichpass, err_failed_to_open_file_access_denied, filename);
337 12 case vfe_not_regular_file:
338 12 throw_err_block(whichpass, err_failed_to_open_not_regular_file, filename);
339 case vfe_unknown:
340 case vfe_none:
341 case vfe_num_errors:
342 throw_err_block(whichpass, err_failed_to_open_file, filename);
343 }
344
345 throw_err_block(whichpass, err_failed_to_open_file, filename);
346 }
347
348 18 virtual_file_error asar_get_last_io_error()
349 {
350
1/3
✓ Branch 2 → 3 taken 18 times.
✗ Branch 2 → 4 not taken.
✗ Branch 2 → 5 not taken.
18 if (filesystem != nullptr)
351 {
352 18 return filesystem->get_last_error();
353 }
354
355 return vfe_unknown;
356 }
357
358 701 int getlenforlabel(int labelpos, int label_fs_id, bool exists)
359 {
360 701 int bank = labelpos>>16;
361 701 unsigned int word = labelpos&0xFFFF;
362 701 bool lbl_is_freespace = label_fs_id > 0;
363 // bank number for mirroring considerations.
364 // this is the number of a bank which has the same "layout" as the current bank.
365 unsigned int relaxed_bank;
366 // nonnegative if we know that DBR is pointing at a certain bank
367 701 int cur_effective_bank = -1;
368
2/2
✓ Branch 2 → 3 taken 24 times.
✓ Branch 2 → 4 taken 677 times.
701 if(optimizeforbank >= 0) {
369 24 cur_effective_bank = relaxed_bank = optimizeforbank;
370 } else {
371
2/2
✓ Branch 4 → 5 taken 517 times.
✓ Branch 4 → 6 taken 160 times.
677 if(freespaceid == 0) {
372 517 cur_effective_bank = relaxed_bank = snespos >> 16;
373 } else {
374 160 int target_bank = freespaces[freespaceid].bank;
375
4/4
✓ Branch 7 → 8 taken 42 times.
✓ Branch 7 → 9 taken 38 times.
✓ Branch 10 → 11 taken 42 times.
✓ Branch 10 → 12 taken 38 times.
160 if(target_bank == -2) relaxed_bank = 0;
376
4/4
✓ Branch 9 → 10 taken 30 times.
✓ Branch 9 → 11 taken 8 times.
✓ Branch 12 → 13 taken 30 times.
✓ Branch 12 → 14 taken 8 times.
76 else if(target_bank == -1) relaxed_bank = 0x40;
377 16 else cur_effective_bank = relaxed_bank = target_bank;
378 }
379 }
380 // hirom has non-mirrored sram in 6000-7fff, so optimize mirrors shouldn't cover it
381
8/12
✓ Branch 12 → 13 taken 342 times.
✓ Branch 12 → 14 taken 6 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 342 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 353 times.
✓ Branch 17 → 18 taken 347 times.
✓ Branch 17 → 21 taken 6 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 347 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 347 times.
701 unsigned int mirror_bound = (mapper == hirom || mapper == exhirom) ? 0x6000 : 0x8000;
382
383
4/4
✓ Branch 16 → 17 taken 90 times.
✓ Branch 16 → 19 taken 258 times.
✓ Branch 23 → 24 taken 90 times.
✓ Branch 23 → 29 taken 263 times.
701 if(lbl_is_freespace) {
384 180 bank = freespaces[label_fs_id].bank;
385 }
386
387
2/4
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 348 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 353 times.
701 if (!exists)
388 {
389 return 2;
390 }
391
12/16
✓ Branch 21 → 22 taken 6 times.
✓ Branch 21 → 26 taken 342 times.
✓ Branch 22 → 23 taken 3 times.
✓ Branch 22 → 26 taken 3 times.
✓ Branch 23 → 24 taken 3 times.
✗ Branch 23 → 26 not taken.
✓ Branch 24 → 25 taken 3 times.
✗ Branch 24 → 26 not taken.
✓ Branch 31 → 32 taken 6 times.
✓ Branch 31 → 36 taken 347 times.
✓ Branch 32 → 33 taken 3 times.
✓ Branch 32 → 36 taken 3 times.
✓ Branch 33 → 34 taken 3 times.
✗ Branch 33 → 36 not taken.
✓ Branch 34 → 35 taken 3 times.
✗ Branch 34 → 36 not taken.
701 else if((optimize_dp == optimize_dp_flag::RAM) && bank == 0x7E && (word-dp_base < 0x100) && !lbl_is_freespace)
392 {
393 6 return 1;
394 }
395
16/20
✓ Branch 26 → 27 taken 222 times.
✓ Branch 26 → 32 taken 123 times.
✓ Branch 27 → 28 taken 222 times.
✗ Branch 27 → 29 not taken.
✓ Branch 28 → 29 taken 156 times.
✓ Branch 28 → 32 taken 66 times.
✓ Branch 29 → 30 taken 9 times.
✓ Branch 29 → 32 taken 147 times.
✓ Branch 30 → 31 taken 9 times.
✗ Branch 30 → 32 not taken.
✓ Branch 36 → 37 taken 227 times.
✓ Branch 36 → 42 taken 123 times.
✓ Branch 37 → 38 taken 227 times.
✗ Branch 37 → 39 not taken.
✓ Branch 38 → 39 taken 161 times.
✓ Branch 38 → 42 taken 66 times.
✓ Branch 39 → 40 taken 14 times.
✓ Branch 39 → 42 taken 147 times.
✓ Branch 40 → 41 taken 14 times.
✗ Branch 40 → 42 not taken.
695 else if(optimize_dp == optimize_dp_flag::ALWAYS && (bank == 0x7E || !(bank & 0x40)) && (word-dp_base < 0x100) && !lbl_is_freespace)
396 {
397 23 return 1;
398 }
399 672 else if (
400 // if we should optimize ram accesses...
401
8/8
✓ Branch 32 → 33 taken 318 times.
✓ Branch 32 → 34 taken 18 times.
✓ Branch 33 → 34 taken 264 times.
✓ Branch 33 → 39 taken 54 times.
✓ Branch 42 → 43 taken 318 times.
✓ Branch 42 → 44 taken 18 times.
✓ Branch 43 → 44 taken 264 times.
✓ Branch 43 → 49 taken 54 times.
672 (optimize_address == optimize_address_flag::RAM || optimize_address == optimize_address_flag::MIRRORS)
402 // and we're in a bank with ram mirrors... (optimizeforbank=0x7E is checked later)
403
4/4
✓ Branch 34 → 35 taken 258 times.
✓ Branch 34 → 39 taken 24 times.
✓ Branch 44 → 45 taken 258 times.
✓ Branch 44 → 49 taken 24 times.
564 && !(relaxed_bank & 0x40)
404 // and the label is in low RAM
405
8/12
✓ Branch 35 → 36 taken 9 times.
✓ Branch 35 → 39 taken 249 times.
✓ Branch 36 → 37 taken 9 times.
✗ Branch 36 → 39 not taken.
✓ Branch 37 → 38 taken 9 times.
✗ Branch 37 → 39 not taken.
✓ Branch 45 → 46 taken 9 times.
✓ Branch 45 → 49 taken 249 times.
✓ Branch 46 → 47 taken 9 times.
✗ Branch 46 → 49 not taken.
✓ Branch 47 → 48 taken 9 times.
✗ Branch 47 → 49 not taken.
516 && bank == 0x7E && word < 0x2000 && !lbl_is_freespace)
406 {
407 18 return 2;
408 }
409 654 else if (
410 // if we should optimize mirrors...
411
4/4
✓ Branch 39 → 40 taken 261 times.
✓ Branch 39 → 45 taken 66 times.
✓ Branch 49 → 50 taken 261 times.
✓ Branch 49 → 55 taken 66 times.
654 optimize_address == optimize_address_flag::MIRRORS
412 // we're in a bank with ram mirrors...
413
4/4
✓ Branch 40 → 41 taken 240 times.
✓ Branch 40 → 45 taken 21 times.
✓ Branch 50 → 51 taken 240 times.
✓ Branch 50 → 55 taken 21 times.
522 && !(relaxed_bank & 0x40)
414 // and the label is in a mirrored section
415
12/12
✓ Branch 41 → 42 taken 176 times.
✓ Branch 41 → 45 taken 64 times.
✓ Branch 42 → 43 taken 15 times.
✓ Branch 42 → 45 taken 161 times.
✓ Branch 43 → 44 taken 12 times.
✓ Branch 43 → 45 taken 3 times.
✓ Branch 51 → 52 taken 176 times.
✓ Branch 51 → 55 taken 64 times.
✓ Branch 52 → 53 taken 15 times.
✓ Branch 52 → 55 taken 161 times.
✓ Branch 53 → 54 taken 12 times.
✓ Branch 53 → 55 taken 3 times.
480 && !(bank & 0x40) && word < mirror_bound && !lbl_is_freespace)
416 {
417 24 return 2;
418 }
419
4/4
✓ Branch 45 → 46 taken 12 times.
✓ Branch 45 → 49 taken 303 times.
✓ Branch 55 → 56 taken 12 times.
✓ Branch 55 → 59 taken 303 times.
630 else if (optimizeforbank>=0)
420 {
421 // if optimizing for a specific bank:
422 // if the label is in freespace, then bank is the freespace's bank, and
423 // if that's non-negative, then the freespace is forced to that bank.
424 // if the freespace isn't forced to a specific bank, then bank is
425 // negative, so this equality will never hold.
426
4/4
✓ Branch 46 → 47 taken 6 times.
✓ Branch 46 → 48 taken 6 times.
✓ Branch 56 → 57 taken 6 times.
✓ Branch 56 → 58 taken 6 times.
24 if (bank == optimizeforbank) return 2;
427 12 else return 3;
428 }
429
430 // check if the label is pinned to the current freespace.
431 // can only be checked after pass 0, as freespace pin targets aren't
432 // computed before then.
433 // This codepath also handles the case of labels that are in the current freespace.
434
12/12
✓ Branch 49 → 50 taken 232 times.
✓ Branch 49 → 56 taken 71 times.
✓ Branch 50 → 51 taken 82 times.
✓ Branch 50 → 56 taken 150 times.
✓ Branch 51 → 52 taken 30 times.
✓ Branch 51 → 56 taken 52 times.
✓ Branch 59 → 60 taken 232 times.
✓ Branch 59 → 72 taken 71 times.
✓ Branch 60 → 61 taken 82 times.
✓ Branch 60 → 72 taken 150 times.
✓ Branch 61 → 62 taken 30 times.
✓ Branch 61 → 72 taken 52 times.
606 if(pass > 0 && lbl_is_freespace && freespaceid > 0) {
435 60 int fs_pin_1 = freespaces[label_fs_id].pin_target_id;
436 60 int fs_pin_2 = freespaces[freespaceid].pin_target_id;
437
4/4
✓ Branch 54 → 55 taken 16 times.
✓ Branch 54 → 56 taken 14 times.
✓ Branch 70 → 71 taken 16 times.
✓ Branch 70 → 72 taken 14 times.
60 if(fs_pin_1 == fs_pin_2) return 2;
438 }
439
440
8/8
✓ Branch 56 → 57 taken 221 times.
✓ Branch 56 → 59 taken 66 times.
✓ Branch 57 → 58 taken 171 times.
✓ Branch 57 → 59 taken 50 times.
✓ Branch 72 → 73 taken 221 times.
✓ Branch 72 → 75 taken 66 times.
✓ Branch 73 → 74 taken 171 times.
✓ Branch 73 → 75 taken 50 times.
574 if (bank >= 0 && bank == cur_effective_bank) return 2;
441 232 else return 3;
442 }
443 689 int getlenforlabel(snes_label thislabel, bool exists) {
444 689 return getlenforlabel(thislabel.pos, thislabel.freespace_id, exists);
445 }
446
447
448 315 bool is_hex_constant(const char* str){
449
4/4
✓ Branch 2 → 3 taken 108 times.
✓ Branch 2 → 9 taken 48 times.
✓ Branch 3 → 4 taken 108 times.
✓ Branch 3 → 14 taken 51 times.
315 if (*str=='$')
450 {
451 216 str++;
452
4/4
✓ Branch 6 → 4 taken 300 times.
✓ Branch 6 → 7 taken 108 times.
✓ Branch 10 → 6 taken 300 times.
✓ Branch 10 → 11 taken 108 times.
816 while(is_xdigit(*str)) {
453 600 str++;
454 }
455
2/4
✓ Branch 7 → 8 taken 108 times.
✗ Branch 7 → 9 not taken.
✓ Branch 12 → 13 taken 108 times.
✗ Branch 12 → 14 not taken.
216 if(*str=='\0'){
456 216 return true;
457 }
458 }
459 99 return false;
460 }
461
462 struct strcompare {
463 bool operator() (const char * lhs, const char * rhs) const
464 {
465 return strcmp(lhs, rhs)<0;
466 }
467 };
468
469 struct stricompare {
470 bool operator() (const char * lhs, const char * rhs) const
471 {
472 return stricmp(lhs, rhs)<0;
473 }
474 };
475
476 struct sourcefile {
477 char *data;
478 char** contents;
479 int numlines;
480 };
481
482 static assocarr<sourcefile> filecontents;
483 assocarr<string> defines;
484 // needs to be separate because defines is reset between parsing arguments and patching
485 assocarr<string> clidefines;
486 assocarr<string> builtindefines;
487
488 201 bool validatedefinename(const char * name)
489 {
490
2/4
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 96 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 105 times.
201 if (!name[0]) return false;
491
4/4
✓ Branch 9 → 5 taken 429 times.
✓ Branch 9 → 10 taken 96 times.
✓ Branch 14 → 6 taken 479 times.
✓ Branch 14 → 15 taken 105 times.
1109 for (int i = 0;name[i];i++)
492 {
493
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 429 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 479 times.
908 if (!is_ualnum(name[i])) return false;
494 }
495
496 201 return true;
497 }
498
499 67435 void resolvedefines(string& out, const char * start)
500 {
501
4/4
✓ Branch 2 → 3 taken 33578 times.
✓ Branch 2 → 264 taken 1 time.
✓ Branch 3 → 4 taken 33855 times.
✓ Branch 3 → 381 taken 1 time.
67435 recurseblock rec;
502 67433 const char * here=start;
503
5/6
✓ Branch 3 → 4 taken 28358 times.
✓ Branch 3 → 6 taken 5220 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 33855 times.
✓ Branch 6 → 7 taken 28603 times.
✓ Branch 6 → 10 taken 5252 times.
67433 if (!strchr(here, '!'))
504 {
505
2/4
✓ Branch 4 → 5 taken 28358 times.
✗ Branch 4 → 262 not taken.
✓ Branch 8 → 9 taken 28603 times.
✗ Branch 8 → 379 not taken.
56961 out += here;
506 56961 return;
507 }
508
4/4
✓ Branch 223 → 7 taken 35955 times.
✓ Branch 223 → 224 taken 5205 times.
✓ Branch 326 → 11 taken 36278 times.
✓ Branch 326 → 327 taken 5236 times.
82674 while (*here)
509 {
510
8/8
✓ Branch 7 → 8 taken 24 times.
✓ Branch 7 → 13 taken 35931 times.
✓ Branch 8 → 9 taken 3 times.
✓ Branch 8 → 13 taken 21 times.
✓ Branch 12 → 13 taken 24 times.
✓ Branch 12 → 23 taken 36254 times.
✓ Branch 15 → 16 taken 3 times.
✓ Branch 15 → 23 taken 21 times.
72233 if (here[0] == '\\' && here[1] == '\\')
511 {
512 // allow using \\ as escape sequence
513
2/8
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 3 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 262 not taken.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 19 taken 3 times.
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 379 not taken.
6 if (in_macro_def > 0) out += "\\";
514
2/4
✓ Branch 11 → 12 taken 3 times.
✗ Branch 11 → 262 not taken.
✓ Branch 20 → 21 taken 3 times.
✗ Branch 20 → 379 not taken.
6 out += "\\";
515 6 here += 2;
516 }
517
6/8
✓ Branch 13 → 14 taken 21 times.
✓ Branch 13 → 19 taken 35931 times.
✓ Branch 14 → 15 taken 21 times.
✗ Branch 14 → 19 not taken.
✓ Branch 24 → 25 taken 21 times.
✓ Branch 24 → 35 taken 36254 times.
✓ Branch 27 → 28 taken 21 times.
✗ Branch 27 → 35 not taken.
72227 else if (here[0] == '\\' && here[1] == '!')
518 {
519 // allow using \! to escape !
520
6/8
✓ Branch 15 → 16 taken 6 times.
✓ Branch 15 → 17 taken 15 times.
✓ Branch 16 → 17 taken 6 times.
✗ Branch 16 → 262 not taken.
✓ Branch 28 → 29 taken 6 times.
✓ Branch 28 → 31 taken 15 times.
✓ Branch 30 → 31 taken 6 times.
✗ Branch 30 → 379 not taken.
42 if (in_macro_def > 0) out += "\\";
521
2/4
✓ Branch 17 → 18 taken 21 times.
✗ Branch 17 → 262 not taken.
✓ Branch 32 → 33 taken 21 times.
✗ Branch 32 → 379 not taken.
42 out+="!";
522 42 here += 2;
523 }
524
4/4
✓ Branch 19 → 20 taken 5601 times.
✓ Branch 19 → 221 taken 30330 times.
✓ Branch 36 → 37 taken 5645 times.
✓ Branch 36 → 320 taken 30609 times.
72185 else if (*here=='!')
525 {
526
20/20
✓ Branch 20 → 21 taken 2727 times.
✓ Branch 20 → 25 taken 2874 times.
✓ Branch 21 → 22 taken 1692 times.
✓ Branch 21 → 26 taken 1035 times.
✓ Branch 22 → 23 taken 1299 times.
✓ Branch 22 → 26 taken 393 times.
✓ Branch 23 → 24 taken 60 times.
✓ Branch 23 → 26 taken 1239 times.
✓ Branch 24 → 25 taken 6 times.
✓ Branch 24 → 26 taken 54 times.
✓ Branch 37 → 38 taken 2759 times.
✓ Branch 37 → 49 taken 2886 times.
✓ Branch 39 → 40 taken 1721 times.
✓ Branch 39 → 50 taken 1038 times.
✓ Branch 42 → 43 taken 1304 times.
✓ Branch 42 → 50 taken 417 times.
✓ Branch 45 → 46 taken 60 times.
✓ Branch 45 → 50 taken 1244 times.
✓ Branch 48 → 49 taken 6 times.
✓ Branch 48 → 50 taken 54 times.
11246 bool first=(here==start || (here>=start+4 && here[-1]==' ' && here[-2]==':' && here[-3]==' '));//check if it's the start of a block
527 11246 string defname;
528 11246 here++;
529
530 11246 int depth = 0;
531
4/4
✓ Branch 30 → 29 taken 57 times.
✓ Branch 30 → 31 taken 5601 times.
✓ Branch 58 → 55 taken 57 times.
✓ Branch 58 → 59 taken 5645 times.
11360 for (const char* depth_str = here; *depth_str=='^'; depth_str++)
532 {
533 114 depth++;
534 }
535 11246 here += depth;
536
537
4/4
✓ Branch 31 → 32 taken 660 times.
✓ Branch 31 → 42 taken 4941 times.
✓ Branch 60 → 61 taken 660 times.
✓ Branch 60 → 73 taken 4985 times.
11246 if (depth != in_macro_def)
538 {
539
2/4
✓ Branch 32 → 33 taken 660 times.
✗ Branch 32 → 259 not taken.
✓ Branch 62 → 63 taken 660 times.
✗ Branch 62 → 375 not taken.
1320 out += '!';
540
6/8
✓ Branch 34 → 35 taken 33 times.
✗ Branch 34 → 259 not taken.
✓ Branch 36 → 34 taken 33 times.
✓ Branch 36 → 37 taken 660 times.
✓ Branch 65 → 66 taken 33 times.
✗ Branch 65 → 375 not taken.
✓ Branch 67 → 64 taken 33 times.
✓ Branch 67 → 68 taken 660 times.
1386 for (int i=0; i < depth; ++i) out += '^';
541
6/8
✓ Branch 37 → 38 taken 9 times.
✓ Branch 37 → 41 taken 651 times.
✓ Branch 38 → 39 taken 9 times.
✗ Branch 38 → 259 not taken.
✓ Branch 68 → 69 taken 9 times.
✓ Branch 68 → 72 taken 651 times.
✓ Branch 69 → 70 taken 9 times.
✗ Branch 69 → 375 not taken.
1320 if (depth > in_macro_def) throw_err_line(0, err_invalid_depth_resolve, "define", "define", depth, in_macro_def);
542 1302 continue;
543 1302 }
544
545
4/4
✓ Branch 42 → 43 taken 54 times.
✓ Branch 42 → 67 taken 4887 times.
✓ Branch 74 → 75 taken 54 times.
✓ Branch 74 → 107 taken 4931 times.
9926 if (*here=='{')
546 {
547 108 here++;
548 108 string unprocessedname;
549 108 int braces=1;
550 while (true)
551 {
552
4/4
✓ Branch 45 → 46 taken 36 times.
✓ Branch 45 → 47 taken 540 times.
✓ Branch 80 → 81 taken 36 times.
✓ Branch 80 → 82 taken 540 times.
1152 if (*here=='{') braces++;
553
4/4
✓ Branch 47 → 48 taken 90 times.
✓ Branch 47 → 49 taken 486 times.
✓ Branch 83 → 84 taken 90 times.
✓ Branch 83 → 85 taken 486 times.
1152 if (*here=='}') braces--;
554
2/8
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 53 taken 576 times.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 231 not taken.
✗ Branch 86 → 87 not taken.
✓ Branch 86 → 90 taken 576 times.
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 335 not taken.
1152 if (!*here) throw_err_line(0, err_mismatched_braces);
555
4/4
✓ Branch 53 → 54 taken 54 times.
✓ Branch 53 → 55 taken 522 times.
✓ Branch 90 → 91 taken 54 times.
✓ Branch 90 → 92 taken 522 times.
1152 if (!braces) break;
556
2/4
✓ Branch 55 → 56 taken 522 times.
✗ Branch 55 → 231 not taken.
✓ Branch 94 → 95 taken 522 times.
✗ Branch 94 → 335 not taken.
1044 unprocessedname+=*here++;
557 }
558 108 here++;
559
2/4
✓ Branch 58 → 59 taken 54 times.
✗ Branch 58 → 231 not taken.
✓ Branch 98 → 99 taken 54 times.
✗ Branch 98 → 335 not taken.
108 resolvedefines(defname, unprocessedname);
560
3/10
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 65 taken 54 times.
✗ Branch 62 → 63 not taken.
✗ Branch 62 → 231 not taken.
✓ Branch 100 → 101 taken 54 times.
✗ Branch 100 → 335 not taken.
✗ Branch 101 → 102 not taken.
✓ Branch 101 → 105 taken 54 times.
✗ Branch 102 → 103 not taken.
✗ Branch 102 → 335 not taken.
108 if (!validatedefinename(defname)) throw_err_line(0, err_invalid_define_name);
561 108 }
562 else
563 {
564
6/8
✓ Branch 68 → 69 taken 24774 times.
✗ Branch 68 → 259 not taken.
✓ Branch 70 → 68 taken 24774 times.
✓ Branch 70 → 71 taken 4887 times.
✓ Branch 110 → 111 taken 24981 times.
✗ Branch 110 → 375 not taken.
✓ Branch 113 → 108 taken 24981 times.
✓ Branch 113 → 114 taken 4931 times.
59573 while (is_ualnum(*here)) defname+=*here++;
565 }
566
567
4/4
✓ Branch 71 → 72 taken 2625 times.
✓ Branch 71 → 197 taken 2316 times.
✓ Branch 114 → 115 taken 2348 times.
✓ Branch 114 → 116 taken 2637 times.
9926 if (first)
568 {
569 enum {
570 null,
571 append,
572 expand,
573 domath,
574 setifnotset,
575 } mode;
576 if(0);
577
4/4
✓ Branch 73 → 74 taken 255 times.
✓ Branch 73 → 75 taken 2370 times.
✓ Branch 117 → 118 taken 264 times.
✓ Branch 117 → 120 taken 2373 times.
5262 else if (stribegin(here, " = ")) { here+=3; mode=null; }
578
4/4
✓ Branch 76 → 77 taken 51 times.
✓ Branch 76 → 78 taken 2319 times.
✓ Branch 121 → 122 taken 51 times.
✓ Branch 121 → 124 taken 2322 times.
4743 else if (stribegin(here, " += ")) { here+=4; mode=append; }
579
4/4
✓ Branch 79 → 80 taken 27 times.
✓ Branch 79 → 81 taken 2292 times.
✓ Branch 125 → 126 taken 27 times.
✓ Branch 125 → 128 taken 2295 times.
4641 else if (stribegin(here, " := ")) { here+=4; mode=expand; }
580
4/4
✓ Branch 82 → 83 taken 963 times.
✓ Branch 82 → 84 taken 1329 times.
✓ Branch 129 → 130 taken 963 times.
✓ Branch 129 → 132 taken 1332 times.
4587 else if (stribegin(here, " #= ")) { here+=4; mode=domath; }
581
2/4
✗ Branch 85 → 86 not taken.
✓ Branch 85 → 87 taken 1329 times.
✗ Branch 133 → 134 not taken.
✓ Branch 133 → 136 taken 1332 times.
2661 else if (stribegin(here, " ?= ")) { here+=4; mode=setifnotset; }
582 2661 else goto notdefineset;
583 2601 string val;
584
4/4
✓ Branch 89 → 90 taken 93 times.
✓ Branch 89 → 102 taken 1203 times.
✓ Branch 140 → 141 taken 96 times.
✓ Branch 140 → 165 taken 1209 times.
2601 if (*here=='"')
585 {
586 189 here++;
587 while (true)
588 {
589
4/4
✓ Branch 91 → 92 taken 96 times.
✓ Branch 91 → 99 taken 414 times.
✓ Branch 144 → 145 taken 99 times.
✓ Branch 144 → 159 taken 414 times.
1023 if (*here=='"')
590 {
591
6/8
✓ Branch 92 → 93 taken 3 times.
✓ Branch 92 → 101 taken 93 times.
✓ Branch 93 → 94 taken 3 times.
✗ Branch 93 → 101 not taken.
✓ Branch 147 → 148 taken 3 times.
✓ Branch 147 → 163 taken 96 times.
✓ Branch 150 → 151 taken 3 times.
✗ Branch 150 → 163 not taken.
195 if (!here[1] || here[1]==' ') break;
592
2/4
✓ Branch 94 → 95 taken 3 times.
✗ Branch 94 → 96 not taken.
✓ Branch 153 → 154 taken 3 times.
✗ Branch 153 → 156 not taken.
6 else if (here[1]=='"') here++;
593 else throw_err_line(0, err_broken_define_declaration);
594 }
595
2/4
✓ Branch 99 → 100 taken 417 times.
✗ Branch 99 → 253 not taken.
✓ Branch 161 → 162 taken 417 times.
✗ Branch 161 → 367 not taken.
834 val+=*here++;
596 }
597 189 here++;
598 }
599 else
600 {
601
8/12
✓ Branch 103 → 104 taken 8286 times.
✗ Branch 103 → 253 not taken.
✓ Branch 104 → 105 taken 8286 times.
✓ Branch 104 → 106 taken 1203 times.
✓ Branch 105 → 103 taken 8286 times.
✗ Branch 105 → 106 not taken.
✓ Branch 168 → 169 taken 8304 times.
✗ Branch 168 → 367 not taken.
✓ Branch 170 → 171 taken 8304 times.
✓ Branch 170 → 173 taken 1209 times.
✓ Branch 172 → 166 taken 8304 times.
✗ Branch 172 → 173 not taken.
19002 while (*here && *here!=' ') val+=*here++;
602 }
603 //if (strqchr(val.data(), ';')) *strqchr(val.data(), ';')=0;
604
4/16
✗ Branch 106 → 107 not taken.
✓ Branch 106 → 110 taken 1296 times.
✗ Branch 108 → 109 not taken.
✗ Branch 108 → 110 not taken.
✗ Branch 111 → 112 not taken.
✓ Branch 111 → 115 taken 1296 times.
✗ Branch 112 → 113 not taken.
✗ Branch 112 → 253 not taken.
✗ Branch 174 → 175 not taken.
✓ Branch 174 → 178 taken 1305 times.
✗ Branch 176 → 177 not taken.
✗ Branch 176 → 178 not taken.
✗ Branch 179 → 180 not taken.
✓ Branch 179 → 183 taken 1305 times.
✗ Branch 180 → 181 not taken.
✗ Branch 180 → 367 not taken.
2601 if (*here && !stribegin(here, " : ")) throw_err_line(0, err_broken_define_declaration);
605 // RPG Hacker: Is it really a good idea to normalize
606 // the content of defines? That kinda violates their
607 // functionality as a string replacement mechanism.
608 //val.qnormalize();
609
610 // RPG Hacker: throw an error if we're trying to overwrite built-in defines.
611
6/8
✓ Branch 116 → 117 taken 1296 times.
✗ Branch 116 → 253 not taken.
✓ Branch 117 → 118 taken 3 times.
✓ Branch 117 → 122 taken 1293 times.
✓ Branch 184 → 185 taken 1305 times.
✗ Branch 184 → 367 not taken.
✓ Branch 185 → 186 taken 3 times.
✓ Branch 185 → 190 taken 1302 times.
2601 if (builtindefines.exists(defname))
612 {
613
2/4
✓ Branch 119 → 120 taken 3 times.
✗ Branch 119 → 253 not taken.
✓ Branch 187 → 188 taken 3 times.
✗ Branch 187 → 367 not taken.
6 throw_err_line(0, err_overriding_builtin_define, defname.data());
614 }
615
616
8/12
✓ Branch 122 → 123 taken 252 times.
✓ Branch 122 → 127 taken 51 times.
✓ Branch 122 → 147 taken 27 times.
✓ Branch 122 → 156 taken 963 times.
✗ Branch 122 → 188 not taken.
✗ Branch 122 → 195 not taken.
✓ Branch 190 → 191 taken 261 times.
✓ Branch 190 → 196 taken 51 times.
✓ Branch 190 → 222 taken 27 times.
✓ Branch 190 → 233 taken 963 times.
✗ Branch 190 → 279 not taken.
✗ Branch 190 → 287 not taken.
2595 switch (mode)
617 {
618 513 case null:
619 {
620
4/8
✓ Branch 124 → 125 taken 252 times.
✗ Branch 124 → 253 not taken.
✓ Branch 125 → 126 taken 252 times.
✗ Branch 125 → 253 not taken.
✓ Branch 192 → 193 taken 261 times.
✗ Branch 192 → 367 not taken.
✓ Branch 194 → 195 taken 261 times.
✗ Branch 194 → 367 not taken.
513 defines.create(defname) = val;
621 513 break;
622 }
623 102 case append:
624 {
625
4/12
✓ Branch 128 → 129 taken 51 times.
✗ Branch 128 → 237 not taken.
✗ Branch 129 → 130 not taken.
✓ Branch 129 → 134 taken 51 times.
✗ Branch 131 → 132 not taken.
✗ Branch 131 → 237 not taken.
✓ Branch 197 → 198 taken 51 times.
✗ Branch 197 → 343 not taken.
✗ Branch 198 → 199 not taken.
✓ Branch 198 → 203 taken 51 times.
✗ Branch 200 → 201 not taken.
✗ Branch 200 → 343 not taken.
102 if (!defines.exists(defname)) throw_err_line(0, err_define_not_found, defname.data());
626
4/8
✓ Branch 135 → 136 taken 51 times.
✗ Branch 135 → 237 not taken.
✓ Branch 136 → 137 taken 51 times.
✗ Branch 136 → 237 not taken.
✓ Branch 205 → 206 taken 51 times.
✗ Branch 205 → 343 not taken.
✓ Branch 207 → 208 taken 51 times.
✗ Branch 207 → 343 not taken.
102 string oldval = defines.find(defname);
627
2/4
✓ Branch 138 → 139 taken 51 times.
✗ Branch 138 → 234 not taken.
✓ Branch 210 → 211 taken 51 times.
✗ Branch 210 → 339 not taken.
102 val=oldval+val;
628
4/8
✓ Branch 142 → 143 taken 51 times.
✗ Branch 142 → 235 not taken.
✓ Branch 143 → 144 taken 51 times.
✗ Branch 143 → 235 not taken.
✓ Branch 216 → 217 taken 51 times.
✗ Branch 216 → 341 not taken.
✓ Branch 218 → 219 taken 51 times.
✗ Branch 218 → 341 not taken.
102 defines.create(defname) = val;
629 102 break;
630 102 }
631 54 case expand:
632 {
633 54 string newval;
634
2/4
✓ Branch 149 → 150 taken 27 times.
✗ Branch 149 → 238 not taken.
✓ Branch 225 → 226 taken 27 times.
✗ Branch 225 → 345 not taken.
54 resolvedefines(newval, val);
635
4/8
✓ Branch 151 → 152 taken 27 times.
✗ Branch 151 → 238 not taken.
✓ Branch 152 → 153 taken 27 times.
✗ Branch 152 → 238 not taken.
✓ Branch 227 → 228 taken 27 times.
✗ Branch 227 → 345 not taken.
✓ Branch 229 → 230 taken 27 times.
✗ Branch 229 → 345 not taken.
54 defines.create(defname) = newval;
636 54 break;
637 54 }
638 1926 case domath:
639 {
640 1926 string newval;
641
2/4
✓ Branch 158 → 159 taken 963 times.
✗ Branch 158 → 250 not taken.
✓ Branch 236 → 237 taken 963 times.
✗ Branch 236 → 361 not taken.
1926 resolvedefines(newval, val);
642
6/8
✓ Branch 160 → 161 taken 963 times.
✗ Branch 160 → 243 not taken.
✓ Branch 162 → 163 taken 960 times.
✓ Branch 162 → 241 taken 3 times.
✓ Branch 240 → 241 taken 963 times.
✗ Branch 240 → 351 not taken.
✓ Branch 243 → 244 taken 960 times.
✓ Branch 243 → 349 taken 3 times.
1932 math_val num = parse_math_expr(newval)->evaluate_static();
643 1920 string num_str;
644
2/12
✗ Branch 165 → 166 not taken.
✓ Branch 165 → 168 taken 960 times.
✗ Branch 166 → 167 not taken.
✗ Branch 166 → 246 not taken.
✗ Branch 167 → 179 not taken.
✗ Branch 167 → 246 not taken.
✗ Branch 248 → 249 not taken.
✓ Branch 248 → 251 taken 960 times.
✗ Branch 249 → 250 not taken.
✗ Branch 249 → 357 not taken.
✗ Branch 250 → 266 not taken.
✗ Branch 250 → 357 not taken.
1920 if(num.m_type == math_val_type::string) num_str = num.get_str();
645
8/12
✓ Branch 168 → 169 taken 6 times.
✓ Branch 168 → 174 taken 954 times.
✓ Branch 169 → 170 taken 6 times.
✗ Branch 169 → 244 not taken.
✓ Branch 170 → 171 taken 6 times.
✗ Branch 170 → 244 not taken.
✓ Branch 251 → 252 taken 6 times.
✓ Branch 251 → 259 taken 954 times.
✓ Branch 253 → 254 taken 6 times.
✗ Branch 253 → 353 not taken.
✓ Branch 254 → 255 taken 6 times.
✗ Branch 254 → 353 not taken.
1920 else if(num.m_type == math_val_type::floating) num_str = ftostr(num.get_double());
646
4/8
✓ Branch 174 → 175 taken 954 times.
✗ Branch 174 → 245 not taken.
✓ Branch 175 → 176 taken 954 times.
✗ Branch 175 → 245 not taken.
✓ Branch 260 → 261 taken 954 times.
✗ Branch 260 → 355 not taken.
✓ Branch 261 → 262 taken 954 times.
✗ Branch 261 → 355 not taken.
1908 else num_str = dec(num.get_integer());
647
2/4
✓ Branch 181 → 182 taken 960 times.
✗ Branch 181 → 246 not taken.
✓ Branch 269 → 270 taken 960 times.
✗ Branch 269 → 357 not taken.
1920 defines.create(defname) = std::move(num_str);
648 1920 break;
649 1926 }
650 case setifnotset:
651 {
652 if (!defines.exists(defname)) defines.create(defname) = val;
653 break;
654 }
655 }
656 2601 }
657 else
658 {
659 5996 notdefineset:
660
6/8
✓ Branch 199 → 200 taken 39 times.
✓ Branch 199 → 201 taken 3606 times.
✓ Branch 200 → 215 taken 39 times.
✗ Branch 200 → 259 not taken.
✓ Branch 294 → 295 taken 42 times.
✓ Branch 294 → 297 taken 3638 times.
✓ Branch 296 → 313 taken 42 times.
✗ Branch 296 → 375 not taken.
7325 if (!defname) out+="!";
661 else
662 {
663
6/12
✓ Branch 202 → 203 taken 3606 times.
✗ Branch 202 → 259 not taken.
✗ Branch 203 → 204 not taken.
✓ Branch 203 → 208 taken 3606 times.
✗ Branch 205 → 206 not taken.
✗ Branch 205 → 259 not taken.
✓ Branch 298 → 299 taken 3638 times.
✗ Branch 298 → 375 not taken.
✓ Branch 299 → 300 taken 1 time.
✓ Branch 299 → 304 taken 3637 times.
✓ Branch 301 → 302 taken 1 time.
✗ Branch 301 → 375 not taken.
7244 if (!defines.exists(defname)) throw_err_line(0, err_define_not_found, defname.data());
664 else {
665
4/8
✓ Branch 209 → 210 taken 3606 times.
✗ Branch 209 → 258 not taken.
✓ Branch 210 → 211 taken 3606 times.
✗ Branch 210 → 258 not taken.
✓ Branch 306 → 307 taken 3637 times.
✗ Branch 306 → 373 not taken.
✓ Branch 308 → 309 taken 3637 times.
✗ Branch 308 → 373 not taken.
7243 string thisone = defines.find(defname);
666
2/4
✓ Branch 212 → 213 taken 3606 times.
✗ Branch 212 → 256 not taken.
✓ Branch 310 → 311 taken 3637 times.
✗ Branch 310 → 371 not taken.
7243 resolvedefines(out, thisone);
667 7243 }
668 }
669 }
670
4/4
✓ Branch 217 → 218 taken 4935 times.
✓ Branch 217 → 220 taken 651 times.
✓ Branch 315 → 316 taken 4978 times.
✓ Branch 315 → 317 taken 651 times.
11246 }
671
2/4
✓ Branch 221 → 222 taken 30330 times.
✗ Branch 221 → 262 not taken.
✓ Branch 323 → 324 taken 30609 times.
✗ Branch 323 → 379 not taken.
60939 else out+=*here++;
672 }
673
4/4
✓ Branch 226 → 227 taken 5205 times.
✓ Branch 226 → 229 taken 28358 times.
✓ Branch 329 → 330 taken 5236 times.
✓ Branch 329 → 331 taken 28603 times.
67433 }
674
675 bool moreonline;
676 bool asarverallowed = false;
677
678 57145 void assembleline(const char * fname, int linenum, const string& line, int& single_line_for_tracker)
679 {
680
2/4
✓ Branch 2 → 3 taken 28451 times.
✗ Branch 2 → 59 not taken.
✓ Branch 3 → 4 taken 28694 times.
✗ Branch 3 → 104 not taken.
57145 recurseblock rec;
681
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 28694 times.
57145 bool moreonlinetmp=moreonline;
682 57145 single_line_for_tracker = 1;
683 try
684 {
685
2/4
✓ Branch 3 → 4 taken 28451 times.
✗ Branch 3 → 52 not taken.
✓ Branch 8 → 9 taken 28694 times.
✗ Branch 8 → 94 not taken.
57145 string out=line;
686
2/4
✓ Branch 5 → 6 taken 28451 times.
✗ Branch 5 → 50 not taken.
✓ Branch 11 → 12 taken 28694 times.
✗ Branch 11 → 92 not taken.
57145 autoptr<char**> blocks=qsplitstr(out.temp_raw(), " : ");
687 57145 moreonline=true;
688
5/6
✓ Branch 35 → 8 taken 29351 times.
✓ Branch 35 → 36 taken 23448 times.
✗ Branch 71 → 72 not taken.
✓ Branch 71 → 73 taken 53354 times.
✓ Branch 73 → 14 taken 29663 times.
✓ Branch 73 → 74 taken 23691 times.
106153 for (int block_i=0;moreonline;block_i++)
689 {
690 59014 moreonline=(blocks[block_i+1] != nullptr);
691 try
692 {
693 // it's possible that our input looks something like:
694 // nop : : nop
695 // nop : : : : : nop
696 // also, it's possible that there were empty blocks at the start or end of the line:
697 // : nop :
698 // after qsplit, we still need to deal with possibly a single ": " from a preceding empty block,
699 // and if it's the last block, possibly a following " :".
700 59014 char* thisblock = strip_whitespace(blocks[block_i]);
701 // if the block starts with ": "
702
8/8
✓ Branch 11 → 12 taken 27 times.
✓ Branch 11 → 16 taken 29324 times.
✓ Branch 12 → 13 taken 12 times.
✓ Branch 12 → 16 taken 15 times.
✓ Branch 22 → 23 taken 27 times.
✓ Branch 22 → 32 taken 29636 times.
✓ Branch 25 → 26 taken 12 times.
✓ Branch 25 → 32 taken 15 times.
59014 if(thisblock[0] == ':' && thisblock[1] == ' ') {
703 24 thisblock++;
704
4/4
✓ Branch 15 → 14 taken 12 times.
✓ Branch 15 → 16 taken 12 times.
✓ Branch 31 → 28 taken 12 times.
✓ Branch 31 → 32 taken 12 times.
48 while(*thisblock == ' ') thisblock++;
705 }
706 // if the block is a single :, skip that too.
707
6/8
✓ Branch 16 → 17 taken 15 times.
✓ Branch 16 → 19 taken 29336 times.
✓ Branch 17 → 18 taken 15 times.
✗ Branch 17 → 19 not taken.
✓ Branch 33 → 34 taken 15 times.
✓ Branch 33 → 39 taken 29648 times.
✓ Branch 36 → 37 taken 15 times.
✗ Branch 36 → 39 not taken.
59014 if(thisblock[0] == ':' && thisblock[1] == 0) thisblock++;
708
709
1/2
✗ Branch 39 → 40 not taken.
✓ Branch 39 → 41 taken 29663 times.
59014 int len_blk = strlen(thisblock);
710 // last block - strip trailing " :" if present.
711
17/18
✓ Branch 19 → 20 taken 28451 times.
✓ Branch 19 → 24 taken 900 times.
✓ Branch 20 → 21 taken 19306 times.
✓ Branch 20 → 24 taken 9145 times.
✓ Branch 21 → 22 taken 1572 times.
✓ Branch 21 → 24 taken 17734 times.
✓ Branch 22 → 23 taken 6 times.
✓ Branch 22 → 24 taken 1566 times.
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 43 taken 29663 times.
✓ Branch 43 → 44 taken 28694 times.
✓ Branch 43 → 54 taken 969 times.
✓ Branch 44 → 45 taken 19489 times.
✓ Branch 44 → 54 taken 9205 times.
✓ Branch 47 → 48 taken 1602 times.
✓ Branch 47 → 54 taken 17887 times.
✓ Branch 50 → 51 taken 6 times.
✓ Branch 50 → 54 taken 1596 times.
59014 if(!moreonline && len_blk >= 2 && thisblock[len_blk-2] == ' ' && thisblock[len_blk-1] == ':') {
712 12 thisblock[len_blk - 2] = 0;
713 }
714
715
2/4
✓ Branch 24 → 25 taken 29351 times.
✗ Branch 24 → 43 not taken.
✓ Branch 55 → 56 taken 29663 times.
✗ Branch 55 → 83 not taken.
59014 callstack_push cs_push(callstack_entry_type::BLOCK, thisblock);
716
717
4/4
✓ Branch 25 → 26 taken 24198 times.
✓ Branch 25 → 41 taken 5153 times.
✓ Branch 56 → 57 taken 24504 times.
✓ Branch 56 → 81 taken 5159 times.
59014 assembleblock(thisblock, single_line_for_tracker);
718
4/4
✓ Branch 26 → 27 taken 24196 times.
✓ Branch 26 → 41 taken 2 times.
✓ Branch 57 → 58 taken 24502 times.
✓ Branch 57 → 81 taken 2 times.
48702 checkbankcross();
719 59014 }
720
4/4
✓ Branch 44 → 45 taken 5003 times.
✓ Branch 44 → 46 taken 152 times.
✓ Branch 85 → 86 taken 5003 times.
✓ Branch 85 → 87 taken 158 times.
10316 catch (errblock&) {}
721
4/4
✓ Branch 30 → 31 taken 15293 times.
✓ Branch 30 → 32 taken 9055 times.
✓ Branch 64 → 65 taken 15551 times.
✓ Branch 64 → 66 taken 9109 times.
49008 if (blocks[block_i][0]!='\0') asarverallowed=false;
722
4/4
✓ Branch 32 → 33 taken 23283 times.
✓ Branch 32 → 34 taken 1065 times.
✓ Branch 67 → 68 taken 23526 times.
✓ Branch 67 → 70 taken 1134 times.
49008 if(single_line_for_tracker == 1) single_line_for_tracker = 0;
723 }
724 67151 }
725
2/4
✓ Branch 53 → 54 taken 5003 times.
✗ Branch 53 → 55 not taken.
✓ Branch 97 → 98 taken 5003 times.
✗ Branch 97 → 99 not taken.
10006 catch (errline&) {}
726 47139 moreonline=moreonlinetmp;
727 80836 }
728
729 int incsrcdepth=0;
730
731 // Returns true if a file is protected via
732 // an "includeonce".
733 11042 bool file_included_once(const char* file)
734 {
735
4/4
✓ Branch 8 → 3 taken 120 times.
✓ Branch 8 → 9 taken 5443 times.
✓ Branch 10 → 3 taken 120 times.
✓ Branch 10 → 11 taken 5557 times.
11240 for (int i = 0; i < includeonce.count; ++i)
736 {
737
4/4
✓ Branch 5 → 6 taken 21 times.
✓ Branch 5 → 7 taken 99 times.
✓ Branch 7 → 8 taken 21 times.
✓ Branch 7 → 9 taken 99 times.
240 if (includeonce[i] == file)
738 {
739 42 return true;
740 }
741 }
742
743 11000 return false;
744 }
745
746 autoarray<string> macro_defs;
747 int in_macro_def=0;
748
749 11012 void assemblefile(const char * filename)
750 {
751 11012 incsrcdepth++;
752
2/5
✓ Branch 3 → 4 taken 11003 times.
✗ Branch 3 → 120 not taken.
✗ Branch 3 → 235 not taken.
✓ Branch 4 → 5 taken 5563 times.
✗ Branch 4 → 235 not taken.
11012 string absolutepath = filesystem->create_absolute_path(get_current_file_name(), filename);
753
754
5/7
✓ Branch 5 → 6 taken 5449 times.
✗ Branch 5 → 118 not taken.
✓ Branch 6 → 7 taken 5584 times.
✓ Branch 6 → 8 taken 5428 times.
✗ Branch 6 → 233 not taken.
✓ Branch 7 → 8 taken 21 times.
✓ Branch 7 → 9 taken 5542 times.
11012 if (file_included_once(absolutepath))
755 {
756 42 return;
757 }
758
759 // don't do this yet; we want "file not found" errors to show the location
760 // that called assemblefile
761 //callstack_push cs_push(callstack_entry_type::FILE, absolutepath);
762
763 5542 sourcefile file;
764 10970 file.contents = nullptr;
765 10970 file.numlines = 0;
766 10970 int startif=numif;
767
6/8
✓ Branch 9 → 10 taken 5428 times.
✗ Branch 9 → 118 not taken.
✓ Branch 10 → 11 taken 150 times.
✓ Branch 10 → 63 taken 5278 times.
✓ Branch 11 → 12 taken 5542 times.
✗ Branch 11 → 233 not taken.
✓ Branch 12 → 13 taken 188 times.
✓ Branch 12 → 156 taken 5354 times.
10970 if (!filecontents.exists(absolutepath))
768 {
769
4/4
✓ Branch 12 → 13 taken 149 times.
✓ Branch 12 → 112 taken 1 time.
✓ Branch 14 → 15 taken 187 times.
✓ Branch 14 → 225 taken 1 time.
338 char * temp = readfile(absolutepath, "");
770
4/4
✓ Branch 13 → 14 taken 3 times.
✓ Branch 13 → 17 taken 146 times.
✓ Branch 15 → 16 taken 3 times.
✓ Branch 15 → 19 taken 184 times.
336 if (!temp)
771 {
772
3/6
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 112 taken 3 times.
✓ Branch 16 → 17 taken 3 times.
✗ Branch 16 → 225 not taken.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 225 taken 3 times.
6 throw_vfile_error(0, asar_get_last_io_error(), filename);
773 return;
774 }
775
2/4
✓ Branch 18 → 19 taken 146 times.
✗ Branch 18 → 112 not taken.
✓ Branch 21 → 22 taken 184 times.
✗ Branch 21 → 225 not taken.
330 callstack_push cs_push(callstack_entry_type::FILE, absolutepath);
776
777
2/4
✓ Branch 20 → 21 taken 146 times.
✗ Branch 20 → 110 not taken.
✓ Branch 23 → 24 taken 184 times.
✗ Branch 23 → 223 not taken.
330 sourcefile& newfile = filecontents.create(absolutepath);
778
2/4
✓ Branch 21 → 22 taken 146 times.
✗ Branch 21 → 110 not taken.
✓ Branch 24 → 25 taken 184 times.
✗ Branch 24 → 223 not taken.
330 newfile.contents =split(temp, '\n');
779 330 newfile.data = temp;
780
4/4
✓ Branch 48 → 23 taken 6167 times.
✓ Branch 48 → 49 taken 146 times.
✓ Branch 102 → 29 taken 6248 times.
✓ Branch 102 → 103 taken 184 times.
12745 for (int i=0;newfile.contents[i];i++)
781 {
782 12415 newfile.numlines++;
783 12415 char * line = newfile.contents[i];
784 12415 int i_temp = i;
785 char * comment;
786
4/4
✓ Branch 38 → 24 taken 1825 times.
✓ Branch 38 → 39 taken 6166 times.
✓ Branch 79 → 38 taken 1825 times.
✓ Branch 79 → 80 taken 6247 times.
16063 while((comment = strqchr(line, ';'))) {
787
6/8
✓ Branch 24 → 25 taken 6 times.
✓ Branch 24 → 35 taken 1819 times.
✓ Branch 25 → 26 taken 6 times.
✗ Branch 25 → 35 not taken.
✓ Branch 40 → 41 taken 6 times.
✓ Branch 40 → 75 taken 1819 times.
✓ Branch 43 → 44 taken 6 times.
✗ Branch 43 → 75 not taken.
3650 if(comment[1] == '[' && comment[2] == '[') {
788 // block comment - find where it ends
789 12 char* theline = comment + 3;
790
1/2
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 6 times.
12 char* comment_end = strstr(theline, "]]");
791
4/4
✓ Branch 33 → 27 taken 10 times.
✓ Branch 33 → 34 taken 5 times.
✓ Branch 66 → 48 taken 10 times.
✓ Branch 66 → 67 taken 5 times.
30 while(comment_end == nullptr) {
792 20 i_temp++;
793 20 char* new_line = newfile.contents[i_temp];
794
4/4
✓ Branch 27 → 28 taken 1 time.
✓ Branch 27 → 32 taken 9 times.
✓ Branch 52 → 53 taken 1 time.
✓ Branch 52 → 59 taken 9 times.
20 if(new_line == nullptr) {
795
2/4
✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 106 not taken.
✓ Branch 54 → 55 taken 1 time.
✗ Branch 54 → 217 not taken.
2 callstack_push cs_push(callstack_entry_type::LINE, line, i);
796
2/4
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 104 not taken.
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 215 not taken.
2 throw_err_null(0, err_unclosed_block_comment);
797 // make sure this line is still parsed correctly
798 2 *comment = 0;
799 // but don't go looking at any other lines
800 2 goto break_outer;
801 2 }
802
1/2
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 61 taken 9 times.
18 comment_end = strstr(new_line, "]]");
803 // this line is itself part of the comment, so ignore it
804 //new_line[0] = 0;
805 // except not like that^, because that will break the
806 // memmove below
807 static char junk[]="";
808 // using a static here should be fine, since if the line
809 // doesn't contain ',' or '\' we won't go mutating it
810 18 newfile.contents[i_temp] = junk;
811 }
812 // comment_end+2 is a valid pointer, since comment_end is
813 // guaranteed to start with ]]
814 10 comment_end += 2;
815 // stitch together the part of the line before the comment,
816 // and the part of the line after it
817
3/6
✗ Branch 68 → 69 not taken.
✓ Branch 68 → 70 taken 5 times.
✗ Branch 70 → 71 not taken.
✓ Branch 70 → 72 taken 5 times.
✗ Branch 72 → 73 not taken.
✓ Branch 72 → 74 taken 5 times.
10 memmove(comment, comment_end, strlen(comment_end) + 1);
818 // and then recheck for ; in the line again...
819 10 } else {
820 3638 *comment = 0;
821 }
822 }
823 12414 break_outer:
824
6/8
✓ Branch 40 → 41 taken 6167 times.
✗ Branch 40 → 110 not taken.
✓ Branch 41 → 42 taken 2 times.
✓ Branch 41 → 46 taken 6165 times.
✓ Branch 84 → 85 taken 6248 times.
✗ Branch 84 → 223 not taken.
✓ Branch 85 → 86 taken 2 times.
✓ Branch 85 → 92 taken 6246 times.
12415 if (!confirmquotes(line)) {
825
2/4
✓ Branch 42 → 43 taken 2 times.
✗ Branch 42 → 109 not taken.
✓ Branch 87 → 88 taken 2 times.
✗ Branch 87 → 221 not taken.
4 callstack_push cs_push(callstack_entry_type::LINE, line, i);
826
2/4
✓ Branch 43 → 44 taken 2 times.
✗ Branch 43 → 107 not taken.
✓ Branch 88 → 89 taken 2 times.
✗ Branch 88 → 219 not taken.
4 throw_err_null(0, err_mismatched_quotes);
827 4 line[0] = '\0';
828 4 }
829 12415 newfile.contents[i] = strip_whitespace(line);
830 }
831
4/4
✓ Branch 60 → 50 taken 6167 times.
✓ Branch 60 → 61 taken 146 times.
✓ Branch 148 → 104 taken 6248 times.
✓ Branch 148 → 149 taken 184 times.
12745 for(int i=0;newfile.contents[i];i++)
832 {
833 12415 char* line = newfile.contents[i];
834
4/4
✓ Branch 50 → 51 taken 2500 times.
✓ Branch 50 → 52 taken 3667 times.
✓ Branch 109 → 110 taken 2514 times.
✓ Branch 109 → 111 taken 3734 times.
12415 if(!*line) continue;
835
7/10
✓ Branch 57 → 58 taken 5 times.
✓ Branch 57 → 59 taken 3667 times.
✓ Branch 58 → 53 taken 5 times.
✗ Branch 58 → 59 not taken.
✗ Branch 133 → 134 not taken.
✓ Branch 133 → 135 taken 3739 times.
✓ Branch 137 → 138 taken 5 times.
✓ Branch 137 → 143 taken 3734 times.
✓ Branch 142 → 112 taken 5 times.
✗ Branch 142 → 143 not taken.
7411 for (int j=1;line[strlen(line) - 1] == ',' && newfile.contents[i+j];j++)
836 {
837 // not using strcat because the source and dest overlap here
838 10 char* otherline = newfile.contents[i+j];
839
1/2
✗ Branch 116 → 117 not taken.
✓ Branch 116 → 118 taken 5 times.
10 char* line_end = line + strlen(line);
840
4/4
✓ Branch 55 → 54 taken 64 times.
✓ Branch 55 → 56 taken 5 times.
✓ Branch 126 → 120 taken 64 times.
✓ Branch 126 → 127 taken 5 times.
138 while(*otherline) *line_end++ = *otherline++;
841 10 *line_end = '\0';
842 static char nullstr[]="";
843 10 newfile.contents[i+j]=nullstr;
844 }
845 }
846 330 file = newfile;
847 330 } else { // filecontents.exists(absolutepath)
848
2/4
✓ Branch 64 → 65 taken 5278 times.
✗ Branch 64 → 118 not taken.
✓ Branch 157 → 158 taken 5354 times.
✗ Branch 157 → 233 not taken.
10632 file = filecontents.find(absolutepath);
849 }
850 // previous callstack_push got dropped by the end of the if scope
851
2/4
✓ Branch 67 → 68 taken 5424 times.
✗ Branch 67 → 118 not taken.
✓ Branch 163 → 164 taken 5538 times.
✗ Branch 163 → 233 not taken.
20970 callstack_push cs_push(callstack_entry_type::FILE, absolutepath);
852 10962 asarverallowed=true;
853
6/8
✓ Branch 83 → 84 taken 26682 times.
✓ Branch 83 → 85 taken 420 times.
✓ Branch 84 → 69 taken 26682 times.
✗ Branch 84 → 85 not taken.
✓ Branch 190 → 191 taken 26925 times.
✓ Branch 190 → 192 taken 534 times.
✓ Branch 191 → 165 taken 26925 times.
✗ Branch 191 → 192 not taken.
54561 for (int i=0;file.contents[i] && i<file.numlines;i++)
854 {
855 53607 string connectedline;
856
2/4
✓ Branch 70 → 71 taken 26682 times.
✗ Branch 70 → 113 not taken.
✓ Branch 167 → 168 taken 26925 times.
✗ Branch 167 → 227 not taken.
53607 int skiplines = getconnectedlines<char**>(file.contents, i, connectedline);
857
858
4/4
✓ Branch 72 → 73 taken 21678 times.
✓ Branch 72 → 113 taken 5004 times.
✓ Branch 169 → 170 taken 21921 times.
✓ Branch 169 → 227 taken 5004 times.
53607 bool was_loop_end = do_line_logic(connectedline, absolutepath, i);
859 43599 i += skiplines;
860
861 // if a loop ended on this line, should it run again?
862
15/18
✓ Branch 73 → 74 taken 780 times.
✓ Branch 73 → 77 taken 20898 times.
✓ Branch 74 → 75 taken 780 times.
✗ Branch 74 → 113 not taken.
✓ Branch 75 → 76 taken 666 times.
✓ Branch 75 → 77 taken 114 times.
✓ Branch 78 → 79 taken 666 times.
✓ Branch 78 → 81 taken 21012 times.
✓ Branch 170 → 171 taken 780 times.
✓ Branch 170 → 178 taken 21141 times.
✓ Branch 172 → 173 taken 780 times.
✗ Branch 172 → 227 not taken.
✗ Branch 174 → 175 not taken.
✓ Branch 174 → 176 taken 780 times.
✓ Branch 176 → 177 taken 666 times.
✓ Branch 176 → 178 taken 114 times.
✓ Branch 179 → 180 taken 666 times.
✓ Branch 179 → 185 taken 21255 times.
43599 if (was_loop_end && whilestatus[numif].cond)
863
2/4
✓ Branch 79 → 80 taken 666 times.
✗ Branch 79 → 113 not taken.
✓ Branch 181 → 182 taken 666 times.
✗ Branch 181 → 227 not taken.
1332 i = whilestatus[numif].startline - 1;
864 53607 }
865
4/4
✓ Branch 93 → 86 taken 6 times.
✓ Branch 93 → 94 taken 420 times.
✓ Branch 201 → 193 taken 6 times.
✓ Branch 201 → 202 taken 534 times.
966 while (in_macro_def > 0)
866 {
867
4/8
✓ Branch 86 → 87 taken 6 times.
✗ Branch 86 → 116 not taken.
✓ Branch 88 → 89 taken 6 times.
✗ Branch 88 → 116 not taken.
✓ Branch 193 → 194 taken 6 times.
✗ Branch 193 → 231 not taken.
✓ Branch 196 → 197 taken 6 times.
✗ Branch 196 → 231 not taken.
12 throw_err_null(0, err_unclosed_macro, macro_defs[in_macro_def-1].data());
868
10/12
✓ Branch 89 → 90 taken 2 times.
✓ Branch 89 → 92 taken 4 times.
✓ Branch 90 → 91 taken 1 time.
✓ Branch 90 → 92 taken 1 time.
✓ Branch 91 → 92 taken 1 time.
✗ Branch 91 → 116 not taken.
✓ Branch 197 → 198 taken 2 times.
✓ Branch 197 → 200 taken 4 times.
✓ Branch 198 → 199 taken 1 time.
✓ Branch 198 → 200 taken 1 time.
✓ Branch 199 → 200 taken 1 time.
✗ Branch 199 → 231 not taken.
12 if (!pass && in_macro_def == 1) endmacro(false);
869 12 in_macro_def--;
870 12 macro_defs.remove(in_macro_def);
871 }
872
2/4
✗ Branch 94 → 95 not taken.
✓ Branch 94 → 96 taken 420 times.
✗ Branch 202 → 203 not taken.
✓ Branch 202 → 204 taken 534 times.
954 if (numif!=startif)
873 {
874 numif=startif;
875 numtrue=startif;
876 throw_err_null(0, err_unclosed_if);
877 }
878 954 incsrcdepth--;
879
4/4
✓ Branch 99 → 100 taken 420 times.
✓ Branch 99 → 102 taken 21 times.
✓ Branch 207 → 208 taken 534 times.
✓ Branch 207 → 209 taken 21 times.
11012 }
880
881 // RPG Hacker: At some point, this should probably be merged
882 // into assembleline(), since the two names just cause
883 // confusion otherwise.
884 // return value is "did a loop end on this line"
885 60681 bool do_line_logic(const string& line, const char* filename, int lineno)
886 {
887 60681 int prevnumif = numif;
888 60681 int single_line_for_tracker = 1;
889 try
890 {
891 60681 string current_line;
892
15/15
✓ Branch 3 → 4 taken 1638 times.
✓ Branch 3 → 8 taken 28581 times.
✓ Branch 4 → 5 taken 1395 times.
✓ Branch 4 → 9 taken 243 times.
✓ Branch 5 → 6 taken 1638 times.
✓ Branch 5 → 11 taken 28824 times.
✓ Branch 6 → 7 taken 1395 times.
✓ Branch 6 → 12 taken 243 times.
✓ Branch 7 → 8 taken 84 times.
✓ Branch 7 → 9 taken 1311 times.
✓ Branch 10 → 11 taken 28749 times.
✓ Branch 10 → 12 taken 1311 times.
✓ Branch 10 → 26 taken 1554 times.
✓ Branch 13 → 14 taken 28908 times.
✓ Branch 13 → 33 taken 1554 times.
60681 if (numif==numtrue || (numtrue+1==numif && stribegin(line, "elseif ")))
893 {
894
2/5
✓ Branch 12 → 13 taken 28665 times.
✗ Branch 12 → 96 not taken.
✗ Branch 12 → 97 not taken.
✓ Branch 17 → 18 taken 28908 times.
✗ Branch 17 → 122 not taken.
57573 callstack_push cs_push(callstack_entry_type::LINE, line, lineno);
895
4/5
✓ Branch 13 → 14 taken 28620 times.
✗ Branch 13 → 94 not taken.
✓ Branch 13 → 95 taken 45 times.
✓ Branch 19 → 20 taken 28863 times.
✓ Branch 19 → 120 taken 45 times.
57573 string tmp=replace_macro_args(line);
896
2/5
✓ Branch 14 → 15 taken 28620 times.
✗ Branch 14 → 92 not taken.
✗ Branch 14 → 93 not taken.
✓ Branch 20 → 21 taken 28863 times.
✗ Branch 20 → 118 not taken.
57483 tmp.qnormalize();
897
4/5
✓ Branch 16 → 17 taken 28604 times.
✗ Branch 16 → 92 not taken.
✓ Branch 16 → 93 taken 16 times.
✓ Branch 22 → 23 taken 28847 times.
✓ Branch 22 → 118 taken 16 times.
57483 resolvedefines(current_line, tmp);
898
8/14
✓ Branch 18 → 19 taken 28604 times.
✗ Branch 18 → 92 not taken.
✗ Branch 18 → 93 not taken.
✓ Branch 19 → 20 taken 3 times.
✓ Branch 19 → 23 taken 28601 times.
✓ Branch 20 → 21 taken 3 times.
✗ Branch 20 → 92 not taken.
✗ Branch 20 → 93 not taken.
✓ Branch 24 → 25 taken 28847 times.
✗ Branch 24 → 118 not taken.
✓ Branch 25 → 26 taken 3 times.
✓ Branch 25 → 29 taken 28844 times.
✓ Branch 26 → 27 taken 3 times.
✗ Branch 26 → 118 not taken.
57451 if (!confirmquotes(current_line)) throw_err_line(0, err_mismatched_quotes);
899 57611 }
900
2/5
✓ Branch 26 → 27 taken 1554 times.
✗ Branch 26 → 111 not taken.
✗ Branch 26 → 112 not taken.
✓ Branch 33 → 34 taken 1554 times.
✗ Branch 33 → 143 not taken.
3108 else current_line=line;
901
902
2/5
✓ Branch 28 → 29 taken 30155 times.
✗ Branch 28 → 111 not taken.
✗ Branch 28 → 112 not taken.
✓ Branch 36 → 37 taken 30398 times.
✗ Branch 36 → 143 not taken.
60553 callstack_push cs_push(callstack_entry_type::LINE, current_line, lineno);
903
904
12/12
✓ Branch 31 → 32 taken 276 times.
✓ Branch 31 → 34 taken 29879 times.
✓ Branch 32 → 33 taken 258 times.
✓ Branch 32 → 34 taken 18 times.
✓ Branch 35 → 36 taken 258 times.
✓ Branch 35 → 53 taken 29897 times.
✓ Branch 39 → 40 taken 276 times.
✓ Branch 39 → 42 taken 30122 times.
✓ Branch 40 → 41 taken 258 times.
✓ Branch 40 → 42 taken 18 times.
✓ Branch 43 → 44 taken 258 times.
✓ Branch 43 → 66 taken 30140 times.
60553 if (stribegin(current_line, "macro ") && numif==numtrue)
905 {
906 // RPG Hacker: Slight redundancy here with code that is
907 // also in startmacro(). Could improve this for Asar 2.0.
908
2/5
✓ Branch 37 → 38 taken 258 times.
✗ Branch 37 → 102 not taken.
✗ Branch 37 → 103 not taken.
✓ Branch 47 → 48 taken 258 times.
✗ Branch 47 → 131 not taken.
516 string macro_name = current_line.data()+6;
909 516 char * startpar=strqchr(macro_name.raw(), '(');
910
2/4
✓ Branch 40 → 41 taken 258 times.
✗ Branch 40 → 42 not taken.
✓ Branch 50 → 51 taken 258 times.
✗ Branch 50 → 53 not taken.
516 if (startpar) *startpar=0;
911
2/5
✓ Branch 42 → 43 taken 258 times.
✗ Branch 42 → 100 not taken.
✗ Branch 42 → 101 not taken.
✓ Branch 53 → 54 taken 258 times.
✗ Branch 53 → 129 not taken.
516 macro_defs.append(macro_name);
912
913 // RPG Hacker: I think it would make more logical sense
914 // to have this ++ after the if, but hat breaks compatibility
915 // with at least one test, and it generally leads to more
916 // errors being output after a broken macro declaration.
917 516 in_macro_def++;
918
4/4
✓ Branch 43 → 44 taken 86 times.
✓ Branch 43 → 51 taken 172 times.
✓ Branch 54 → 55 taken 86 times.
✓ Branch 54 → 64 taken 172 times.
516 if (!pass)
919 {
920
8/9
✓ Branch 44 → 45 taken 70 times.
✓ Branch 44 → 47 taken 16 times.
✓ Branch 46 → 51 taken 69 times.
✗ Branch 46 → 100 not taken.
✓ Branch 46 → 101 taken 1 time.
✓ Branch 55 → 56 taken 70 times.
✓ Branch 55 → 59 taken 16 times.
✓ Branch 58 → 64 taken 69 times.
✓ Branch 58 → 129 taken 1 time.
172 if (in_macro_def == 1) startmacro(current_line.data()+6);
921
4/10
✓ Branch 47 → 48 taken 16 times.
✗ Branch 47 → 99 not taken.
✗ Branch 47 → 100 not taken.
✓ Branch 48 → 49 taken 16 times.
✗ Branch 48 → 97 not taken.
✗ Branch 48 → 98 not taken.
✓ Branch 60 → 61 taken 16 times.
✗ Branch 60 → 127 not taken.
✓ Branch 61 → 62 taken 16 times.
✗ Branch 61 → 125 not taken.
32 else tomacro(current_line);
922 }
923 516 }
924
14/20
✓ Branch 54 → 55 taken 29897 times.
✗ Branch 54 → 57 not taken.
✗ Branch 54 → 110 not taken.
✓ Branch 55 → 56 taken 270 times.
✗ Branch 55 → 57 not taken.
✓ Branch 55 → 58 taken 29627 times.
✓ Branch 56 → 57 taken 252 times.
✓ Branch 56 → 58 taken 18 times.
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 71 not taken.
✓ Branch 59 → 60 taken 252 times.
✓ Branch 59 → 72 taken 29645 times.
✗ Branch 67 → 68 not taken.
✓ Branch 67 → 69 taken 30140 times.
✓ Branch 69 → 70 taken 270 times.
✓ Branch 69 → 72 taken 29870 times.
✓ Branch 70 → 71 taken 252 times.
✓ Branch 70 → 72 taken 18 times.
✓ Branch 73 → 74 taken 252 times.
✓ Branch 73 → 87 taken 29888 times.
60037 else if (!stricmp(current_line, "endmacro") && numif==numtrue)
925 {
926
2/11
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 63 not taken.
✗ Branch 60 → 61 not taken.
✓ Branch 60 → 64 taken 252 times.
✗ Branch 60 → 109 not taken.
✗ Branch 61 → 62 not taken.
✗ Branch 61 → 110 not taken.
✗ Branch 74 → 75 not taken.
✓ Branch 74 → 78 taken 252 times.
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 141 not taken.
504 if (in_macro_def == 0) throw_err_line(0, err_misplaced_endmacro);
927 else
928 {
929 504 in_macro_def--;
930 504 macro_defs.remove(in_macro_def);
931
4/6
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 78 not taken.
✓ Branch 65 → 66 taken 84 times.
✓ Branch 65 → 79 taken 168 times.
✓ Branch 79 → 80 taken 84 times.
✓ Branch 79 → 95 taken 168 times.
504 if (!pass)
932 {
933
6/12
✗ Branch 65 → 66 not taken.
✗ Branch 65 → 67 not taken.
✓ Branch 66 → 67 taken 69 times.
✓ Branch 66 → 68 taken 15 times.
✗ Branch 66 → 78 not taken.
✗ Branch 66 → 109 not taken.
✓ Branch 67 → 79 taken 69 times.
✗ Branch 67 → 110 not taken.
✓ Branch 80 → 81 taken 69 times.
✓ Branch 80 → 82 taken 15 times.
✓ Branch 81 → 95 taken 69 times.
✗ Branch 81 → 141 not taken.
168 if (in_macro_def == 0) endmacro(true);
934
4/11
✗ Branch 67 → 68 not taken.
✗ Branch 67 → 105 not taken.
✓ Branch 68 → 69 taken 15 times.
✗ Branch 68 → 103 not taken.
✗ Branch 68 → 106 not taken.
✓ Branch 69 → 70 taken 15 times.
✗ Branch 69 → 104 not taken.
✓ Branch 83 → 84 taken 15 times.
✗ Branch 83 → 135 not taken.
✓ Branch 84 → 85 taken 15 times.
✗ Branch 84 → 133 not taken.
30 else tomacro(current_line);
935 }
936 }
937 }
938
4/6
✗ Branch 71 → 72 not taken.
✗ Branch 71 → 77 not taken.
✓ Branch 72 → 73 taken 1194 times.
✓ Branch 72 → 78 taken 28451 times.
✓ Branch 87 → 88 taken 1194 times.
✓ Branch 87 → 94 taken 28694 times.
59533 else if (in_macro_def > 0)
939 {
940
8/16
✗ Branch 72 → 73 not taken.
✗ Branch 72 → 78 not taken.
✓ Branch 73 → 74 taken 398 times.
✓ Branch 73 → 79 taken 796 times.
✗ Branch 73 → 108 not taken.
✓ Branch 74 → 75 taken 398 times.
✗ Branch 74 → 106 not taken.
✗ Branch 74 → 109 not taken.
✓ Branch 75 → 76 taken 398 times.
✗ Branch 75 → 107 not taken.
✓ Branch 88 → 89 taken 398 times.
✓ Branch 88 → 95 taken 796 times.
✓ Branch 90 → 91 taken 398 times.
✗ Branch 90 → 139 not taken.
✓ Branch 91 → 92 taken 398 times.
✗ Branch 91 → 137 not taken.
2388 if (!pass) tomacro(current_line);
941 }
942 else
943 {
944
4/6
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 109 not taken.
✓ Branch 78 → 79 taken 23448 times.
✓ Branch 78 → 110 taken 5003 times.
✓ Branch 94 → 95 taken 23691 times.
✓ Branch 94 → 141 taken 5003 times.
57145 assembleline(filename, lineno, current_line, single_line_for_tracker);
945 }
946 70689 }
947
4/6
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 116 not taken.
✓ Branch 115 → 116 taken 5004 times.
✓ Branch 115 → 117 taken 64 times.
✓ Branch 148 → 149 taken 5004 times.
✓ Branch 148 → 150 taken 64 times.
10136 catch (errline&) {}
948
4/6
✗ Branch 82 → 83 not taken.
✗ Branch 82 → 88 not taken.
✓ Branch 83 → 84 taken 30 times.
✓ Branch 83 → 89 taken 23820 times.
✓ Branch 100 → 101 taken 30 times.
✓ Branch 100 → 114 taken 24063 times.
47943 return (numif < prevnumif || single_line_for_tracker == 3)
949
18/31
✗ Branch 81 → 82 not taken.
✗ Branch 81 → 83 not taken.
✓ Branch 82 → 83 taken 23850 times.
✓ Branch 82 → 84 taken 1365 times.
✗ Branch 83 → 84 not taken.
✗ Branch 83 → 118 not taken.
✓ Branch 84 → 85 taken 1395 times.
✗ Branch 84 → 87 not taken.
✗ Branch 84 → 119 not taken.
✓ Branch 85 → 86 taken 432 times.
✓ Branch 85 → 88 taken 963 times.
✗ Branch 85 → 118 not taken.
✓ Branch 86 → 87 taken 432 times.
✗ Branch 86 → 88 not taken.
✗ Branch 86 → 119 not taken.
✓ Branch 87 → 88 taken 174 times.
✓ Branch 87 → 89 taken 258 times.
✓ Branch 99 → 100 taken 24093 times.
✓ Branch 99 → 101 taken 1365 times.
✓ Branch 102 → 103 taken 1395 times.
✗ Branch 102 → 153 not taken.
✗ Branch 104 → 105 not taken.
✓ Branch 104 → 106 taken 1395 times.
✓ Branch 106 → 107 taken 432 times.
✓ Branch 106 → 113 taken 963 times.
✓ Branch 108 → 109 taken 432 times.
✗ Branch 108 → 153 not taken.
✗ Branch 110 → 111 not taken.
✓ Branch 110 → 112 taken 432 times.
✓ Branch 112 → 113 taken 174 times.
✓ Branch 112 → 114 taken 258 times.
149289 && (whilestatus[numif].iswhile || whilestatus[numif].is_for);
950 }
951
952
953 4 void parse_std_includes(const char* textfile, autoarray<string>& outarray)
954 {
955 4 char* content = readfilenative(textfile);
956
957
2/3
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 34 not taken.
✓ Branch 3 → 49 taken 3 times.
4 if (content != nullptr)
958 {
959 1 char* pos = content;
960
961
2/4
✗ Branch 32 → 5 not taken.
✗ Branch 32 → 33 not taken.
✓ Branch 47 → 5 taken 4 times.
✓ Branch 47 → 48 taken 1 time.
5 while (pos[0] != '\0')
962 {
963 4 string stdinclude;
964
965 do
966 {
967
3/8
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 9 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✓ Branch 8 → 9 taken 30 times.
✗ Branch 8 → 13 not taken.
✓ Branch 10 → 11 taken 27 times.
✓ Branch 10 → 13 taken 3 times.
30 if (pos[0] != '\r' && pos[0] != '\n')
968 {
969
1/4
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 42 not taken.
✓ Branch 12 → 13 taken 27 times.
✗ Branch 12 → 60 not taken.
27 stdinclude += pos[0];
970 }
971 30 pos++;
972
4/8
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 12 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✓ Branch 15 → 16 taken 29 times.
✓ Branch 15 → 19 taken 1 time.
✓ Branch 17 → 18 taken 26 times.
✓ Branch 17 → 19 taken 3 times.
30 } while (pos[0] != '\0' && pos[0] != '\n');
973
974
1/4
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 42 not taken.
✓ Branch 19 → 20 taken 4 times.
✗ Branch 19 → 60 not taken.
4 strip_whitespace(stdinclude);
975
976
2/4
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 30 not taken.
✓ Branch 21 → 22 taken 3 times.
✓ Branch 21 → 44 taken 1 time.
4 if (stdinclude != "")
977 {
978
3/8
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 42 not taken.
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 25 not taken.
✓ Branch 23 → 24 taken 3 times.
✗ Branch 23 → 60 not taken.
✓ Branch 24 → 25 taken 1 time.
✓ Branch 24 → 36 taken 2 times.
3 if (!path_is_absolute(stdinclude))
979 {
980
2/8
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 37 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 35 not taken.
✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 52 not taken.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 50 not taken.
1 stdinclude = dir(textfile) + stdinclude;
981 }
982
2/8
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 41 not taken.
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 39 not taken.
✓ Branch 39 → 40 taken 3 times.
✗ Branch 39 → 58 not taken.
✓ Branch 41 → 42 taken 3 times.
✗ Branch 41 → 56 not taken.
3 outarray.append(normalize_path(stdinclude));
983 }
984 4 }
985
986 1 free(content);
987 }
988 4 }
989
990 289 void parse_std_defines(const char* textfile)
991 {
992
993 // RPG Hacker: add built-in defines.
994 // (They're not really standard defines, but I was lazy and this was
995 // one convenient place for doing it).
996 289 builtindefines.create("assembler") = "asar";
997
4/9
✓ Branch 5 → 6 taken 129 times.
✗ Branch 5 → 122 not taken.
✓ Branch 6 → 7 taken 286 times.
✗ Branch 6 → 120 not taken.
✗ Branch 6 → 186 not taken.
✓ Branch 7 → 8 taken 160 times.
✗ Branch 7 → 186 not taken.
✓ Branch 9 → 10 taken 160 times.
✗ Branch 9 → 184 not taken.
289 builtindefines.create("assembler_ver") = dec(get_version_int());
998
4/8
✓ Branch 10 → 11 taken 129 times.
✗ Branch 10 → 125 not taken.
✓ Branch 11 → 12 taken 129 times.
✗ Branch 11 → 123 not taken.
✓ Branch 16 → 17 taken 160 times.
✗ Branch 16 → 190 not taken.
✓ Branch 18 → 19 taken 160 times.
✗ Branch 18 → 188 not taken.
289 builtindefines.create("assembler_time") = dec(time(nullptr));
999
1000
3/4
✓ Branch 14 → 15 taken 129 times.
✗ Branch 14 → 16 not taken.
✓ Branch 23 → 24 taken 156 times.
✓ Branch 23 → 25 taken 4 times.
289 if(textfile == nullptr) return;
1001
1002 4 char* content = readfilenative(textfile);
1003
1004
2/4
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 119 not taken.
✓ Branch 26 → 27 taken 1 time.
✓ Branch 26 → 183 taken 3 times.
4 if (content != nullptr)
1005 {
1006 1 char* pos = content;
1007
2/4
✗ Branch 117 → 19 not taken.
✗ Branch 117 → 118 not taken.
✓ Branch 181 → 28 taken 5 times.
✓ Branch 181 → 182 taken 1 time.
6 while (*pos != 0) {
1008 5 string define_name;
1009 5 string define_val;
1010
1011
4/8
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 29 not taken.
✗ Branch 28 → 22 not taken.
✗ Branch 28 → 29 not taken.
✓ Branch 43 → 44 taken 27 times.
✓ Branch 43 → 46 taken 2 times.
✓ Branch 45 → 33 taken 24 times.
✓ Branch 45 → 46 taken 3 times.
29 while (*pos != '=' && *pos != '\n') {
1012
1/4
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 37 taken 24 times.
24 if(*pos == '\r') { pos++; continue; }
1013
1/4
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 129 not taken.
✓ Branch 38 → 39 taken 24 times.
✗ Branch 38 → 196 not taken.
24 define_name += *pos;
1014 24 pos++;
1015 }
1016
4/12
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 33 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 33 not taken.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 33 not taken.
✓ Branch 47 → 48 taken 5 times.
✗ Branch 47 → 54 not taken.
✓ Branch 49 → 50 taken 5 times.
✗ Branch 49 → 54 not taken.
✓ Branch 51 → 52 taken 2 times.
✓ Branch 51 → 54 taken 3 times.
5 if (*pos != 0 && *pos != '\r' && *pos != '\n') pos++; // skip =
1017
3/8
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
✗ Branch 40 → 34 not taken.
✗ Branch 40 → 41 not taken.
✓ Branch 65 → 66 taken 18 times.
✗ Branch 65 → 68 not taken.
✓ Branch 67 → 55 taken 13 times.
✓ Branch 67 → 68 taken 5 times.
18 while (*pos != 0 && *pos != '\n') {
1018
1/4
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 36 not taken.
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 59 taken 13 times.
13 if(*pos == '\r') { pos++; continue; }
1019
1/4
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 129 not taken.
✓ Branch 60 → 61 taken 13 times.
✗ Branch 60 → 196 not taken.
13 define_val += *pos;
1020 13 pos++;
1021 }
1022
1/4
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 43 not taken.
✓ Branch 69 → 70 taken 5 times.
✗ Branch 69 → 72 not taken.
5 if (*pos != 0)
1023 5 pos++; // skip \n
1024 // clean define_name
1025
1/4
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 129 not taken.
✓ Branch 72 → 73 taken 5 times.
✗ Branch 72 → 196 not taken.
5 strip_whitespace(define_name);
1026
1/4
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 129 not taken.
✓ Branch 73 → 74 taken 5 times.
✗ Branch 73 → 196 not taken.
5 define_name.strip_prefix('!'); // remove leading ! if present
1027
1028
2/4
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 51 not taken.
✓ Branch 75 → 76 taken 1 time.
✓ Branch 75 → 80 taken 4 times.
5 if (define_name == "")
1029 {
1030
1/4
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 50 not taken.
✓ Branch 77 → 78 taken 1 time.
✗ Branch 77 → 79 not taken.
1 if (define_val == "")
1031 {
1032 1 continue;
1033 }
1034
1035 throw_err_null(pass, err_stddefines_no_identifier);
1036 }
1037
1038
2/10
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 56 not taken.
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 129 not taken.
✓ Branch 81 → 82 taken 4 times.
✗ Branch 81 → 196 not taken.
✗ Branch 82 → 83 not taken.
✓ Branch 82 → 85 taken 4 times.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 196 not taken.
4 if (!validatedefinename(define_name)) throw_err_null(pass, err_cmdl_define_invalid, "stddefines.txt", define_name.data());
1039
1040 // clean define_val
1041 4 const char* defval = define_val.data();
1042 4 string cleaned_defval;
1043
1044
2/4
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 68 not taken.
✓ Branch 89 → 90 taken 2 times.
✓ Branch 89 → 100 taken 2 times.
4 if (*defval == 0) {
1045 // no value
1046
2/12
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 127 not taken.
✗ Branch 61 → 62 not taken.
✗ Branch 61 → 64 not taken.
✗ Branch 63 → 64 not taken.
✗ Branch 63 → 127 not taken.
✓ Branch 91 → 92 taken 2 times.
✗ Branch 91 → 194 not taken.
✗ Branch 92 → 93 not taken.
✓ Branch 92 → 95 taken 2 times.
✗ Branch 94 → 95 not taken.
✗ Branch 94 → 194 not taken.
2 if (clidefines.exists(define_name)) throw_err_null(pass, err_cmdl_define_override, "Std define", define_name.data());
1047
2/8
✗ Branch 65 → 66 not taken.
✗ Branch 65 → 127 not taken.
✗ Branch 66 → 67 not taken.
✗ Branch 66 → 127 not taken.
✓ Branch 96 → 97 taken 2 times.
✗ Branch 96 → 194 not taken.
✓ Branch 98 → 99 taken 2 times.
✗ Branch 98 → 194 not taken.
2 clidefines.create(define_name) = "";
1048 2 continue;
1049 }
1050
1051
3/8
✗ Branch 70 → 69 not taken.
✗ Branch 70 → 71 not taken.
✗ Branch 71 → 69 not taken.
✗ Branch 71 → 72 not taken.
✓ Branch 104 → 101 taken 2 times.
✓ Branch 104 → 105 taken 2 times.
✗ Branch 106 → 101 not taken.
✓ Branch 106 → 107 taken 2 times.
4 while (*defval == ' ' || *defval == '\t') defval++; // skip whitespace in beginning
1052
2/4
✗ Branch 72 → 73 not taken.
✗ Branch 72 → 95 not taken.
✓ Branch 108 → 109 taken 1 time.
✓ Branch 108 → 144 taken 1 time.
2 if (*defval == '"') {
1053 1 defval++; // skip opening quote
1054
3/8
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 77 not taken.
✗ Branch 76 → 74 not taken.
✗ Branch 76 → 77 not taken.
✓ Branch 115 → 116 taken 5 times.
✓ Branch 115 → 118 taken 1 time.
✓ Branch 117 → 111 taken 5 times.
✗ Branch 117 → 118 not taken.
6 while (*defval != '"' && *defval != 0)
1055
1/4
✗ Branch 74 → 75 not taken.
✗ Branch 74 → 127 not taken.
✓ Branch 113 → 114 taken 5 times.
✗ Branch 113 → 194 not taken.
5 cleaned_defval += *defval++;
1056
1057
1/4
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 79 not taken.
✗ Branch 119 → 120 not taken.
✓ Branch 119 → 121 taken 1 time.
1 if (*defval == 0) {
1058 throw_err_null(pass, err_mismatched_quotes);
1059 }
1060 1 defval++; // skip closing quote
1061
2/8
✗ Branch 81 → 80 not taken.
✗ Branch 81 → 82 not taken.
✗ Branch 82 → 80 not taken.
✗ Branch 82 → 83 not taken.
✗ Branch 126 → 123 not taken.
✓ Branch 126 → 127 taken 1 time.
✗ Branch 128 → 123 not taken.
✓ Branch 128 → 129 taken 1 time.
1 while (*defval == ' ' || *defval == '\t') defval++; // skip whitespace
1062
1/8
✗ Branch 83 → 84 not taken.
✗ Branch 83 → 86 not taken.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 86 not taken.
✗ Branch 130 → 131 not taken.
✓ Branch 130 → 134 taken 1 time.
✗ Branch 132 → 133 not taken.
✗ Branch 132 → 134 not taken.
1 if (*defval != 0 && *defval != '\n')
1063 throw_err_null(pass, err_stddefine_after_closing_quote);
1064
1065
2/12
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 127 not taken.
✗ Branch 88 → 89 not taken.
✗ Branch 88 → 91 not taken.
✗ Branch 90 → 91 not taken.
✗ Branch 90 → 127 not taken.
✓ Branch 135 → 136 taken 1 time.
✗ Branch 135 → 194 not taken.
✗ Branch 136 → 137 not taken.
✓ Branch 136 → 139 taken 1 time.
✗ Branch 138 → 139 not taken.
✗ Branch 138 → 194 not taken.
1 if (clidefines.exists(define_name)) throw_err_null(pass, err_cmdl_define_override, "Std define", define_name.data());
1066
2/8
✗ Branch 92 → 93 not taken.
✗ Branch 92 → 127 not taken.
✗ Branch 93 → 94 not taken.
✗ Branch 93 → 127 not taken.
✓ Branch 140 → 141 taken 1 time.
✗ Branch 140 → 194 not taken.
✓ Branch 142 → 143 taken 1 time.
✗ Branch 142 → 194 not taken.
1 clidefines.create(define_name) = cleaned_defval;
1067 1 continue;
1068 }
1069 else
1070 {
1071 // slightly hacky way to remove trailing whitespace
1072
1/2
✗ Branch 144 → 145 not taken.
✓ Branch 144 → 146 taken 1 time.
1 const char* defval_end = strchr(defval, '\n'); // slightly hacky way to get end of string or newline
1073
2/6
✗ Branch 95 → 96 not taken.
✗ Branch 95 → 97 not taken.
✓ Branch 146 → 147 taken 1 time.
✗ Branch 146 → 150 not taken.
✗ Branch 147 → 148 not taken.
✓ Branch 147 → 149 taken 1 time.
1 if (!defval_end) defval_end = strchr(defval, 0);
1074 1 defval_end--;
1075
3/8
✗ Branch 99 → 98 not taken.
✗ Branch 99 → 100 not taken.
✗ Branch 100 → 98 not taken.
✗ Branch 100 → 101 not taken.
✓ Branch 155 → 152 taken 3 times.
✓ Branch 155 → 156 taken 1 time.
✗ Branch 157 → 152 not taken.
✓ Branch 157 → 158 taken 1 time.
4 while (*defval_end == ' ' || *defval_end == '\t') defval_end--;
1076
1/4
✗ Branch 101 → 102 not taken.
✗ Branch 101 → 126 not taken.
✓ Branch 159 → 160 taken 1 time.
✗ Branch 159 → 192 not taken.
1 cleaned_defval = string(defval, (int)(defval_end - defval + 1));
1077
1078
2/12
✗ Branch 105 → 106 not taken.
✗ Branch 105 → 127 not taken.
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 109 not taken.
✗ Branch 108 → 109 not taken.
✗ Branch 108 → 127 not taken.
✓ Branch 165 → 166 taken 1 time.
✗ Branch 165 → 194 not taken.
✗ Branch 166 → 167 not taken.
✓ Branch 166 → 169 taken 1 time.
✗ Branch 168 → 169 not taken.
✗ Branch 168 → 194 not taken.
1 if (clidefines.exists(define_name)) throw_err_null(pass, err_cmdl_define_override, "Std define", define_name.data());
1079
2/8
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 127 not taken.
✗ Branch 111 → 112 not taken.
✗ Branch 111 → 127 not taken.
✓ Branch 170 → 171 taken 1 time.
✗ Branch 170 → 194 not taken.
✓ Branch 172 → 173 taken 1 time.
✗ Branch 172 → 194 not taken.
1 clidefines.create(define_name) = cleaned_defval;
1080 1 continue;
1081 1 }
1082
1083 5 }
1084 1 free(content);
1085 }
1086 }
1087
1088 bool checksum_fix_enabled = true;
1089 bool force_checksum_fix = false;
1090
1091 #define cfree(x) free((void*)x)
1092 138 static void clearmacro(const string & key, macrodata* & macro)
1093 {
1094 (void)key;
1095 138 freemacro(macro);
1096 138 }
1097
1098 330 static void clearfile(const string & key, sourcefile& filecontent)
1099 {
1100 (void)key;
1101 330 cfree(filecontent.data);
1102 330 cfree(filecontent.contents);
1103 330 }
1104 #undef cfree
1105
1106 870 static void adddefine(const string & key, string & value)
1107 {
1108
2/4
✓ Branch 4 → 5 taken 387 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 483 times.
✗ Branch 5 → 12 not taken.
870 if (!defines.exists(key)) defines.create(key) = value;
1109 870 }
1110
1111 1 string create_symbols_file(string format, uint32_t romCrc){
1112 1 string symbolfile;
1113
1114 1 std::vector<std::pair<unsigned int, const char*>> all_labels;
1115
1/5
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 70 not taken.
✗ Branch 4 → 75 not taken.
✓ Branch 6 → 7 taken 1 time.
✗ Branch 6 → 141 not taken.
1 labels.each([&all_labels](const string& key, snes_label& label) {
1116
2/8
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 6 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 17 not taken.
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 17 not taken.
2 all_labels.push_back(std::make_pair(label.pos, key.data()));
1117 2 });
1118
1/5
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 70 not taken.
✗ Branch 7 → 75 not taken.
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 141 not taken.
1 std::sort(all_labels.begin(), all_labels.end(),
1119 1 [](auto& l, auto& r) {
1120
1/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 14 taken 1 time.
1 if (l.first == r.first)
1121 return strcmp(l.second, r.second) < 0;
1122 1 return l.first < r.first;
1123 });
1124
1125
1/5
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 70 not taken.
✗ Branch 9 → 75 not taken.
✓ Branch 12 → 13 taken 1 time.
✗ Branch 12 → 141 not taken.
1 format = lower(format);
1126
1/5
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 45 not taken.
✗ Branch 11 → 49 not taken.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 94 not taken.
1 if(format == "wla")
1127 {
1128
1/5
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 70 not taken.
✗ Branch 12 → 75 not taken.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 141 not taken.
1 symbolfile = "; wla symbolic information file\n";
1129
1/5
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 70 not taken.
✗ Branch 13 → 75 not taken.
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 141 not taken.
1 symbolfile += "; generated by asar\n";
1130
1131
1/5
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 70 not taken.
✗ Branch 14 → 75 not taken.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 141 not taken.
1 symbolfile += "\n[labels]\n";
1132
2/6
✗ Branch 23 → 17 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 24 → 17 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 39 → 24 taken 2 times.
✓ Branch 39 → 40 taken 1 time.
3 for (auto& p : all_labels) {
1133 2 char buffer[10];
1134
1/4
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 68 not taken.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 2 times.
2 std::snprintf(buffer, sizeof(buffer), "%02X:%04X ", (p.first >> 16) & 0xFF, p.first & 0xFFFF);
1135
1136
1/6
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 63 not taken.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 68 not taken.
✓ Branch 31 → 32 taken 2 times.
✗ Branch 31 → 125 not taken.
2 symbolfile += buffer;
1137
1/6
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 63 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 68 not taken.
✓ Branch 34 → 35 taken 2 times.
✗ Branch 34 → 125 not taken.
2 symbolfile += p.second;
1138
1/6
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 63 not taken.
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 68 not taken.
✓ Branch 35 → 36 taken 2 times.
✗ Branch 35 → 125 not taken.
2 symbolfile += "\n";
1139 }
1140
1141
1/6
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 70 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 75 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 141 not taken.
1 symbolfile += "\n[source files]\n";
1142 1 const autoarray<AddressToLineMapping::FileInfo>& addrToLineFileList = addressToLineMapping.getFileList();
1143
2/6
✗ Branch 32 → 27 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 34 → 28 not taken.
✗ Branch 34 → 35 not taken.
✓ Branch 61 → 45 taken 1 time.
✓ Branch 61 → 62 taken 1 time.
2 for (int i = 0; i < addrToLineFileList.count; ++i)
1144 {
1145 1 char addrToFileListStr[256];
1146 1 snprintf(addrToFileListStr, 256, "%.4x %.8x %s\n",
1147 i,
1148
2/10
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 65 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 70 not taken.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 70 not taken.
✓ Branch 52 → 53 taken 1 time.
✗ Branch 52 → 130 not taken.
✗ Branch 55 → 56 not taken.
✓ Branch 55 → 57 taken 1 time.
1 addrToLineFileList[i].fileCrc,
1149
1/6
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 65 not taken.
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 70 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 130 not taken.
1 addrToLineFileList[i].filename.data()
1150 );
1151
1/6
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 65 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 70 not taken.
✓ Branch 57 → 58 taken 1 time.
✗ Branch 57 → 130 not taken.
1 symbolfile += addrToFileListStr;
1152 }
1153
1154
1/6
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 70 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 75 not taken.
✓ Branch 62 → 63 taken 1 time.
✗ Branch 62 → 141 not taken.
1 symbolfile += "\n[rom checksum]\n";
1155 {
1156 1 char romCrcStr[32];
1157
1/4
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 71 not taken.
✗ Branch 64 → 65 not taken.
✓ Branch 64 → 66 taken 1 time.
1 snprintf(romCrcStr, 32, "%.8x\n",
1158 romCrc
1159 );
1160
1/6
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 66 not taken.
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 71 not taken.
✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 132 not taken.
1 symbolfile += romCrcStr;
1161 }
1162
1163
1/6
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 70 not taken.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 75 not taken.
✓ Branch 68 → 69 taken 1 time.
✗ Branch 68 → 141 not taken.
1 symbolfile += "\n[addr-to-line mapping]\n";
1164 1 const autoarray<AddressToLineMapping::AddrToLineInfo>& addrToLineInfo = addressToLineMapping.getAddrToLineInfo();
1165
2/6
✗ Branch 44 → 38 not taken.
✗ Branch 44 → 60 not taken.
✗ Branch 48 → 41 not taken.
✗ Branch 48 → 65 not taken.
✓ Branch 93 → 71 taken 3 times.
✓ Branch 93 → 122 taken 1 time.
4 for (int i = 0; i < addrToLineInfo.count; ++i)
1166 {
1167 3 char addrToLineStr[32];
1168 snprintf(addrToLineStr, 32, "%.2x:%.4x %.4x:%.8x\n",
1169
2/6
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 72 not taken.
✓ Branch 84 → 85 taken 3 times.
✗ Branch 84 → 134 not taken.
✗ Branch 87 → 88 not taken.
✓ Branch 87 → 89 taken 3 times.
3 (addrToLineInfo[i].addr & 0xFF0000) >> 16,
1170
1/6
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 67 not taken.
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 72 not taken.
✓ Branch 80 → 81 taken 3 times.
✗ Branch 80 → 134 not taken.
3 addrToLineInfo[i].addr & 0xFFFF,
1171
1/6
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 67 not taken.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 72 not taken.
✓ Branch 77 → 78 taken 3 times.
✗ Branch 77 → 134 not taken.
3 addrToLineInfo[i].fileIdx & 0xFFFF,
1172
1/10
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 67 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 67 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 72 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 72 not taken.
✓ Branch 73 → 74 taken 3 times.
✗ Branch 73 → 134 not taken.
3 addrToLineInfo[i].line & 0xFFFFFFFF
1173 );
1174
1/6
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 67 not taken.
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 72 not taken.
✓ Branch 89 → 90 taken 3 times.
✗ Branch 89 → 134 not taken.
3 symbolfile += addrToLineStr;
1175 }
1176
1177 }
1178 else if (format == "nocash")
1179 {
1180 symbolfile = ";no$sns symbolic information file\n";
1181 symbolfile += ";generated by asar\n";
1182 symbolfile += "\n";
1183 for (auto& p : all_labels) {
1184 char buffer[10];
1185 std::snprintf(buffer, sizeof(buffer), "%08X ", p.first & 0xFFFFFF);
1186
1187 symbolfile += buffer;
1188 symbolfile += p.second;
1189 symbolfile += "\n";
1190 }
1191 }
1192 1 return symbolfile;
1193 1 }
1194
1195
1196 2 bool in_top_level_file()
1197 {
1198 2 int num_files = 0;
1199
4/4
✓ Branch 9 → 4 taken 3 times.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 10 → 4 taken 3 times.
✓ Branch 10 → 11 taken 1 time.
8 for (int i = (int)callstack.size()-1; i >= 0; --i)
1200 {
1201
4/4
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 8 taken 2 times.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 9 taken 2 times.
6 if (callstack[i].type == callstack_entry_type::FILE)
1202 {
1203 2 num_files++;
1204
2/4
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1 time.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
2 if (num_files > 1) break;
1205 }
1206 }
1207 2 return (num_files <= 1);
1208 }
1209
1210 17086 const char* get_current_file_name()
1211 {
1212
4/4
✓ Branch 9 → 4 taken 24168 times.
✓ Branch 9 → 10 taken 379 times.
✓ Branch 12 → 4 taken 24330 times.
✓ Branch 12 → 13 taken 473 times.
49350 for (int i = (int)callstack.size()-1; i >= 0; --i)
1213 {
1214
4/4
✓ Branch 5 → 6 taken 8090 times.
✓ Branch 5 → 8 taken 16078 times.
✓ Branch 6 → 7 taken 8144 times.
✓ Branch 6 → 11 taken 16186 times.
48498 if (callstack[i].type == callstack_entry_type::FILE)
1215 16234 return callstack[i].content;
1216 }
1217 852 return nullptr;
1218 }
1219
1220 9062 int get_current_line()
1221 {
1222
4/4
✓ Branch 9 → 4 taken 8925 times.
✓ Branch 9 → 10 taken 5 times.
✓ Branch 12 → 4 taken 8991 times.
✓ Branch 12 → 13 taken 6 times.
17927 for (int i = (int)callstack.size()-1; i >= 0; --i)
1223 {
1224
4/4
✓ Branch 5 → 6 taken 4509 times.
✓ Branch 5 → 8 taken 4416 times.
✓ Branch 6 → 7 taken 4542 times.
✓ Branch 6 → 11 taken 4449 times.
17916 if (callstack[i].type == callstack_entry_type::LINE) return callstack[i].lineno;
1225 }
1226 11 return -1;
1227 }
1228
1229 270 const char* get_current_block()
1230 {
1231
4/4
✓ Branch 14 → 4 taken 131 times.
✓ Branch 14 → 15 taken 5 times.
✓ Branch 18 → 4 taken 134 times.
✓ Branch 18 → 19 taken 6 times.
276 for (int i = (int)callstack.size()-1; i >= 0; --i)
1232 {
1233
12/12
✓ Branch 5 → 6 taken 105 times.
✓ Branch 5 → 8 taken 26 times.
✓ Branch 6 → 7 taken 108 times.
✓ Branch 6 → 10 taken 26 times.
✓ Branch 7 → 8 taken 102 times.
✓ Branch 7 → 9 taken 3 times.
✓ Branch 9 → 10 taken 105 times.
✓ Branch 9 → 11 taken 3 times.
✓ Branch 10 → 11 taken 128 times.
✓ Branch 10 → 13 taken 3 times.
✓ Branch 12 → 13 taken 131 times.
✓ Branch 12 → 17 taken 3 times.
265 if (callstack[i].type == callstack_entry_type::LINE || callstack[i].type == callstack_entry_type::BLOCK) return callstack[i].content;
1234 }
1235 11 return nullptr;
1236 }
1237
1238
1239 292 void reseteverything()
1240 {
1241 292 string str;
1242 292 labels.reset();
1243 292 defines.reset();
1244
2/4
✓ Branch 5 → 6 taken 130 times.
✗ Branch 5 → 17 not taken.
✓ Branch 7 → 8 taken 162 times.
✗ Branch 7 → 24 not taken.
292 builtindefines.each(adddefine);
1245
2/4
✓ Branch 6 → 7 taken 130 times.
✗ Branch 6 → 17 not taken.
✓ Branch 8 → 9 taken 162 times.
✗ Branch 8 → 24 not taken.
292 clidefines.each(adddefine);
1246 292 structs.reset();
1247
1248
2/4
✓ Branch 8 → 9 taken 130 times.
✗ Branch 8 → 17 not taken.
✓ Branch 12 → 13 taken 162 times.
✗ Branch 12 → 24 not taken.
292 macros.each(clearmacro);
1249 292 macros.reset();
1250
1251
2/4
✓ Branch 10 → 11 taken 130 times.
✗ Branch 10 → 17 not taken.
✓ Branch 15 → 16 taken 162 times.
✗ Branch 15 → 24 not taken.
292 filecontents.each(clearfile);
1252 292 filecontents.reset();
1253
1254 292 writtenblocks.reset();
1255
1256 292 optimizeforbank=-1;
1257 292 optimize_dp = optimize_dp_flag::ALWAYS;
1258 292 dp_base = 0;
1259 292 optimize_address = optimize_address_flag::MIRRORS;
1260
1261
2/4
✓ Branch 13 → 14 taken 130 times.
✗ Branch 13 → 17 not taken.
✓ Branch 19 → 20 taken 162 times.
✗ Branch 19 → 24 not taken.
292 closecachedfiles();
1262
1263 292 incsrcdepth=0;
1264 292 label_counter = 0;
1265 292 errored = false;
1266 292 checksum_fix_enabled = true;
1267 292 force_checksum_fix = false;
1268
1269 292 in_macro_def = 0;
1270
1271 292 callstack.clear();
1272 292 simple_callstacks = true;
1273 454 }
1274