asar coverage - build #269


src/asar/
File: src/asar/macro.cpp
Date: 2025-03-03 03:30:06
Lines:
238/247
96.4%
Functions:
10/10
100.0%
Branches:
358/508
70.5%

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 static 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 static macrodata* current_macro;
19 static const char* const* current_macro_args;
20 static int current_macro_numargs;
21
22 142 void startmacro(const char * line_)
23 {
24 142 thisone= nullptr;
25
2/4
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 142 times.
142 if (!confirmqpar(line_)) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
26
2/3
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
142 string line=line_;
27
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 line.qnormalize();
28
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
142 char * startpar=(char *)strchr(line.data(), '(');
29
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
30 142 *startpar=0;
31 142 startpar++;
32
2/4
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 142 times.
142 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_invalid_macro_name);
33
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 defining_macro_name=line;
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
142 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
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 72 times.
142 if (*endpar != ')') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
37 142 *endpar=0;
38
4/4
✓ Branch 0 taken 389 times.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 391 times.
✓ Branch 3 taken 72 times.
922 for (int i=0;startpar[i];i++)
39 {
40 780 char c=startpar[i];
41
8/10
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 572 times.
✓ Branch 2 taken 162 times.
✓ Branch 3 taken 46 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 156 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 780 times.
780 if (!is_ualnum(c)&& c!=','&& c!='.'&& c!=' ') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
42
5/8
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 734 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 412 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 391 times.
780 if (c==',' && is_digit(startpar[i+1])) asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
43 }
44
10/15
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 70 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 70 times.
✓ Branch 5 taken 72 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 70 times.
✓ Branch 8 taken 72 times.
✓ Branch 9 taken 142 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 72 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 72 times.
142 if (*startpar==',' || is_digit(*startpar) || strstr(startpar, ",,") || endpar[-1]==',') asar_throw_error(0, error_type_block, error_id_broken_macro_declaration);
45
2/4
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 142 times.
142 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 142 thisone=(macrodata*)malloc(sizeof(macrodata));
54
2/5
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
142 new(thisone) macrodata;
55
3/3
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 23 times.
142 if (*startpar)
56 {
57
2/4
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
96 char **arguments = split(duplicate_string(startpar), ',', &thisone->numargs);
58 96 thisone->arguments_buffer = arguments[0];
59
4/4
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 49 times.
238 for (int i=0;arguments[i];i++)
60 {
61 142 arguments[i] = strip_whitespace(arguments[i]);
62 }
63 96 thisone->arguments=(const char* const*)arguments;
64 }
65 else
66 {
67 46 const char ** noargs=(const char**)malloc(sizeof(const char**));
68 46 *noargs=nullptr;
69 46 thisone->arguments=noargs;
70 46 thisone->arguments_buffer = nullptr;
71 46 thisone->numargs=0;
72 }
73 142 thisone->variadic = false;
74
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 thisone->fname= duplicate_string(get_current_file_name());
75
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 thisone->startline=get_current_line();
76 142 thisone->parent_macro=current_macro;
77 142 thisone->parent_macro_num_varargs=0;
78 // RPG Hacker: -1 to take the ... into account, which is also being counted.
79
4/4
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 46 times.
142 if (thisone->parent_macro != nullptr) thisone->parent_macro_num_varargs = current_macro_numargs-(current_macro->numargs-1);
80
4/4
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 71 times.
280 for (int i=0;thisone->arguments[i];i++)
81 {
82
9/10
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 71 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 45 times.
✓ Branch 8 taken 25 times.
✓ Branch 9 taken 1 times.
140 if(!strcmp(thisone->arguments[i], "...") && !thisone->arguments[i+1]) thisone->variadic = true;
83
5/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 45 times.
90 else if(!strcmp(thisone->arguments[i], "...")) asar_throw_error(0, error_type_block, error_id_vararg_must_be_last);
84
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 45 times.
88 else if(strchr(thisone->arguments[i], '.')) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
85
4/8
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
✓ Branch 4 taken 45 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 45 times.
88 else if (!confirmname(thisone->arguments[i])) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
86
4/4
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 70 times.
188 for (int j=i+1;thisone->arguments[j];j++)
87 {
88
4/8
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 25 times.
50 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 140 numlines=0;
92 213 }
93
94 824 void tomacro(const char * line)
95 {
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 824 times.
824 if (!thisone) return;
97 824 thisone->lines[numlines++]=line;
98 }
99
100 142 void endmacro(bool insert)
101 {
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 if (!thisone) return;
103 142 thisone->numlines=numlines;
104
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 2 times.
142 if (insert) macros.create(defining_macro_name) = thisone;
105 else
106 {
107 2 freemacro(thisone);
108 2 thisone=nullptr;
109 }
110 }
111
112 #define cfree(x) free((void*)x)
113 142 void freemacro(macrodata* & macro)
114 {
115 142 macro->lines.~autoarray();
116 142 cfree(macro->fname);
117 142 cfree(macro->arguments_buffer);
118 142 cfree(macro->arguments);
119 142 cfree(macro);
120 142 }
121 #undef cfree
122
123
124 534 void callmacro(const char * data)
125 {
126 534 int prev_numvarargs = numvarargs;
127 macrodata * thismacro;
128
2/4
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 534 times.
534 if (!confirmqpar(data)) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
129
2/3
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 273 times.
✗ Branch 2 not taken.
534 string line=data;
130
1/2
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
534 line.qnormalize();
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 273 times.
534 char * startpar=(char *)strchr(line.data(), '(');
132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 534 times.
534 if (!startpar) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
133 534 *startpar=0;
134 534 startpar++;
135
2/4
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 534 times.
534 if (!confirmname(line)) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
136
2/4
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 534 times.
534 if (!macros.exists(line)) asar_throw_error(0, error_type_block, error_id_macro_not_found, line.data());
137
1/2
✓ Branch 0 taken 534 times.
✗ Branch 1 not taken.
534 thismacro = macros.find(line);
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 273 times.
534 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
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
✓ Branch 2 taken 273 times.
534 if (*endpar != ')') asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
141 534 *endpar=0;
142 534 autoptr<const char * const*> args;
143 534 int numargs=0;
144
3/3
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 273 times.
✓ Branch 2 taken 60 times.
534 if (*startpar) {
145
1/2
✓ Branch 0 taken 414 times.
✗ Branch 1 not taken.
414 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/2
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
414 if(args == nullptr) asar_throw_error(0, error_type_block, error_id_broken_macro_usage);
148 }
149
6/8
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 195 times.
✓ Branch 2 taken 66 times.
✓ Branch 3 taken 273 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 66 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 66 times.
534 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
6/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 255 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 267 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
534 if (numargs < thismacro->numargs - 1 && thismacro->variadic) asar_throw_error(1, error_type_block, error_id_macro_wrong_min_params);
152
153 522 macrorecursion++;
154 522 inmacro=true;
155 522 int old_calledmacros = calledmacros;
156 522 calledmacros = reallycalledmacros++;
157 522 int startif=numif;
158
159
2/2
✓ Branch 0 taken 894 times.
✓ Branch 1 taken 522 times.
1416 for (int i = 0; i < numargs; ++i)
160 {
161 // RPG Hacker: These casts make me feel very nasty.
162
2/4
✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 453 times.
✗ Branch 3 not taken.
894 (*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
5/5
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 165 times.
✓ Branch 2 taken 267 times.
✓ Branch 3 taken 90 times.
✓ Branch 4 taken 177 times.
522 if(thismacro->variadic) numvarargs = numargs-(thismacro->numargs-1);
167 342 else numvarargs = -1;
168
169 522 autoarray<int>* oldmacroposlabels = macroposlabels;
170 522 autoarray<int>* oldmacroneglabels = macroneglabels;
171 522 autoarray<string>* oldmacrosublabels = macrosublabels;
172
173 522 autoarray<int> newmacroposlabels;
174 522 autoarray<int> newmacroneglabels;
175 522 autoarray<string> newmacrosublabels;
176
177 522 macroposlabels = &newmacroposlabels;
178 522 macroneglabels = &newmacroneglabels;
179 522 macrosublabels = &newmacrosublabels;
180
181 522 macrodata* old_macro = current_macro;
182 522 const char* const* old_macro_args = current_macro_args;
183 522 int old_numargs = current_macro_numargs;
184 522 current_macro = thismacro;
185 522 current_macro_args = args;
186 522 current_macro_numargs = numargs;
187
188
2/3
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 267 times.
✗ Branch 2 not taken.
522 callstack_push cs_push(callstack_entry_type::MACRO_CALL, data);
189
190 {
191
2/4
✓ Branch 0 taken 255 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 267 times.
✗ Branch 3 not taken.
522 callstack_push cs_push(callstack_entry_type::FILE, thismacro->fname);
192
193
4/4
✓ Branch 0 taken 3513 times.
✓ Branch 1 taken 255 times.
✓ Branch 2 taken 3525 times.
✓ Branch 3 taken 267 times.
7560 for (int i=0;i<thismacro->numlines;i++)
194 {
195
4/8
✓ Branch 0 taken 3513 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3513 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3525 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3525 times.
✗ Branch 7 not taken.
7038 bool was_loop_end = do_line_logic(thismacro->lines[i], thismacro->fname, thismacro->startline+i+1);
196
197
12/12
✓ Branch 0 taken 1220 times.
✓ Branch 1 taken 5818 times.
✓ Branch 2 taken 610 times.
✓ Branch 3 taken 610 times.
✓ Branch 4 taken 291 times.
✓ Branch 5 taken 319 times.
✓ Branch 6 taken 291 times.
✓ Branch 7 taken 3832 times.
✓ Branch 8 taken 291 times.
✓ Branch 9 taken 319 times.
✓ Branch 10 taken 291 times.
✓ Branch 11 taken 3234 times.
7038 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
2/3
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 291 times.
✗ Branch 2 not taken.
582 i = whilestatus[numif].startline - thismacro->startline - 2;
201 }
202 522 }
203
204 522 macroposlabels = oldmacroposlabels;
205 522 macroneglabels = oldmacroneglabels;
206 522 macrosublabels = oldmacrosublabels;
207
208 522 current_macro = old_macro;
209 522 current_macro_args = old_macro_args;
210 522 current_macro_numargs = old_numargs;
211
212 522 macrorecursion--;
213 522 inmacro = macrorecursion;
214 522 numvarargs = prev_numvarargs;
215 522 calledmacros = old_calledmacros;
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 522 times.
522 if (numif!=startif)
217 {
218 numif=startif;
219 numtrue=startif;
220 asar_throw_error(0, error_type_block, error_id_unclosed_if);
221 }
222 813 }
223
224 56 static string generate_macro_arg_string(const char* named_arg, int depth)
225 {
226 56 string ret="<";
227
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 56 times.
116 for (int i = 0; i < depth;++i)
228 {
229
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 ret += '^';
230 }
231
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 ret += named_arg;
232
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 ret += ">";
233 56 return ret;
234 }
235
236 42 static string generate_macro_arg_string(int var_arg, int depth)
237 {
238 42 string ret="<";
239
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 42 times.
60 for (int i = 0; i < depth;++i)
240 {
241
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 ret += '^';
242 }
243
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 ret += "...[";
244
4/7
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
✗ Branch 6 not taken.
42 ret += dec(var_arg);
245
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 ret += "]>";
246 42 return ret;
247 }
248
249 76 static string generate_macro_hint_string(const char* named_arg, const macrodata* thismacro, int desired_depth, int current_depth=0)
250 {
251 // RPG Hacker: This only work when the incorrectly used parameter
252 // is inside the macro that is currently being defined. Not great,
253 // but still better than nothing.
254
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)
255 {
256
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 5 times.
30 for (int j=0;thisone->arguments[j];j++)
257 {
258
6/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 9 times.
20 if (!strcmp(named_arg, thisone->arguments[j]))
259 {
260
2/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 string ret=" Did you mean: '";
261
4/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 ret += generate_macro_arg_string(thisone->arguments[j], 0);
262
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ret += "'?";
263 2 return ret;
264 2 }
265 }
266 }
267
268 // RPG Hacker: Technically, we could skip a level here and go straight
269 // to the parent, but maybe at some point we'll want to expand this to
270 // also look for similar args in the current level, so I'll leave it
271 // like this, just in case.
272
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 16 times.
74 if (thismacro != nullptr)
273 {
274
4/4
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 20 times.
132 for (int j=0;thismacro->arguments[j];j++)
275 {
276
6/8
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 46 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 37 times.
92 if (!strcmp(named_arg, thismacro->arguments[j]))
277 {
278
2/3
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 string ret=" Did you mean: '";
279
4/8
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
18 ret += generate_macro_arg_string(thismacro->arguments[j], desired_depth+current_depth);
280
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 ret += "'?";
281 18 return ret;
282 18 }
283 }
284 40 return generate_macro_hint_string(named_arg, thismacro->parent_macro, desired_depth, current_depth+1);
285 }
286
287 16 return "";
288 }
289
290 42 static string generate_macro_hint_string(int var_arg, const macrodata* thismacro, int desired_depth, int current_depth=0)
291 {
292
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 12 times.
42 if (thismacro != nullptr)
293 {
294
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 9 times.
30 if (thismacro->parent_macro_num_varargs > var_arg)
295 {
296
2/3
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
12 string ret=" Did you mean: '";
297
4/7
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
12 ret += generate_macro_arg_string(var_arg, desired_depth+current_depth+1);
298
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 ret += "'?";
299 12 return ret;
300 12 }
301 18 return generate_macro_hint_string(var_arg, thismacro->parent_macro, desired_depth, current_depth+1);
302 }
303
304 12 return "";
305 }
306
307 49320 string replace_macro_args(const char* line) {
308 49320 string out;
309
4/4
✓ Branch 0 taken 22015 times.
✓ Branch 1 taken 27305 times.
✓ Branch 2 taken 21239 times.
✓ Branch 3 taken 3039 times.
49320 if(!inmacro)
310 {
311
1/2
✓ Branch 0 taken 43254 times.
✗ Branch 1 not taken.
43254 out += line;
312 43254 return out;
313 }
314
3/3
✓ Branch 0 taken 40092 times.
✓ Branch 1 taken 43188 times.
✓ Branch 2 taken 2988 times.
86268 for (const char * in=line;*in;)
315 {
316
8/9
✓ Branch 0 taken 1134 times.
✓ Branch 1 taken 40104 times.
✓ Branch 2 taken 39075 times.
✓ Branch 3 taken 1125 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 1137 times.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
80304 if (*in=='<' && in[1]=='<' && in[2] != ':')
317 {
318
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
18 if (in[2] == '^')
319 {
320
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 out+="<";
321 18 in+=1;
322 }
323 else
324 {
325 out+="<<";
326 in+=2;
327 }
328 }
329
3/3
✓ Branch 0 taken 1125 times.
✓ Branch 1 taken 40095 times.
✓ Branch 2 taken 39066 times.
80286 else if (*in=='<')
330 {
331 2262 const char * end=in+1;
332 // RPG Hacker: Added checking for space here, because this code would consider
333 // if a < b && a > c
334 // a macro arg expansion. In practice, this is still a sloppy solution and is
335 // likely to fail in some edge case I can't think of right now. Should parse
336 // this in a much more robust way at some point...
337
3/3
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 1125 times.
✓ Branch 2 taken 777 times.
2262 if (*end==' ')
338 {
339
2/4
✓ Branch 0 taken 360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 360 times.
✗ Branch 3 not taken.
720 out += *(in++);
340 807 continue;
341 }
342
343
9/12
✓ Branch 0 taken 6642 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 12552 times.
✓ Branch 3 taken 765 times.
✓ Branch 4 taken 5886 times.
✓ Branch 5 taken 5898 times.
✓ Branch 6 taken 6654 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5898 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5898 times.
✗ Branch 11 not taken.
13326 while (*end && *end!='>'&& *end!='<' && *(end+1)!=':') end++; //allow for conditionals and <:
344
3/3
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 765 times.
✓ Branch 2 taken 768 times.
1542 if (*end!='>')
345 {
346
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
18 out+=*(in++);
347 18 continue;
348 }
349
350 1524 int depth = 0;
351
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 756 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 768 times.
1710 for (const char* depth_str = in+1; *depth_str=='^'; depth_str++)
352 {
353 186 depth++;
354 }
355
356
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 1362 times.
1524 if (depth != in_macro_def)
357 {
358
2/3
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
162 string temp(in, end-in+1);
359
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
162 out+=temp;
360 162 in=end+1;
361
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 144 times.
162 if (depth > in_macro_def)
362 {
363
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 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);
364 //else asar_throw_error(0, error_type_block, error_id_macro_param_outside_macro);
365 }
366 156 continue;
367 162 }
368
369
4/6
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1230 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 132 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 66 times.
1362 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);
370 1362 in += depth+1;
371
372 1362 bool is_variadic_arg = false;
373
8/12
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 675 times.
✓ Branch 2 taken 687 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 315 times.
✓ Branch 5 taken 315 times.
✓ Branch 6 taken 315 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 315 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 315 times.
✗ Branch 11 not taken.
1362 if (in[0] == '.' && in[1] == '.' && in[2] == '.' && in[3] == '[')
374 {
375
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 312 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 312 times.
630 if (end[-1] != ']')
376 6 asar_throw_error(0, error_type_block, error_id_unclosed_vararg);
377
378 624 is_variadic_arg = true;
379 624 in += 4;
380 624 end--;
381 }
382
383 //if(!inmacro) asar_throw_error(0, error_type_block, error_id_macro_param_outside_macro);
384
7/7
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 732 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 309 times.
✓ Branch 4 taken 312 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 309 times.
1356 if(is_variadic_arg && !current_macro->variadic) asar_throw_error(0, error_type_block, error_id_macro_not_varadic, "<...[math]>");
385 //*end=0;
386 1350 string param;
387
2/3
✓ Branch 0 taken 669 times.
✓ Branch 1 taken 681 times.
✗ Branch 2 not taken.
1350 string temp(in, end-in);
388
1/2
✓ Branch 0 taken 1350 times.
✗ Branch 1 not taken.
1350 resolvedefines(param, temp);
389 1350 in = param.data();
390
1/2
✓ Branch 0 taken 1350 times.
✗ Branch 1 not taken.
1350 bool valid_named_param = confirmname(in);
391
2/2
✓ Branch 0 taken 732 times.
✓ Branch 1 taken 618 times.
1350 if (!is_variadic_arg)
392 {
393
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 720 times.
732 if (!valid_named_param) asar_throw_error(0, error_type_block, error_id_invalid_macro_param_name);
394 720 bool found=false;
395
4/4
✓ Branch 0 taken 444 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 456 times.
✓ Branch 3 taken 18 times.
936 for (int j=0;current_macro->arguments[j];j++)
396 {
397
6/8
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 456 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 456 times.
✓ Branch 6 taken 348 times.
✓ Branch 7 taken 108 times.
900 if (!strcmp(in, current_macro->arguments[j]))
398 {
399 684 found=true;
400
2/4
✓ Branch 0 taken 336 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 348 times.
✗ Branch 3 not taken.
684 out+=current_macro_args[j];
401 684 break;
402 }
403 }
404
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 684 times.
720 if (!found)
405 {
406
4/7
✓ 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.
✗ Branch 6 not taken.
126 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());
407 }
408 }
409 else
410 {
411
7/10
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 615 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 306 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 306 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 306 times.
✗ Branch 9 not taken.
627 int arg_num = parse_math_expr(in)->evaluate_static().get_integer();
412
413
4/5
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 606 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
618 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(), "");
414
7/10
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 291 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 291 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
666 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());
415
2/4
✓ Branch 0 taken 291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 291 times.
✗ Branch 3 not taken.
582 out+=current_macro_args[arg_num+current_macro->numargs-1];
416 }
417 1266 in=end+1;
418
2/2
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 684 times.
1266 if (is_variadic_arg) in++;
419 1434 }
420
2/4
✓ Branch 0 taken 38958 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39066 times.
✗ Branch 3 not taken.
78024 else out+=*(in++);
421 }
422 5964 return out;
423 102 }
424