YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_param.c
Go to the documentation of this file.
1// Copyright (c) 2026 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdlib.h>
6#include <string.h>
7#include <math.h>
8#include <limits.h>
9#include <stdint.h>
10
11#include "parameter/param.h"
12#include "parameter/param_int.h"
19#include "parameter/param_str.h"
23#include "tests.h"
24
34static void utest_null_param_interfaces(void);
35static void utest_get_last_error(void);
36static void utest_deg_rad_conversion(void);
37static void utest_int_param_interfaces(void);
38static void utest_bool_param_interfaces(void);
39static void utest_dble_param_interfaces(void);
40static void utest_angle_param_interfaces(void);
41static void utest_distance_param_interfaces(void);
42static void utest_str_param_interfaces(void);
43static void utest_enum_param_interfaces(void);
44static void utest_struct_param_interfaces(void);
45static void utest_oneof_param_interfaces(void);
46static void utest_list_param_interfaces(void);
47static void utest_usage_demo(void);
48
49static double const tol = 1e-12;
50
51int main(void) {
52
53 utest_null_param_interfaces();
54 utest_get_last_error();
55 utest_deg_rad_conversion();
56 utest_int_param_interfaces();
57 utest_bool_param_interfaces();
58 utest_dble_param_interfaces();
59 utest_angle_param_interfaces();
60 utest_distance_param_interfaces();
61 utest_str_param_interfaces();
62 utest_enum_param_interfaces();
63 utest_struct_param_interfaces();
64 utest_oneof_param_interfaces();
65 utest_list_param_interfaces();
66 utest_usage_demo();
67
68 return TEST_EXIT_CODE;
69}
70
71static char const *oneof_int_param_name = "int_sub";
72static int oneof_int_val = 7;
73static int oneof_int_default = 42;
74static int oneof_int_min = 0;
75static int oneof_int_max = 100;
76static int oneof_has_default = 1;
77static int oneof_is_defined = 1;
78
79static char const *oneof_bool_param_name = "bool_sub";
80static int oneof_bool_val = 1;
81static int oneof_bool_default = 0;
83static int oneof_bool_is_defined = 1;
84
85static char const * oneof_default_param_name = "int_sub";
86
87// Factory for oneof subparam (int_sub)
88static int utest_oneof_factory(
89 const char *name, void **obj,
90 struct yac_param **param, int *is_default) {
91 UNUSED(name);
92
93 enum {
94 INT_PARAM,
95 BOOL_PARAM
96 };
97
98 struct yac_name_type_pair subparam_types[] = {
99 {oneof_int_param_name, INT_PARAM},
100 {oneof_bool_param_name, BOOL_PARAM}
101 };
102 enum {
103 NUM_SUBPARAM_TYPES = sizeof(subparam_types) / sizeof(subparam_types[0])};
104
105 if (name == NULL) {
106 // No name provided, use default subparam
108 }
109
110 int type =
111 yac_name_type_pair_get_type(subparam_types, NUM_SUBPARAM_TYPES, name);
112
113 if (type == INT_MAX) {
114 // Unsupported subparam name
115 YAC_PARAM_ASSERT(0, "unsupported subparam name");
116 return 1;
117 }
118
119 switch (type) {
120 default: {__attribute__((fallthrough));}
121 case (INT_PARAM): {
122
123 int *val = xmalloc(sizeof(int));
124 *val = oneof_int_val;
125 *obj = val;
126 *param = yac_param_int_new(
129 *is_default = 1;
130 break;
131 }
132 case (BOOL_PARAM): {
133
134 int *val = xmalloc(sizeof(int));
135 *val = oneof_bool_val;
136 *obj = val;
137 *param = yac_param_bool_new(
140 *is_default = 0;
141 break;
142 }
143 }
144
145 return 0;
146}
147
148// Factory that always fails (for testing error handling in oneof)
149static int utest_oneof_failing_factory(
150 const char *name, void **obj,
151 struct yac_param **param, int *is_default) {
152 UNUSED(name);
153 UNUSED(obj);
154 UNUSED(param);
155 UNUSED(is_default);
156 return 1;
157}
158
159// Test oneof struct parameter interfaces
160static void utest_oneof_param_interfaces(void) {
161
162 { // main test (active subparam is set to default by factory)
163
164 // Factory for oneof default subparam (int_sub)
165 void *created_obj = NULL;
166
167 char const * param_name = "oneof_param";
168 struct yac_param * subparam = NULL;
169 int subparam_is_default = 0;
170 struct yac_param *param =
172 param_name, utest_oneof_factory, &created_obj, subparam, subparam_is_default);
173
174 // get_type
175 enum yac_param_type type =
176 yac_param_get_type(param);
178 PUT_ERR("oneof param get_type should return TYPE_STRUCT");
179
181 int scalar_kind_ret = yac_param_get_scalar_kind(param, &scalar_kind);
182 if ((scalar_kind_ret == 0) ||
183 (scalar_kind != YAC_PARAM_SCALAR_KIND_INVALID))
184 PUT_ERR("oneof param get_scalar_kind should fail");
185
186 // get_name
187 const char *name = yac_param_get_name(param);
188 if (!name || strcmp(name, param_name) != 0)
189 PUT_ERR("oneof param get_name should return 'oneof_param'");
190
191 // is_default (undefined oneof counts as default)
192 int ret = yac_param_is_default(param);
193 if (ret != 1)
194 PUT_ERR("oneof param is_default should be 1 (default)");
195
196 // get_sub_count (should always be 1)
197 size_t count = 0;
198 ret = yac_param_get_sub_count(param, &count);
199 if (ret != 0 || count != 1)
200 PUT_ERR("oneof param get_sub_count should return 1");
201
202 // get_sub_by_name (should fail for any unsupported name)
203 struct yac_param *sub = NULL;
204 char const * unsupported_name = "unsupported_sub";
206 param, unsupported_name, &sub);
207 if (ret == 0)
208 PUT_ERR("oneof param get_sub_by_name should fail for non-default");
209
210 // get_sub_by_index (only 0 allowed, should return the default subparam)
211 sub = NULL;
212 ret = yac_param_get_sub_by_index(param, 0, &sub);
213 if (ret != 0 || !sub)
214 PUT_ERR("oneof param get_sub_by_index failed for index 0");
215 char const *sub_name = yac_param_get_name(sub);
216 if (!sub_name || strcmp(sub_name, oneof_int_param_name) != 0)
217 PUT_ERR(
218 "oneof param get_sub_by_index should return subparam "
219 "with name 'int_sub' for index 0");
220
221 // get_sub_by_index should have selected the default subparam (int_sub)
222 // and created it with the initial value
223 if (!created_obj)
224 PUT_ERR("oneof factory should have allocated an object for the subparam");
225 if (*(int *)created_obj != oneof_int_val)
226 PUT_ERR(
227 "oneof factory should have set the created object to the initial value");
228
229 // get_sub_by_index (out of bounds)
230 ret = yac_param_get_sub_by_index(param, 1, &sub);
231 if (ret == 0)
232 PUT_ERR("oneof param get_sub_by_index should fail for idx != 0");
233
234 // get_sub_by_name
235 // (should fail for any name different from the one currently set)
236 sub = NULL;
237 ret =
239 param, oneof_bool_param_name, &sub);
240 if (ret == 0)
241 PUT_ERR(
242 "oneof param get_sub_by_name should fail for valid but "
243 "non-active subparam name");
244
245 // get_sub_by_name (should succeed for int_sub)
246 sub = NULL;
248 param, oneof_int_param_name, &sub);
249 if (ret != 0 || !sub)
250 PUT_ERR("oneof param get_sub_by_name failed for 'int_sub'");
251 sub_name = yac_param_get_name(sub);
252 if (!sub_name || strcmp(sub_name, oneof_int_param_name) != 0)
253 PUT_ERR(
254 "oneof param get_sub_by_name should return "
255 "subparam with name 'int_sub'");
256
257 // is_default (should be false initially)
258 ret = yac_param_is_default(param);
259 if (ret != 0)
260 PUT_ERR("oneof param is_default should be 0 (not default)");
261
262 // Set active subparam to default value
263 struct yac_param *int_sub = NULL;
264 ret =
266 param, oneof_int_param_name, &int_sub);
267 if (ret != 0 || !int_sub)
268 PUT_ERR("oneof param get_sub_by_name failed for 'int_sub'");
270 int_sub, oneof_int_default);
271
272 // is_default (should be true now)
273 ret = yac_param_is_default(param);
274 if (ret != 1)
275 PUT_ERR("oneof param is_default should be 1 (default)");
276
277 // destroy
278 yac_param_delete(param);
279 free(created_obj);
280 }
281
282 { // Test which sets param to non-default value in factory
283
284 // Factory for oneof default subparam (int_sub)
285 void *created_obj = NULL;
286
287 char const * param_name = "oneof_param_non_default";
288 struct yac_param * subparam = NULL;
289 int subparam_is_default = 0;
290 struct yac_param *param =
292 param_name, utest_oneof_factory, &created_obj, subparam, subparam_is_default);
293
294 // is_default (undefined oneof counts as default)
295 int ret = yac_param_is_default(param);
296 if (ret != 1)
297 PUT_ERR("oneof param is_default should be 1 (default)");
298
299 // Set active subparam to non-default value
300 struct yac_param *bool_sub = NULL;
301 ret =
303 param, oneof_bool_param_name, &bool_sub);
304 if (ret != 0 || !bool_sub)
305 PUT_ERR("oneof param get_sub_by_name failed for 'bool_sub'");
306 if (!created_obj)
307 PUT_ERR("oneof factory should have allocated an object for the subparam");
308 if (*(int *)created_obj != oneof_bool_val)
309 PUT_ERR(
310 "oneof factory should have set the created object to the initial value");
311 char const * bool_sub_name =
312 yac_param_get_name(bool_sub);
313 if (!bool_sub_name || strcmp(bool_sub_name, oneof_bool_param_name) != 0)
314 PUT_ERR(
315 "oneof param get_sub_by_name should return subparam with name 'bool_sub'");
316
317 // is_default (should be false because bool_sub has non-default value)
318 ret = yac_param_is_default(param);
319 if (ret != 0)
320 PUT_ERR("oneof param is_default should be 0 (not default)");
321
322 // set active subparam to default value
324 bool_sub, oneof_bool_default);
325
326 // is_default (should still be false because active subparam is not "
327 // the default type)
328 ret = yac_param_is_default(param);
329 if (ret != 0)
330 PUT_ERR("oneof param is_default should be 0 (not default)");
331
332 // destroy
333 yac_param_delete(param);
334 free(created_obj);
335 }
336
337 { // Test with preinitialised parameter (default type)
338 int predef_int_val = oneof_int_val;
339 void * predef_val = &predef_int_val;
340 struct yac_param *predef_subparam =
342 oneof_int_param_name, &predef_int_val, oneof_int_default,
344 int subparam_is_default = 1;
345 char const * param_name = "oneof_param_predefined";
346 struct yac_param *param =
348 param_name, utest_oneof_factory, &predef_val, predef_subparam,
349 subparam_is_default);
350
351 // get_sub_by_index should return the pre-defined subparam unchanged
352 struct yac_param *sub = NULL;
353 int ret = yac_param_get_sub_by_index(param, 0, &sub);
354 if (ret != 0 || (sub != predef_subparam))
355 PUT_ERR("oneof predefined subparam should be returned unchanged");
356
357 // is_default should be false because the pre-defined subparam has a
358 // non-default value
359 ret = yac_param_is_default(param);
360 if (ret != 0)
361 PUT_ERR("oneof param is_default should be 0 (not default)");
362
363 // set integer value to the default value
364 predef_int_val = oneof_int_default;
365
366 // is_default should now be true because the active subparam has
367 // the default value
368 ret = yac_param_is_default(param);
369 if (ret != 1)
370 PUT_ERR("oneof param is_default should be 1 (default)");
371
372 // destroy
373 yac_param_delete(param);
374 }
375
376 { // Test with preinitialised parameter (non-default type)
377 int predef_bool_val = oneof_bool_val;
378 void * predef_val = &predef_bool_val;
379 struct yac_param *predef_subparam =
381 oneof_bool_param_name, &predef_bool_val, oneof_bool_default,
383 int subparam_is_default = 0;
384 char const * param_name = "oneof_param_predefined";
385 struct yac_param *param =
387 param_name, utest_oneof_factory, &predef_val, predef_subparam,
388 subparam_is_default);
389
390 // get_sub_by_index should return the pre-defined subparam unchanged
391 struct yac_param *sub = NULL;
392 int ret = yac_param_get_sub_by_index(param, 0, &sub);
393 if (ret != 0 || (sub != predef_subparam))
394 PUT_ERR("oneof predefined subparam should be returned unchanged");
395
396 // is_default should be false because the pre-defined subparam has a
397 // non-default value
398 ret = yac_param_is_default(param);
399 if (ret != 0)
400 PUT_ERR("oneof param is_default should be 0 (not default)");
401
402 // set boolean value to the default value
403 predef_bool_val = oneof_bool_default;
404
405 // is_default should still be false because the active subparam is
406 // not the default type
407 ret = yac_param_is_default(param);
408 if (ret != 0)
409 PUT_ERR("oneof param is_default should be 0 (not default)");
410
411 // destroy
412 yac_param_delete(param);
413 }
414
415 {// Test error handling in factory
416
417 // failing factory path in get_sub_by_index
418 void * created_obj = NULL;
419 int subparam_is_default = 0;
420 struct yac_param *param =
422 "oneof_param_fail_idx", utest_oneof_failing_factory, &created_obj, NULL,
423 subparam_is_default);
424 struct yac_param *sub = NULL;
425 int ret = yac_param_get_sub_by_index(param, 0, &sub);
426 if (ret == 0)
427 PUT_ERR("oneof get_sub_by_index should fail if factory fails");
428 yac_param_delete(param);
429 }
430
431 {// Test error handling in factory
432
433 // failing factory path in get_sub_by_name
434 void * created_obj = NULL;
435 int subparam_is_default = 0;
436 struct yac_param *param =
438 "oneof_param_fail_name", utest_oneof_failing_factory, &created_obj, NULL,
439 subparam_is_default);
440 struct yac_param *sub = NULL;
441 int ret =
442 yac_param_get_sub_by_name(param, "int_sub", &sub);
443 if (ret == 0)
444 PUT_ERR("oneof get_sub_by_name should fail if factory fails");
445 yac_param_delete(param);
446 }
447}
448
449static struct yac_param * utest_get_sub_by_name(
450 struct yac_param *param, char const *name) {
451 struct yac_param *sub = NULL;
452 int ret = yac_param_get_sub_by_name(param, name, &sub);
453 if (ret != 0)
454 return NULL;
455 return sub;
456}
457
458// Test struct parameter interfaces
459static void utest_struct_param_interfaces(void) {
460
461 char const * int_param_name = "int_sub";
462 int int_val = 5;
463 int int_default = 42;
464 int int_has_default = 1;
465 int int_is_defined = 1;
466 int int_min_value = 0;
467 int int_max_value = 100;
468
469 char const * bool_param_name = "bool_sub";
470 int bool_val = 1;
471 int bool_default = 0;
472 int bool_has_default = 1;
473 int bool_is_defined = 1;
474
475 char const * str_param_name = "str_sub";
476 char *str_val = strdup("foo");
477 const char *str_default = "bar";
478 int str_allow_null = 0;
479 int str_allow_empty = 0;
480 int str_has_default = 1;
481 int str_is_defined = 1;
482 size_t max_str_len = 8;
483 int ret;
484
485 struct yac_param *subparams[] = {
487 int_param_name, &int_val, int_default, int_min_value, int_max_value,
488 int_has_default, int_is_defined),
490 bool_param_name, &bool_val, bool_default,
491 bool_has_default, bool_is_defined),
493 str_param_name, &str_val, str_default, str_allow_null, str_allow_empty,
494 max_str_len, str_has_default, str_is_defined)
495 };
496 enum {NUM_SUBPARAMS = sizeof(subparams) / sizeof(subparams[0])};
497
498 char const * param_name = "struct_param";
499 struct yac_param *param =
501 param_name, subparams, NUM_SUBPARAMS);
502
503 // get_type
504 enum yac_param_type type =
505 yac_param_get_type(param);
507 PUT_ERR("struct param get_type should return TYPE_STRUCT");
508
510 ret = yac_param_get_scalar_kind(param, &scalar_kind);
511 if ((ret == 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_INVALID))
512 PUT_ERR("struct param get_scalar_kind should fail");
513
514 // get_name
515 const char *name = yac_param_get_name(param);
516 if (!name || strcmp(name, param_name) != 0)
517 PUT_ERR("struct param get_name should return 'struct_param'");
518
519 // get_sub_count
520 size_t count = 0;
521 ret = yac_param_get_sub_count(param, &count);
522 if (ret != 0 || count != NUM_SUBPARAMS)
523 PUT_ERR("struct param get_sub_count should return 3");
524
525 // get_sub_by_name (existing)
526 struct yac_param *sub = NULL;
527 ret =
528 yac_param_get_sub_by_name(param, int_param_name, &sub);
529 if (ret != 0 || !sub)
530 PUT_ERR("struct param get_sub_by_name failed for 'int_sub'");
531 if (sub != subparams[0])
532 PUT_ERR("struct param get_sub_by_name did not return "
533 "the actual subparam pointer");
534
535 // get_sub_by_name (nonexistent)
536 char const * nonexistent_param_name = "nope";
537 ret =
539 param, nonexistent_param_name, &sub);
540 if (ret == 0)
541 PUT_ERR(
542 "struct param get_sub_by_name should fail for nonexistent subparam");
543
544 // get_sub_by_index (in bounds)
545 sub = NULL;
546 ret = yac_param_get_sub_by_index(param, 1, &sub);
547 if (ret != 0 || !sub)
548 PUT_ERR("struct param get_sub_by_index failed for index 1");
549 if (sub != subparams[1])
550 PUT_ERR("struct param get_sub_by_index did not return "
551 "the actual subparam pointer");
552
553 // get_sub_by_index (out of bounds)
554 ret =
555 yac_param_get_sub_by_index(param, NUM_SUBPARAMS, &sub);
556 if (ret == 0)
557 PUT_ERR("struct param get_sub_by_index should fail for out-of-bounds");
558
559 // is_default (should be false initially)
560 ret = yac_param_is_default(param);
561 if (ret != 0)
562 PUT_ERR("struct param is_default should be 0 (not default)");
563
564 // Set subset of subparams to default
566 utest_get_sub_by_name(param, int_param_name), int_default);
568 utest_get_sub_by_name(param, bool_param_name), bool_default);
569
570 // is_default (should still be false since str_sub is not default)
571 ret = yac_param_is_default(param);
572 if (ret != 0)
573 PUT_ERR("struct param is_default should be 0 (not default)");
574
575 // Set remaining subparam to default
577 utest_get_sub_by_name(param, str_param_name), str_default);
578
579 // is_default (should be true now)
580 ret = yac_param_is_default(param);
581 if (ret != 1)
582 PUT_ERR("struct param is_default should be 1 (default)");
583
584 // destroy
585 yac_param_delete(param);
586 free(str_val);
587}
588
589// Test enum parameter interfaces
590static void utest_enum_param_interfaces(void) {
591
592 enum {RED, GREEN, BLUE, COLOR_TABLE_SIZE};
593 static const struct yac_name_type_pair color_table[COLOR_TABLE_SIZE] = {
594 {"red", RED}, {"green", GREEN}, {"blue", BLUE}
595 };
596
597 { // Test enum param with default (has_default = 1)
598 char const * param_name = "color_param";
599 int value = GREEN;
600 int default_value = RED;
601 int has_default = 1;
602 int is_defined = 1;
603 char buf[32];
604 int ret;
605 struct yac_param *param =
607 param_name, &value, default_value, color_table, COLOR_TABLE_SIZE,
608 has_default, is_defined);
609
610 // get_type
611 enum yac_param_type type =
612 yac_param_get_type(param);
614 PUT_ERR("enum param get_type should return TYPE_SCALAR");
615
617 ret = yac_param_get_scalar_kind(param, &scalar_kind);
618 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_INT))
619 PUT_ERR("enum param get_scalar_kind should return INT");
620
621 // get_name
622 const char *name = yac_param_get_name(param);
623 if (!name || strcmp(name, param_name) != 0)
624 PUT_ERR("enum param get_name should return 'color_param'");
625
626 // is_default (should be false initially)
627 ret = yac_param_is_default(param);
628 if (ret != 0)
629 PUT_ERR("enum param is_default should be 0 (not default)");
630
631 // set_scalar_int to default value
633 param, default_value);
634 if ((ret != 0) || (value != default_value))
635 PUT_ERR("enum param set_scalar_int failed");
636
637 // is_default (should be true now)
638 ret = yac_param_is_default(param);
639 if (ret != 1)
640 PUT_ERR("enum param is_default should be 1 (default)");
641
642 // set_scalar
644 param, "blue");
645 if (ret != 0 || value != BLUE)
646 PUT_ERR("enum param set_scalar string failed");
647
648 // get_scalar
649 strcpy(buf, "garbage");
651 param, buf, sizeof(buf));
652 if (ret != 0 || strcmp(buf, "blue") != 0)
653 PUT_ERR("enum param get_scalar string failed");
654
655 // set_scalar_int
657 param, GREEN);
658 if (ret != 0 || value != GREEN)
659 PUT_ERR("enum param set_scalar_int failed (again)");
660
661 // get_scalar_int
662 int out_val = -1;
664 param, &out_val);
665 if (ret != 0 || out_val != GREEN)
666 PUT_ERR("enum param get_scalar_int failed");
667
668 // set_scalar to invalid string (should fail)
670 param, "yellow");
671 if (ret == 0)
672 PUT_ERR("enum param set_scalar should fail for invalid string");
673
674 // set_scalar to NULL (should fail)
676 param, NULL);
677 if (ret == 0)
678 PUT_ERR("enum param set_scalar should fail for NULL value");
679
680 // set_scalar_int to invalid value (should fail)
682 param, 999);
683 if (ret == 0)
684 PUT_ERR("enum param set_scalar_int should fail for invalid value");
685
686 // get_scalar with too small buffer (should fail)
687 int const small_buf_len = 2;
689 param, buf, small_buf_len);
690 if (ret == 0)
691 PUT_ERR("enum param get_scalar should fail for small buffer");
692
693 // destroy
694 yac_param_delete(param);
695 }
696
697 { // Test enum param without default (has_default = 0)
698 char const * param_name = "color_param";
699 int value = GREEN;
700 int default_value = RED;
701 int has_default = 0;
702 int is_defined = 0;
703 char buf[32];
704 int ret;
705 struct yac_param *param =
707 param_name, &value, default_value, color_table,
708 COLOR_TABLE_SIZE, has_default, is_defined);
709
710 // is_default should always be 0
711 ret = yac_param_is_default(param);
712 if (ret != 0)
713 PUT_ERR("enum param (no default) is_default should be 0");
714
715 // get_scalar_int should fail (undefined)
716 int out_val = -1;
718 param, &out_val);
719 if (ret == 0)
720 PUT_ERR("enum param (no default) get_scalar_int should fail if undefined");
721
722 // get_scalar should fail (undefined)
724 param, buf, sizeof(buf));
725 if (ret == 0)
726 PUT_ERR("enum param (no default) get_scalar should fail if undefined");
727
728 // set_scalar_int should define value
730 param, GREEN);
731 if (ret != 0 || value != GREEN)
732 PUT_ERR("enum param (no default) set_scalar_int failed");
733
734 // Now get_scalar_int should succeed
735 out_val = -1;
737 param, &out_val);
738 if (ret != 0 || out_val != GREEN)
739 PUT_ERR("enum param (no default) get_scalar_int should succeed after set");
740
741 // get_scalar should succeed
743 param, buf, sizeof(buf));
744 if (ret != 0 || strcmp(buf, "green") != 0)
745 PUT_ERR("enum param (no default) get_scalar should succeed after set");
746
747 // Set default value
749 param, default_value);
750 if (ret != 0 || value != default_value)
751 PUT_ERR("enum param (no default) set_scalar_int failed");
752
753 // is_default should still be 0
754 ret = yac_param_is_default(param);
755 if (ret != 0)
756 PUT_ERR("enum param (no default) is_default should still be 0");
757
758 yac_param_delete(param);
759 }
760}
761
762// Test string parameter interfaces
763static void utest_str_param_interfaces(void) {
764
765 { // Test str param with default (has_default = 1)
766 char const * param_name = "str_param";
767 char *value = strdup("init");
768 const char *default_value = "default";
769 int allow_null = 0;
770 int allow_empty = 1;
771 size_t max_str_len = 16;
772 int has_default = 1;
773 int is_defined = 1;
774 char buf[32];
775 int ret;
776 struct yac_param *param =
778 param_name, &value, default_value, allow_null, allow_empty,
779 max_str_len, has_default, is_defined);
780
781 // get_type
782 enum yac_param_type type =
783 yac_param_get_type(param);
785 PUT_ERR("str param get_type should return TYPE_SCALAR");
786
788 ret = yac_param_get_scalar_kind(param, &scalar_kind);
789 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_STR))
790 PUT_ERR("str param get_scalar_kind should return STR");
791
792 // get_name
793 const char *name = yac_param_get_name(param);
794 if (!name || strcmp(name, param_name) != 0)
795 PUT_ERR("str param get_name should return 'str_param'");
796
797 // is_default (should be false initially)
798 ret = yac_param_is_default(param);
799 if (ret != 0)
800 PUT_ERR("str param is_default should be 0 (not default)");
801
802 // set_scalar to default value
804 param, default_value);
805 if (ret != 0)
806 PUT_ERR("str param set_scalar to default failed");
807 if (strcmp(value, default_value) != 0)
808 PUT_ERR("str param value not set to default");
809
810 // is_default (should be true now)
811 ret = yac_param_is_default(param);
812 if (ret != 1)
813 PUT_ERR("str param is_default should be 1 (default)");
814
815 // set_scalar (string)
817 param, "foo");
818 if (ret != 0 || strcmp(value, "foo") != 0)
819 PUT_ERR("str param set_scalar string failed");
820
821 // get_scalar (string)
822 strcpy(buf, "garbage");
824 param, buf, sizeof(buf));
825 if (ret != 0 || strcmp(buf, "foo") != 0)
826 PUT_ERR("str param get_scalar string failed");
827
828 // set_scalar to empty string (allowed)
830 param, "");
831 if (ret != 0 || strcmp(value, "") != 0)
832 PUT_ERR("str param set_scalar empty string failed");
833
834 // get_scalar (empty string)
835 strcpy(buf, "garbage");
837 param, buf, sizeof(buf));
838 if (ret != 0 || strcmp(buf, "") != 0)
839 PUT_ERR("str param get_scalar empty string failed");
840
841 // set_scalar to too long string (should fail)
842 char longstr[32];
843 memset(longstr, 'x', max_str_len+1); longstr[max_str_len+1] = '\0';
845 param, longstr);
846 if (ret == 0)
847 PUT_ERR("str param set_scalar should fail for too long string");
848
849 // set_scalar to NULL (should fail, allow_NULL=0)
851 param, NULL);
852 if (ret == 0)
853 PUT_ERR("str param set_scalar should fail for NULL value");
854
855 // set_scalar to non empty string
857 param, "foo");
858 if (ret != 0 || strcmp(value, "foo") != 0)
859 PUT_ERR("str param set_scalar non empty string failed");
860
861 // get_scalar with too small buffer (should fail)
863 param, buf, 1);
864 if (ret == 0)
865 PUT_ERR("str param get_scalar should fail for too small buffer");
866
867 yac_param_delete(param);
868 free(value);
869 }
870
871 { // Test str param with no default (has_default = 0)
872 char const * param_name = "str_param";
873 char *value = NULL;
874 const char *default_value = "default";
875 int allow_null = 1;
876 int allow_empty = 1;
877 int has_default = 0;
878 int is_defined = 0;
879 size_t max_str_len = 16;
880 char buf[32];
881 int ret;
882 struct yac_param *param =
884 param_name, &value, default_value, allow_null, allow_empty,
885 max_str_len, has_default, is_defined);
886
887 // is_default should always be 0
888 ret = yac_param_is_default(param);
889 if (ret != 0)
890 PUT_ERR("str param (no default) is_default should be 0");
891
892 // get_scalar should fail (undefined)
894 param, buf, sizeof(buf));
895 if (ret == 0)
896 PUT_ERR("str param (no default) get_scalar should fail if undefined");
897
898 // set_scalar should define value
900 param, "abc");
901 if (ret != 0 || !value || strcmp(value, "abc") != 0)
902 PUT_ERR("str param (no default) set_scalar failed");
903
904 // Now get_scalar should succeed
906 param, buf, sizeof(buf));
907 if (ret != 0 || strcmp(buf, "abc") != 0)
908 PUT_ERR("str param (no default) get_scalar should succeed after set");
909
910 // Set to default
912 param, default_value);
913 if (ret != 0 || !value || strcmp(value, default_value) != 0)
914 PUT_ERR("str param (no default) set_scalar failed");
915
916 // is_default should still be 0
917 ret = yac_param_is_default(param);
918 if (ret != 0)
919 PUT_ERR("str param (no default) is_default should still be 0");
920
921 // allow_NULL branch in set_scalar
923 param, NULL);
924 if (ret != 0 || value != NULL)
925 PUT_ERR("str param (allow_NULL) set_scalar(NULL) should succeed");
926
927 // allow_NULL branch in is_default
928 ret = yac_param_is_default(param);
929 if (ret != 0)
930
931 // get_scalar should return empty string for NULL value if allow_NULL=1
932 strcpy(buf, "garbage");
934 param, buf, sizeof(buf));
935 if (ret != 0 || strcmp(buf, "") != 0)
936 PUT_ERR(
937 "str param (allow_NULL) get_scalar should return empty string for NULL");
938
939 yac_param_delete(param);
940 free(value);
941 }
942
943 { // empty-string disallowed in get/set paths
944 char const * param_name = "str_no_empty";
945 char *value = strdup("non-empty");
946 char const *default_value = "x";
947 int allow_null = 1;
948 int allow_empty = 0;
949 size_t max_str_len = 16;
950 int has_default = 1;
951 int is_defined = 1;
952 int ret;
953 struct yac_param *param =
955 param_name, &value, default_value, allow_null, allow_empty,
956 max_str_len, has_default, is_defined);
957
958 // set_scalar to empty string should fail
960 param, "");
961 if (ret == 0)
962 PUT_ERR("str param set_scalar should fail for empty value if disallowed");
963
964 // force value to empty string and test get_scalar
965 free(value);
966 value = strdup("");
967
968 // get_scalar should fail if value is empty string and allow_empty=0
969 char buf[32];
971 param, buf, sizeof(buf));
972 if (ret == 0)
973 PUT_ERR("str param get_scalar should fail for empty value if disallowed");
974
975 yac_param_delete(param);
976 free(value);
977 }
978
979 { // NULL value disallowed in get path
980 char const * param_name = "str_no_null";
981 char *value = strdup("non-NULL");;
982 int ret;
983 int allow_null = 0;
984 int allow_empty = 1;
985 char const *default_value = "x";
986 size_t max_str_len = 16;
987 int has_default = 1;
988 int is_defined = 1;
989 struct yac_param *param =
991 param_name, &value, default_value, allow_null, allow_empty,
992 max_str_len, has_default, is_defined);
993
994 // set_scalar to NULL should fail
996 param, NULL);
997 if (ret == 0)
998 PUT_ERR("str param set_scalar should fail for NULL value if disallowed");
999
1000 // force value to NULL and test get_scalar
1001 free(value);
1002 value = NULL;
1003
1004 // get_scalar should fail if value is NULL and allow_NULL=0
1005 char buf[32];
1007 param, buf, sizeof(buf));
1008 if (ret == 0)
1009 PUT_ERR("str param get_scalar should fail for NULL value if disallowed");
1010
1011 yac_param_delete(param);
1012 free(value);
1013 }
1014
1015 { // Test with NULL default value and allow_NULL=1
1016 char const * param_name = "str_null_default";
1017 char *value = NULL;
1018 char const *default_value = NULL;
1019 int allow_null = 1;
1020 int allow_empty = 1;
1021 size_t max_str_len = 16;
1022 int has_default = 1;
1023 int is_defined = 1;
1024 int ret;
1025 struct yac_param *param =
1027 param_name, &value, default_value, allow_null, allow_empty,
1028 max_str_len, has_default, is_defined);
1029
1030 // is_default should be true initially since value equals default (both NULL)
1031 ret = yac_param_is_default(param);
1032 if (ret != 1)
1033 PUT_ERR("str param with NULL default should be default initially");
1034
1035 // set_scalar to non-empty string
1037 param, "hello");
1038 if (ret != 0 || strcmp(value, "hello") != 0)
1039 PUT_ERR("str param set_scalar failed for non-empty string");
1040
1041 // is_default should now be false
1042 ret = yac_param_is_default(param);
1043 if (ret != 0)
1044 PUT_ERR("str param with NULL default should not be default after set");
1045
1046 // set_scalar to NULL
1048 param, NULL);
1049 if (ret != 0 || value != NULL)
1050 PUT_ERR("str param set_scalar failed for NULL value");
1051
1052 // is_default should be true again
1053 ret = yac_param_is_default(param);
1054 if (ret != 1)
1055 PUT_ERR("str param with NULL default should be default after setting back to NULL");
1056
1057 yac_param_delete(param);
1058 }
1059
1060 { // Test with empty default value and allow_empty=1
1061 char const * param_name = "str_empty_default";
1062 char *value = strdup("");
1063 char const *default_value = "";
1064 int allow_null = 1;
1065 int allow_empty = 1;
1066 size_t max_str_len = 16;
1067 int has_default = 1;
1068 int is_defined = 1;
1069 int ret;
1070 struct yac_param *param =
1072 param_name, &value, default_value, allow_null, allow_empty,
1073 max_str_len, has_default, is_defined);
1074
1075 // is_default should be true initially since value equals default
1076 ret = yac_param_is_default(param);
1077 if (ret != 1)
1078 PUT_ERR("str param with empty default should be default initially");
1079
1080 // set_scalar to non-empty string
1082 param, "hello");
1083 if (ret != 0 || strcmp(value, "hello") != 0)
1084 PUT_ERR("str param set_scalar failed for non-empty string");
1085
1086 // is_default should now be false
1087 ret = yac_param_is_default(param);
1088 if (ret != 0)
1089 PUT_ERR("str param with empty default should not be default after set");
1090
1091 // set_scalar to empty string
1093 param, "");
1094 if (ret != 0 || strcmp(value, "") != 0)
1095 PUT_ERR("str param set_scalar failed for empty string");
1096
1097 // is_default should be true again
1098 ret = yac_param_is_default(param);
1099 if (ret != 1)
1100 PUT_ERR(
1101 "str param with empty default should be default after "
1102 "setting back to empty");
1103
1104 yac_param_delete(param);
1105 free(value);
1106 }
1107}
1108
1109// Test double parameter interfaces
1110static void utest_dble_param_interfaces(void) {
1111
1112 { // Test dble param with default (has_default = 1)
1113 char const * param_name = "dble_param";
1114 double value = 1.5;
1115 double default_value = 3.14;
1116 double min_value = -10.0;
1117 double max_value = 10.0;
1118 int allow_nan = 0;
1119 int allow_inf = 0;
1120 int has_default = 1;
1121 int is_defined = 1;
1122 char buf[64];
1123 int ret;
1124 double out_val = -999.0;
1125 struct yac_param *param =
1127 param_name, &value, default_value, min_value, max_value,
1128 allow_nan, allow_inf, has_default, is_defined);
1129
1130 // get_type
1131 enum yac_param_type type =
1132 yac_param_get_type(param);
1134 PUT_ERR("dble param get_type should return TYPE_SCALAR");
1135
1137 ret = yac_param_get_scalar_kind(param, &scalar_kind);
1138 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_DBLE))
1139 PUT_ERR("dble param get_scalar_kind should return DBLE");
1140
1141 // get_name
1142 const char *name = yac_param_get_name(param);
1143 if (!name || strcmp(name, param_name) != 0)
1144 PUT_ERR("dble param get_name should return 'dble_param'");
1145
1146 // is_default (should be false initially)
1147 ret = yac_param_is_default(param);
1148 if (ret != 0)
1149 PUT_ERR("dble param is_default should be 0 (not default)");
1150
1151 // set_scalar_dble to default value
1153 param, default_value);
1154 if (ret != 0)
1155 PUT_ERR("dble param set_scalar_dble failed");
1156 if (value != default_value)
1157 PUT_ERR("dble param value not set to default");
1158
1159 // is_default (should be true now)
1160 ret = yac_param_is_default(param);
1161 if (ret != 1)
1162 PUT_ERR("dble param is_default should be 1 (default)");
1163
1164 // set_scalar (string)
1166 param, "2.5");
1167 if (ret != 0 || value != 2.5)
1168 PUT_ERR("dble param set_scalar string failed");
1169
1170 // set_scalar with NULL/invalid string (should fail)
1172 param, NULL);
1173 if (ret == 0)
1174 PUT_ERR("dble param set_scalar should fail for NULL string");
1176 param, "2.0x");
1177 if (ret == 0)
1178 PUT_ERR("dble param set_scalar should fail for invalid string");
1179
1180 // get_scalar (string)
1181 strcpy(buf, "garbage");
1183 param, buf, sizeof(buf));
1184 if (ret != 0 || atof(buf) != 2.5)
1185 PUT_ERR("dble param get_scalar string failed");
1186
1187 // get_scalar with too small buffer (should fail)
1188 int const small_buf_size = 2; // needs to hold at least "2.5\0"
1190 param, buf, small_buf_size);
1191 if (ret == 0)
1192 PUT_ERR("dble param get_scalar should fail for too small buffer");
1193
1194 // set_scalar_dble (again)
1196 param, -5.5);
1197 if (ret != 0 || value != -5.5)
1198 PUT_ERR("dble param set_scalar_dble failed (again)");
1199
1200 // get_scalar_dble
1201 out_val = -999.0;
1203 param, &out_val);
1204 if (ret != 0 || out_val != -5.5)
1205 PUT_ERR("dble param get_scalar_dble failed");
1206
1207 // set_scalar_int (should succeed for integer-valued double)
1209 param, 5);
1210 if (ret != 0 || value != 5.0)
1211 PUT_ERR("dble param set_scalar_int should succeed for integer value");
1212
1213 // get_scalar_int (should succeed when value is integer)
1214 int ival = 0;
1216 param, &ival);
1217 if (ret != 0 || ival != 5)
1218 PUT_ERR("dble param get_scalar_int should succeed for integer value");
1219
1220 // get_scalar_int should fail for non-integer value
1221 ret = yac_param_set_scalar_dble(param, 2.5);
1222 if (ret != 0) PUT_ERR("dble param set_scalar_dble failed");
1223 ret = yac_param_get_scalar_int(param, &ival);
1224 if (ret == 0)
1225 PUT_ERR("dble param get_scalar_int should fail for non-integer value");
1226
1227 // test out-of-range
1229 param, min_value - 1.0);
1230 if (ret == 0)
1231 PUT_ERR("dble param set_scalar_dble should fail for out-of-range");
1233 param, max_value + 1.0);
1234 if (ret == 0)
1235 PUT_ERR("dble param set_scalar_dble should fail for out-of-range");
1236
1237 // test NaN (should fail)
1239 param, NAN);
1240 if (ret == 0)
1241 PUT_ERR("dble param set_scalar_dble should fail for NaN");
1242
1243 // test Inf (should fail)
1245 param, INFINITY);
1246 if (ret == 0)
1247 PUT_ERR("dble param set_scalar_dble should fail for Inf");
1248
1249 // destroy
1250 yac_param_delete(param);
1251 }
1252
1253 { // Additional test: dble param with no default (has_default = 0)
1254 double value = 0.0;
1255 double default_value = 3.14;
1256 double min_value = -10.0, max_value = 10.0;
1257 int allow_nan = 0;
1258 int allow_inf = 0;
1259 int has_default = 0;
1260 int is_defined = 0;
1261 int ret;
1262 char buf[64];
1263 double out_val = -999.0;
1264 struct yac_param *param =
1266 "dble_param_nodef", &value, default_value,
1267 min_value, max_value, allow_nan, allow_inf, has_default, is_defined);
1268
1269 // is_default should always be 0
1270 ret = yac_param_is_default(param);
1271 if (ret != 0)
1272 PUT_ERR("dble param (no default) is_default should be 0");
1273
1274 // get_scalar/get_scalar_dble should fail before set
1276 param, buf, sizeof(buf));
1277 if (ret == 0)
1278 PUT_ERR("dble param (no default) get_scalar should fail if not set");
1279 out_val = -999.0;
1281 param, &out_val);
1282 if (ret == 0)
1283 PUT_ERR("dble param (no default) get_scalar_dble should fail if not set");
1284
1285 // set_scalar_dble, then get_scalar/get_scalar_dble should succeed
1287 param, 5.5);
1288 if (ret != 0 || value != 5.5)
1289 PUT_ERR("dble param (no default) set_scalar_dble failed");
1291 param, buf, sizeof(buf));
1292 if (ret != 0 || atof(buf) != 5.5)
1293 PUT_ERR("dble param (no default) get_scalar after set failed");
1294 out_val = -999.0;
1296 param, &out_val);
1297 if (ret != 0 || out_val != 5.5)
1298 PUT_ERR("dble param (no default) get_scalar_dble after set failed");
1299
1300 // Set to default
1302 param, default_value);
1303 if (ret != 0 || value != default_value)
1304 PUT_ERR("dble param (no default) set_scalar_dble failed");
1305
1306 // is_default should still be 0
1307 ret = yac_param_is_default(param);
1308 if (ret != 0)
1309 PUT_ERR("dble param (no default) is_default should be 0");
1310
1311 yac_param_delete(param);
1312 }
1313
1314 { // Additional test: dble param with allowed nan and inf values
1315 double value = 0.0;
1316 double default_value = INFINITY;
1317 double min_value = -1.0;
1318 double max_value = 1.0;
1319 int allow_nan = 1;
1320 int allow_inf = 1;
1321 int has_default = 1;
1322 int is_defined = 1;
1323 int ret;
1324 char buf[64];
1325 double out_val = 0.0;
1326 struct yac_param *param =
1328 "dble_param_nan_inf", &value, default_value,
1329 min_value, max_value, allow_nan, allow_inf, has_default, is_defined);
1330
1331 // set/get NaN should succeed when allow_nan=1
1333 param, NAN);
1334 if (ret != 0 || !isnan(value))
1335 PUT_ERR("dble param set_scalar_dble should accept NaN if allowed");
1336 out_val = 0.0;
1338 param, &out_val);
1339 if (ret != 0 || !isnan(out_val))
1340 PUT_ERR("dble param get_scalar_dble should return NaN if set");
1341
1342 // set/get +Inf should succeed when allow_inf=1
1344 param, INFINITY);
1345 if (ret != 0 || !isinf(value) || (value < 0.0))
1346 PUT_ERR("dble param set_scalar_dble should accept +Inf if allowed");
1347 out_val = 0.0;
1349 param, &out_val);
1350 if (ret != 0 || !isinf(out_val) || (out_val < 0.0))
1351 PUT_ERR("dble param get_scalar_dble should return +Inf if set");
1352
1353 // string-based set/get for non-finite values
1355 param, "nan");
1356 if (ret != 0 || !isnan(value))
1357 PUT_ERR("dble param set_scalar should accept 'nan' if allowed");
1359 param, "inf");
1360 if (ret != 0 || !isinf(value) || (value < 0.0))
1361 PUT_ERR("dble param set_scalar should accept 'inf' if allowed");
1362 strcpy(buf, "garbage");
1364 param, buf, sizeof(buf));
1365 if (ret != 0 || !isinf(atof(buf)) || (atof(buf) < 0.0))
1366 PUT_ERR("dble param get_scalar should serialize +Inf");
1367
1368 // finite values still obey range constraints
1370 param, 2.0);
1371 if (ret == 0)
1372 PUT_ERR("dble param finite out-of-range should still fail");
1373
1374 // test out-of-range
1376 param, min_value - 1.0);
1377 if (ret == 0)
1378 PUT_ERR("dble param set_scalar_dble should fail for out-of-range");
1380 param, max_value + 1.0);
1381 if (ret == 0)
1382 PUT_ERR("dble param set_scalar_dble should fail for out-of-range");
1383
1384 // default is +Inf, so setting +Inf should report default state
1386 param, default_value);
1387 if (ret != 0)
1388 PUT_ERR("dble param set to default +Inf failed");
1389 ret = yac_param_is_default(param);
1390 if (ret != 1)
1391 PUT_ERR("dble param is_default should be 1 for +Inf default value");
1392
1393 yac_param_delete(param);
1394 }
1395}
1396
1397// Test yac_param_get_last_error
1398static void utest_get_last_error(void) {
1399
1400 // Cause a known error: set_scalar_int(NULL, ...)
1401 int ret = yac_param_set_scalar_int(
1402 NULL, 123);
1403 if (ret == 0)
1404 PUT_ERR("set_scalar_int(NULL) should fail");
1405 const char *err = yac_param_get_last_error();
1406 if (!err) PUT_ERR("get_last_error did not report expected error message");
1407}
1408
1409// Test bool parameter interfaces
1410static void utest_bool_param_interfaces(void) {
1411
1412 { // Test bool param with default (has_default = 1)
1413 char const * param_name = "bool_param";
1414 int value = 0;
1415 int default_value = 1;
1416 int has_default = 1;
1417 int is_defined = 1;
1418 char buf[32];
1419 int ret;
1420 int out_val = -1;
1421 struct yac_param *param =
1423 param_name, &value, default_value, has_default, is_defined);
1424
1425 // get_type
1426 enum yac_param_type type =
1427 yac_param_get_type(param);
1429 PUT_ERR("bool param get_type should return TYPE_SCALAR");
1430
1432 ret = yac_param_get_scalar_kind(param, &scalar_kind);
1433 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_INT))
1434 PUT_ERR("bool param get_scalar_kind should return INT");
1435
1436 // get_name
1437 const char *name = yac_param_get_name(param);
1438 if (!name || strcmp(name, param_name) != 0)
1439 PUT_ERR("bool param get_name should return 'bool_param'");
1440
1441 // is_default (should be false initially)
1442 ret = yac_param_is_default(param);
1443 if (ret != 0)
1444 PUT_ERR("bool param is_default should be 0 (not default)");
1445
1446 // set_scalar_int to default value (1)
1448 param, default_value);
1449 if (ret != 0)
1450 PUT_ERR("bool param set_scalar_int failed");
1451 if (value != default_value)
1452 PUT_ERR("bool param value not set to default");
1453
1454 // is_default (should be true now)
1455 ret = yac_param_is_default(param);
1456 if (ret != 1)
1457 PUT_ERR("bool param is_default should be 1 (default)");
1458
1459 // set_scalar (string)
1461 param, "0");
1462 if (ret != 0 || value != 0)
1463 PUT_ERR("bool param set_scalar string failed");
1464
1465 // invalid/NULL parser input
1467 param, NULL);
1468 if (ret == 0)
1469 PUT_ERR("bool param set_scalar should fail for NULL value");
1471 param, "maybe");
1472 if (ret == 0)
1473 PUT_ERR("bool param set_scalar should fail for invalid value");
1474
1475 // get_scalar (string)
1476 strcpy(buf, "garbage");
1478 param, buf, sizeof(buf));
1479 if (ret != 0 || strcmp(buf, "false") != 0)
1480 PUT_ERR("bool param get_scalar string failed");
1481
1482 // get_scalar with too small buffer (should fail)
1483 int const small_buf_size = 2; // "true"/"false" + null terminator is 5 chars
1485 param, buf, small_buf_size);
1486 if (ret == 0)
1487 PUT_ERR("bool param get_scalar should fail for too small buffer");
1488
1489 // set_scalar_int (again)
1491 param, 1);
1492 if (ret != 0 || value != 1)
1493 PUT_ERR("bool param set_scalar_int failed (again)");
1494
1495 // get_scalar_int
1496 out_val = -1;
1498 param, &out_val);
1499 if (ret != 0 || out_val != 1)
1500 PUT_ERR("bool param get_scalar_int failed");
1501
1502 // set_scalar_dble (should fail)
1504 param, 0.0);
1505 if (ret == 0)
1506 PUT_ERR("bool param set_scalar_dble should fail");
1507
1508 // get_scalar_dble (should fail)
1509 double dval = 0.0;
1511 param, &dval);
1512 if (ret == 0)
1513 PUT_ERR("bool param get_scalar_dble should fail");
1514
1515 // destroy
1516 yac_param_delete(param);
1517 }
1518
1519 { // Test bool param with no default (has_default = 0)
1520 int value = 0;
1521 int default_value = 1;
1522 int has_default = 0;
1523 int is_defined = 0;
1524 char buf[32];
1525 int ret;
1526 int out_val = -1;
1527 struct yac_param *param =
1529 "bool_param_nodef", &value, default_value, has_default, is_defined);
1530
1531 // is_default should always be 0
1532 ret = yac_param_is_default(param);
1533 if (ret != 0)
1534 PUT_ERR("bool param (no default) is_default should be 0");
1535
1536 // get_scalar/get_scalar_int should fail before set
1538 param, buf, sizeof(buf));
1539 if (ret == 0)
1540 PUT_ERR("bool param (no default) get_scalar should fail if not set");
1541 out_val = -1;
1543 param, &out_val);
1544 if (ret == 0)
1545 PUT_ERR("bool param (no default) get_scalar_int should fail if not set");
1546
1547 // Set to default value
1549 param, default_value);
1550 if (ret != 0 || value != default_value)
1551 PUT_ERR("bool param (no default) set_scalar_int to default failed");
1552
1553 // get_scalar/get_scalar_int should succeed after set
1555 param, buf, sizeof(buf));
1556 if (ret != 0 || strcmp(buf, "true") != 0)
1557 PUT_ERR("bool param (no default) get_scalar after set failed");
1558 out_val = -1;
1560 param, &out_val);
1561 if (ret != 0 || out_val != 1)
1562 PUT_ERR("bool param (no default) get_scalar_int after set failed");
1563
1564 // is_default should still be 0
1565 ret = yac_param_is_default(param);
1566 if (ret != 0)
1567 PUT_ERR("bool param (no default) is_default should still be 0");
1568
1569 yac_param_delete(param);
1570 }
1571}
1572
1573// Test int parameter interfaces
1574static void utest_int_param_interfaces(void) {
1575
1576 { // Test int param with with default (has_default = 1)
1577 char const * param_name = "int_param";
1578 int value = 7;
1579 int default_value = 42;
1580 int min_value = 0;
1581 int max_value = 100;
1582 char buf[32];
1583 int ret;
1584 int out_val = -1;
1585 int has_default = 1;
1586 int is_defined = 1;
1587 struct yac_param *param =
1589 param_name, &value, default_value, min_value, max_value,
1590 has_default, is_defined);
1591
1592 // get_type
1593 enum yac_param_type type =
1594 yac_param_get_type(param);
1596 PUT_ERR("int param get_type should return TYPE_SCALAR");
1597
1599 ret = yac_param_get_scalar_kind(param, &scalar_kind);
1600 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_INT))
1601 PUT_ERR("int param get_scalar_kind should return INT");
1602
1603 // get_name
1604 const char *name = yac_param_get_name(param);
1605 if (!name || strcmp(name, param_name) != 0)
1606 PUT_ERR("int param get_name should return 'int_param'");
1607
1608 // is_default (should be false initially)
1609 ret = yac_param_is_default(param);
1610 if (ret != 0)
1611 PUT_ERR("int param is_default should be 0 (not default)");
1612
1613 // set_scalar_int to default value
1615 param, default_value);
1616 if (ret != 0)
1617 PUT_ERR("int param set_scalar_int failed");
1618 if (value != default_value)
1619 PUT_ERR("int param value not set to default");
1620
1621 // is_default (should be true now)
1622 ret = yac_param_is_default(param);
1623 if (ret != 1)
1624 PUT_ERR("int param is_default should be 1 (default)");
1625
1626 // set_scalar (string)
1628 param, "13");
1629 if (ret != 0 || value != 13)
1630 PUT_ERR("int param set_scalar string failed");
1631
1632 // is_default (should be false again)
1633 ret = yac_param_is_default(param);
1634 if (ret != 0)
1635 PUT_ERR("int param is_default should be 0 (not default)");
1636
1637 // set_scalar with NULL string (should fail)
1639 param, NULL);
1640 if (ret == 0)
1641 PUT_ERR("int param set_scalar should fail for NULL value");
1642
1643 // set_scalar with invalid string (should fail)
1645 param, "13x");
1646 if (ret == 0)
1647 PUT_ERR("int param set_scalar should fail for invalid string");
1648
1649 // get_scalar (string)
1650 strcpy(buf, "garbage");
1652 param, buf, sizeof(buf));
1653 if (ret != 0 || strcmp(buf, "13") != 0)
1654 PUT_ERR("int param get_scalar string failed");
1655
1656 // get_scalar with too small buffer (should fail)
1657 size_t const small_buf_size = 2; // "13" + null terminator = 3 bytes needed
1659 param, buf, small_buf_size);
1660 if (ret == 0)
1661 PUT_ERR("int param get_scalar should fail for too small buffer");
1662
1663 // set_scalar_int (again)
1665 param, 77);
1666 if (ret != 0 || value != 77)
1667 PUT_ERR("int param set_scalar_int failed (again)");
1668
1669 // out-of-range integer
1671 param, min_value - 1);
1672 if (ret == 0 || value != 77)
1673 PUT_ERR("int param set_scalar_int should fail for out-of-range value");
1675 param, max_value + 1);
1676 if (ret == 0 || value != 77)
1677 PUT_ERR("int param set_scalar_int should fail for out-of-range value");
1678
1679 // get_scalar_int
1680 out_val = -1;
1682 param, &out_val);
1683 if (ret != 0 || out_val != 77)
1684 PUT_ERR("int param get_scalar_int failed");
1685
1686 // set_scalar_dble (should succeed for integer-valued double)
1688 param, 50.0);
1689 if (ret != 0 || value != 50)
1690 PUT_ERR("int param set_scalar_dble should succeed for integer value");
1691
1692 // set_scalar_dble should fail for non-integer value
1694 param, 3.14);
1695 if (ret == 0)
1696 PUT_ERR("int param set_scalar_dble should fail for non-integer value");
1697 if (value != 50)
1698 PUT_ERR("int param value should not change after failed set_scalar_dble");
1699
1700 // get_scalar_dble (should succeed)
1701 double dval = 0.0;
1703 param, &dval);
1704 if (ret != 0 || dval != 50.0)
1705 PUT_ERR("int param get_scalar_dble should succeed");
1706
1707 // destroy
1708 yac_param_delete(param);
1709 }
1710
1711 { // Test int param with no default (has_default = 0)
1712 int value = 0;
1713 int default_value = 42;
1714 int min_value = 0, max_value = 100;
1715 int has_default = 0;
1716 int is_defined = 0;
1717 int ret;
1718 char buf[32];
1719 struct yac_param *param =
1721 "int_param_nodef", &value, default_value, min_value, max_value,
1722 has_default, is_defined);
1723
1724 // is_default should always be 0
1725 ret = yac_param_is_default(param);
1726 if (ret != 0)
1727 PUT_ERR("int param (no default) is_default should be 0");
1728
1729 // get_scalar/get_scalar_int should fail before set
1731 param, buf, sizeof(buf));
1732 if (ret == 0)
1733 PUT_ERR("int param (no default) get_scalar should fail if not set");
1734 int out_val = -1;
1736 param, &out_val);
1737 if (ret == 0)
1738 PUT_ERR("int param (no default) get_scalar_int should fail if not set");
1739
1740 // set_scalar_int, then get_scalar/get_scalar_int should succeed
1742 param, default_value);
1743
1744 // is_default should still be 0
1745 ret = yac_param_is_default(param);
1746 if (ret != 0)
1747 PUT_ERR("int param (no default) is_default should be 0");
1748
1749 // get_scalar/get_scalar_int should be successful
1750 if (ret != 0)
1751 PUT_ERR("int param (no default) set_scalar_int failed");
1753 param, buf, sizeof(buf));
1754 if (ret != 0 || strcmp(buf, "42") != 0)
1755 PUT_ERR("int param (no default) get_scalar after set failed");
1756 out_val = -1;
1758 param, &out_val);
1759 if (ret != 0 || out_val != 42)
1760 PUT_ERR("int param (no default) get_scalar_int after set failed");
1761 yac_param_delete(param);
1762 }
1763}
1764
1765// Test all basic interfaces with NULL param
1766static void utest_null_param_interfaces(void) {
1767
1768 struct yac_param *null_param = NULL;
1769 size_t count = 1234;
1770 int i_val = 42;
1771 double d_val = 3.14;
1772 char buf[32] = "garbage";
1773 const char *name;
1774 int ret;
1775
1776 // get_type
1777 enum yac_param_type type =
1778 yac_param_get_type(null_param);
1780 PUT_ERR("get_type(NULL) should return TYPE_EMPTY");
1781
1783 ret = yac_param_get_scalar_kind(null_param, &scalar_kind);
1784 if ((ret != 1) || (scalar_kind != YAC_PARAM_SCALAR_KIND_INVALID))
1785 PUT_ERR("get_scalar_kind(NULL) should return error and INVALID");
1786
1787 // is_default
1788 ret = yac_param_is_default(null_param);
1789 if (!ret) PUT_ERR("is_default(NULL) should return 1");
1790
1791 // get_name
1792 name = yac_param_get_name(null_param);
1793 if (name != NULL) PUT_ERR("get_name(NULL) should return NULL");
1794
1795 // get_sub_count
1796 count = 1234;
1797 ret = yac_param_get_sub_count(null_param, &count);
1798 if (ret != 0 || count != 0)
1799 PUT_ERR("get_sub_count(NULL) should return 0, count=0");
1800
1801 // get_sub_by_name
1802 struct yac_param *sub_param = (void*)0x1;
1804 null_param, "foo", &sub_param);
1805 if (ret != 1)
1806 PUT_ERR("get_sub_by_name(NULL) should return 1");
1807
1808 // get_sub_by_index
1809 sub_param = (void*)0x1;
1811 null_param, 0, &sub_param);
1812 if (ret != 1)
1813 PUT_ERR("get_sub_by_index(NULL) should return 1");
1814
1815 // append
1816 sub_param = NULL;
1817 ret = yac_param_append(null_param, &sub_param);
1818 if (ret != 1)
1819 PUT_ERR("append(NULL) should return 1");
1820
1821 // set_scalar
1822 ret =
1824 null_param, "42");
1825 if (ret != 1)
1826 PUT_ERR("set_scalar(NULL) should return 1");
1827
1828 // get_scalar
1829 strcpy(buf, "garbage");
1831 null_param, buf, sizeof(buf));
1832 if (ret != 1 || buf[0] != '\0')
1833 PUT_ERR("get_scalar(NULL) should return 1, buf=\0");
1834
1835 // set_scalar_int
1837 null_param, 42);
1838 if (ret != 1)
1839 PUT_ERR("set_scalar_int(NULL) should return 1");
1840
1841 // set_scalar_dble
1843 null_param, 3.14);
1844 if (ret != 1)
1845 PUT_ERR("set_scalar_dble(NULL) should return 1");
1846
1847 // get_scalar_int
1848 i_val = 42;
1850 null_param, &i_val);
1851 if (ret != 1)
1852 PUT_ERR("get_scalar_int(NULL) should return 1");
1853
1854 // get_scalar_dble
1855 d_val = 3.14;
1857 null_param, &d_val);
1858 if (ret != 1)
1859 PUT_ERR("get_scalar_dble(NULL) should return 1");
1860
1861 // destroy (should not crash)
1862 yac_param_delete(null_param);
1863}
1864
1865static void utest_distance_param_interfaces(void) {
1866
1867 { // Test distance param with default (has_default = 1)
1868 char const * param_name = "distance_param";
1869 double value = M_PI_4; // radians
1870 double default_value = M_PI_2; // radians
1871 double min_value = 0.0;
1872 double max_value = M_PI;
1873 int has_default = 1;
1874 int is_defined = 1;
1875 char buf[64];
1876 int ret;
1877 double out_val = -999.0;
1878 struct yac_param *param =
1880 param_name, &value, default_value, min_value, max_value,
1881 has_default, is_defined);
1882
1883 // get_type
1886 PUT_ERR("distance param get_type should return TYPE_SCALAR");
1887
1889 ret = yac_param_get_scalar_kind(param, &scalar_kind);
1890 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_DBLE))
1891 PUT_ERR("distance param get_scalar_kind should return DBLE");
1892
1893 // get_name
1894 const char *name = yac_param_get_name(param);
1895 if (!name || strcmp(name, param_name) != 0)
1896 PUT_ERR("distance param get_name should return 'distance_param'");
1897
1898 // is_default (should be false initially)
1899 ret = yac_param_is_default(param);
1900 if (ret != 0)
1901 PUT_ERR("distance param is_default should be 0 (not default)");
1902
1903 // set_scalar_dble to default value (radians)
1904 ret = yac_param_set_scalar_dble(param, default_value);
1905 if (ret != 0)
1906 PUT_ERR("distance param set_scalar_dble failed");
1907 if (value != default_value)
1908 PUT_ERR("distance param value not set to default");
1909
1910 // is_default (should be true now)
1911 ret = yac_param_is_default(param);
1912 if (ret != 1)
1913 PUT_ERR("distance param is_default should be 1 (default)");
1914
1915 // set_scalar defaults to degrees
1916 ret = yac_param_set_scalar(param, "90.0");
1917 if (ret != 0 || (value != M_PI_2))
1918 PUT_ERR("distance param set_scalar string default-degree failed");
1919
1920 // set_scalar with explicit rad suffix
1921 ret = yac_param_set_scalar(param, "0.5 rad");
1922 if (ret != 0 || (value != 0.5))
1923 PUT_ERR("distance param set_scalar explicit rad suffix failed");
1924
1925 // set_scalar with case-insensitive short suffix
1926 ret = yac_param_set_scalar(param, "45 D");
1927 if (ret != 0 || (value != M_PI_4))
1928 PUT_ERR("distance param set_scalar short degree suffix failed");
1929
1930 // numeric setter/getter use radians
1931 ret = yac_param_set_scalar_dble(param, M_PI_2);
1932 if (ret != 0 || (value != M_PI_2))
1933 PUT_ERR("distance param set_scalar_dble (radians) failed");
1934
1935 out_val = -999.0;
1936 ret = yac_param_get_scalar_dble(param, &out_val);
1937 if (ret != 0 || (out_val != M_PI_2))
1938 PUT_ERR("distance param get_scalar_dble (radians) failed");
1939
1940 // string getter always returns degrees
1941 strcpy(buf, "garbage");
1942 ret = yac_param_get_scalar(param, buf, sizeof(buf));
1943 if (ret != 0 || fabs(atof(buf) - 90.0) > tol)
1944 PUT_ERR("distance param get_scalar should return degrees");
1945
1946 // invalid/NULL parser input
1947 ret = yac_param_set_scalar(param, NULL);
1948 if (ret == 0)
1949 PUT_ERR("distance param set_scalar should fail for NULL string");
1950 ret = yac_param_set_scalar(param, "90x");
1951 if (ret == 0)
1952 PUT_ERR("distance param set_scalar should fail for invalid string");
1953 ret = yac_param_set_scalar(param, "90 deg");
1954 if (ret == 0)
1955 PUT_ERR("distance param set_scalar should reject double space before unit");
1956 ret = yac_param_set_scalar(param, "90 deg ");
1957 if (ret == 0)
1958 PUT_ERR("distance param set_scalar should reject trailing whitespace");
1959
1960 // get_scalar with too small buffer (should fail)
1961 int const small_buf_size = 2;
1963 param, buf, small_buf_size);
1964 if (ret == 0)
1965 PUT_ERR("distance param get_scalar should fail for too small buffer");
1966
1967 // set_scalar_int (should succeed for integer degree values)
1969 param, 1);
1970 if (ret != 0 || (value != 1.0))
1971 PUT_ERR("distance param set_scalar_int should succeed for 1 deg");
1972
1973 // get_scalar_int (should succeed when value is integer degrees)
1974 int ival = 0;
1976 param, &ival);
1977 if (ret != 0 || ival != 1)
1978 PUT_ERR("distance param get_scalar_int should succeed for 1 deg");
1979
1980 // get_scalar_int should fail for non-integer degree value
1981 ret = yac_param_set_scalar_dble(param, 0.5);
1982 if (ret != 0) PUT_ERR("distance param set_scalar_dble failed");
1983 ret = yac_param_get_scalar_int(param, &ival);
1984 if (ret == 0)
1985 PUT_ERR("distance param get_scalar_int should fail for non-integer deg");
1986
1987 // test out-of-range (should fail)
1989 param, min_value - 0.01);
1990 if (ret == 0)
1991 PUT_ERR("distance param set_scalar_dble should fail for out-of-range");
1993 param, max_value + 0.01);
1994 if (ret == 0)
1995 PUT_ERR("distance param set_scalar_dble should fail for out-of-range");
1996
1997 // test NaN (should fail)
1999 param, NAN);
2000 if (ret == 0)
2001 PUT_ERR("distance param set_scalar_dble should fail for NaN");
2002
2003 // test Inf (should fail)
2005 param, INFINITY);
2006 if (ret == 0)
2007 PUT_ERR("distance param set_scalar_dble should fail for Inf");
2008
2009 // destroy
2010 yac_param_delete(param);
2011 }
2012
2013 { // Test distance param with no default (has_default = 0)
2014 char const * param_name = "distance_param_nodef";
2015 double value = 0.0;
2016 double default_value = 1.0;
2017 double min_value = 0.0, max_value = M_PI;
2018 int has_default = 0;
2019 int is_defined = 0;
2020 int ret;
2021 char buf[64];
2022 double out_val = -999.0;
2023 struct yac_param *param =
2025 param_name, &value, default_value, min_value, max_value,
2026 has_default, is_defined);
2027
2028 // is_default should always be 0
2029 ret = yac_param_is_default(param);
2030 if (ret != 0)
2031 PUT_ERR("distance param (no default) is_default should be 0");
2032
2033 // get_scalar/get_scalar_dble should fail before set
2035 param, buf, sizeof(buf));
2036 if (ret == 0)
2037 PUT_ERR("distance param (no default) get_scalar should fail if not set");
2038 out_val = -999.0;
2040 param, &out_val);
2041 if (ret == 0)
2042 PUT_ERR(
2043 "distance param (no default) get_scalar_dble should fail if not set");
2044
2045 // set_scalar_dble, then get_scalar/get_scalar_dble should succeed
2047 param, 0.7);
2048 if (ret != 0 || value != 0.7)
2049 PUT_ERR("distance param (no default) set_scalar_dble failed");
2050 ret = yac_param_get_scalar(param, buf, sizeof(buf));
2051 if (ret != 0 || fabs(atof(buf) - yac_rad_to_deg(0.7, param_name)) > tol)
2052 PUT_ERR("distance param (no default) get_scalar after set failed");
2053 out_val = -999.0;
2055 param, &out_val);
2056 if (ret != 0 || out_val != 0.7)
2057 PUT_ERR("distance param (no default) get_scalar_dble after set failed");
2058
2059 // Set to default
2061 param, default_value);
2062 if (ret != 0 || value != default_value)
2063 PUT_ERR("distance param (no default) set_scalar_dble failed");
2064
2065 // is_default should still be 0
2066 ret = yac_param_is_default(param);
2067 if (ret != 0)
2068 PUT_ERR("distance param (no default) is_default should be 0");
2069
2070 yac_param_delete(param);
2071 }
2072}
2073
2074static void utest_angle_param_interfaces(void) {
2075
2076 { // Angle parameter with mandatory wrapping to [-pi, pi)
2077 char const * param_name = "angle_param";
2078 double value = 0.5;
2079 double default_value = 0.0;
2080 double value_min = -M_PI_2;
2081 double value_max = M_PI_2;
2082 int has_default = 1;
2083 int is_defined = 1;
2084 char buf[64];
2085 double out_val = -999.0;
2086 int ret;
2087
2088 struct yac_param *param =
2090 param_name, &value, default_value, value_min, value_max,
2091 has_default, is_defined);
2092
2093 // get_type
2094 enum yac_param_type type =
2095 yac_param_get_type(param);
2097 PUT_ERR("angle param get_type should return TYPE_SCALAR");
2098
2100 ret = yac_param_get_scalar_kind(param, &scalar_kind);
2101 if ((ret != 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_DBLE))
2102 PUT_ERR("angle param get_scalar_kind should return DBLE");
2103
2104 // get_name
2105 const char *name = yac_param_get_name(param);
2106 if (!name || strcmp(name, param_name) != 0)
2107 PUT_ERR("angle param get_name should return 'angle_param'");
2108
2109 // is_default (should be false initially)
2110 ret = yac_param_is_default(param);
2111 if (ret != 0)
2112 PUT_ERR("angle param is_default should be 0 (not default)");
2113
2114 // set_scalar defaults to degrees
2115 ret = yac_param_set_scalar(param, "90.0");
2116 if (ret != 0 || (value != M_PI_2))
2117 PUT_ERR("angle param default degree string conversion failed");
2118
2119 // explicit rad suffix overrides degree default
2120 ret = yac_param_set_scalar(param, "0.5rad");
2121 if (ret != 0 || (value != 0.5))
2122 PUT_ERR("angle param explicit rad suffix conversion failed");
2123
2124 // numeric set/get are radians
2125 ret = yac_param_set_scalar_dble(param, -M_PI_2);
2126 if (ret != 0 || (value != -M_PI_2))
2127 PUT_ERR("angle param numeric radian assignment failed");
2128
2129 ret = yac_param_get_scalar_dble(param, &out_val);
2130 if (ret != 0 || (out_val != -M_PI_2))
2131 PUT_ERR("angle param numeric radian retrieval failed");
2132
2133 // string getter is in degrees
2134 ret = yac_param_get_scalar(param, buf, sizeof(buf));
2135 if (ret != 0 || fabs(atof(buf) - (-90.0)) > tol)
2136 PUT_ERR("angle param string getter should return degrees");
2137
2138 // invalid/NULL input
2139 ret = yac_param_set_scalar(param, NULL);
2140 if (ret == 0)
2141 PUT_ERR("angle param set_scalar should fail for NULL string");
2142 ret = yac_param_set_scalar(param, "180x");
2143 if (ret == 0)
2144 PUT_ERR("angle param set_scalar should fail for invalid string");
2145
2146 // numeric setter expects radians; degree-like values are out of range
2147 ret = yac_param_set_scalar_dble(param, 91.0);
2148 if (ret == 0)
2149 PUT_ERR("angle param set_scalar_dble should fail for out-of-range value");
2150 ret = yac_param_set_scalar_dble(param, -91.0);
2151 if (ret == 0)
2152 PUT_ERR("angle param set_scalar_dble should fail for out-of-range value");
2153
2154
2155 // get_scalar with too small buffer (should fail)
2156 int const small_buf_size = 2; // "45.0" + null terminator is 5 chars
2158 param, buf, small_buf_size);
2159 if (ret == 0)
2160 PUT_ERR("angle param get_scalar should fail for too small buffer");
2161
2162 // set_scalar with out-of-range value (should fail)
2164 param, value_min - 0.1);
2165 if (ret == 0)
2166 PUT_ERR("angle param should fail if wrapped value is out of range");
2168 param, value_max + 0.1);
2169 if (ret == 0)
2170 PUT_ERR("angle param should fail if wrapped value is out of range");
2171
2172 // set_scalar_int (integer degrees, should succeed)
2173 ret = yac_param_set_scalar_int(param, 1);
2174 if (ret != 0 || (value != 1.0))
2175 PUT_ERR("angle param set_scalar_int should succeed for 1 deg");
2176
2177 // get_scalar_int (should succeed when angle is integer degrees)
2178 int ival = 0;
2179 ret = yac_param_get_scalar_int(param, &ival);
2180 if (ret != 0 || ival != 1)
2181 PUT_ERR("angle param get_scalar_int should succeed for 1 deg");
2182
2183 // get_scalar_int should fail for non-integer degree value
2184 ret = yac_param_set_scalar_dble(param, 0.5);
2185 if (ret != 0) PUT_ERR("angle param set_scalar_dble failed");
2186 ret = yac_param_get_scalar_int(param, &ival);
2187 if (ret == 0)
2188 PUT_ERR("angle param get_scalar_int should fail for non-integer deg");
2189
2190 yac_param_delete(param);
2191 }
2192
2193 { // Angle parameter wrapping for string-degree and numeric-radian input
2194 char const * param_name = "angle_wrap_param";
2195 double value = 2.0 * M_PI; // 360 degrees, should wrap to 0
2196 double default_value = 0.0;
2197 double value_min = -M_PI_2; // -90 degrees
2198 double value_max = M_PI_2; // +90 degrees
2199 int has_default = 1;
2200 int is_defined = 1;
2201 char buf[64];
2202 int ret;
2203
2204 struct yac_param *param =
2206 param_name, &value, default_value + 2.0 * M_PI,
2207 value_min, value_max, has_default, is_defined);
2208
2209 // set_scalar with degree value that wraps
2210 ret = yac_param_set_scalar(param, "270.0");
2211 if (ret != 0 || (value != -M_PI_2))
2212 PUT_ERR("angle param wrapping from degree string input failed");
2213
2214 // get_scalar should reflect wrapped value in degrees
2215 ret = yac_param_get_scalar(param, buf, sizeof(buf));
2216 if (ret != 0 || (fabs(atof(buf) - (-90.0)) > tol))
2217 PUT_ERR("angle param wrapped degree retrieval failed");
2218
2219 // set_scalar_dble with radian value that wraps
2220 ret = yac_param_set_scalar_dble(param, M_PI_2 + 2.0 * M_PI);
2221 if (ret != 0 || (value != M_PI_2))
2222 PUT_ERR("angle param wrapping from numeric radian input failed");
2223
2224 // get_scalar_dble should reflect wrapped value in radians
2225 double out_val = -999.0;
2226 ret = yac_param_get_scalar_dble(param, &out_val);
2227 if (ret != 0 || (fabs(out_val - M_PI_2) > tol))
2228 PUT_ERR("angle param wrapped radian retrieval failed");
2229
2230 // set_scalar_dble with radian value that wraps negatively
2231 ret = yac_param_set_scalar_dble(param, -M_PI_2 - 2.0 * M_PI);
2232 if (ret != 0 || (value != -M_PI_2))
2233 PUT_ERR("angle param wrapping from numeric radian input failed");
2234
2235 // set_scalar with out-of-range value with wrapping (should fail)
2237 param, value_min - 0.1 - 2.0 * M_PI);
2238 if (ret == 0)
2239 PUT_ERR("angle param should fail if wrapped value is out of range");
2241 param, value_max + 0.1 + 2.0 * M_PI);
2242 if (ret == 0)
2243 PUT_ERR("angle param should fail if wrapped value is out of range");
2244
2245 yac_param_delete(param);
2246 }
2247
2248 { // Wrapping is also applied during constructor initialization
2249 char const * param_name = "angle_init_wrap_param";
2250 double value = 3.0 * M_PI;
2251 double default_value = value;
2252 double value_min = -M_PI; // -180 degrees
2253 double value_max = M_PI; // +180 degrees
2254 int has_default = 1;
2255 int is_defined = 1;
2256 struct yac_param *param =
2258 param_name, &value, default_value,
2259 value_min, value_max, has_default, is_defined);
2260 if (!param)
2261 PUT_ERR("angle param constructor with wrap should succeed");
2262 if (value != -M_PI)
2263 PUT_ERR("angle param constructor did not wrap initial value");
2264 if (yac_param_is_default(param) != 1)
2265 PUT_ERR("angle param wrapped initial/default should match");
2266 yac_param_delete(param);
2267 }
2268
2269 { // Angle parameter without default
2270 char const * param_name = "angle_param_nodef";
2271 double value = 0.0;
2272 double default_value = 1.0;
2273 double value_min = -M_PI_2;
2274 double value_max = M_PI_2;
2275 int has_default = 0;
2276 int is_defined = 0;
2277 int ret;
2278 char buf[64];
2279 double out_val = -999.0;
2280 struct yac_param *param =
2282 param_name, &value, default_value, value_min, value_max,
2283 has_default, is_defined);
2284
2285 // is_default should always be 0
2286 ret = yac_param_is_default(param);
2287 if (ret != 0)
2288 PUT_ERR("angle param (no default) is_default should be 0");
2289
2290 // get_scalar/get_scalar_dble should fail before set
2292 param, buf, sizeof(buf));
2293 if (ret == 0)
2294 PUT_ERR("angle param (no default) get_scalar should fail if not set");
2296 param, &out_val);
2297 if (ret == 0)
2298 PUT_ERR("angle param (no default) get_scalar_dble should fail if not set");
2299
2300 // set_scalar_dble
2302 param, M_PI_4);
2303 if (ret != 0 || value != M_PI_4)
2304 PUT_ERR("angle param (no default) set_scalar_dble failed");
2305
2306 // get_scalar/get_scalar_dble should be successful
2308 param, buf, sizeof(buf));
2309 if (ret != 0 || fabs(atof(buf) - 45.0) > tol)
2310 PUT_ERR("angle param (no default) get_scalar after set failed");
2311 out_val = -999.0;
2313 param, &out_val);
2314 if (ret != 0 || out_val != M_PI_4)
2315 PUT_ERR("angle param (no default) get_scalar_dble after set failed");
2316
2317 // is default should still be 0
2318 ret = yac_param_is_default(param);
2319 if (ret != 0)
2320 PUT_ERR("angle param (no default) is_default should be 0");
2321
2322 // set to default
2324 param, default_value);
2325 if (ret != 0 || value != default_value)
2326 PUT_ERR("angle param (no default) set_scalar_dble failed");
2327
2328 // is default should still be 0
2329 ret = yac_param_is_default(param);
2330 if (ret != 0)
2331 PUT_ERR("angle param (no default) is_default should be 0");
2332
2333 yac_param_delete(param);
2334 }
2335}
2336
2337static void utest_deg_rad_conversion(void) {
2338
2339 double const deg_to_rad = M_PI / 180.0;
2340
2341 for (int deg = -720; deg <= 720; ++deg) {
2342
2343 double wrapped_deg = (double)deg;
2344 while (wrapped_deg < -180.0) wrapped_deg += 360.0;
2345 while (wrapped_deg >= 180.0) wrapped_deg -= 360.0;
2346
2347 double expected_rad = wrapped_deg * deg_to_rad;
2348 double converted_rad = yac_deg_to_rad((double)deg, "deg_to_rad_test");
2349
2350 if (fabs(converted_rad - expected_rad) > tol)
2351 PUT_ERR("yac_deg_to_rad conversion failed in [-720,720] degree loop");
2352
2353 double expected_deg = wrapped_deg;
2354 double converted_deg =
2355 yac_rad_to_deg((double)deg * deg_to_rad, "rad_to_deg_test");
2356
2357 if (fabs(converted_deg - expected_deg) > tol)
2358 PUT_ERR("yac_rad_to_deg conversion failed in [-720,720] degree loop");
2359 }
2360}
2361
2362static struct yac_param * utest_get_sub_by_index(
2363 struct yac_param *param, size_t idx) {
2364 struct yac_param *sub = NULL;
2365 int ret = yac_param_get_sub_by_index(param, idx, &sub);
2366 if (ret != 0)
2367 return NULL;
2368 return sub;
2369}
2370
2371static char const * list_param_name = "int_sub";
2374static int list_param_min = 0;
2375static int list_param_max = 100;
2378
2379// Factory for unnamed int param (for append)
2380static int utest_default_factory(
2381 void **element_ptr, struct yac_param **param_ptr) {
2382 int *elem = xmalloc(sizeof(int));
2383 *elem = list_param_init_value;
2384 *element_ptr = elem;
2385 *param_ptr = yac_param_int_new(
2386 list_param_name, elem,
2389 return 0;
2390}
2391
2392static int utest_failing_default_factory(
2393 void **element_ptr, struct yac_param **param_ptr) {
2394 UNUSED(element_ptr);
2395 UNUSED(param_ptr);
2396 return 1;
2397}
2398
2399static int utest_list_existing_element_get_param(
2400 void *element, struct yac_param **param_ptr) {
2401 *param_ptr = yac_param_int_new(
2402 list_param_name, (int *)element,
2405 return 0;
2406}
2407
2408// Test list parameter interfaces
2409static void utest_list_param_interfaces(void) {
2410
2411 int ret;
2412
2413 { // Main test of list param interfaces
2414
2415 // Start with no backing array; append allocates and grows the array.
2416 char const * param_name = "list_param";
2417 void **list = NULL;
2418 struct yac_param *param =
2420 param_name, &list, utest_default_factory, NULL);
2421
2422 // get_type
2423 enum yac_param_type type =
2424 yac_param_get_type(param);
2426 PUT_ERR("list param get_type should return TYPE_LIST");
2427
2429 ret = yac_param_get_scalar_kind(param, &scalar_kind);
2430 if ((ret == 0) || (scalar_kind != YAC_PARAM_SCALAR_KIND_INVALID))
2431 PUT_ERR("list param get_scalar_kind should fail");
2432
2433 // get_name
2434 const char *name = yac_param_get_name(param);
2435 if (!name || strcmp(name, param_name) != 0)
2436 PUT_ERR("list param get_name should return 'list_param'");
2437
2438 // get_sub_count
2439 size_t count = SIZE_MAX;
2440 ret = yac_param_get_sub_count(param, &count);
2441 if (ret != 0 || count != 0)
2442 PUT_ERR("list param get_sub_count should return 0");
2443
2444 // is_default (should be true initially)
2445 ret = yac_param_is_default(param);
2446 if (ret != 1)
2447 PUT_ERR("list param is_default should be 1 (default)");
2448
2449 // Append three elements and set their values to 1, 2, 3
2450 for (int i = 0; i < 3; ++i) {
2451 struct yac_param *added = NULL;
2452 ret = yac_param_append(param, &added);
2453 if (ret != 0 || !added)
2454 PUT_ERR("list param append failed (bulk append)");
2456 added, i + 1);
2457 if (ret != 0)
2458 PUT_ERR("list param set_scalar_int failed after append");
2459 if (*(int*)list[i] != i + 1)
2460 PUT_ERR("list param appended element value not set correctly");
2461 }
2462
2463 // is_default (should be false now)
2464 ret = yac_param_is_default(param);
2465 if (ret != 0)
2466 PUT_ERR("list param is_default should be 0 (not default)");
2467
2468 // get_sub_count
2469 ret = yac_param_get_sub_count(param, &count);
2470 if (ret != 0 || count != 3)
2471 PUT_ERR("list param get_sub_count should return 3");
2472
2473 // get_sub_by_index (in bounds)
2474 for (size_t i = 0; i < count; ++i) {
2475 struct yac_param *sub = NULL;
2476 ret = yac_param_get_sub_by_index(param, i, &sub);
2477 if (ret != 0 || !sub)
2478 PUT_ERR("list param get_sub_by_index failed for valid index");
2479 int sub_val = -1;
2481 sub, &sub_val);
2482 if (ret != 0 || sub_val != (int)(i + 1))
2483 PUT_ERR(
2484 "list param get_sub_by_index returned subparam with wrong value");
2485 }
2486
2487 // get_sub_by_index (out of bounds)
2488 struct yac_param *sub = NULL;
2489 ret = yac_param_get_sub_by_index(param, count, &sub);
2490 if (ret == 0)
2491 PUT_ERR("list param get_sub_by_index should fail for out-of-bounds");
2492
2493 // Set all subparams to default
2494 for (size_t i = 0; i < count; ++i) {
2495 struct yac_param *sub = NULL;
2496 ret = yac_param_get_sub_by_index(param, i, &sub);
2497 if (ret != 0 || !sub)
2498 PUT_ERR(
2499 "list param get_sub_by_index failed for valid index (set default)");
2501 utest_get_sub_by_index(param, i), list_param_default_value);
2502 }
2503
2504 // is_default (should still be false, since the list is not empty)
2505 ret = yac_param_is_default(param);
2506 if (ret != 0)
2507 PUT_ERR("list param is_default should be 0 (not default)");
2508
2509 // destroy
2510 yac_param_delete(param);
2511 for (size_t i = 0; i < count; ++i) free(list[i]);
2512 free(list);
2513 }
2514
2515 { // append error path
2516 char const * param_name = "list_param_append_error";
2517 void **err_list = NULL;
2518 void **err_list_ptr = err_list;
2519 void ***err_list_handle = &err_list_ptr;
2520 struct yac_param *err_param =
2522 param_name, err_list_handle, utest_failing_default_factory, NULL);
2523 struct yac_param *added = NULL;
2524 ret = yac_param_append(err_param, &added);
2525 if (ret == 0)
2526 PUT_ERR("list param append should fail if factory fails");
2527 yac_param_delete(err_param);
2528 }
2529
2530 { // constructor path with existing elements and element_get_param callback
2531 char const * param_name = "list_param_existing";
2532 int existing_values[3] = {10, 20, 30};
2533 void ** existing_list = xmalloc(4 * sizeof(void*));
2534 existing_list[0] = &existing_values[0];
2535 existing_list[1] = &existing_values[1];
2536 existing_list[2] = &existing_values[2];
2537 existing_list[3] = NULL;
2538 struct yac_param *existing_param =
2540 param_name, &existing_list, utest_default_factory,
2541 utest_list_existing_element_get_param);
2542
2543 // is_default should be false since the list is not empty
2544 ret = yac_param_is_default(existing_param);
2545 if (ret != 0)
2546 PUT_ERR("list param with existing elements should not be default");
2547
2548 // get_sub_count should reflect the existing elements
2549 size_t existing_count = 0;
2551 existing_param, &existing_count);
2552 if (ret != 0 || existing_count != 3)
2553 PUT_ERR("list param with existing elements should have size 3");
2554
2555 // get_sub_by_index should return subparams reflecting the existing elements
2556 for (size_t i = 0; i < existing_count; ++i) {
2557 struct yac_param *sub = NULL;
2559 existing_param, i, &sub);
2560 if (ret != 0 || !sub)
2561 PUT_ERR("list param get_sub_by_index failed for existing element");
2562 int sub_val = -1;
2564 sub, &sub_val);
2565 if (ret != 0 || sub_val != existing_values[i])
2566 PUT_ERR(
2567 "list param get_sub_by_index returned subparam with wrong "
2568 "value for existing element");
2569 }
2570
2571 // get_sub_by_index should fail for out-of-bounds index
2572 struct yac_param *sub = NULL;
2574 existing_param, existing_count, &sub);
2575 if (ret == 0)
2576 PUT_ERR("list param get_sub_by_index should fail for out-of-bounds on "
2577 "existing list");
2578
2579 // append should still work and add new elements after the existing ones
2580 struct yac_param *added = NULL;
2581 ret = yac_param_append(existing_param, &added);
2582 if (ret != 0 || !added)
2583 PUT_ERR("list param append failed when existing elements are present");
2585 added, 40);
2586 if (ret != 0)
2587 PUT_ERR("list param set_scalar_int failed after append with existing "
2588 "elements");
2589 if (*(int*)existing_list[3] != 40)
2590 PUT_ERR(
2591 "list param appended element value not set correctly with existing "
2592 "elements");
2593
2594 yac_param_delete(existing_param);
2595 free(existing_list[3]);
2596 free(existing_list);
2597 }
2598}
2599
2600// ---------------------------------------------------------------------------
2601// Usage demo: a dummy interpolation configuration combining int (count),
2602// distance, and oneof (sub variant) parameter types backed by:
2606 double distance; // stored in radians
2607 struct dummy_sub {
2608 enum {
2612 union {
2613 struct { double scale; } A;
2614 struct { char *name; } B;
2617};
2619// ---------------------------------------------------------------------------
2620
2621// Remark:
2622// using DEF_NAME_TYPE_PAIRS macro outside of function scope caused problems
2623// for doxygen, so defining the name-type pairs manually instead
2626 DEF_NAME_TYPE_PAIR(option_a, DUMMY_OPTION_A),
2627 DEF_NAME_TYPE_PAIR(option_b, DUMMY_OPTION_B),
2628 DEF_NAME_TYPE_PAIR(a, DUMMY_OPTION_A), // alias for option_a
2629 DEF_NAME_TYPE_PAIR(b, DUMMY_OPTION_B) // alias for option_b
2630};
2631enum {
2633 sizeof(dummy_option_types) / sizeof(dummy_option_types[0])
2636
2637// default options
2639int const DUMMY_COUNT_DEFAULT = 3; // default count value
2640double const DUMMY_DISTANCE_DEFAULT = 1.0 * M_PI / 180.0; // default distance value (1 degree)
2641static int const DUMMY_SUB_DEFAULT = (int)DUMMY_OPTION_A; // default sub variant
2642double const DUMMY_SCALE_DEFAULT = 0.5; // default scale value for DUMMY_OPTION_A
2643char const * const DUMMY_NAME_DEFAULT = "default_name"; // default name value for DUMMY_OPTION_B
2645
2655static struct yac_param * dummy_sub_build_param(struct dummy_sub *dummy_sub) {
2656
2657 if (!dummy_sub) return NULL;
2658
2659 enum {
2660 DUMMY_SCALE_HAS_DEFAULT = 1,
2661 DUMMY_SCALE_IS_DEFINE = 1,
2662 DUMMY_NAME_ALLOW_NULL = 0,
2663 DUMMY_NAME_ALLOW_EMPTY = 0,
2664 DUMMY_NAME_MAX_STR_LEN = 64,
2665 DUMMY_NAME_HAS_DEFAULT = 1,
2666 DUMMY_NAME_IS_DEFINE = 1
2667 };
2668 double const DUMMY_SCALE_MIN = 0.00001;
2669 double const DUMMY_SCALE_MAX = 90.0 * M_PI / 180.0; // 90 degree
2670
2671 switch (dummy_sub->sub_type) {
2672
2674 "ERROR(dummy_sub_build_param): unknown option type in dummy_sub");
2675
2676 case (DUMMY_OPTION_A): {
2677
2678 struct yac_param * scale_subparam =
2680 "scale", &dummy_sub->sub_data.A.scale, DUMMY_SCALE_DEFAULT,
2681 DUMMY_SCALE_MIN, DUMMY_SCALE_MAX, DUMMY_SCALE_HAS_DEFAULT,
2682 DUMMY_SCALE_IS_DEFINE);
2683 struct yac_param *sub_params[] = {
2684 scale_subparam
2685 };
2686 return
2689 dummy_option_types, dummy_option_types_size, dummy_sub->sub_type),
2690 sub_params, sizeof(sub_params)/sizeof(sub_params[0]));
2691 }
2692
2693 case (DUMMY_OPTION_B): {
2694
2695 struct yac_param * name_subparam =
2697 "name", &dummy_sub->sub_data.B.name, DUMMY_NAME_DEFAULT,
2698 DUMMY_NAME_ALLOW_NULL, DUMMY_NAME_ALLOW_EMPTY, DUMMY_NAME_MAX_STR_LEN,
2699 DUMMY_NAME_HAS_DEFAULT, DUMMY_NAME_IS_DEFINE);
2700 struct yac_param *sub_params[] = {
2701 name_subparam
2702 };
2703 return
2706 dummy_option_types, dummy_option_types_size, dummy_sub->sub_type),
2707 sub_params, sizeof(sub_params)/sizeof(sub_params[0]));
2708 }
2709 }
2710}
2711
2735 const char *name, void **obj,
2736 struct yac_param **param, int *is_default) {
2737
2738 YAC_ASSERT(obj, "missing dummy sub config object");
2739 YAC_ASSERT(param, "param is NULL");
2740 YAC_ASSERT(is_default, "is_default is NULL");
2741
2742 struct dummy_sub **dummy_sub_ptr = (struct dummy_sub **)obj;
2743
2744 YAC_ASSERT(
2745 *dummy_sub_ptr == NULL, "dummy sub config object is already defined");
2746
2747 struct dummy_sub * dummy_sub = xmalloc(1 * sizeof(*dummy_sub));
2748
2749 int type =
2750 (name == NULL)?
2751 (int)DUMMY_OPTION_A:
2754
2755 int ret = 1;
2756
2757 switch (type) {
2758 case DUMMY_OPTION_A:
2759 dummy_sub->sub_type = DUMMY_OPTION_A;
2760 dummy_sub->sub_data.A.scale = DUMMY_SCALE_DEFAULT;
2761 ret = 0;
2762 break;
2763
2764 case DUMMY_OPTION_B:
2765 dummy_sub->sub_type = DUMMY_OPTION_B;
2766 dummy_sub->sub_data.B.name = strdup(DUMMY_NAME_DEFAULT);
2767 ret = 0;
2768 break;
2769
2770 default:
2771 free(dummy_sub);
2772 dummy_sub = NULL;
2774 0, "ERROR(dummy_sub_factory): unknown option type");
2775 break;
2776 }
2777
2778 *dummy_sub_ptr = dummy_sub;
2779 *param = dummy_sub_build_param(dummy_sub);
2780 *is_default = (ret == 0) && ((int)dummy_sub->sub_type == DUMMY_SUB_DEFAULT);
2781
2782 return ret;
2783}
2784
2793 struct dummy_config *cfg) {
2794
2795 enum {
2796 DUMMY_COUNT_MIN = 1,
2797 DUMMY_COUNT_MAX = 100,
2798 DUMMY_COUNT_HAS_DEFAULT = 1,
2799 DUMMY_COUNT_IS_DEFAULT = 1
2800 };
2801
2802 // count param
2803 struct yac_param *count_param =
2805 "count", &cfg->count,
2806 DUMMY_COUNT_DEFAULT, DUMMY_COUNT_MIN, DUMMY_COUNT_MAX,
2807 DUMMY_COUNT_HAS_DEFAULT, DUMMY_COUNT_IS_DEFAULT);
2808
2809 double const DUMMY_DISTANCE_MIN = 0.0;
2810 double const DUMMY_DISTANCE_MAX = M_PI; // 180 degrees
2811 enum {
2812 DUMMY_DISTANCE_HAS_DEFAULT = 1,
2813 DUMMY_DISTANCE_IS_DEFAULT = 1
2814 };
2815
2816 // distance param (stores radians; PARSER source converts from degrees)
2817 struct yac_param *dist_param =
2819 "distance", &cfg->distance,
2820 DUMMY_DISTANCE_DEFAULT, DUMMY_DISTANCE_MIN, DUMMY_DISTANCE_MAX,
2821 DUMMY_DISTANCE_HAS_DEFAULT, DUMMY_DISTANCE_IS_DEFAULT);
2822
2823 // create subparam for cfg.sub
2824 struct yac_param *dummy_sub_param =
2825 dummy_sub_build_param(cfg->sub);
2826
2827 int const DUMMY_SUB_IS_DEFAULT =
2828 (cfg->sub == NULL) || ((int)cfg->sub->sub_type == DUMMY_SUB_DEFAULT);
2829
2830 // oneof param for sub — factory populates cfg.sub on first access
2831 struct yac_param *sub_param =
2833 "sub", dummy_sub_factory, (void **)&cfg->sub,
2834 dummy_sub_param, DUMMY_SUB_IS_DEFAULT);
2835
2836 // Outer struct param bundles all three
2837 struct yac_param *root_subs[] = {
2838 count_param, dist_param, sub_param
2839 };
2840 struct yac_param *root =
2842 "config", root_subs, sizeof(root_subs)/sizeof(root_subs[0]));
2843
2844 return root;
2845}
2846
2847// Demonstrate application of config param interfaces in a realistic usage
2848// scenario with a dummy interpolation config.
2849static void utest_usage_demo(void) {
2850
2851 // Default configuration struct for usage demo
2853 struct dummy_config cfg = {
2854 .count = DUMMY_COUNT_DEFAULT,
2855 .distance = DUMMY_DISTANCE_DEFAULT,
2856 .sub = NULL
2857 };
2859
2860 // Create the config param tree for dummy_config, which is backed by cfg.
2862 struct yac_param *config_param =
2865
2866 // Set distance in config to 10 degree through the string interface.
2868 struct yac_param *dist_param;
2870 config_param, "distance", &dist_param);
2871 yac_param_set_scalar(dist_param, "10");
2873
2874 // Set the dummy sub variant to option_b and set its name field to "test_name"
2876 struct yac_param *sub_param;
2877 yac_param_get_sub_by_name(config_param, "sub", &sub_param);
2878 struct yac_param *option_b_param;
2879 yac_param_get_sub_by_name(sub_param, "option_b", &option_b_param);
2880 struct yac_param *option_b_name_param;
2881 yac_param_get_sub_by_name(option_b_param, "name", &option_b_name_param);
2882 yac_param_set_scalar(option_b_name_param, "test_name");
2884
2885 // Getting the count param
2887 int count_value;
2888 struct yac_param *count_param;
2889 yac_param_get_sub_by_name(config_param, "count", &count_param);
2890 yac_param_get_scalar_int(count_param, &count_value);
2891 printf("count value = %d\n", count_value);
2893
2894 // Delete the config param tree
2895 // (does not free cfg since config params do not own their backing data)
2897 yac_param_delete(config_param);
2899
2900 // Print contents of cfg to verify that the config params correctly updated it
2902 printf("cfg.count = %d\n", cfg.count);
2903 printf("cfg.distance (radians) = %f\n", cfg.distance);
2904 if (cfg.sub) {
2905 printf("cfg.sub->sub_type = %d\n", cfg.sub->sub_type);
2906 if (cfg.sub->sub_type == DUMMY_OPTION_A) {
2907 printf("cfg.sub->sub_data.A.scale (radians) = %f\n", cfg.sub->sub_data.A.scale);
2908 } else if (cfg.sub->sub_type == DUMMY_OPTION_B) {
2909 printf("cfg.sub->sub_data.B.name = %s\n", cfg.sub->sub_data.B.name);
2910 }
2911 } else {
2912 printf("cfg.sub = NULL\n");
2913 }
2915
2916 // Cleanup
2917 if (cfg.sub) {
2918 if (cfg.sub->sub_type == DUMMY_OPTION_B) {
2919 free(cfg.sub->sub_data.B.name);
2920 }
2921 free(cfg.sub);
2922 }
2923}
#define YAC_ASSERT(exp, msg)
#define UNUSED(x)
Definition core.h:72
#define __attribute__(x)
Definition core.h:69
int yac_name_type_pair_get_type(struct yac_name_type_pair const *pairs, size_t count, char const *name)
Definition utils_core.c:23
#define DEF_NAME_TYPE_PAIR(NAME, TYPE)
char const * yac_name_type_pair_get_name(struct yac_name_type_pair const *pairs, size_t count, int type)
Definition utils_core.c:14
enum callback_type type
struct @23::@24 value
int yac_param_get_scalar_dble(const struct yac_param *param, double *value)
Get the value of a scalar parameter as a double.
Definition param.c:174
void yac_param_delete(struct yac_param *param)
Definition param.c:304
int yac_param_get_sub_by_index(struct yac_param *param, size_t idx, struct yac_param **sub_param)
Get a handle to a subparameter by index.
Definition param.c:89
int yac_param_is_default(const struct yac_param *param)
Check whether a parameter is at its default value.
Definition param.c:37
double yac_deg_to_rad(double deg, char const *param_name)
Definition param.c:385
int yac_param_get_scalar_kind(const struct yac_param *param, enum yac_param_scalar_kind *scalar_kind)
Get the storage kind of a scalar parameter.
Definition param.c:134
double yac_rad_to_deg(double rad, char const *param_name)
Definition param.c:398
int yac_param_get_scalar(const struct yac_param *param, char *buf, size_t buflen)
Get the value of a scalar parameter as a string.
Definition param.c:123
int yac_param_set_scalar(struct yac_param *param, const char *value_str)
Set the value of a scalar parameter from a string.
Definition param.c:113
enum yac_param_type yac_param_get_type(const struct yac_param *param)
Get the type of a parameter.
Definition param.c:24
int yac_param_append(struct yac_param *param, struct yac_param **sub_param)
Append a new default subparameter to a list parameter and return a handle to it.
Definition param.c:102
int yac_param_set_scalar_int(struct yac_param *param, int value)
Set the value of a scalar parameter as an int.
Definition param.c:147
int yac_param_get_sub_count(const struct yac_param *param, size_t *count)
Get the number of subparameters.
Definition param.c:61
int yac_param_set_scalar_dble(struct yac_param *param, double value)
Set the value of a scalar parameter as a double.
Definition param.c:156
double deg
Definition param.c:345
const char * yac_param_get_last_error(void)
Retrieve the last error message for the calling thread.
Definition param.c:298
int yac_param_get_scalar_int(const struct yac_param *param, int *value)
Get the value of a scalar parameter as an int.
Definition param.c:165
const char * yac_param_get_name(const struct yac_param *param)
Get the name of the current parameter.
Definition param.c:50
int yac_param_get_sub_by_name(struct yac_param *param, const char *name, struct yac_param **sub_param)
Get a handle to a subparameter by name.
Definition param.c:75
Public interface for YAC parameters.
yac_param_scalar_kind
Scalar parameter storage kind.
Definition param.h:185
@ YAC_PARAM_SCALAR_KIND_INVALID
Invalid or unsupported scalar kind.
Definition param.h:187
@ YAC_PARAM_SCALAR_KIND_INT
Scalar value backed by int storage.
Definition param.h:189
@ YAC_PARAM_SCALAR_KIND_DBLE
Scalar value backed by double storage.
Definition param.h:191
@ YAC_PARAM_SCALAR_KIND_STR
Scalar value backed by string storage.
Definition param.h:193
yac_param_type
Parameter type for generic configuration interface.
Definition param.h:171
@ YAC_PARAM_TYPE_SCALAR
Single typed value (e.g., int, double, string, enum)
Definition param.h:177
@ YAC_PARAM_TYPE_LIST
Ordered, growable list of subparameters.
Definition param.h:181
@ YAC_PARAM_TYPE_EMPTY
No value (used for optional/absent parameters)
Definition param.h:175
@ YAC_PARAM_TYPE_STRUCT
Named, fixed set of subparameters.
Definition param.h:179
struct yac_param * yac_param_angle_new(const char *name, double *value_ptr, double default_value, double value_min, double value_max, int has_default, int is_defined)
Create an angle parameter (stored in radians)
struct yac_param * yac_param_bool_new(const char *name, int *value_ptr, int default_value, int has_default, int is_defined)
Create a bool parameter (backed by int)
Definition param_bool.c:159
struct yac_param * yac_param_dble_new(const char *name, double *value_ptr, double default_value, double value_min, double value_max, int allow_nan, int allow_inf, int has_default, int is_defined)
Create a double parameter.
Definition param_dble.c:166
struct yac_param * yac_param_distance_new(const char *name, double *value_ptr, double default_value, double value_min, double value_max, int has_default, int is_defined)
Create a distance parameter (stored in radians)
struct yac_param * yac_param_enum_new(const char *name, int *value_ptr, int default_value, struct yac_name_type_pair const *enum_table, size_t enum_table_size, int has_default, int is_defined)
Create a new enum parameter for configuration.
Definition param_enum.c:148
struct yac_param * yac_param_int_new(const char *name, int *value_ptr, int default_value, int value_min, int value_max, int has_default, int is_defined)
Create an int parameter.
Definition param_int.c:163
#define YAC_PARAM_ASSERT(COND,...)
struct yac_param * yac_param_list_new(const char *name, void ***list, yac_param_factory_ptr default_factory, yac_param_element_get_param_ptr element_get_param)
Create a new list parameter.
Definition param_list.c:134
struct yac_param * yac_param_oneof_new(const char *name, yac_param_oneof_factory_ptr default_factory, void **value_ptr, struct yac_param *subparam, int subparam_is_default)
Create a new one-of struct parameter with a given name and a default_factory.
struct yac_param * yac_param_str_new(const char *name, char **value_ptr, const char *default_value, int allow_NULL, int allow_empty, size_t max_str_len, int has_default, int is_defined)
Create a string parameter.
Definition param_str.c:176
struct yac_param * yac_param_struct_new(const char *name, struct yac_param **subparams, size_t subparam_count)
Create a new struct parameter with a given name and subparameters.
#define xmalloc(size)
Definition ppm_xfuncs.h:66
struct dummy_config::dummy_sub::@92::@93 A
union dummy_config::dummy_sub::@92 sub_data
struct dummy_config::dummy_sub::@92::@94 B
enum dummy_config::dummy_sub::@91 sub_type
[icparam_example_struct]
double distance
struct dummy_config::dummy_sub * sub
int const DUMMY_COUNT_DEFAULT
[icparam_example_lookup]
static char const * oneof_default_param_name
Definition test_param.c:85
static char const * oneof_bool_param_name
Definition test_param.c:79
static int oneof_is_defined
Definition test_param.c:77
static int oneof_int_max
Definition test_param.c:75
static int list_param_has_default
static int oneof_int_min
Definition test_param.c:74
@ dummy_option_types_size
static int oneof_has_default
Definition test_param.c:76
static struct yac_name_type_pair const dummy_option_types[]
[icparam_example_struct]
static int list_param_is_defined
static char const * list_param_name
static struct yac_param * dummy_config_get_param(struct dummy_config *cfg)
char const *const DUMMY_NAME_DEFAULT
double const DUMMY_DISTANCE_DEFAULT
static int list_param_max
static int list_param_min
static int oneof_int_default
Definition test_param.c:73
double const DUMMY_SCALE_DEFAULT
static int const DUMMY_SUB_DEFAULT
static struct yac_param * dummy_sub_build_param(struct dummy_sub *dummy_sub)
[icparam_example_defaults]
static int list_param_init_value
static char const * oneof_int_param_name
Definition test_param.c:71
static int oneof_bool_has_default
Definition test_param.c:82
static double const tol
Definition test_param.c:49
static int oneof_int_val
Definition test_param.c:72
static int dummy_sub_factory(const char *name, void **obj, struct yac_param **param, int *is_default)
static int oneof_bool_default
Definition test_param.c:81
static int list_param_default_value
static int oneof_bool_val
Definition test_param.c:80
static int oneof_bool_is_defined
Definition test_param.c:83
#define TEST_EXIT_CODE
Definition tests.h:15
#define PUT_ERR(string)
Definition tests.h:10
char const * name
Definition toy_scrip.c:114
#define YAC_UNREACHABLE_DEFAULT(msg)
Definition yac_assert.h:56