GCC Code Coverage Report


Directory: src/gate/
File: src/gate/cxx_applications.cpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 328 413 79.4%
Functions: 64 73 87.7%
Branches: 123 200 61.5%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/applications.hpp"
30 #include "gate/results.h"
31 #include "gate/exceptions.hpp"
32 #include "gate/utilities.hpp"
33 #include "gate/utilities.h"
34 #include "gate/mathematics.hpp"
35
36 namespace gate
37 {
38
39 6 AppOptionDef::AppOptionDef(String const& key, OptionTypeEnum type, void* targetValue, String const alias,
40 6 String const& optionName, String const& description)
41 {
42 6 Mem::clear(this->variants);
43 6 gate_app_option_init(&this->impl, key.c_impl(), (gate_enumint_t)type, targetValue, alias.c_impl(),
44 optionName.c_impl(), description.c_impl());
45 6 }
46 AppOptionDef::AppOptionDef(gate_app_option_t const& src)
47 {
48 Mem::clear(this->variants);
49 gate_app_option_copy(&this->impl, &src);
50 }
51
52 13 AppOptionDef::AppOptionDef(AppOptionDef const& src)
53 {
54 13 Mem::clear(this->variants);
55 13 gate_app_option_init(&this->impl, &src.impl.option_key, src.impl.option_type, src.impl.option_value, &src.impl.option_alias,
56 &src.impl.option_name, &src.impl.option_description);
57
6/7
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
13 switch (src.Type())
58 {
59 3 case OptionType_Switch:
60 case OptionType_Boolean:
61 {
62
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (src.impl.option_value == (void*)&src.variants.bool_impl)
63 {
64 2 this->variants.bool_impl = src.variants.bool_impl;
65 2 this->impl.option_value = (void*)&this->variants.bool_impl;
66 }
67 3 break;
68 }
69 2 case OptionType_Int32:
70 {
71
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.int32_impl)
72 {
73 1 this->variants.int32_impl = src.variants.int32_impl;
74 1 this->impl.option_value = (void*)&this->variants.int32_impl;
75 }
76 2 break;
77 }
78 2 case OptionType_Int64:
79 {
80
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.int64_impl)
81 {
82 1 this->variants.int64_impl = src.variants.int64_impl;
83 1 this->impl.option_value = (void*)&this->variants.int64_impl;
84 }
85 2 break;
86 }
87 2 case OptionType_Real:
88 {
89
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.real_impl)
90 {
91 1 this->variants.real_impl = src.variants.real_impl;
92 1 this->impl.option_value = (void*)&this->variants.real_impl;
93 }
94 2 break;
95 }
96 2 case OptionType_String:
97 {
98
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.string_impl)
99 {
100 1 gate_string_duplicate(&this->variants.string_impl, &src.variants.string_impl);
101 1 this->impl.option_value = (void*)&this->variants.string_impl;
102 }
103 2 break;
104 }
105 2 case OptionType_StringArray:
106 {
107
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.arraylist_impl)
108 {
109 1 this->variants.arraylist_impl = gate_arraylist_copy(src.variants.arraylist_impl);
110 1 this->impl.option_value = (void*)&this->variants.arraylist_impl;
111 }
112 2 break;
113 }
114 }
115
116 13 }
117 13 AppOptionDef& AppOptionDef::operator=(AppOptionDef const& src)
118 {
119
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (this != &src)
120 {
121 13 String::assign(this->impl.option_key, src.impl.option_key);
122 13 String::assign(this->impl.option_alias, src.impl.option_alias);
123 13 String::assign(this->impl.option_name, src.impl.option_name);
124 13 String::assign(this->impl.option_description, src.impl.option_description);
125 13 this->impl.option_type = src.impl.option_type;
126 13 this->impl.option_value = src.impl.option_value;
127
6/7
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
13 switch (src.Type())
128 {
129 3 case OptionType_Switch:
130 case OptionType_Boolean:
131 {
132
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (src.impl.option_value == (void*)&src.variants.bool_impl)
133 {
134 2 this->variants.bool_impl = src.variants.bool_impl;
135 2 this->impl.option_value = (void*)&this->variants.bool_impl;
136 }
137 3 break;
138 }
139 2 case OptionType_Int32:
140 {
141
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.int32_impl)
142 {
143 1 this->variants.int32_impl = src.variants.int32_impl;
144 1 this->impl.option_value = (void*)&this->variants.int32_impl;
145 }
146 2 break;
147 }
148 2 case OptionType_Int64:
149 {
150
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.int64_impl)
151 {
152 1 this->variants.int64_impl = src.variants.int64_impl;
153 1 this->impl.option_value = (void*)&this->variants.int64_impl;
154 }
155 2 break;
156 }
157 2 case OptionType_Real:
158 {
159
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.real_impl)
160 {
161 1 this->variants.real_impl = src.variants.real_impl;
162 1 this->impl.option_value = (void*)&this->variants.real_impl;
163 }
164 2 break;
165 }
166 2 case OptionType_String:
167 {
168
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.string_impl)
169 {
170 1 gate_string_duplicate(&this->variants.string_impl, &src.variants.string_impl);
171 1 this->impl.option_value = (void*)&this->variants.string_impl;
172 }
173 2 break;
174 }
175 2 case OptionType_StringArray:
176 {
177
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (src.impl.option_value == (void*)&src.variants.arraylist_impl)
178 {
179 1 this->variants.arraylist_impl = gate_arraylist_copy(src.variants.arraylist_impl);
180 1 this->impl.option_value = (void*)&this->variants.arraylist_impl;
181 }
182 2 break;
183 }
184 }
185 }
186 13 return *this;
187 }
188 82 AppOptionDef::~AppOptionDef() noexcept
189 {
190
3/3
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 28 times.
41 switch (this->Type())
191 {
192 7 case OptionType_String:
193 {
194
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 if (this->impl.option_value == (void*)&this->variants.string_impl)
195 {
196 4 gate_string_release(&this->variants.string_impl);
197 }
198 7 break;
199 }
200 6 case OptionType_StringArray:
201 {
202
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (this->impl.option_value == (void*)&this->variants.arraylist_impl)
203 {
204 3 gate_arraylist_release(this->variants.arraylist_impl);
205 }
206 6 break;
207 }
208 28 default:
209 {
210 // primitive types do not need cleanup
211 28 break;
212 }
213 }
214 41 gate_app_option_release(&this->impl);
215 41 }
216
217 26 String AppOptionDef::Key() const
218 {
219 26 return String::duplicate(this->impl.option_key);
220 }
221 26 String AppOptionDef::OptionName() const
222 {
223 26 return String::duplicate(this->impl.option_name);
224 }
225 26 String AppOptionDef::Alias() const
226 {
227 26 return String::duplicate(this->impl.option_alias);
228 }
229 26 String AppOptionDef::Description() const
230 {
231 26 return String::duplicate(this->impl.option_description);
232 }
233 252 AppOptionDef::OptionTypeEnum AppOptionDef::Type() const noexcept
234 {
235 252 return static_cast<OptionTypeEnum>(this->impl.option_type);
236 }
237 28 bool_t AppOptionDef::getBool() const noexcept
238 {
239
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 20 times.
28 switch (this->Type())
240 {
241 8 case OptionType_Switch:
242 case OptionType_Boolean:
243 8 return *(gate_bool_t*)this->impl.option_value;
244 20 default:
245 20 return false;
246 }
247 }
248 28 int32_t AppOptionDef::getInt32() const noexcept
249 {
250
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 22 times.
28 if (this->Type() == OptionType_Int32)
251 {
252 6 return *(gate_int32_t*)this->impl.option_value;
253 }
254 22 return 0;
255 }
256 27 int64_t AppOptionDef::getInt64() const noexcept
257 {
258
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 22 times.
27 if (this->Type() == OptionType_Int64)
259 {
260 5 return *(gate_int64_t*)this->impl.option_value;
261 }
262 22 return 0;
263 }
264 27 real64_t AppOptionDef::getReal() const noexcept
265 {
266
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 22 times.
27 if (this->Type() == OptionType_Real)
267 {
268 5 return *(gate_real64_t*)this->impl.option_value;
269 }
270 22 return 0;
271 }
272 28 String AppOptionDef::getString() const
273 {
274
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 22 times.
28 if (this->Type() == OptionType_String)
275 {
276 6 return String::duplicate(*((gate_string_t*)this->impl.option_value));
277 }
278 22 return String();
279 }
280 14 Array<String> AppOptionDef::getStringArray() const
281 {
282 14 Array<String> ret;
283
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 11 times.
14 if (this->Type() == OptionType_StringArray)
284 {
285 3 gate_arraylist_t const* arrlist = (gate_arraylist_t const*)this->impl.option_value;
286
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 ArrayList<String> arr = util::convertStringArray(*arrlist);
287
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 ret = arr.toArray();
288 }
289 14 return ret;
290 }
291 9 gate_app_option_t* AppOptionDef::c_impl() noexcept
292 {
293 9 return &this->impl;
294 }
295 9 gate_app_option_t const* AppOptionDef::c_impl() const noexcept
296 {
297 9 return &this->impl;
298 }
299 7 bool AppOptionDef::operator!() const noexcept
300 {
301
6/7
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
7 switch (this->Type())
302 {
303 2 case OptionType_Switch:
304 2 case OptionType_Boolean: return !(*(gate_bool_t*)this->impl.option_value);
305 1 case OptionType_Int32: return 0 == (*(gate_int32_t*)this->impl.option_value);
306 1 case OptionType_Int64: return 0 == (*(gate_int64_t*)this->impl.option_value);
307 1 case OptionType_Real: return math::isZero(*(gate_int64_t*)this->impl.option_value);
308 1 case OptionType_String: return gate_string_is_empty((gate_string_t*)this->impl.option_value);
309 1 case OptionType_StringArray:return 0 == gate_arraylist_length(*(gate_arraylist_t const*)this->impl.option_value);
310 }
311 return true;
312 }
313
314
315 22 AppOptionDef::AppOptionDef()
316 {
317 22 Mem::clear(this->impl);
318 22 Mem::clear(this->variants);
319 22 }
320
321 14 AppOptionDef AppOptionDef::createSwitch(String const& key, String const& alias, String const& name, String const& description)
322 {
323 14 AppOptionDef ret;
324 14 ret.variants.bool_impl = false;
325
1/2
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
14 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_SWITCH, &ret.variants.bool_impl, alias.c_impl(),
326 name.c_impl(), description.c_impl());
327 14 return ret;
328 }
329 14 AppOptionDef AppOptionDef::createSwitch(char const* key, char const* alias, char const* name, char const* description)
330 {
331
1/2
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
14 return AppOptionDef::createSwitch(StaticString(key), StaticString(alias), StaticString(name), StaticString(description));
332 }
333
334
335 1 AppOptionDef AppOptionDef::createBool(String const& key, String const& alias, bool_t default_value,
336 String const& name, String const& description)
337 {
338 1 AppOptionDef ret;
339 1 ret.variants.bool_impl = default_value;
340
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_BOOL, &ret.variants.bool_impl, alias.c_impl(),
341 name.c_impl(), description.c_impl());
342 1 return ret;
343 }
344 1 AppOptionDef AppOptionDef::createBool(char const* key, char const* alias, bool_t default_value, char const* name, char const* description)
345 {
346
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 return AppOptionDef::createBool(StaticString(key), StaticString(alias), default_value, StaticString(name), StaticString(description));
347 }
348
349
350 2 AppOptionDef AppOptionDef::createInt32(String const& key, String const& alias, int32_t default_value,
351 String const& name, String const& description)
352 {
353 2 AppOptionDef ret;
354 2 ret.variants.int32_impl = default_value;
355
1/2
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_I32, &ret.variants.int32_impl, alias.c_impl(),
356 name.c_impl(), description.c_impl());
357 2 return ret;
358 }
359 1 AppOptionDef AppOptionDef::createInt32(char const* key, char const* alias, int32_t default_value, char const* name, char const* description)
360 {
361
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 return AppOptionDef::createInt32(StaticString(key), StaticString(alias), default_value, StaticString(name), StaticString(description));
362 }
363
364
365 1 AppOptionDef AppOptionDef::createInt64(String const& key, String const& alias, int64_t default_value,
366 String const& name, String const& description)
367 {
368 1 AppOptionDef ret;
369 1 ret.variants.int64_impl = default_value;
370
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_I64, &ret.variants.int64_impl, alias.c_impl(),
371 name.c_impl(), description.c_impl());
372 1 return ret;
373 }
374 1 AppOptionDef AppOptionDef::createInt64(char const* key, char const* alias, int64_t default_value, char const* name, char const* description)
375 {
376
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 return AppOptionDef::createInt64(StaticString(key), StaticString(alias), default_value, StaticString(name), StaticString(description));
377 }
378
379
380 1 AppOptionDef AppOptionDef::createReal64(String const& key, String const& alias, real64_t default_value,
381 String const& name, String const& description)
382 {
383 1 AppOptionDef ret;
384 1 ret.variants.real_impl = default_value;
385
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_REAL, &ret.variants.real_impl, alias.c_impl(),
386 name.c_impl(), description.c_impl());
387 1 return ret;
388 }
389 1 AppOptionDef AppOptionDef::createReal64(char const* key, char const* alias, real64_t default_value, char const* name, char const* description)
390 {
391
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 return AppOptionDef::createReal64(StaticString(key), StaticString(alias), default_value, StaticString(name), StaticString(description));
392 }
393
394
395 2 AppOptionDef AppOptionDef::createString(String const& key, String const& alias, String const& default_value,
396 String const& name, String const& description)
397 {
398 2 AppOptionDef ret;
399
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 gate_string_duplicate(&ret.variants.string_impl, default_value.c_impl());
400
1/2
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_STRING, &ret.variants.string_impl, alias.c_impl(),
401 name.c_impl(), description.c_impl());
402 2 return ret;
403 }
404 1 AppOptionDef AppOptionDef::createString(char const* key, char const* alias, char const* default_value, char const* name, char const* description)
405 {
406
1/2
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1 return AppOptionDef::createString(StaticString(key), StaticString(alias), StaticString(default_value), StaticString(name), StaticString(description));
407 }
408
409
410 1 AppOptionDef AppOptionDef::createArray(String const& key, String const& alias,
411 String const& name, String const& description)
412 {
413 1 AppOptionDef ret;
414
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ret.variants.arraylist_impl = gate_util_stringarray_create();
415
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 gate_app_option_init(&ret.impl, key.c_impl(), GATE_APP_OPTION_TYPE_ARRAY, &ret.variants.arraylist_impl, alias.c_impl(),
416 name.c_impl(), description.c_impl());
417 1 return ret;
418 }
419 1 AppOptionDef AppOptionDef::createArray(char const* key, char const* alias, char const* name, char const* description)
420 {
421
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 return AppOptionDef::createArray(StaticString(key), StaticString(alias), StaticString(name), StaticString(description));
422 }
423
424
425
426 1 App::App()
427 1 : appHandle(0), exitCode(0)
428 {
429 1 this->impl.parent = this;
430 1 this->impl.init = &App::init;
431 1 this->impl.run = &App::run;
432 1 this->impl.on_signal = &App::on_signal;
433 1 }
434 2 App::~App() noexcept
435 {
436 2 }
437
438 1 int App::runApp(App& app, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
439 {
440 1 app.appHandle = apphandle;
441 1 return gate_app_run(&app.impl, program, arguments, argcount, apphandle);
442 }
443
444 1 Array<String> App::parseCommandLine(String const& cmdLine)
445 {
446 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
447 char const* args[256];
448
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 size_t arg_count = gate_app_parse_args_buffer(cmdLine.c_impl(), buffer, sizeof(buffer), &args[0], sizeof(args) / sizeof(args[0]));
449
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 ArrayList<String> list(arg_count);
450
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 for (size_t n = 0; n != arg_count; ++n)
451 {
452
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 list.add(String(args[n]));
453 }
454
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return list.toArray();
455 }
456
457
458 1 size_t App::parseAppOptions(Array<String> const& args, AppOptionDef** defs, size_t defsCount)
459 {
460 gate_string_t c_args[128];
461 gate_app_option_t options[32];
462 static size_t const opt_max = sizeof(options) / sizeof(options[0]);
463 gate_size_t ndx;
464 size_t arg_count;
465
466
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_mem_clear(&c_args[0], sizeof(c_args));
467
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_mem_clear(&options[0], sizeof(options));
468
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 arg_count = util::convertStringArray(args, c_args, sizeof(c_args) / sizeof(c_args[0]));
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (defsCount > opt_max)
470 {
471 defsCount = opt_max;
472 }
473
474
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for (ndx = 0; ndx != defsCount; ++ndx)
475 {
476
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 gate_mem_copy(&options[ndx], defs[ndx]->c_impl(), sizeof(gate_app_option_t));
477 }
478
479
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 size_t ret = gate_app_options_parse(c_args, arg_count, options, defsCount);
480
481
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 times.
20 for (ndx = 0; ndx != arg_count; ++ndx)
482 {
483
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 gate_string_release(&c_args[ndx]);
484 }
485 1 return ret;
486 }
487
488 size_t App::parseAppOptions(Array<String> const& args, AppOptionDef* defs, size_t defsCount)
489 {
490 AppOptionDef* defsArray[64];
491 size_t const defsArrayMax = sizeof(defsArray) / sizeof(defsArray[0]);
492 if (defsCount > defsArrayMax)
493 {
494 defsCount = defsArrayMax;
495 }
496 for (size_t n = 0; n != defsCount; ++n)
497 {
498 defsArray[n] = &defs[n];
499 }
500 return parseAppOptions(args, defsArray, defsCount);
501 }
502
503 1 void App::printAppOptions(AppOptionDef const* const* defs, size_t defsCount, Stream& stream)
504 {
505 gate_app_option_t options[64];
506
507
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for (size_t ndx = 0; ndx != defsCount; ++ndx)
508 {
509
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 gate_mem_copy(&options[ndx], defs[ndx]->c_impl(), sizeof(gate_app_option_t));
510 }
511
512
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result_t result = gate_app_options_print(options, defsCount, stream.c_impl());
513
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_EXCEPTION(result);
514 1 }
515 void App::printAppOptions(AppOptionDef const* defs, size_t defsCount, Stream& stream)
516 {
517 AppOptionDef const* defsArray[64];
518 size_t const defsArrayMax = sizeof(defsArray) / sizeof(defsArray[0]);
519 if (defsCount > defsArrayMax)
520 {
521 defsCount = defsArrayMax;
522 }
523 for (size_t n = 0; n != defsCount; ++n)
524 {
525 defsArray[n] = &defs[n];
526 }
527 printAppOptions(defsArray, defsCount, stream);
528 }
529
530
531
532 void App::onSignal(int appsignal)
533 {
534 GATE_UNUSED_ARG(appsignal);
535 // default: ignore all signals
536 }
537
538 1 void App::onInit()
539 {
540
541 1 }
542
543 1 uintptr_t App::getHandle() const
544 {
545 1 return this->appHandle;
546 }
547 1 String const& App::getPath() const
548 {
549 1 return this->appPath;
550 }
551 1 Array<String> const& App::getArgs() const
552 {
553 1 return this->appArgs;
554 }
555 1 void App::setExitCode(int value)
556 {
557 1 this->exitCode = value;
558 1 }
559
560 1 gate_result_t App::init(gate_app_t* app, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
561 {
562 1 AppImpl* impl = static_cast<AppImpl*>(app);
563 try
564 {
565 1 impl->parent->appHandle = apphandle;
566
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 impl->parent->appPath = String(program);
567
568
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ArrayList<String> args(argcount);
569
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for (size_t n = 0; n != argcount; ++n)
570 {
571
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 args.add(String(arguments[n]));
572 }
573
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 impl->parent->appArgs = args.toArray();
574
575
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 impl->parent->onInit();
576 1 return results::Ok;
577 }
578 catch (Throwable const& th)
579 {
580 return th.getResult();
581 }
582 catch (...)
583 {
584 return GATE_RESULT_UNKNOWNEXCEPTION;
585 }
586 }
587
588 1 gate_result_t App::run(gate_app_t* app)
589 {
590 1 gate_result_t ret = results::Ok;
591 1 AppImpl* impl = static_cast<AppImpl*>(app);
592 1 impl->parent->exitCode = 0;
593 try
594 {
595
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 impl->parent->run();
596 1 ret = impl->parent->exitCode;
597 }
598 catch (Throwable const& th)
599 {
600 ret = th.getResult();
601 }
602 catch (...)
603 {
604 ret = GATE_RESULT_UNKNOWNEXCEPTION;
605 }
606 1 return ret;
607 }
608 gate_result_t App::on_signal(gate_app_t* app, int appsignal)
609 {
610 AppImpl* impl = static_cast<AppImpl*>(app);
611 try
612 {
613 impl->parent->onSignal(appsignal);
614 return results::Ok;
615 }
616 catch (Throwable const& th)
617 {
618 return th.getResult();
619 }
620 catch (...)
621 {
622 return GATE_RESULT_UNKNOWNEXCEPTION;
623 }
624 }
625
626
627
628
629 /////////////////////////////////
630 // AppService implementation //
631 /////////////////////////////////
632
633 2 int AppService::runService(AppService& service, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
634 {
635 2 return gate_appservice_run(&service.impl, program, arguments, argcount, apphandle);
636 }
637
638 2 AppService::AppService(String const& appSvcName)
639 2 : serviceName(appSvcName), appHandle(0)
640 {
641 2 this->impl.init = &AppService::init;
642 2 this->impl.run = &AppService::run;
643
644 2 this->impl.on_signal = &AppService::on_signal;
645
646 2 this->impl.get_servicename = &AppService::get_servicename;
647
648 2 this->impl.on_start = &AppService::on_start;
649 2 this->impl.on_stop = &AppService::on_stop;
650 2 this->impl.on_pause = &AppService::on_pause;
651 2 this->impl.on_continue = &AppService::on_continue;
652 2 this->impl.on_error = &AppService::on_error;
653
654 2 this->impl.parent = this;
655 2 }
656
657 4 AppService::~AppService() noexcept
658 {
659 4 }
660
661 2 gate_appservice_t* AppService::c_impl()
662 {
663 2 return &this->impl;
664 }
665
666 2 void AppService::cancel()
667 {
668 2 }
669
670 4 String AppService::getServiceName()
671 {
672 4 return this->serviceName;
673 }
674
675 void AppService::onSignal(int appsignal)
676 {
677 GATE_UNUSED_ARG(appsignal);
678 }
679
680 void AppService::onInit()
681 {
682
683 }
684 2 void AppService::onStart()
685 {
686
687 2 }
688 2 void AppService::onStop()
689 {
690
691 2 }
692 2 void AppService::onPause()
693 {
694
695 2 }
696 2 void AppService::onContinue()
697 {
698
699 2 }
700 2 void AppService::onError(result_t resultCode, int32_t nativeCode, String const& message)
701 {
702 GATE_UNUSED_ARG(resultCode);
703 GATE_UNUSED_ARG(nativeCode);
704 GATE_UNUSED_ARG(message);
705 2 }
706
707
708 2 gate_result_t AppService::init(gate_appservice_t* service, char const* program, char const* const* arguments, size_t argcount, uintptr_t apphandle)
709 {
710 GATE_UNUSED_ARG(apphandle);
711 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
712 try
713 {
714
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 ArrayList<String> arglist;
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 for (size_t ndx = 0; ndx != argcount; ++ndx)
716 {
717 arglist.add(String::createStatic(arguments[ndx]));
718 }
719
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->appArgs = arglist.toArray();
720 2 impl->parent->appPath = String::createStatic(program);
721
722
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 impl->parent->onInit();
723 return GATE_RESULT_OK;
724 }
725 4 catch (Throwable const& th)
726 {
727 2 return th.getResult();
728 }
729 catch (...)
730 {
731 return GATE_RESULT_FAILED;
732 }
733 }
734 gate_result_t AppService::run(gate_appservice_t* service)
735 {
736 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
737 try
738 {
739 impl->parent->run();
740 return GATE_RESULT_OK;
741 }
742 catch (Throwable const& th)
743 {
744 return th.getErrorCode();
745 }
746 catch (...)
747 {
748 return GATE_RESULT_FAILED;
749 }
750 }
751
752 gate_result_t AppService::on_signal(gate_appservice_t* service, int appsignal)
753 {
754 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
755 try
756 {
757 impl->parent->onSignal(appsignal);
758 return GATE_RESULT_OK;
759 }
760 catch (Throwable const& th)
761 {
762 return th.getErrorCode();
763 }
764 catch (...)
765 {
766 return GATE_RESULT_FAILED;
767 }
768 }
769
770 2 gate_size_t AppService::get_servicename(gate_appservice_t* service, char* buffer, size_t bufferlength)
771 {
772 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
773 try
774 {
775
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 String name = impl->parent->getServiceName();
776
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 return name.copyTo(buffer, bufferlength);
777 }
778 catch (...)
779 {
780 return 0;
781 }
782 }
783
784 2 gate_result_t AppService::on_start(gate_appservice_t* service)
785 {
786 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
787 try
788 {
789
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onStart();
790 2 return GATE_RESULT_OK;
791 }
792 catch (Throwable const& th)
793 {
794 return th.getErrorCode();
795 }
796 catch (...)
797 {
798 return GATE_RESULT_FAILED;
799 }
800 }
801 2 gate_result_t AppService::on_stop(gate_appservice_t* service)
802 {
803 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
804 try
805 {
806
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onStop();
807 2 return GATE_RESULT_OK;
808 }
809 catch (Throwable const& th)
810 {
811 return th.getErrorCode();
812 }
813 catch (...)
814 {
815 return GATE_RESULT_FAILED;
816 }
817 }
818 2 gate_result_t AppService::on_pause(gate_appservice_t* service)
819 {
820 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
821 try
822 {
823
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onPause();
824 2 return GATE_RESULT_OK;
825 }
826 catch (Throwable const& th)
827 {
828 return th.getErrorCode();
829 }
830 catch (...)
831 {
832 return GATE_RESULT_FAILED;
833 }
834 }
835 2 gate_result_t AppService::on_continue(gate_appservice_t* service)
836 {
837 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
838 try
839 {
840
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onContinue();
841 2 return GATE_RESULT_OK;
842 }
843 catch (Throwable const& th)
844 {
845 return th.getErrorCode();
846 }
847 catch (...)
848 {
849 return GATE_RESULT_FAILED;
850 }
851 }
852 2 gate_result_t AppService::on_error(gate_appservice_t* service, result_t resultcode, int32_t nativecode, char const* message)
853 {
854 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
855 try
856 {
857
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 impl->parent->onError(resultcode, nativecode, String::createStatic(message));
858 2 return GATE_RESULT_OK;
859 }
860 catch (Throwable const& th)
861 {
862 return th.getErrorCode();
863 }
864 catch (...)
865 {
866 return GATE_RESULT_FAILED;
867 }
868 }
869
870 } // end of namespace gate
871