Line |
Branch |
Exec |
Source |
1 |
|
|
#include "asar.h" |
2 |
|
|
#include "crc32.h" |
3 |
|
|
#include "virtualfile.h" |
4 |
|
|
#include "platform/file-helpers.h" |
5 |
|
|
#include "interface-shared.h" |
6 |
|
|
#include "assembleblock.h" |
7 |
|
|
#include "asar_math.h" |
8 |
|
|
#include "platform/thread-helpers.h" |
9 |
|
|
#include <algorithm> |
10 |
|
|
|
11 |
|
|
#if defined(CPPCLI) |
12 |
|
|
#define EXPORT extern "C" |
13 |
|
|
#elif defined(_WIN32) |
14 |
|
|
#ifdef ASAR_SHARED |
15 |
|
|
#define EXPORT extern "C" __declspec(dllexport) |
16 |
|
|
#elif defined(ASAR_STATIC) |
17 |
|
|
#define EXPORT extern "C" |
18 |
|
|
#endif |
19 |
|
|
#else |
20 |
|
|
#define EXPORT extern "C" __attribute__ ((visibility ("default"))) |
21 |
|
|
#endif |
22 |
|
|
|
23 |
|
|
static autoarray<const char *> prints; |
24 |
|
|
static string symbolsfile; |
25 |
|
|
static int numprint; |
26 |
|
|
static uint32_t romCrc; |
27 |
|
|
|
28 |
|
|
#define APIVERSION 400 |
29 |
|
|
|
30 |
|
|
// note: somewhat fragile, assumes that every patchparams struct inherits from exactly the previous one |
31 |
|
|
/* $EXPORTSTRUCT_PP$ |
32 |
|
|
*/ |
33 |
|
|
struct patchparams_base { |
34 |
|
|
// The size of this struct. Set to (int)sizeof(patchparams). |
35 |
|
|
int structsize; |
36 |
|
|
}; |
37 |
|
|
|
38 |
|
|
|
39 |
|
|
/* $EXPORTSTRUCT$ |
40 |
|
|
*/ |
41 |
|
|
struct stackentry { |
42 |
|
|
const char * fullpath; |
43 |
|
|
const char * prettypath; |
44 |
|
|
int lineno; |
45 |
|
|
const char * details; |
46 |
|
|
}; |
47 |
|
|
|
48 |
|
|
/* $EXPORTSTRUCT$ |
49 |
|
|
*/ |
50 |
|
|
struct errordata { |
51 |
|
|
const char * fullerrdata; |
52 |
|
|
const char * rawerrdata; |
53 |
|
|
const char * block; |
54 |
|
|
const char * filename; |
55 |
|
|
int line; |
56 |
|
|
const struct stackentry * callstack; |
57 |
|
|
int callstacksize; |
58 |
|
|
const char * errname; |
59 |
|
|
}; |
60 |
|
|
static autoarray<errordata> errors; |
61 |
|
|
static int numerror; |
62 |
|
|
|
63 |
|
|
static autoarray<errordata> warnings; |
64 |
|
|
static int numwarn; |
65 |
|
|
|
66 |
|
|
/* $EXPORTSTRUCT$ |
67 |
|
|
*/ |
68 |
|
|
struct labeldata { |
69 |
|
|
const char * name; |
70 |
|
|
int location; |
71 |
|
|
}; |
72 |
|
|
|
73 |
|
|
/* $EXPORTSTRUCT$ |
74 |
|
|
*/ |
75 |
|
|
struct definedata { |
76 |
|
|
const char * name; |
77 |
|
|
const char * contents; |
78 |
|
|
}; |
79 |
|
|
|
80 |
|
|
/* $EXPORTSTRUCT$ |
81 |
|
|
*/ |
82 |
|
|
struct warnsetting { |
83 |
|
|
const char * warnid; |
84 |
|
|
bool enabled; |
85 |
|
|
}; |
86 |
|
|
|
87 |
|
|
/* $EXPORTSTRUCT$ |
88 |
|
|
*/ |
89 |
|
|
struct memoryfile { |
90 |
|
|
const char* path; |
91 |
|
|
const void* buffer; |
92 |
|
|
size_t length; |
93 |
|
|
}; |
94 |
|
|
|
95 |
|
98 |
void print(const char * str) |
96 |
|
|
{ |
97 |
|
98 |
prints[numprint++]= duplicate_string(str); |
98 |
|
98 |
} |
99 |
|
|
|
100 |
|
272 |
static void fillerror(errordata& myerr, const char* errname, const char * type, const char * str, bool show_block) |
101 |
|
|
{ |
102 |
1/2
✓ Branch 0 taken 272 times.
✗ Branch 1 not taken.
|
272 |
const char* current_filename = get_current_file_name(); |
103 |
2/2
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 1 times.
|
272 |
if(current_filename) myerr.filename= duplicate_string(current_filename); |
104 |
|
1 |
else myerr.filename = duplicate_string(""); |
105 |
1/2
✓ Branch 0 taken 272 times.
✗ Branch 1 not taken.
|
272 |
myerr.line=get_current_line(); |
106 |
1/2
✓ Branch 0 taken 272 times.
✗ Branch 1 not taken.
|
272 |
const char* current_block = get_current_block(); |
107 |
2/2
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 11 times.
|
272 |
if (current_block) myerr.block= duplicate_string(current_block); |
108 |
|
11 |
else myerr.block= duplicate_string(""); |
109 |
|
272 |
myerr.rawerrdata= duplicate_string(str); |
110 |
|
272 |
string location; |
111 |
|
272 |
string details; |
112 |
1/2
✓ Branch 0 taken 272 times.
✗ Branch 1 not taken.
|
272 |
get_current_line_details(&location, &details); |
113 |
11/21
✓ Branch 0 taken 133 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 133 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 133 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 133 times.
✓ Branch 9 taken 139 times.
✓ Branch 10 taken 133 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 139 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 139 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 139 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 139 times.
✗ Branch 20 not taken.
|
272 |
myerr.fullerrdata= duplicate_string(location+": "+type+str+details+get_callstack()); |
114 |
|
272 |
myerr.errname = duplicate_string(errname); |
115 |
|
|
|
116 |
|
272 |
autoarray<printable_callstack_entry> printable_stack; |
117 |
1/2
✓ Branch 0 taken 272 times.
✗ Branch 1 not taken.
|
272 |
get_full_printable_callstack(&printable_stack, 0, false); |
118 |
|
|
|
119 |
|
272 |
myerr.callstacksize = printable_stack.count; |
120 |
|
272 |
myerr.callstack = static_cast<stackentry*>(malloc(sizeof(stackentry) * myerr.callstacksize)); |
121 |
|
|
|
122 |
4/4
✓ Branch 0 taken 2334 times.
✓ Branch 1 taken 133 times.
✓ Branch 2 taken 1259 times.
✓ Branch 3 taken 139 times.
|
3865 |
for (int i = 0; i < myerr.callstacksize; ++i) |
123 |
|
|
{ |
124 |
|
3593 |
stackentry& entry = const_cast<stackentry&>(myerr.callstack[i]); |
125 |
|
|
|
126 |
1/2
✓ Branch 0 taken 3593 times.
✗ Branch 1 not taken.
|
3593 |
entry.fullpath = duplicate_string(printable_stack[i].fullpath); |
127 |
1/2
✓ Branch 0 taken 3593 times.
✗ Branch 1 not taken.
|
3593 |
entry.prettypath = duplicate_string(printable_stack[i].prettypath); |
128 |
1/2
✓ Branch 0 taken 3593 times.
✗ Branch 1 not taken.
|
3593 |
entry.lineno = printable_stack[i].lineno; |
129 |
1/2
✓ Branch 0 taken 3593 times.
✗ Branch 1 not taken.
|
3593 |
entry.details = duplicate_string(printable_stack[i].details); |
130 |
|
|
} |
131 |
|
411 |
} |
132 |
|
|
|
133 |
|
|
static bool ismath=false; |
134 |
|
|
static string matherror; |
135 |
|
|
|
136 |
|
541 |
void error_interface(int errid, int whichpass, const char * e_) |
137 |
|
|
{ |
138 |
|
541 |
errored = true; |
139 |
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 541 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 274 times.
|
541 |
if (ismath) matherror = e_; |
140 |
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 311 times.
|
539 |
else if (pass == whichpass) { |
141 |
|
|
// don't show current block if the error came from an error command |
142 |
|
228 |
bool show_block = (errid != error_id_error_command); |
143 |
13/20
✓ Branch 0 taken 113 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 228 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 113 times.
✓ Branch 5 taken 115 times.
✓ Branch 6 taken 113 times.
✓ Branch 7 taken 115 times.
✓ Branch 8 taken 113 times.
✓ Branch 9 taken 115 times.
✓ Branch 10 taken 113 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 113 times.
✓ Branch 13 taken 115 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 115 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 115 times.
✗ Branch 19 not taken.
|
228 |
fillerror(errors[numerror++], get_error_name((asar_error_id)errid), STR "error: (" + get_error_name((asar_error_id)errid) + "): ", e_, show_block); |
144 |
|
|
} |
145 |
|
|
else {}//ignore anything else |
146 |
|
541 |
} |
147 |
|
|
|
148 |
|
44 |
void warn(int errid, const char * str) |
149 |
|
|
{ |
150 |
|
|
// don't show current block if the warning came from a warn command |
151 |
|
44 |
bool show_block = (errid != warning_id_warn_command); |
152 |
13/20
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 24 times.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 24 times.
✓ Branch 8 taken 20 times.
✓ Branch 9 taken 24 times.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 20 times.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 24 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 24 times.
✗ Branch 19 not taken.
|
44 |
fillerror(warnings[numwarn++], get_warning_name((asar_warning_id)errid), STR "warning: (" + get_warning_name((asar_warning_id)errid) + "): ", str, show_block); |
153 |
|
44 |
} |
154 |
|
|
|
155 |
|
|
static autoarray<labeldata> ldata; |
156 |
|
|
static int labelsinldata = 0; |
157 |
|
|
static autoarray<definedata> ddata; |
158 |
|
|
static int definesinddata=0; |
159 |
|
|
|
160 |
|
285 |
static void resetdllstuff() |
161 |
|
|
{ |
162 |
|
|
#define free_and_null(x) free((void*)x); x = nullptr |
163 |
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 285 times.
|
383 |
for (int i=0;i<numprint;i++) |
164 |
|
|
{ |
165 |
|
98 |
free_and_null(prints[i]); |
166 |
|
|
} |
167 |
|
285 |
prints.reset(); |
168 |
|
285 |
numprint=0; |
169 |
|
|
|
170 |
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 285 times.
|
513 |
for (int i=0;i<numerror;i++) |
171 |
|
|
{ |
172 |
|
228 |
free_and_null(errors[i].filename); |
173 |
|
228 |
free_and_null(errors[i].rawerrdata); |
174 |
|
228 |
free_and_null(errors[i].fullerrdata); |
175 |
|
228 |
free_and_null(errors[i].block); |
176 |
|
228 |
free_and_null(errors[i].errname); |
177 |
|
|
|
178 |
4/4
✓ Branch 0 taken 2334 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 1255 times.
✓ Branch 3 taken 115 times.
|
3817 |
for (int j=0;j<errors[i].callstacksize;++j) |
179 |
|
|
{ |
180 |
|
3589 |
stackentry& entry = const_cast<stackentry&>(errors[i].callstack[j]); |
181 |
|
3589 |
free_and_null(entry.fullpath); |
182 |
|
3589 |
free_and_null(entry.prettypath); |
183 |
|
3589 |
free_and_null(entry.details); |
184 |
|
|
} |
185 |
|
228 |
free_and_null(errors[i].callstack); |
186 |
|
|
} |
187 |
|
285 |
errors.reset(); |
188 |
|
285 |
numerror=0; |
189 |
|
|
|
190 |
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 285 times.
|
329 |
for (int i=0;i<numwarn;i++) |
191 |
|
|
{ |
192 |
|
44 |
free_and_null(warnings[i].filename); |
193 |
|
44 |
free_and_null(warnings[i].rawerrdata); |
194 |
|
44 |
free_and_null(warnings[i].fullerrdata); |
195 |
|
44 |
free_and_null(warnings[i].block); |
196 |
|
44 |
free_and_null(warnings[i].errname); |
197 |
|
|
|
198 |
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 24 times.
|
48 |
for (int j=0;j<warnings[i].callstacksize;++j) |
199 |
|
|
{ |
200 |
|
4 |
stackentry& entry = const_cast<stackentry&>(warnings[i].callstack[j]); |
201 |
|
4 |
free_and_null(entry.fullpath); |
202 |
|
4 |
free_and_null(entry.prettypath); |
203 |
|
4 |
free_and_null(entry.details); |
204 |
|
|
} |
205 |
|
44 |
free_and_null(warnings[i].callstack); |
206 |
|
|
} |
207 |
|
285 |
warnings.reset(); |
208 |
|
285 |
numwarn=0; |
209 |
|
|
|
210 |
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 285 times.
|
308 |
for (int i=0;i<definesinddata;i++) |
211 |
|
|
{ |
212 |
|
23 |
free_and_null(ddata[i].name); |
213 |
|
23 |
free_and_null(ddata[i].contents); |
214 |
|
|
} |
215 |
|
285 |
ddata.reset(); |
216 |
|
285 |
definesinddata=0; |
217 |
|
|
|
218 |
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 285 times.
|
292 |
for (int i=0;i<labelsinldata;i++) |
219 |
|
7 |
free((void*)ldata[i].name); |
220 |
|
285 |
ldata.reset(); |
221 |
|
285 |
labelsinldata=0; |
222 |
|
|
#undef free_and_null |
223 |
|
|
|
224 |
|
285 |
romCrc = 0; |
225 |
|
285 |
clidefines.reset(); |
226 |
|
285 |
reset_warnings_to_default(); |
227 |
|
|
|
228 |
|
285 |
reseteverything(); |
229 |
|
285 |
} |
230 |
|
|
|
231 |
|
|
#define maxromsize (16*1024*1024) |
232 |
|
|
|
233 |
|
|
static bool expectsNewAPI = false; |
234 |
|
|
|
235 |
|
|
/* $EXPORTSTRUCT_PP$ |
236 |
|
|
*/ |
237 |
|
|
struct patchparams_v200 : public patchparams_base |
238 |
|
|
{ |
239 |
|
|
// Same parameters as asar_patch() |
240 |
|
|
const char * patchloc; |
241 |
|
|
char * romdata; |
242 |
|
|
int buflen; |
243 |
|
|
int * romlen; |
244 |
|
|
|
245 |
|
|
// Include paths to use when searching files. |
246 |
|
|
const char** includepaths; |
247 |
|
|
int numincludepaths; |
248 |
|
|
|
249 |
|
|
// A list of additional defines to make available to the patch. |
250 |
|
|
const struct definedata* additional_defines; |
251 |
|
|
int additional_define_count; |
252 |
|
|
|
253 |
|
|
// Path to a text file to parse standard include search paths from. |
254 |
|
|
// Set to NULL to not use any standard includes search paths. |
255 |
|
|
const char* stdincludesfile; |
256 |
|
|
|
257 |
|
|
// Path to a text file to parse standard defines from. |
258 |
|
|
// Set to NULL to not use any standard defines. |
259 |
|
|
const char* stddefinesfile; |
260 |
|
|
|
261 |
|
|
// A list of warnings to enable or disable. |
262 |
|
|
// Specify warnings in the format "WXXXX" where XXXX = warning ID. |
263 |
|
|
const struct warnsetting * warning_settings; |
264 |
|
|
int warning_setting_count; |
265 |
|
|
|
266 |
|
|
// List of memory files to create on the virtual filesystem. |
267 |
|
|
const struct memoryfile * memory_files; |
268 |
|
|
int memory_file_count; |
269 |
|
|
|
270 |
|
|
// Set override_checksum_gen to true and generate_checksum to true/false |
271 |
|
|
// to force generating/not generating a checksum. |
272 |
|
|
bool override_checksum_gen; |
273 |
|
|
bool generate_checksum; |
274 |
|
|
|
275 |
|
|
// Set this to true for generated error and warning texts to always |
276 |
|
|
// contain their full call stack. |
277 |
|
|
bool full_call_stack; |
278 |
|
|
}; |
279 |
|
|
|
280 |
|
|
/* $EXPORTSTRUCT_PP$ |
281 |
|
|
*/ |
282 |
|
|
struct patchparams : public patchparams_v200 |
283 |
|
|
{ |
284 |
|
|
|
285 |
|
|
}; |
286 |
|
|
|
287 |
|
281 |
static void asar_patch_begin(char * romdata_, int buflen, int * romlen_) |
288 |
|
|
{ |
289 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
|
281 |
if (buflen != maxromsize) |
290 |
|
|
{ |
291 |
|
✗ |
romdata_r = (unsigned char*)malloc(maxromsize); |
292 |
|
✗ |
memcpy(const_cast<unsigned char*>(romdata_r)/*we just allocated this, it's safe to violate its const*/, romdata_, (size_t)*romlen_); |
293 |
|
|
} |
294 |
|
281 |
else romdata_r = (unsigned char*)romdata_; |
295 |
|
281 |
romdata = (unsigned char*)malloc(maxromsize); |
296 |
|
|
// RPG Hacker: Without this memset, freespace commands can (and probably will) fail. |
297 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
|
281 |
memset((void*)romdata, 0, maxromsize); |
298 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
|
281 |
memcpy(const_cast<unsigned char*>(romdata), romdata_, (size_t)*romlen_); |
299 |
|
281 |
resetdllstuff(); |
300 |
|
281 |
romlen = *romlen_; |
301 |
|
281 |
romlen_r = *romlen_; |
302 |
|
281 |
} |
303 |
|
|
|
304 |
|
281 |
static void asar_patch_main(const char * patchloc) |
305 |
|
|
{ |
306 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 280 times.
|
281 |
if (!path_is_absolute(patchloc)) asar_throw_warning(pass, warning_id_relative_path_used, "patch file"); |
307 |
|
|
|
308 |
|
|
try |
309 |
|
|
{ |
310 |
2/2
✓ Branch 0 taken 823 times.
✓ Branch 1 taken 271 times.
|
1094 |
for (pass = 0;pass < 3;pass++) |
311 |
|
|
{ |
312 |
1/2
✓ Branch 0 taken 823 times.
✗ Branch 1 not taken.
|
823 |
initstuff(); |
313 |
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 10 times.
|
823 |
assemblefile(patchloc); |
314 |
|
|
// RPG Hacker: Necessary, because finishpass() can throws warning and errors. |
315 |
2/3
✓ Branch 0 taken 363 times.
✓ Branch 1 taken 450 times.
✗ Branch 2 not taken.
|
813 |
string asmpath = filesystem->create_absolute_path(nullptr, patchloc); |
316 |
2/3
✓ Branch 0 taken 363 times.
✓ Branch 1 taken 450 times.
✗ Branch 2 not taken.
|
813 |
callstack_push cs_push(callstack_entry_type::FILE, asmpath); |
317 |
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
|
813 |
finishpass(); |
318 |
|
813 |
} |
319 |
|
|
} |
320 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 |
catch (errfatal&) {} |
321 |
|
281 |
} |
322 |
|
|
|
323 |
|
281 |
static bool asar_patch_end(char * romdata_, int buflen, int * romlen_) |
324 |
|
|
{ |
325 |
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 130 times.
|
281 |
if (checksum_fix_enabled) fixchecksum(); |
326 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
|
281 |
if (romdata_ != (const char*)romdata_r) free(const_cast<unsigned char*>(romdata_r)); |
327 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
|
281 |
if (buflen < romlen) asar_throw_error(pass, error_type_null, error_id_buffer_too_small); |
328 |
4/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 244 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 117 times.
|
281 |
if (errored) |
329 |
|
|
{ |
330 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
|
75 |
if (numerror==0) |
331 |
|
✗ |
asar_throw_error(pass, error_type_null, error_id_internal_error, "phantom error"); |
332 |
|
75 |
free(const_cast<unsigned char*>(romdata)); |
333 |
|
75 |
return false; |
334 |
|
|
} |
335 |
2/3
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
|
206 |
if (*romlen_ != buflen) |
336 |
|
|
{ |
337 |
|
206 |
*romlen_ = romlen; |
338 |
|
|
} |
339 |
|
206 |
romCrc = crc32((const uint8_t*)romdata, (size_t)romlen); |
340 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 117 times.
|
206 |
memcpy(romdata_, romdata, (size_t)romlen); |
341 |
|
206 |
free(const_cast<unsigned char*>(romdata)); |
342 |
|
206 |
return true; |
343 |
|
|
} |
344 |
|
|
|
345 |
|
|
#if defined(__clang__) |
346 |
|
|
# pragma clang diagnostic push |
347 |
|
|
# pragma clang diagnostic ignored "-Wmissing-prototypes" |
348 |
|
|
#endif |
349 |
|
|
|
350 |
|
|
// this and asar_close are hardcoded in each api |
351 |
|
4 |
EXPORT bool asar_init() |
352 |
|
|
{ |
353 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
4 |
if (!expectsNewAPI) return false; |
354 |
|
4 |
return true; |
355 |
|
|
} |
356 |
|
|
|
357 |
|
|
/* $EXPORT$ |
358 |
|
|
* Returns the version, in the format major*10000+minor*100+bugfix*1. This |
359 |
|
|
* means that 1.2.34 would be returned as 10234. |
360 |
|
|
*/ |
361 |
|
2 |
EXPORT int asar_version() |
362 |
|
|
{ |
363 |
|
2 |
return get_version_int(); |
364 |
|
|
} |
365 |
|
|
|
366 |
|
|
/* $EXPORT$ |
367 |
|
|
* Returns the API version, format major*100+minor. Minor is incremented on |
368 |
|
|
* backwards compatible changes; major is incremented on incompatible changes. |
369 |
|
|
* Does not have any correlation with the Asar version. |
370 |
|
|
* |
371 |
|
|
* It's not very useful directly, since asar_init() verifies this automatically. |
372 |
|
|
* Calling this one also sets a flag that makes asar_init not instantly return |
373 |
|
|
* false; this is so programs expecting an older API won't do anything unexpected. |
374 |
|
|
*/ |
375 |
|
8 |
EXPORT int asar_apiversion() |
376 |
|
|
{ |
377 |
|
8 |
expectsNewAPI=true; |
378 |
|
8 |
return APIVERSION; |
379 |
|
|
} |
380 |
|
|
|
381 |
|
|
/* $EXPORT$ |
382 |
|
|
* Clears out all errors, warnings and printed statements, and clears the file |
383 |
|
|
* cache. Not really useful, since asar_patch() already does this. |
384 |
|
|
*/ |
385 |
|
✗ |
EXPORT bool asar_reset() |
386 |
|
|
{ |
387 |
|
✗ |
resetdllstuff(); |
388 |
|
✗ |
pass=0; |
389 |
|
✗ |
return true; |
390 |
|
|
} |
391 |
|
|
|
392 |
|
4 |
EXPORT void asar_close() |
393 |
|
|
{ |
394 |
|
4 |
resetdllstuff(); |
395 |
|
4 |
} |
396 |
|
|
|
397 |
|
|
/* $EXPORT$ |
398 |
|
|
* Applies a patch. The first argument is a filename (so Asar knows where to |
399 |
|
|
* look for incsrc'd stuff); however, the ROM is in memory. |
400 |
|
|
* This function assumes there are no headers anywhere, neither in romdata nor |
401 |
|
|
* the sizes. romlen may be altered by this function; if this is undesirable, |
402 |
|
|
* set romlen equal to buflen. |
403 |
|
|
* The return value is whether any errors appeared (false=errors, call |
404 |
|
|
* asar_geterrors for details). If there is an error, romdata and romlen will |
405 |
|
|
* be left unchanged. |
406 |
|
|
* See the documentation of struct patchparams for more information. |
407 |
|
|
*/ |
408 |
|
281 |
EXPORT bool asar_patch(const struct patchparams_base *params) |
409 |
|
|
{ |
410 |
|
281 |
auto execute_patch = [&]() { |
411 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
|
281 |
if (params == nullptr) |
412 |
|
|
{ |
413 |
|
✗ |
asar_throw_error(pass, error_type_null, error_id_params_null); |
414 |
|
|
} |
415 |
|
|
|
416 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
|
281 |
if (params->structsize != sizeof(patchparams_v200)) |
417 |
|
|
{ |
418 |
|
✗ |
asar_throw_error(pass, error_type_null, error_id_params_invalid_size); |
419 |
|
|
} |
420 |
|
|
|
421 |
|
155 |
patchparams paramscurrent; |
422 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
|
281 |
memset(¶mscurrent, 0, sizeof(paramscurrent)); |
423 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
|
281 |
memcpy(¶mscurrent, params, (size_t)params->structsize); |
424 |
|
|
|
425 |
|
|
|
426 |
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 |
asar_patch_begin(paramscurrent.romdata, paramscurrent.buflen, paramscurrent.romlen); |
427 |
|
|
|
428 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
|
281 |
simple_callstacks = !paramscurrent.full_call_stack; |
429 |
|
|
|
430 |
|
281 |
autoarray<string> includepaths; |
431 |
|
281 |
autoarray<const char*> includepath_cstrs; |
432 |
|
|
|
433 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 281 times.
|
282 |
for (int i = 0; i < paramscurrent.numincludepaths; ++i) |
434 |
|
|
{ |
435 |
2/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
1 |
if (!path_is_absolute(paramscurrent.includepaths[i])) asar_throw_warning(pass, warning_id_relative_path_used, "include search"); |
436 |
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 |
string& newpath = includepaths.append(paramscurrent.includepaths[i]); |
437 |
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 |
includepath_cstrs.append((const char*)newpath); |
438 |
|
|
} |
439 |
|
|
|
440 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 280 times.
|
281 |
if (paramscurrent.stdincludesfile != nullptr) { |
441 |
2/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
1 |
if (!path_is_absolute(paramscurrent.stdincludesfile)) asar_throw_warning(pass, warning_id_relative_path_used, "std includes file"); |
442 |
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 |
string stdincludespath = paramscurrent.stdincludesfile; |
443 |
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 |
parse_std_includes(stdincludespath, includepaths); |
444 |
|
1 |
} |
445 |
|
|
|
446 |
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 281 times.
|
285 |
for (int i = 0; i < includepaths.count; ++i) |
447 |
|
|
{ |
448 |
2/7
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 |
includepath_cstrs.append((const char*)includepaths[i]); |
449 |
|
|
} |
450 |
|
|
|
451 |
|
281 |
size_t includepath_count = (size_t)includepath_cstrs.count; |
452 |
2/3
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
|
281 |
virtual_filesystem new_filesystem; |
453 |
2/4
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 281 times.
✗ Branch 3 not taken.
|
281 |
new_filesystem.initialize(&includepath_cstrs[0], includepath_count); |
454 |
|
281 |
filesystem = &new_filesystem; |
455 |
|
|
|
456 |
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 281 times.
|
315 |
for(int i = 0; i < paramscurrent.memory_file_count; ++i) { |
457 |
|
34 |
memoryfile f = paramscurrent.memory_files[i]; |
458 |
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 |
filesystem->add_memory_file(f.path, f.buffer, f.length); |
459 |
|
|
} |
460 |
|
|
|
461 |
|
281 |
clidefines.reset(); |
462 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 281 times.
|
284 |
for (int i = 0; i < paramscurrent.additional_define_count; ++i) |
463 |
|
|
{ |
464 |
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 |
string name = (paramscurrent.additional_defines[i].name != nullptr ? paramscurrent.additional_defines[i].name : ""); |
465 |
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 |
strip_whitespace(name); |
466 |
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 |
name.strip_prefix('!'); // remove leading ! if present |
467 |
2/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
3 |
if (!validatedefinename(name)) asar_throw_error(pass, error_type_null, error_id_cmdl_define_invalid, "asar_patch_ex() additional defines", name.data()); |
468 |
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
|
3 |
if (clidefines.exists(name)) { |
469 |
|
✗ |
asar_throw_error(pass, error_type_null, error_id_cmdl_define_override, "asar_patch_ex() additional define", name.data()); |
470 |
|
✗ |
return false; |
471 |
|
|
} |
472 |
2/7
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 |
string contents = (paramscurrent.additional_defines[i].contents != nullptr ? paramscurrent.additional_defines[i].contents : ""); |
473 |
2/7
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 |
clidefines.create(name) = contents; |
474 |
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 |
} |
475 |
|
|
|
476 |
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 280 times.
|
281 |
if (paramscurrent.stddefinesfile != nullptr) { |
477 |
2/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
1 |
if (!path_is_absolute(paramscurrent.stddefinesfile)) asar_throw_warning(pass, warning_id_relative_path_used, "std defines file"); |
478 |
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 |
string stddefinespath = paramscurrent.stddefinesfile; |
479 |
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 |
parse_std_defines(stddefinespath); |
480 |
|
1 |
} else { |
481 |
1/2
✓ Branch 0 taken 280 times.
✗ Branch 1 not taken.
|
280 |
parse_std_defines(nullptr); // needed to populate builtin defines |
482 |
|
|
} |
483 |
|
|
|
484 |
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 281 times.
|
283 |
for (int i = 0; i < paramscurrent.warning_setting_count; ++i) |
485 |
|
|
{ |
486 |
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 |
asar_warning_id warnid = parse_warning_id_from_string(paramscurrent.warning_settings[i].warnid); |
487 |
|
|
|
488 |
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 |
if (warnid != warning_id_end) |
489 |
|
|
{ |
490 |
2/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
2 |
set_warning_enabled(warnid, paramscurrent.warning_settings[i].enabled); |
491 |
|
|
} |
492 |
|
|
else |
493 |
|
|
{ |
494 |
|
✗ |
asar_throw_warning(pass, warning_id_invalid_warning_id, paramscurrent.warning_settings[i].warnid, "asar_patch_ex() warning_settings"); |
495 |
|
|
} |
496 |
|
|
} |
497 |
|
|
|
498 |
4/4
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 130 times.
✓ Branch 3 taken 25 times.
|
281 |
if(paramscurrent.override_checksum_gen) { |
499 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130 times.
|
256 |
checksum_fix_enabled = paramscurrent.generate_checksum; |
500 |
|
256 |
force_checksum_fix = true; |
501 |
|
|
} |
502 |
|
|
|
503 |
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 |
asar_patch_main(paramscurrent.patchloc); |
504 |
|
|
|
505 |
|
|
// RPG Hacker: Required before the destroy() below, |
506 |
|
|
// otherwise it will leak memory. |
507 |
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 |
closecachedfiles(); |
508 |
|
|
|
509 |
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 |
new_filesystem.destroy(); |
510 |
|
281 |
filesystem = nullptr; |
511 |
|
|
|
512 |
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 |
return asar_patch_end(paramscurrent.romdata, paramscurrent.buflen, paramscurrent.romlen); |
513 |
|
281 |
}; |
514 |
|
|
#if defined(RUN_VIA_FIBER) |
515 |
|
|
return run_as_fiber(execute_patch); |
516 |
|
|
#elif defined(RUN_VIA_THREAD) |
517 |
1/2
✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
562 |
return run_as_thread(execute_patch); |
518 |
|
|
#else |
519 |
|
|
return execute_patch(); |
520 |
|
|
#endif |
521 |
|
|
} |
522 |
|
|
|
523 |
|
|
/* $EXPORT$ |
524 |
|
|
* Returns the maximum possible size of the output ROM from asar_patch(). |
525 |
|
|
* Giving this size to buflen guarantees you will not get any buffer too small |
526 |
|
|
* errors; however, it is safe to give smaller buffers if you don't expect any |
527 |
|
|
* ROMs larger than 4MB or something. |
528 |
|
|
*/ |
529 |
|
57 |
EXPORT int asar_maxromsize() |
530 |
|
|
{ |
531 |
|
57 |
return maxromsize; |
532 |
|
|
} |
533 |
|
|
|
534 |
|
|
/* $EXPORT$ |
535 |
|
|
* Get a list of all errors. |
536 |
|
|
* All pointers from these functions are valid only until the same function is |
537 |
|
|
* called again, or until asar_patch, asar_reset or asar_close is called, |
538 |
|
|
* whichever comes first. Copy the contents if you need it for a longer time. |
539 |
|
|
*/ |
540 |
|
271 |
EXPORT const struct errordata * asar_geterrors(int * count) |
541 |
|
|
{ |
542 |
|
271 |
*count=numerror; |
543 |
|
271 |
return errors; |
544 |
|
|
} |
545 |
|
|
|
546 |
|
|
/* $EXPORT$ |
547 |
|
|
* Get a list of all warnings. |
548 |
|
|
*/ |
549 |
|
271 |
EXPORT const struct errordata * asar_getwarnings(int * count) |
550 |
|
|
{ |
551 |
|
271 |
*count=numwarn; |
552 |
|
271 |
return warnings; |
553 |
|
|
} |
554 |
|
|
|
555 |
|
|
/* $EXPORT$ |
556 |
|
|
* Get a list of all printed data. |
557 |
|
|
*/ |
558 |
|
253 |
EXPORT const char * const * asar_getprints(int * count) |
559 |
|
|
{ |
560 |
|
253 |
*count=numprint; |
561 |
|
253 |
return prints; |
562 |
|
|
} |
563 |
|
|
|
564 |
|
|
/* $EXPORT$ |
565 |
|
|
* Get a list of all labels. |
566 |
|
|
*/ |
567 |
|
2 |
EXPORT const struct labeldata * asar_getalllabels(int * count) |
568 |
|
|
{ |
569 |
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 |
for (int i=0;i<labelsinldata;i++) free((void*)ldata[i].name); |
570 |
|
2 |
labelsinldata=0; |
571 |
|
2 |
labels.each([](const string& name, const snes_label& label_data) { |
572 |
|
7 |
labeldata label; |
573 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 |
label.name = strdup(name); |
574 |
|
7 |
label.location = (int)(label_data.pos & 0xFFFFFF); |
575 |
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 |
ldata[labelsinldata++] = label; |
576 |
|
7 |
}); |
577 |
|
2 |
*count=labelsinldata; |
578 |
|
2 |
std::sort<labeldata*>(ldata, ldata + labelsinldata, |
579 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
11 |
[](auto& l, auto& r) { return strcmp(l.name, r.name) < 0; }); |
580 |
|
2 |
return ldata; |
581 |
|
|
} |
582 |
|
|
|
583 |
|
|
/* $EXPORT$ |
584 |
|
|
* Get the ROM location of one label. -1 means "not found". |
585 |
|
|
*/ |
586 |
|
4 |
EXPORT int asar_getlabelval(const char * name) |
587 |
|
|
{ |
588 |
|
|
int i; |
589 |
|
|
try { |
590 |
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 |
i=(int)labelval(&name).pos; |
591 |
|
|
} |
592 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 |
catch(errfatal&) { return -1; } |
593 |
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
2 |
if (*name || i<0) return -1; |
594 |
|
2 |
else return i&0xFFFFFF; |
595 |
|
|
} |
596 |
|
|
|
597 |
|
|
/* $EXPORT$ |
598 |
|
|
* Get the value of a define. |
599 |
|
|
*/ |
600 |
|
4 |
EXPORT const char * asar_getdefine(const char * name) |
601 |
|
|
{ |
602 |
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 |
if (!defines.exists(name)) return ""; |
603 |
|
2 |
return defines.find(name); |
604 |
|
|
} |
605 |
|
|
|
606 |
|
|
/* $EXPORT$ |
607 |
|
|
* Parses all defines in the parameter. |
608 |
|
|
* If there were any errors, returns an empty string. |
609 |
|
|
*/ |
610 |
|
4 |
EXPORT const char * asar_resolvedefines(const char * data) |
611 |
|
|
{ |
612 |
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 |
static string out; |
613 |
|
4 |
out = ""; |
614 |
|
|
try |
615 |
|
|
{ |
616 |
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
|
4 |
resolvedefines(out, data); |
617 |
|
|
} |
618 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 |
catch(errfatal&){ |
619 |
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 |
out = ""; |
620 |
|
1 |
} |
621 |
|
4 |
return out; |
622 |
|
|
} |
623 |
|
|
|
624 |
|
|
/* $EXPORT$ |
625 |
|
|
* Gets the values and names of all defines. |
626 |
|
|
*/ |
627 |
|
4 |
EXPORT const struct definedata * asar_getalldefines(int * count) |
628 |
|
|
{ |
629 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 |
for (int i=0;i<definesinddata;i++) |
630 |
|
|
{ |
631 |
|
✗ |
free((void*)ddata[i].name); |
632 |
|
✗ |
free((void*)ddata[i].contents); |
633 |
|
|
} |
634 |
|
4 |
definesinddata=0; |
635 |
|
4 |
defines.each([](const string& name, string& value) { |
636 |
|
23 |
definedata define; |
637 |
|
23 |
define.name = duplicate_string(name); |
638 |
|
23 |
define.contents = duplicate_string(value); |
639 |
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
|
23 |
ddata[definesinddata++] = define; |
640 |
|
23 |
}); |
641 |
|
4 |
*count=definesinddata; |
642 |
|
4 |
std::sort<definedata*>(ddata, ddata + definesinddata, |
643 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57 times.
|
57 |
[](auto& l, auto& r) { return strcmp(l.name, r.name) < 0; }); |
644 |
|
4 |
return ddata; |
645 |
|
|
} |
646 |
|
|
|
647 |
|
|
/* $EXPORT$ |
648 |
|
|
* Parses a string containing math. It automatically assumes global scope (no |
649 |
|
|
* namespaces), and has access to all functions and labels from the last call |
650 |
|
|
* to asar_patch. Remember to check error to see if it's successful (NULL) or |
651 |
|
|
* if it failed (non-NULL, contains a descriptive string). It does not affect |
652 |
|
|
* asar_geterrors. |
653 |
|
|
*/ |
654 |
|
5 |
EXPORT double asar_math(const char * math_, const char ** error) |
655 |
|
|
{ |
656 |
|
5 |
ns=""; |
657 |
|
5 |
namespace_list.reset(); |
658 |
|
5 |
sublabels.reset(); |
659 |
|
5 |
errored=false; |
660 |
|
5 |
ismath=true; |
661 |
|
5 |
initmathcore(); |
662 |
|
5 |
double rval=0; |
663 |
|
|
try |
664 |
|
|
{ |
665 |
4/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
|
18 |
rval = parse_math_expr(math_)->evaluate().get_double(); |
666 |
|
|
} |
667 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 |
catch(errfatal&) |
668 |
|
|
{ |
669 |
|
2 |
*error=matherror; |
670 |
|
2 |
} |
671 |
|
5 |
ismath=false; |
672 |
|
5 |
deinitmathcore(); |
673 |
|
5 |
return rval; |
674 |
|
5 |
} |
675 |
|
|
|
676 |
|
|
/* $EXPORT$ |
677 |
|
|
* Get a list of all the blocks written to the ROM by calls such as |
678 |
|
|
* asar_patch(). |
679 |
|
|
*/ |
680 |
|
4 |
EXPORT const struct writtenblockdata * asar_getwrittenblocks(int * count) |
681 |
|
|
{ |
682 |
|
4 |
*count = writtenblocks.count; |
683 |
|
4 |
return writtenblocks; |
684 |
|
|
} |
685 |
|
|
|
686 |
|
|
/* $EXPORT$ |
687 |
|
|
* Get the mapper currently used by Asar. |
688 |
|
|
*/ |
689 |
|
9 |
EXPORT enum mapper_t asar_getmapper() |
690 |
|
|
{ |
691 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 |
return mapper; |
692 |
|
|
} |
693 |
|
|
|
694 |
|
|
/* $EXPORT$ |
695 |
|
|
* Generates the contents of a symbols file for in a specific format. |
696 |
|
|
*/ |
697 |
|
2 |
EXPORT const char * asar_getsymbolsfile(const char* type){ |
698 |
2/7
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 |
symbolsfile = create_symbols_file(type, romCrc); |
699 |
|
2 |
return symbolsfile; |
700 |
|
|
} |
701 |
|
|
|
702 |
|
|
#if defined(__clang__) |
703 |
|
|
# pragma clang diagnostic pop |
704 |
|
|
#endif |
705 |
|
|
|