GCC Code Coverage Report


Directory: src/gate/
File: src/gate/cxx_applications.cpp
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 318 403 78.9%
Functions: 64 73 87.7%
Branches: 125 204 61.3%

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 90 AppOptionDef::~AppOptionDef() noexcept
189 {
190
3/3
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 32 times.
45 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 32 default:
209 {
210 // primitive types do not need cleanup
211 32 break;
212 }
213 }
214 45 gate_app_option_release(&this->impl);
215 45 }
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 259 AppOptionDef::OptionTypeEnum AppOptionDef::Type() const noexcept
234 {
235 259 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 13 gate_app_option_t* AppOptionDef::c_impl() noexcept
292 {
293 13 return &this->impl;
294 }
295 9 gate_app_option_t const* AppOptionDef::c_impl() const noexcept
296 {
297 9 return &this->impl;
298 }
299 10 bool AppOptionDef::operator!() const noexcept
300 {
301
6/7
✓ Branch 1 taken 5 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.
10 switch (this->Type())
302 {
303 5 case OptionType_Switch:
304 5 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 26 AppOptionDef::AppOptionDef()
316 {
317 26 Mem::clear(this->impl);
318 26 Mem::clear(this->variants);
319 26 }
320
321 18 AppOptionDef AppOptionDef::createSwitch(String const& key, String const& alias, String const& name, String const& description)
322 {
323 18 AppOptionDef ret;
324 18 ret.variants.bool_impl = false;
325
1/2
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
18 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 18 return ret;
328 }
329 18 AppOptionDef AppOptionDef::createSwitch(char const* key, char const* alias, char const* name, char const* description)
330 {
331
1/2
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
18 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 4 App::App()
427 4 : appHandle(0), exitCode(0)
428 {
429 4 this->impl.parent = this;
430
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 gate_app_init(&this->impl, &App::init, &App::run, &App::on_signal);
431 4 }
432 4 App::~App() noexcept
433 {
434 4 }
435
436 4 int App::runApp(App& app, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
437 {
438 4 app.appHandle = apphandle;
439 4 return gate_app_run(&app.impl, program, arguments, argcount, apphandle);
440 }
441
442 1 Array<String> App::parseCommandLine(String const& cmdLine)
443 {
444 char buffer[GATE_MAX_COPYBUFFER_LENGTH];
445 char const* args[256];
446
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]));
447
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 ArrayList<String> list(arg_count);
448
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 for (size_t n = 0; n != arg_count; ++n)
449 {
450
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]));
451 }
452
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return list.toArray();
453 }
454
455
456 3 size_t App::parseAppOptions(Array<String> const& args, AppOptionDef** defs, size_t defsCount)
457 {
458 gate_string_t c_args[128];
459 gate_app_option_t options[32];
460 static size_t const opt_max = sizeof(options) / sizeof(options[0]);
461 gate_size_t ndx;
462 size_t arg_count;
463
464
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 gate_mem_clear(&c_args[0], sizeof(c_args));
465
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 gate_mem_clear(&options[0], sizeof(options));
466
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 arg_count = util::convertStringArray(args, c_args, sizeof(c_args) / sizeof(c_args[0]));
467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (defsCount > opt_max)
468 {
469 defsCount = opt_max;
470 }
471
472
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
16 for (ndx = 0; ndx != defsCount; ++ndx)
473 {
474
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 gate_mem_copy(&options[ndx], defs[ndx]->c_impl(), sizeof(gate_app_option_t));
475 }
476
477
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 size_t ret = gate_app_options_parse(c_args, arg_count, options, defsCount);
478
479
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (ndx = 0; ndx != arg_count; ++ndx)
480 {
481
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 gate_string_release(&c_args[ndx]);
482 }
483 3 return ret;
484 }
485
486 size_t App::parseAppOptions(Array<String> const& args, AppOptionDef* defs, size_t defsCount)
487 {
488 AppOptionDef* defsArray[64];
489 size_t const defsArrayMax = sizeof(defsArray) / sizeof(defsArray[0]);
490 if (defsCount > defsArrayMax)
491 {
492 defsCount = defsArrayMax;
493 }
494 for (size_t n = 0; n != defsCount; ++n)
495 {
496 defsArray[n] = &defs[n];
497 }
498 return parseAppOptions(args, defsArray, defsCount);
499 }
500
501 1 void App::printAppOptions(AppOptionDef const* const* defs, size_t defsCount, Stream& stream)
502 {
503 gate_app_option_t options[64];
504
505
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for (size_t ndx = 0; ndx != defsCount; ++ndx)
506 {
507
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));
508 }
509
510
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result_t result = gate_app_options_print(options, defsCount, stream.c_impl());
511
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_EXCEPTION(result);
512 1 }
513 void App::printAppOptions(AppOptionDef const* defs, size_t defsCount, Stream& stream)
514 {
515 AppOptionDef const* defsArray[64];
516 size_t const defsArrayMax = sizeof(defsArray) / sizeof(defsArray[0]);
517 if (defsCount > defsArrayMax)
518 {
519 defsCount = defsArrayMax;
520 }
521 for (size_t n = 0; n != defsCount; ++n)
522 {
523 defsArray[n] = &defs[n];
524 }
525 printAppOptions(defsArray, defsCount, stream);
526 }
527
528
529
530 void App::onSignal(int appsignal)
531 {
532 GATE_UNUSED_ARG(appsignal);
533 // default: ignore all signals
534 }
535
536 3 void App::onInit()
537 {
538
539 3 }
540
541 2 uintptr_t App::getHandle() const
542 {
543 2 return this->appHandle;
544 }
545 1 String const& App::getPath() const
546 {
547 1 return this->appPath;
548 }
549 3 Array<String> const& App::getArgs() const
550 {
551 3 return this->appArgs;
552 }
553 1 void App::setExitCode(int value)
554 {
555 1 this->exitCode = value;
556 1 }
557
558 4 gate_result_t App::init(gate_app_t* app, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
559 {
560 4 AppImpl* impl = static_cast<AppImpl*>(app);
561 try
562 {
563 4 impl->parent->appHandle = apphandle;
564
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 impl->parent->appPath = String(program);
565
566
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 ArrayList<String> args(argcount);
567
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 for (size_t n = 0; n != argcount; ++n)
568 {
569
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 args.add(String(arguments[n]));
570 }
571
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 impl->parent->appArgs = args.toArray();
572
573
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 impl->parent->onInit();
574 4 return results::Ok;
575 }
576 catch (Throwable const& th)
577 {
578 return th.getResult();
579 }
580 catch (...)
581 {
582 return GATE_RESULT_UNKNOWNEXCEPTION;
583 }
584 }
585
586 4 gate_result_t App::run(gate_app_t* app)
587 {
588 4 gate_result_t ret = results::Ok;
589 4 AppImpl* impl = static_cast<AppImpl*>(app);
590 4 impl->parent->exitCode = 0;
591 try
592 {
593
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 impl->parent->run();
594 2 ret = impl->parent->exitCode;
595 }
596 catch (Throwable const& th)
597 {
598 ret = th.getResult();
599 }
600 catch (...)
601 {
602 ret = GATE_RESULT_UNKNOWNEXCEPTION;
603 }
604 2 return ret;
605 }
606 gate_result_t App::on_signal(gate_app_t* app, int appsignal)
607 {
608 AppImpl* impl = static_cast<AppImpl*>(app);
609 try
610 {
611 impl->parent->onSignal(appsignal);
612 return results::Ok;
613 }
614 catch (Throwable const& th)
615 {
616 return th.getResult();
617 }
618 catch (...)
619 {
620 return GATE_RESULT_UNKNOWNEXCEPTION;
621 }
622 }
623
624
625
626
627 /////////////////////////////////
628 // AppService implementation //
629 /////////////////////////////////
630
631 2 int AppService::runService(AppService& service, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
632 {
633 2 return gate_appservice_run(&service.impl, program, arguments, argcount, apphandle);
634 }
635
636 2 AppService::AppService(String const& appSvcName)
637 2 : serviceName(appSvcName), appHandle(0)
638 {
639
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 gate_appservice_init(&this->impl, &AppService::init, &AppService::run,
640 &AppService::on_signal, &AppService::get_servicename,
641 &AppService::on_start, &AppService::on_stop,
642 &AppService::on_pause, &AppService::on_continue,
643 &AppService::on_error);
644
645 2 this->impl.parent = this;
646 2 }
647
648 4 AppService::~AppService() noexcept
649 {
650 4 }
651
652 2 gate_appservice_t* AppService::c_impl()
653 {
654 2 return &this->impl;
655 }
656
657 2 void AppService::cancel()
658 {
659 2 }
660
661 4 String AppService::getServiceName()
662 {
663 4 return this->serviceName;
664 }
665
666 void AppService::onSignal(int appsignal)
667 {
668 GATE_UNUSED_ARG(appsignal);
669 }
670
671 void AppService::onInit()
672 {
673
674 }
675 2 void AppService::onStart()
676 {
677
678 2 }
679 2 void AppService::onStop()
680 {
681
682 2 }
683 2 void AppService::onPause()
684 {
685
686 2 }
687 2 void AppService::onContinue()
688 {
689
690 2 }
691 2 void AppService::onError(result_t resultCode, int32_t nativeCode, String const& message)
692 {
693 GATE_UNUSED_ARG(resultCode);
694 GATE_UNUSED_ARG(nativeCode);
695 GATE_UNUSED_ARG(message);
696 2 }
697
698
699 2 gate_result_t AppService::init(gate_appservice_t* service, char const* program, char const* const* arguments, size_t argcount, uintptr_t apphandle)
700 {
701 GATE_UNUSED_ARG(apphandle);
702 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
703 try
704 {
705
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 ArrayList<String> arglist;
706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 for (size_t ndx = 0; ndx != argcount; ++ndx)
707 {
708 arglist.add(String::createStatic(arguments[ndx]));
709 }
710
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->appArgs = arglist.toArray();
711 2 impl->parent->appPath = String::createStatic(program);
712
713
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 impl->parent->onInit();
714 return GATE_RESULT_OK;
715 }
716 4 catch (Throwable const& th)
717 {
718 2 return th.getResult();
719 }
720 catch (...)
721 {
722 return GATE_RESULT_FAILED;
723 }
724 }
725 gate_result_t AppService::run(gate_appservice_t* service)
726 {
727 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
728 try
729 {
730 impl->parent->run();
731 return GATE_RESULT_OK;
732 }
733 catch (Throwable const& th)
734 {
735 return th.getErrorCode();
736 }
737 catch (...)
738 {
739 return GATE_RESULT_FAILED;
740 }
741 }
742
743 gate_result_t AppService::on_signal(gate_appservice_t* service, int appsignal)
744 {
745 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
746 try
747 {
748 impl->parent->onSignal(appsignal);
749 return GATE_RESULT_OK;
750 }
751 catch (Throwable const& th)
752 {
753 return th.getErrorCode();
754 }
755 catch (...)
756 {
757 return GATE_RESULT_FAILED;
758 }
759 }
760
761 2 gate_size_t AppService::get_servicename(gate_appservice_t* service, char* buffer, size_t bufferlength)
762 {
763 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
764 try
765 {
766
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 String name = impl->parent->getServiceName();
767
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 return name.copyTo(buffer, bufferlength);
768 }
769 catch (...)
770 {
771 return 0;
772 }
773 }
774
775 2 gate_result_t AppService::on_start(gate_appservice_t* service)
776 {
777 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
778 try
779 {
780
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onStart();
781 2 return GATE_RESULT_OK;
782 }
783 catch (Throwable const& th)
784 {
785 return th.getErrorCode();
786 }
787 catch (...)
788 {
789 return GATE_RESULT_FAILED;
790 }
791 }
792 2 gate_result_t AppService::on_stop(gate_appservice_t* service)
793 {
794 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
795 try
796 {
797
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onStop();
798 2 return GATE_RESULT_OK;
799 }
800 catch (Throwable const& th)
801 {
802 return th.getErrorCode();
803 }
804 catch (...)
805 {
806 return GATE_RESULT_FAILED;
807 }
808 }
809 2 gate_result_t AppService::on_pause(gate_appservice_t* service)
810 {
811 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
812 try
813 {
814
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onPause();
815 2 return GATE_RESULT_OK;
816 }
817 catch (Throwable const& th)
818 {
819 return th.getErrorCode();
820 }
821 catch (...)
822 {
823 return GATE_RESULT_FAILED;
824 }
825 }
826 2 gate_result_t AppService::on_continue(gate_appservice_t* service)
827 {
828 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
829 try
830 {
831
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl->parent->onContinue();
832 2 return GATE_RESULT_OK;
833 }
834 catch (Throwable const& th)
835 {
836 return th.getErrorCode();
837 }
838 catch (...)
839 {
840 return GATE_RESULT_FAILED;
841 }
842 }
843 2 gate_result_t AppService::on_error(gate_appservice_t* service, result_t resultcode, int32_t nativecode, char const* message)
844 {
845 2 AppServiceImpl* impl = static_cast<AppServiceImpl*>(service);
846 try
847 {
848
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 impl->parent->onError(resultcode, nativecode, String::createStatic(message));
849 2 return GATE_RESULT_OK;
850 }
851 catch (Throwable const& th)
852 {
853 return th.getErrorCode();
854 }
855 catch (...)
856 {
857 return GATE_RESULT_FAILED;
858 }
859 }
860
861 } // end of namespace gate
862