asar coverage - build #68


src/asar/
File: src/asar/macro.cpp
Date: 2024-01-17 04:36:48
Lines:
238/245
97.1%
Functions:
10/10
100.0%
Branches:
257/408
63.0%

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 140 void startmacro(const char * line_)
23 {
24 140 thisone= nullptr;
25
3/6
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 70 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
140 if (!confirmqpar(line_)) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
26
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
140 string line=line_;
27
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
140 line.qnormalize();
28 70 char * startpar=(char *)strchr(line.data(), '(');
29
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
140 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
30 140 *startpar=0;
31
2/4
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70 times.
✗ Branch 3 not taken.
210 startpar++;
32
2/6
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 140 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
140 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_invalid_macro_name);
33
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 defining_macro_name=line;
34 140 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 140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
140 if (*endpar != ')') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
37 140 *endpar=0;
38
2/2
✓ Branch 0 taken 778 times.
✓ Branch 1 taken 140 times.
918 for (int i=0;startpar[i];i++)
39 {
40 389 char c=startpar[i];
41
8/12
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 570 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 124 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 81 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 389 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
778 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 46 times.
✓ Branch 1 taken 732 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 389 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
778 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 140 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 140 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 140 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 140 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 70 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
140 if (*startpar==',' || is_digit(*startpar) || strstr(startpar, ",,") || endpar[-1]==',') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
45
3/6
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 70 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
140 if (macros.exists(defining_macro_name)) asar_throw_error(0, error_type_block, error_id_macro_redefined, defining_macro_name.data());
46 140 thisone=(macrodata*)malloc(sizeof(macrodata));
47
1/4
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
70 new(thisone) macrodata;
48
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 46 times.
140 if (*startpar)
49 {
50
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 char **arguments = split(duplicate_string(startpar), ',', &thisone->numargs);
51 94 thisone->arguments_buffer = arguments[0];
52
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 94 times.
234 for (int i=0;arguments[i];i++)
53 {
54 140 arguments[i] = strip_whitespace(arguments[i]);
55 }
56 94 thisone->arguments=(const char* const*)arguments;
57 }
58 else
59 {
60 46 const char ** noargs=(const char**)malloc(sizeof(const char**));
61 46 *noargs=nullptr;
62 46 thisone->arguments=noargs;
63 46 thisone->arguments_buffer = nullptr;
64 46 thisone->numargs=0;
65 }
66 140 thisone->variadic = false;
67
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
140 thisone->fname= duplicate_string(get_current_file_name());
68
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
140 thisone->startline=get_current_line();
69 140 thisone->parent_macro=current_macro;
70 140 thisone->parent_macro_num_varargs=0;
71 // RPG Hacker: -1 to take the ... into account, which is also being counted.
72
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 88 times.
140 if (thisone->parent_macro != nullptr) thisone->parent_macro_num_varargs = current_macro_numargs-(current_macro->numargs-1);
73
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 138 times.
276 for (int i=0;thisone->arguments[i];i++)
74 {
75
4/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 86 times.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 2 times.
138 if(!strcmp(thisone->arguments[i], "...") && !thisone->arguments[i+1]) thisone->variadic = true;
76
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
88 else if(!strcmp(thisone->arguments[i], "...")) asar_throw_error(0, error_type_block, error_id_vararg_must_be_last);
77
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
86 else if(strchr(thisone->arguments[i], '.')) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
78
2/6
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 86 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
86 else if (!confirmname(thisone->arguments[i])) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
79
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 136 times.
186 for (int j=i+1;thisone->arguments[j];j++)
80 {
81
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
50 if (!strcmp(thisone->arguments[i], thisone->arguments[j])) asar_throw_error(0, error_type_block, error_id_macro_param_redefined, thisone->arguments[i]);
82 }
83 }
84 138 numlines=0;
85 140 }
86
87 822 void tomacro(const char * line)
88 {
89
2/2
✓ Branch 0 taken 411 times.
✓ Branch 1 taken 411 times.
822 if (!thisone) return;
90 822 thisone->lines[numlines++]=line;
91 }
92
93 140 void endmacro(bool insert)
94 {
95
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
140 if (!thisone) return;
96 140 thisone->numlines=numlines;
97
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 2 times.
140 if (insert) macros.create(defining_macro_name) = thisone;
98 else
99 {
100 2 freemacro(thisone);
101 2 thisone=nullptr;
102 }
103 }
104
105 #define cfree(x) free((void*)x)
106 140 void freemacro(macrodata* & macro)
107 {
108 140 macro->lines.~autoarray();
109 140 cfree(macro->fname);
110 140 cfree(macro->arguments_buffer);
111 140 cfree(macro->arguments);
112 140 cfree(macro);
113 140 }
114 #undef cfree
115
116
117 522 void callmacro(const char * data)
118 {
119 522 int prev_numvarargs = numvarargs;
120 macrodata * thismacro;
121
3/6
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
522 if (!confirmqpar(data)) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
122
1/2
✓ Branch 0 taken 261 times.
✗ Branch 1 not taken.
522 string line=data;
123
1/2
✓ Branch 0 taken 522 times.
✗ Branch 1 not taken.
522 line.qnormalize();
124 261 char * startpar=(char *)strchr(line.data(), '(');
125
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 522 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
522 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
126 522 *startpar=0;
127
1/2
✓ Branch 0 taken 261 times.
✗ Branch 1 not taken.
522 startpar++;
128
2/6
✓ Branch 0 taken 522 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 522 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
522 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
129
3/6
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 261 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
522 if (!macros.exists(line)) asar_throw_error(0, error_type_block, error_id_macro_not_found, line.data());
130
1/2
✓ Branch 0 taken 261 times.
✗ Branch 1 not taken.
522 thismacro = macros.find(line);
131 522 char * endpar=startpar+strlen(startpar)-1;
132 //confirmqpar requires that all parentheses are matched, and a starting one exists, therefore it is harmless to not check for nullptrs
133
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 522 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
522 if (*endpar != ')') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
134
2/2
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 60 times.
522 *endpar=0;
135 261 autoptr<const char * const*> args;
136 522 int numargs=0;
137
3/4
✓ Branch 0 taken 402 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 402 times.
✗ Branch 3 not taken.
522 if (*startpar) args=(const char* const*)qpsplit(startpar, ',', &numargs);
138
3/6
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 390 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 132 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
522 if (numargs != thismacro->numargs && !thismacro->variadic) asar_throw_error(1, error_type_block, error_id_macro_wrong_num_params);
139 // RPG Hacker: -1, because the ... is also counted as an argument, yet we want it to be entirely optional.
140
4/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 510 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
522 if (numargs < thismacro->numargs - 1 && thismacro->variadic) asar_throw_error(1, error_type_block, error_id_macro_wrong_min_params);
141
142 510 macrorecursion++;
143 510 inmacro=true;
144 510 int old_calledmacros = calledmacros;
145 510 calledmacros = reallycalledmacros++;
146 510 int startif=numif;
147
148
2/2
✓ Branch 0 taken 882 times.
✓ Branch 1 taken 510 times.
1392 for (int i = 0; i < numargs; ++i)
149 {
150 // RPG Hacker: These casts make me feel very nasty.
151
1/2
✓ Branch 0 taken 882 times.
✗ Branch 1 not taken.
882 (*reinterpret_cast<autoptr<const char**>*>(&args))[i] = safedequote(strip_whitespace((char*)args[i]));
152 }
153
154 // RPG Hacker: -1 to take the ... into account, which is also being counted.
155
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 330 times.
510 if(thismacro->variadic) numvarargs = numargs-(thismacro->numargs-1);
156 330 else numvarargs = -1;
157
158 510 autoarray<int>* oldmacroposlabels = macroposlabels;
159 510 autoarray<int>* oldmacroneglabels = macroneglabels;
160 510 autoarray<string>* oldmacrosublabels = macrosublabels;
161
162 510 autoarray<int> newmacroposlabels;
163 510 autoarray<int> newmacroneglabels;
164 510 autoarray<string> newmacrosublabels;
165
166 510 macroposlabels = &newmacroposlabels;
167 510 macroneglabels = &newmacroneglabels;
168 510 macrosublabels = &newmacrosublabels;
169
170 510 macrodata* old_macro = current_macro;
171 510 const char* const* old_macro_args = current_macro_args;
172 510 int old_numargs = current_macro_numargs;
173 510 current_macro = thismacro;
174 510 current_macro_args = args;
175 510 current_macro_numargs = numargs;
176
177
1/2
✓ Branch 0 taken 255 times.
✗ Branch 1 not taken.
510 callstack_push cs_push(callstack_entry_type::MACRO_CALL, data);
178
179 {
180
1/2
✓ Branch 0 taken 255 times.
✗ Branch 1 not taken.
510 callstack_push cs_push(callstack_entry_type::FILE, thismacro->fname);
181
182
2/2
✓ Branch 0 taken 7020 times.
✓ Branch 1 taken 510 times.
7530 for (int i=0;i<thismacro->numlines;i++)
183 {
184
2/4
✓ Branch 0 taken 7020 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3510 times.
✗ Branch 3 not taken.
7020 bool was_loop_end = do_line_logic(thismacro->lines[i], thismacro->fname, thismacro->startline+i+1);
185
186
8/8
✓ Branch 0 taken 1122 times.
✓ Branch 1 taken 5898 times.
✓ Branch 2 taken 831 times.
✓ Branch 3 taken 291 times.
✓ Branch 4 taken 291 times.
✓ Branch 5 taken 270 times.
✓ Branch 6 taken 291 times.
✓ Branch 7 taken 3219 times.
7020 if (was_loop_end && whilestatus[numif].cond)
187 // RPG Hacker: -1 to compensate for the i++, and another -1
188 // because ->lines doesn't include the macro header.
189
1/2
✓ Branch 0 taken 291 times.
✗ Branch 1 not taken.
582 i = whilestatus[numif].startline - thismacro->startline - 2;
190 }
191 510 }
192
193 510 macroposlabels = oldmacroposlabels;
194 510 macroneglabels = oldmacroneglabels;
195 510 macrosublabels = oldmacrosublabels;
196
197 510 current_macro = old_macro;
198 510 current_macro_args = old_macro_args;
199 510 current_macro_numargs = old_numargs;
200
201 510 macrorecursion--;
202 510 inmacro = macrorecursion;
203 510 numvarargs = prev_numvarargs;
204 510 calledmacros = old_calledmacros;
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 510 times.
510 if (numif!=startif)
206 {
207 numif=startif;
208 numtrue=startif;
209 asar_throw_error(0, error_type_block, error_id_unclosed_if);
210 }
211 534 }
212
213 56 string generate_macro_arg_string(const char* named_arg, int depth)
214 {
215 56 string ret="<";
216
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 56 times.
116 for (int i = 0; i < depth;++i)
217 {
218
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
60 ret += '^';
219 }
220
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
56 ret += named_arg;
221
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
56 ret += ">";
222 56 return ret;
223 }
224
225 42 string generate_macro_arg_string(int var_arg, int depth)
226 {
227 42 string ret="<";
228
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 42 times.
60 for (int i = 0; i < depth;++i)
229 {
230
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 ret += '^';
231 }
232
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
42 ret += dec(var_arg);
233
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
42 ret += ">";
234 42 return ret;
235 }
236
237 76 string generate_macro_hint_string(const char* named_arg, const macrodata* thismacro, int desired_depth, int current_depth=0)
238 {
239 // RPG Hacker: This only work when the incorrectly used parameter
240 // is inside the macro that is currently being defined. Not great,
241 // but still better than nothing.
242
4/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 24 times.
76 if (current_depth == 0 && thisone != nullptr)
243 {
244
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int j=0;thisone->arguments[j];j++)
245 {
246
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
20 if (!strcmp(named_arg, thisone->arguments[j]))
247 {
248
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 string ret=" Did you mean: '";
249
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ret += generate_macro_arg_string(thisone->arguments[j], 0);
250
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 ret += "'?";
251
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 return ret;
252 2 }
253 }
254 }
255
256 // RPG Hacker: Technically, we could skip a level here and go straight
257 // to the parent, but maybe at some point we'll want to expand this to
258 // also look for similar args in the current level, so I'll leave it
259 // like this, just in case.
260
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 16 times.
74 if (thismacro != nullptr)
261 {
262
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 40 times.
132 for (int j=0;thismacro->arguments[j];j++)
263 {
264
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 74 times.
92 if (!strcmp(named_arg, thismacro->arguments[j]))
265 {
266
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 string ret=" Did you mean: '";
267
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
18 ret += generate_macro_arg_string(thismacro->arguments[j], desired_depth+current_depth);
268
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 ret += "'?";
269
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 return ret;
270 18 }
271 }
272 40 return generate_macro_hint_string(named_arg, thismacro->parent_macro, desired_depth, current_depth+1);
273 }
274
275 16 return "";
276 }
277
278 42 string generate_macro_hint_string(int var_arg, const macrodata* thismacro, int desired_depth, int current_depth=0)
279 {
280
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 12 times.
42 if (thismacro != nullptr)
281 {
282
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18 times.
30 if (thismacro->parent_macro_num_varargs > var_arg)
283 {
284
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 string ret=" Did you mean: '";
285
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 ret += generate_macro_arg_string(var_arg, desired_depth+current_depth+1);
286
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 ret += "'?";
287
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 return ret;
288 12 }
289 18 return generate_macro_hint_string(var_arg, thismacro->parent_macro, desired_depth, current_depth+1);
290 }
291
292 12 return "";
293 }
294
295 45807 string replace_macro_args(const char* line) {
296 45807 string out;
297
2/2
✓ Branch 0 taken 39759 times.
✓ Branch 1 taken 6048 times.
45807 if(!inmacro)
298 {
299
1/2
✓ Branch 0 taken 20985 times.
✗ Branch 1 not taken.
39759 out += line;
300 20985 return out;
301 }
302
2/2
✓ Branch 0 taken 80184 times.
✓ Branch 1 taken 5946 times.
86130 for (const char * in=line;*in;)
303 {
304
5/6
✓ Branch 0 taken 2268 times.
✓ Branch 1 taken 77916 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 2250 times.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
80184 if (*in=='<' && in[1]=='<' && in[2] != ':')
305 {
306
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (in[2] == '^')
307 {
308
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 out+="<";
309 18 in+=1;
310 }
311 else
312 {
313 out+="<<";
314 in+=2;
315 }
316 }
317
2/2
✓ Branch 0 taken 2250 times.
✓ Branch 1 taken 77916 times.
80166 else if (*in=='<')
318 {
319 2250 const char * end=in+1;
320 // RPG Hacker: Added checking for space here, because this code would consider
321 // if a < b && a > c
322 // a macro arg expansion. In practice, this is still a sloppy solution and is
323 // likely to fail in some edge case I can't think of right now. Should parse
324 // this in a much more robust way at some point...
325
2/2
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 1530 times.
2250 if (*end==' ')
326 {
327
1/2
✓ Branch 0 taken 360 times.
✗ Branch 1 not taken.
720 out += *(in++);
328 1254 continue;
329 }
330
331
6/8
✓ Branch 0 taken 13284 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 11772 times.
✓ Branch 3 taken 1512 times.
✓ Branch 4 taken 11772 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11772 times.
✗ Branch 7 not taken.
13302 while (*end && *end!='>'&& *end!='<' && *(end+1)!=':') end++; //allow for conditionals and <:
332
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1512 times.
1530 if (*end!='>')
333 {
334
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 out+=*(in++);
335 18 continue;
336 }
337
338 756 int depth = 0;
339
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 1512 times.
1698 for (const char* depth_str = in+1; *depth_str=='^'; depth_str++)
340 {
341 186 depth++;
342 }
343
344
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 1350 times.
1512 if (depth != in_macro_def)
345 {
346
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
162 string temp(in, end-in+1);
347
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
162 out+=temp;
348 162 in=end+1;
349
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 144 times.
162 if (depth > in_macro_def)
350 {
351
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
18 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);
352 //else asar_throw_error(0, error_type_block, error_id_macro_param_outside_macro);
353 }
354 78 continue;
355 162 }
356
357
3/6
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1218 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 132 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1350 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);
358 1350 in += depth+1;
359
360 675 bool is_variadic_arg = false;
361
5/8
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 720 times.
✓ Branch 2 taken 630 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 630 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 630 times.
✗ Branch 7 not taken.
1350 if (in[0] == '.' && in[1] == '.' && in[2] == '.' && in[3] == '[')
362 {
363
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 624 times.
630 if (end[-1] != ']')
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 asar_throw_error(0, error_type_block, error_id_unclosed_vararg);
365
366 312 is_variadic_arg = true;
367 624 in += 4;
368 624 end--;
369 }
370
371 //if(!inmacro) asar_throw_error(0, error_type_block, error_id_macro_param_outside_macro);
372
5/6
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 720 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 618 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
1344 if(is_variadic_arg && !current_macro->variadic) asar_throw_error(0, error_type_block, error_id_macro_not_varadic, "<...[math]>");
373 //*end=0;
374 1338 string param;
375
1/2
✓ Branch 0 taken 669 times.
✗ Branch 1 not taken.
1338 string temp(in, end-in);
376
1/2
✓ Branch 0 taken 1338 times.
✗ Branch 1 not taken.
1338 resolvedefines(param, temp);
377 669 in = param.data();
378
1/2
✓ Branch 0 taken 1338 times.
✗ Branch 1 not taken.
1338 bool valid_named_param = confirmname(in);
379
2/2
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 618 times.
1338 if (!is_variadic_arg)
380 {
381
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 708 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
720 if (!valid_named_param) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
382 354 bool found=false;
383
2/2
✓ Branch 0 taken 888 times.
✓ Branch 1 taken 36 times.
924 for (int j=0;current_macro->arguments[j];j++)
384 {
385
2/2
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 216 times.
888 if (!strcmp(in, current_macro->arguments[j]))
386 {
387 336 found=true;
388
1/2
✓ Branch 0 taken 336 times.
✗ Branch 1 not taken.
672 out+=current_macro_args[j];
389 336 break;
390 }
391 }
392
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 336 times.
354 if (!found)
393 {
394
4/6
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
90 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());
395 }
396 }
397 else
398 {
399 618 snes_label ret;
400
12/16
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 606 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 309 times.
✓ Branch 8 taken 6 times.
✓ Branch 9 taken 306 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 306 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
621 if(valid_named_param && !labelval(in, &ret, false)) asar_throw_error(0, error_type_block, error_id_invalid_vararg, in);
401
1/2
✓ Branch 0 taken 612 times.
✗ Branch 1 not taken.
612 int arg_num = getnum(in);
402
403
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 612 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
612 if(forwardlabel) asar_throw_error(0, error_type_block, error_id_label_forward);
404
405
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 606 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
615 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(), "");
406
6/8
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 582 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12 times.
642 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());
407
1/2
✓ Branch 0 taken 291 times.
✗ Branch 1 not taken.
582 out+=current_macro_args[arg_num+current_macro->numargs-1];
408 }
409 1254 in=end+1;
410
2/2
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 672 times.
1254 if (is_variadic_arg) in++;
411 1422 }
412
1/2
✓ Branch 0 taken 38958 times.
✗ Branch 1 not taken.
77916 else out+=*(in++);
413 }
414 2973 return out;
415 102 }
416