asar coverage - build #175


src/asar/
File: src/asar/macro.cpp
Date: 2024-01-28 00:44:31
Lines:
240/249
96.4%
Functions:
10/10
100.0%
Branches:
258/414
62.3%

Line Branch Exec Source
1 #include "asar.h"
2 #include "assembleblock.h"
3 #include "macro.h"
4 #include "asar_math.h"
5 #include "warnings.h"
6
7 assocarr<macrodata*> macros;
8 string defining_macro_name;
9 static macrodata * thisone;
10 static int numlines;
11
12 int calledmacros;
13 int reallycalledmacros;
14 int macrorecursion;
15 bool inmacro;
16 int numvarargs;
17
18 macrodata* current_macro;
19 const char* const* current_macro_args;
20 int current_macro_numargs;
21
22 420 void startmacro(const char * line_)
23 {
24 420 thisone= nullptr;
25
3/6
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 210 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
420 if (!confirmqpar(line_)) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
26
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
210 string line=line_;
27
1/2
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
420 line.qnormalize();
28 420 char * startpar=(char *)strchr(line.data(), '(');
29
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
420 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
30 420 *startpar=0;
31
2/4
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 210 times.
✗ Branch 3 not taken.
630 startpar++;
32
2/6
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 420 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
420 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_invalid_macro_name);
33
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
210 defining_macro_name=line;
34 420 char * endpar=startpar+strlen(startpar)-1;
35 //confirmqpar requires that all parentheses are matched, and a starting one exists, therefore it is harmless to not check for nullptrs
36
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
420 if (*endpar != ')') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
37 420 *endpar=0;
38
2/2
✓ Branch 0 taken 2334 times.
✓ Branch 1 taken 420 times.
2754 for (int i=0;startpar[i];i++)
39 {
40 1167 char c=startpar[i];
41
8/12
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 1710 times.
✓ Branch 2 taken 252 times.
✓ Branch 3 taken 372 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 243 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1167 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2334 if (!is_ualnum(c)&& c!=','&& c!='.'&& c!=' ') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
42
4/8
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 2196 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1167 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2334 if (c==',' && is_digit(startpar[i+1])) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
43 }
44
5/12
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 420 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 420 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 420 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 210 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
420 if (*startpar==',' || is_digit(*startpar) || strstr(startpar, ",,") || endpar[-1]==',') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
45
3/4
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 210 times.
420 if (macros.exists(defining_macro_name))
46 {
47 const auto macro = macros[defining_macro_name];
48 // i think theoretically it would be "more correct" to print the entire
49 // callstack here, but this should be good enough for an error message.
50 // needs +1 because startline is 0-indexed
51 asar_throw_error(0, error_type_block, error_id_macro_redefined, defining_macro_name.data(), macro->fname, macro->startline + 1);
52 }
53 420 thisone=(macrodata*)malloc(sizeof(macrodata));
54
1/4
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
210 new(thisone) macrodata;
55
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 138 times.
420 if (*startpar)
56 {
57
1/2
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
282 char **arguments = split(duplicate_string(startpar), ',', &thisone->numargs);
58 282 thisone->arguments_buffer = arguments[0];
59
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 282 times.
702 for (int i=0;arguments[i];i++)
60 {
61 420 arguments[i] = strip_whitespace(arguments[i]);
62 }
63 282 thisone->arguments=(const char* const*)arguments;
64 }
65 else
66 {
67 138 const char ** noargs=(const char**)malloc(sizeof(const char**));
68 138 *noargs=nullptr;
69 138 thisone->arguments=noargs;
70 138 thisone->arguments_buffer = nullptr;
71 138 thisone->numargs=0;
72 }
73 420 thisone->variadic = false;
74
1/2
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
420 thisone->fname= duplicate_string(get_current_file_name());
75
1/2
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
420 thisone->startline=get_current_line();
76 420 thisone->parent_macro=current_macro;
77 420 thisone->parent_macro_num_varargs=0;
78 // RPG Hacker: -1 to take the ... into account, which is also being counted.
79
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 264 times.
420 if (thisone->parent_macro != nullptr) thisone->parent_macro_num_varargs = current_macro_numargs-(current_macro->numargs-1);
80
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 414 times.
828 for (int i=0;thisone->arguments[i];i++)
81 {
82
4/4
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 258 times.
✓ Branch 2 taken 150 times.
✓ Branch 3 taken 6 times.
414 if(!strcmp(thisone->arguments[i], "...") && !thisone->arguments[i+1]) thisone->variadic = true;
83
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
264 else if(!strcmp(thisone->arguments[i], "...")) asar_throw_error(0, error_type_block, error_id_vararg_must_be_last);
84
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
258 else if(strchr(thisone->arguments[i], '.')) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
85
2/6
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 258 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
258 else if (!confirmname(thisone->arguments[i])) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
86
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 408 times.
558 for (int j=i+1;thisone->arguments[j];j++)
87 {
88
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
150 if (!strcmp(thisone->arguments[i], thisone->arguments[j])) asar_throw_error(0, error_type_block, error_id_macro_param_redefined, thisone->arguments[i]);
89 }
90 }
91 414 numlines=0;
92 420 }
93
94 2466 void tomacro(const char * line)
95 {
96
2/2
✓ Branch 0 taken 1233 times.
✓ Branch 1 taken 1233 times.
2466 if (!thisone) return;
97 2466 thisone->lines[numlines++]=line;
98 }
99
100 420 void endmacro(bool insert)
101 {
102
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 210 times.
420 if (!thisone) return;
103 420 thisone->numlines=numlines;
104
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 6 times.
420 if (insert) macros.create(defining_macro_name) = thisone;
105 else
106 {
107 6 freemacro(thisone);
108 6 thisone=nullptr;
109 }
110 }
111
112 #define cfree(x) free((void*)x)
113 420 void freemacro(macrodata* & macro)
114 {
115 420 macro->lines.~autoarray();
116 420 cfree(macro->fname);
117 420 cfree(macro->arguments_buffer);
118 420 cfree(macro->arguments);
119 420 cfree(macro);
120 420 }
121 #undef cfree
122
123
124 1566 void callmacro(const char * data)
125 {
126 1566 int prev_numvarargs = numvarargs;
127 macrodata * thismacro;
128
3/6
✓ Branch 0 taken 783 times.
✓ Branch 1 taken 783 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 783 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1566 if (!confirmqpar(data)) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
129
1/2
✓ Branch 0 taken 783 times.
✗ Branch 1 not taken.
783 string line=data;
130
1/2
✓ Branch 0 taken 1566 times.
✗ Branch 1 not taken.
1566 line.qnormalize();
131 1566 char * startpar=(char *)strchr(line.data(), '(');
132
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1566 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1566 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
133 1566 *startpar=0;
134
1/2
✓ Branch 0 taken 783 times.
✗ Branch 1 not taken.
1566 startpar++;
135
2/6
✓ Branch 0 taken 1566 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1566 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1566 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
136
3/6
✓ Branch 0 taken 783 times.
✓ Branch 1 taken 783 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 783 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1566 if (!macros.exists(line)) asar_throw_error(0, error_type_block, error_id_macro_not_found, line.data());
137
1/2
✓ Branch 0 taken 783 times.
✗ Branch 1 not taken.
1566 thismacro = macros.find(line);
138 1566 char * endpar=startpar+strlen(startpar)-1;
139 //confirmqpar requires that all parentheses are matched, and a starting one exists, therefore it is harmless to not check for nullptrs
140
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1566 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1566 if (*endpar != ')') asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
141
2/2
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 180 times.
1566 *endpar=0;
142 783 autoptr<const char * const*> args;
143 1566 int numargs=0;
144
2/2
✓ Branch 0 taken 1206 times.
✓ Branch 1 taken 360 times.
1566 if (*startpar) {
145
1/2
✓ Branch 0 taken 1206 times.
✗ Branch 1 not taken.
1206 args=(const char* const*)qpsplit(startpar, ',', &numargs);
146 // qpsplit returns a nullptr when the input is broken, e.g. closing paren before opening or whatnot
147
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1206 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1206 if(args == nullptr) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
148 }
149
3/6
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 1170 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 396 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1566 if (numargs != thismacro->numargs && !thismacro->variadic) asar_throw_error(1, error_type_block, error_id_macro_wrong_num_params);
150 // RPG Hacker: -1, because the ... is also counted as an argument, yet we want it to be entirely optional.
151
4/6
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1530 times.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36 times.
1566 if (numargs < thismacro->numargs - 1 && thismacro->variadic) asar_throw_error(1, error_type_block, error_id_macro_wrong_min_params);
152
153 1530 macrorecursion++;
154 1530 inmacro=true;
155 1530 int old_calledmacros = calledmacros;
156 1530 calledmacros = reallycalledmacros++;
157 1530 int startif=numif;
158
159
2/2
✓ Branch 0 taken 2646 times.
✓ Branch 1 taken 1530 times.
4176 for (int i = 0; i < numargs; ++i)
160 {
161 // RPG Hacker: These casts make me feel very nasty.
162
1/2
✓ Branch 0 taken 2646 times.
✗ Branch 1 not taken.
2646 (*reinterpret_cast<autoptr<const char**>*>(&args))[i] = safedequote(strip_whitespace((char*)args[i]));
163 }
164
165 // RPG Hacker: -1 to take the ... into account, which is also being counted.
166
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 990 times.
1530 if(thismacro->variadic) numvarargs = numargs-(thismacro->numargs-1);
167 990 else numvarargs = -1;
168
169 1530 autoarray<int>* oldmacroposlabels = macroposlabels;
170 1530 autoarray<int>* oldmacroneglabels = macroneglabels;
171 1530 autoarray<string>* oldmacrosublabels = macrosublabels;
172
173 765 autoarray<int> newmacroposlabels;
174 765 autoarray<int> newmacroneglabels;
175 765 autoarray<string> newmacrosublabels;
176
177 1530 macroposlabels = &newmacroposlabels;
178 1530 macroneglabels = &newmacroneglabels;
179 1530 macrosublabels = &newmacrosublabels;
180
181 1530 macrodata* old_macro = current_macro;
182 1530 const char* const* old_macro_args = current_macro_args;
183 1530 int old_numargs = current_macro_numargs;
184 1530 current_macro = thismacro;
185 1530 current_macro_args = args;
186 1530 current_macro_numargs = numargs;
187
188
1/2
✓ Branch 0 taken 765 times.
✗ Branch 1 not taken.
765 callstack_push cs_push(callstack_entry_type::MACRO_CALL, data);
189
190 {
191
1/2
✓ Branch 0 taken 765 times.
✗ Branch 1 not taken.
1530 callstack_push cs_push(callstack_entry_type::FILE, thismacro->fname);
192
193
2/2
✓ Branch 0 taken 21072 times.
✓ Branch 1 taken 1530 times.
22602 for (int i=0;i<thismacro->numlines;i++)
194 {
195
2/4
✓ Branch 0 taken 21072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10536 times.
✗ Branch 3 not taken.
21072 bool was_loop_end = do_line_logic(thismacro->lines[i], thismacro->fname, thismacro->startline+i+1);
196
197
8/8
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 17510 times.
✓ Branch 2 taken 2689 times.
✓ Branch 3 taken 873 times.
✓ Branch 4 taken 873 times.
✓ Branch 5 taken 908 times.
✓ Branch 6 taken 873 times.
✓ Branch 7 taken 9663 times.
21072 if (was_loop_end && whilestatus[numif].cond)
198 // RPG Hacker: -1 to compensate for the i++, and another -1
199 // because ->lines doesn't include the macro header.
200
1/2
✓ Branch 0 taken 873 times.
✗ Branch 1 not taken.
1746 i = whilestatus[numif].startline - thismacro->startline - 2;
201 }
202 1530 }
203
204 1530 macroposlabels = oldmacroposlabels;
205 1530 macroneglabels = oldmacroneglabels;
206 1530 macrosublabels = oldmacrosublabels;
207
208 1530 current_macro = old_macro;
209 1530 current_macro_args = old_macro_args;
210 1530 current_macro_numargs = old_numargs;
211
212 1530 macrorecursion--;
213 1530 inmacro = macrorecursion;
214 1530 numvarargs = prev_numvarargs;
215 1530 calledmacros = old_calledmacros;
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
1530 if (numif!=startif)
217 {
218 numif=startif;
219 numtrue=startif;
220 asar_throw_error(0, error_type_block, error_id_unclosed_if);
221 }
222 1602 }
223
224 168 string generate_macro_arg_string(const char* named_arg, int depth)
225 {
226 84 string ret="<";
227
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 168 times.
348 for (int i = 0; i < depth;++i)
228 {
229
1/2
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
180 ret += '^';
230 }
231
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
168 ret += named_arg;
232
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
168 ret += ">";
233 168 return ret;
234 }
235
236 126 string generate_macro_arg_string(int var_arg, int depth)
237 {
238 63 string ret="<";
239
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 126 times.
180 for (int i = 0; i < depth;++i)
240 {
241
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
54 ret += '^';
242 }
243
2/4
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
126 ret += dec(var_arg);
244
1/2
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
126 ret += ">";
245 126 return ret;
246 }
247
248 228 string generate_macro_hint_string(const char* named_arg, const macrodata* thismacro, int desired_depth, int current_depth=0)
249 {
250 // RPG Hacker: This only work when the incorrectly used parameter
251 // is inside the macro that is currently being defined. Not great,
252 // but still better than nothing.
253
4/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 72 times.
228 if (current_depth == 0 && thisone != nullptr)
254 {
255
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 30 times.
90 for (int j=0;thisone->arguments[j];j++)
256 {
257
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 54 times.
60 if (!strcmp(named_arg, thisone->arguments[j]))
258 {
259
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 string ret=" Did you mean: '";
260
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 ret += generate_macro_arg_string(thisone->arguments[j], 0);
261
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 ret += "'?";
262
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 return ret;
263 6 }
264 }
265 }
266
267 // RPG Hacker: Technically, we could skip a level here and go straight
268 // to the parent, but maybe at some point we'll want to expand this to
269 // also look for similar args in the current level, so I'll leave it
270 // like this, just in case.
271
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 48 times.
222 if (thismacro != nullptr)
272 {
273
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 120 times.
396 for (int j=0;thismacro->arguments[j];j++)
274 {
275
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 222 times.
276 if (!strcmp(named_arg, thismacro->arguments[j]))
276 {
277
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 string ret=" Did you mean: '";
278
2/4
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
54 ret += generate_macro_arg_string(thismacro->arguments[j], desired_depth+current_depth);
279
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
54 ret += "'?";
280
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 return ret;
281 54 }
282 }
283 120 return generate_macro_hint_string(named_arg, thismacro->parent_macro, desired_depth, current_depth+1);
284 }
285
286 24 return "";
287 }
288
289 126 string generate_macro_hint_string(int var_arg, const macrodata* thismacro, int desired_depth, int current_depth=0)
290 {
291
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 36 times.
126 if (thismacro != nullptr)
292 {
293
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 54 times.
90 if (thismacro->parent_macro_num_varargs > var_arg)
294 {
295
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 string ret=" Did you mean: '";
296
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
36 ret += generate_macro_arg_string(var_arg, desired_depth+current_depth+1);
297
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
36 ret += "'?";
298
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 return ret;
299 36 }
300 54 return generate_macro_hint_string(var_arg, thismacro->parent_macro, desired_depth, current_depth+1);
301 }
302
303 18 return "";
304 }
305
306 157593 string replace_macro_args(const char* line) {
307 75792 string out;
308
2/2
✓ Branch 0 taken 139437 times.
✓ Branch 1 taken 18156 times.
157593 if(!inmacro)
309 {
310
1/2
✓ Branch 0 taken 66714 times.
✗ Branch 1 not taken.
139437 out += line;
311 66714 return out;
312 }
313
2/2
✓ Branch 0 taken 240552 times.
✓ Branch 1 taken 17850 times.
258402 for (const char * in=line;*in;)
314 {
315
5/6
✓ Branch 0 taken 6804 times.
✓ Branch 1 taken 233748 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 6750 times.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
240552 if (*in=='<' && in[1]=='<' && in[2] != ':')
316 {
317
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 if (in[2] == '^')
318 {
319
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
54 out+="<";
320 54 in+=1;
321 }
322 else
323 {
324 out+="<<";
325 in+=2;
326 }
327 }
328
2/2
✓ Branch 0 taken 6750 times.
✓ Branch 1 taken 233748 times.
240498 else if (*in=='<')
329 {
330 6750 const char * end=in+1;
331 // RPG Hacker: Added checking for space here, because this code would consider
332 // if a < b && a > c
333 // a macro arg expansion. In practice, this is still a sloppy solution and is
334 // likely to fail in some edge case I can't think of right now. Should parse
335 // this in a much more robust way at some point...
336
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 4590 times.
6750 if (*end==' ')
337 {
338
1/2
✓ Branch 0 taken 1080 times.
✗ Branch 1 not taken.
2160 out += *(in++);
339 3762 continue;
340 }
341
342
6/8
✓ Branch 0 taken 39852 times.
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 35316 times.
✓ Branch 3 taken 4536 times.
✓ Branch 4 taken 35316 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 35316 times.
✗ Branch 7 not taken.
39906 while (*end && *end!='>'&& *end!='<' && *(end+1)!=':') end++; //allow for conditionals and <:
343
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 4536 times.
4590 if (*end!='>')
344 {
345
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
54 out+=*(in++);
346 54 continue;
347 }
348
349 2268 int depth = 0;
350
2/2
✓ Branch 0 taken 558 times.
✓ Branch 1 taken 4536 times.
5094 for (const char* depth_str = in+1; *depth_str=='^'; depth_str++)
351 {
352 558 depth++;
353 }
354
355
2/2
✓ Branch 0 taken 486 times.
✓ Branch 1 taken 4050 times.
4536 if (depth != in_macro_def)
356 {
357
1/2
✓ Branch 0 taken 243 times.
✗ Branch 1 not taken.
486 string temp(in, end-in+1);
358
1/2
✓ Branch 0 taken 243 times.
✗ Branch 1 not taken.
486 out+=temp;
359 486 in=end+1;
360
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 432 times.
486 if (depth > in_macro_def)
361 {
362
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
54 if (in_macro_def > 0) asar_throw_error(0, error_type_line, error_id_invalid_depth_resolve, "macro parameter", "macro parameter", depth, in_macro_def-1);
363 //else asar_throw_error(0, error_type_block, error_id_macro_param_outside_macro);
364 }
365 234 continue;
366 486 }
367
368
3/6
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 3654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 396 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4050 if (depth > 0 && !inmacro) asar_throw_error(0, error_type_line, error_id_invalid_depth_resolve, "macro parameter", "macro parameter", depth, in_macro_def-1);
369 4050 in += depth+1;
370
371 2025 bool is_variadic_arg = false;
372
5/8
✓ Branch 0 taken 1890 times.
✓ Branch 1 taken 2160 times.
✓ Branch 2 taken 1890 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1890 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1890 times.
✗ Branch 7 not taken.
4050 if (in[0] == '.' && in[1] == '.' && in[2] == '.' && in[3] == '[')
373 {
374
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1872 times.
1890 if (end[-1] != ']')
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 asar_throw_error(0, error_type_block, error_id_unclosed_vararg);
376
377 936 is_variadic_arg = true;
378 1872 in += 4;
379 1872 end--;
380 }
381
382 //if(!inmacro) asar_throw_error(0, error_type_block, error_id_macro_param_outside_macro);
383
5/6
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 2160 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 1854 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
4032 if(is_variadic_arg && !current_macro->variadic) asar_throw_error(0, error_type_block, error_id_macro_not_varadic, "<...[math]>");
384 //*end=0;
385 2007 string param;
386
1/2
✓ Branch 0 taken 2007 times.
✗ Branch 1 not taken.
4014 string temp(in, end-in);
387
1/2
✓ Branch 0 taken 4014 times.
✗ Branch 1 not taken.
4014 resolvedefines(param, temp);
388 2007 in = param.data();
389
1/2
✓ Branch 0 taken 4014 times.
✗ Branch 1 not taken.
4014 bool valid_named_param = confirmname(in);
390
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 1854 times.
4014 if (!is_variadic_arg)
391 {
392
3/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 2124 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
2160 if (!valid_named_param) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
393 1062 bool found=false;
394
2/2
✓ Branch 0 taken 2664 times.
✓ Branch 1 taken 108 times.
2772 for (int j=0;current_macro->arguments[j];j++)
395 {
396
2/2
✓ Branch 0 taken 2016 times.
✓ Branch 1 taken 648 times.
2664 if (!strcmp(in, current_macro->arguments[j]))
397 {
398 1008 found=true;
399
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
2016 out+=current_macro_args[j];
400 1008 break;
401 }
402 }
403
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 1008 times.
1062 if (!found)
404 {
405
4/6
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 54 times.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 54 times.
270 asar_throw_error(0, error_type_block, error_id_macro_param_not_found, generate_macro_arg_string(in, depth).raw(), generate_macro_hint_string(in, current_macro, depth).raw());
406 }
407 }
408 else
409 {
410 927 snes_label ret;
411
12/16
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1818 times.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 927 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 918 times.
✓ Branch 10 taken 9 times.
✓ Branch 11 taken 918 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 9 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
1881 if(valid_named_param && !labelval(in, &ret, false)) asar_throw_error(0, error_type_block, error_id_invalid_vararg, in);
412
1/2
✓ Branch 0 taken 1836 times.
✗ Branch 1 not taken.
1836 int arg_num = getnum(in);
413
414
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1836 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1836 if(forwardlabel) asar_throw_error(0, error_type_block, error_id_label_forward);
415
416
5/6
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1818 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
1845 if (arg_num < 0) asar_throw_error(1, error_type_block, error_id_vararg_out_of_bounds, generate_macro_arg_string(arg_num, depth).raw(), "");
417
6/8
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 1746 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 36 times.
1926 if (arg_num > current_macro_numargs-current_macro->numargs) asar_throw_error(1, error_type_block, error_id_vararg_out_of_bounds, generate_macro_arg_string(arg_num, depth).raw(), generate_macro_hint_string(arg_num, current_macro, depth).raw());
418
1/2
✓ Branch 0 taken 873 times.
✗ Branch 1 not taken.
1746 out+=current_macro_args[arg_num+current_macro->numargs-1];
419 }
420 3762 in=end+1;
421
2/2
✓ Branch 0 taken 1746 times.
✓ Branch 1 taken 2016 times.
3762 if (is_variadic_arg) in++;
422 4266 }
423
1/2
✓ Branch 0 taken 116874 times.
✗ Branch 1 not taken.
233748 else out+=*(in++);
424 }
425 8925 return out;
426 306 }
427