55 #include <sys/resource.h>
56 #include <sys/types.h>
71 #include <amxc/amxc.h>
72 #include <amxp/amxp_signal.h>
73 #include <amxp/amxp_slot.h>
74 #include <amxd/amxd_dm.h>
75 #include <amxd/amxd_object.h>
76 #include <amxd/amxd_parameter.h>
77 #include <amxd/amxd_transaction.h>
78 #include <amxs/amxs.h>
83 #include "../../include_priv/amxo_parser_priv.h"
85 #include <amxc/amxc_macros.h>
88 UNUSED amxs_sync_direction_t direction,
89 UNUSED const amxc_var_t* input,
92 printf(
"Translate object\n");
93 return amxs_status_ok;
97 UNUSED amxs_sync_direction_t direction,
100 printf(
"Apply object\n");
101 return amxs_status_ok;
105 UNUSED amxs_sync_direction_t direction,
106 UNUSED const amxc_var_t* input,
107 UNUSED amxc_var_t* output,
109 printf(
"Translate param\n");
110 return amxs_status_ok;
114 UNUSED amxs_sync_direction_t direction,
117 printf(
"Apply param\n");
118 return amxs_status_ok;
124 const char* file =
"./odl/valid_synchronize.odl";
128 " synchronize 'A.' <-> 'B.' {"
129 " %batch parameter param_A <-> param_B;"
130 " object 'A_template.' <-> 'B_template.' {"
131 " %batch parameter uint_A <-> uint_B;"
132 " %batch parameter string_A <-> string_B;"
154 const char* file =
"./odl/valid_synchronize.odl";
158 " synchronize 'A.' <-> 'B.' {"
159 " %batch parameter param_A -> param_B;"
160 " %batch parameter param_A <- param_B;"
166 " synchronize 'A.' <-> 'B.' {"
167 " %batch parameter param_A -> param_B;"
168 " %batch parameter param_B -> param_A;"
194 const char* file =
"./odl/valid_synchronize.odl";
198 " synchronize '${prefix_}C.' <-> '${prefix_}D.' {"
199 " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
200 " object '${prefix_}C_template.' <-> '${prefix_}D_template.' {"
201 " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
223 const char* file =
"./odl/valid_synchronize.odl";
227 " synchronize 'A.' <-> 'B.' {"
228 " parameter param_A <-> param_B {"
229 " on action translate call translate_param;"
230 " on action apply call apply_param;"
232 " object 'A_template.' <-> 'B_template.' {"
233 " on action translate call translate_object;"
234 " on action apply call apply_object;"
235 " %batch parameter uint_A <-> uint_B;"
236 " %batch parameter string_A <-> string_B;"
261 const char* file =
"./odl/valid_synchronize.odl";
265 " synchronize 'A.' <-> 'B.' {"
266 " %batch parameter param_A -> param_B;"
267 " %batch parameter param_A -> param_B;"
285 const char* file =
"./odl/valid_synchronize.odl";
289 " synchronize 'A.' <-> 'B.' { }"
306 const char* file =
"./odl/valid_synchronize.odl";
310 " synchronize 'A' -> 'B' {"
311 " %batch parameter param_A -> param_B;"
317 " synchronize '' -> '' {"
318 " %batch parameter param_A -> param_B;"
339 const char* file =
"./odl/valid_synchronize.odl";
343 " synchronize 'A.' <-> 'B.' {"
344 " object 'A_template.' <-> 'B_template.' {"
363 const char* file =
"./odl/valid_synchronize.odl";
367 " synchronize 'A.' <-> 'B.' {"
368 " object 'A_template.' <-> 'B_template.' {"
369 " on action translate call object_translate;"
390 const char* file =
"./odl/valid_synchronize.odl";
394 " synchronize 'A.' <-> 'B.' {"
395 " %batch parameter param_A <-> param_B {"
396 " on action translate call param_translate;"
402 " synchronize 'A.' <-> 'B.' {"
403 " %batch parameter param_A <-> param_B {"
404 " on action apply call param_apply;"
429 const char* file =
"./odl/valid_synchronize.odl";
433 " synchronize 'A.' -> 'B.' {"
434 " %batch parameter param_A <- param_B;"
439 " synchronize 'A.' <- 'B.' {"
440 " object 'A_template.' -> 'B_template.' {"
441 " %batch parameter uint_A <-> uint_B;"
463 const char* file =
"./odl/valid_synchronize.odl";
467 " synchronize 'A.' <-> 'B.' {"
468 " %batch parameter param_A <-> param_B {"
469 " on action read call data_read;"
490 const char* file =
"./odl/valid_synchronize.odl";
494 " synchronize 'A.' <-> 'B.' {"
495 " %batch parameter param_A <-> param_B;"
496 " object 'A_template.' <-> 'B_template.' {"
497 " %batch parameter uint_A <-> uint_B;"
498 " %batch parameter string_A <-> string_B;"
518 amxd_dm_t* dm = amxut_bus_dm();
520 amxd_object_t*
object = NULL;
521 amxd_trans_t transaction;
524 const char* file =
"./odl/valid_synchronize.odl";
528 " synchronize 'A.' <-> 'B.' {"
529 " %batch parameter param_A <-> param_B;"
530 " object 'A_template.' <-> 'B_template.' {"
531 " %batch parameter uint_A <-> uint_B;"
532 " %batch parameter string_A <-> string_B;"
538 amxd_trans_init(&transaction);
547 object = amxd_dm_findf(dm,
"B");
548 assert_non_null(
object);
549 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"param_B", NULL), 2);
551 amxd_trans_select_pathf(&transaction,
"B.B_template.");
552 amxd_trans_add_inst(&transaction, 0, NULL);
553 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
554 amxd_trans_clean(&transaction);
556 while(amxp_signal_read() == 0) {
559 object = amxd_dm_findf(dm,
"A.A_template.1.");
560 assert_non_null(
object);
561 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"uint_A", NULL), 3);
562 txt = amxd_object_get_value(cstring_t,
object,
"string_A", NULL);
563 assert_string_equal(txt,
"I am B");
570 amxd_dm_t* dm = amxut_bus_dm();
573 const char* file =
"./odl/valid_synchronize.odl";
577 " synchronize '${prefix_}C.' <-> '${prefix_}D.' {"
578 " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
579 " object '${prefix_}C_template.' <-> '${prefix_}D_template.' {"
580 " %batch parameter '${prefix_}string_C' <-> '${prefix_}string_D';"
596 amxd_dm_t* dm = amxut_bus_dm();
598 amxd_object_t*
object = NULL;
599 amxd_trans_t transaction;
602 const char* file =
"./odl/valid_synchronize.odl";
606 " synchronize 'A.' -> 'B.' {"
607 " parameter param_A -> param_B;"
608 " object 'A_template.' -> 'B_template.' {"
609 " parameter uint_A -> uint_B;"
610 " parameter string_A -> string_B;"
616 amxd_trans_init(&transaction);
625 object = amxd_dm_findf(dm,
"A");
626 assert_non_null(
object);
627 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"param_A", NULL), 2);
629 amxd_trans_select_pathf(&transaction,
"A.A_template.");
630 amxd_trans_add_inst(&transaction, 0, NULL);
631 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
632 amxd_trans_clean(&transaction);
634 while(amxp_signal_read() == 0) {
637 object = amxd_dm_findf(dm,
"B.B_template.1.");
638 assert_non_null(
object);
639 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"uint_B", NULL), 1);
640 txt = amxd_object_get_value(cstring_t,
object,
"string_B", NULL);
641 assert_string_equal(txt,
"I am A");
644 amxd_trans_select_pathf(&transaction,
"B.B_template.1.");
645 amxd_trans_set_value(cstring_t, &transaction,
"string_B",
"Hello");
646 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
647 amxd_trans_clean(&transaction);
649 while(amxp_signal_read() == 0) {
652 object = amxd_dm_findf(dm,
"A.A_template.1.");
653 assert_non_null(
object);
654 txt = amxd_object_get_value(cstring_t,
object,
"string_A", NULL);
655 assert_string_equal(txt,
"I am A");
662 amxd_dm_t* dm = amxut_bus_dm();
664 amxd_object_t*
object = NULL;
665 amxd_trans_t transaction;
668 const char* file =
"./odl/valid_synchronize.odl";
672 " synchronize 'A.' <-> 'B.' {"
673 " parameter param_A <-> param_B;"
674 " object 'A_template.' -> 'B_template.' {"
675 " parameter uint_A -> uint_B;"
676 " parameter string_A -> string_B;"
682 amxd_trans_init(&transaction);
691 object = amxd_dm_findf(dm,
"A");
692 assert_non_null(
object);
693 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"param_A", NULL), 2);
695 amxd_trans_select_pathf(&transaction,
"A.A_template.");
696 amxd_trans_add_inst(&transaction, 0, NULL);
697 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
698 amxd_trans_clean(&transaction);
700 while(amxp_signal_read() == 0) {
703 object = amxd_dm_findf(dm,
"B.B_template.1.");
704 assert_non_null(
object);
705 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"uint_B", NULL), 1);
706 txt = amxd_object_get_value(cstring_t,
object,
"string_B", NULL);
707 assert_string_equal(txt,
"I am A");
710 amxd_trans_select_pathf(&transaction,
"B.B_template.1.");
711 amxd_trans_set_value(cstring_t, &transaction,
"string_B",
"Hello");
712 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
713 amxd_trans_clean(&transaction);
715 while(amxp_signal_read() == 0) {
718 object = amxd_dm_findf(dm,
"A.A_template.1.");
719 assert_non_null(
object);
720 txt = amxd_object_get_value(cstring_t,
object,
"string_A", NULL);
721 assert_string_equal(txt,
"I am A");
728 amxd_dm_t* dm = amxut_bus_dm();
730 amxd_object_t*
object = NULL;
731 amxd_trans_t transaction;
734 const char* file =
"./odl/valid_synchronize.odl";
738 " synchronize 'A.' <-> 'B.' {"
739 " %batch parameter param_A <-> param_B;"
740 " object 'A_template.' <-> 'B_template.' {"
741 " %batch parameter uint_A -> uint_B;"
742 " %batch parameter string_A -> string_B;"
748 amxd_trans_init(&transaction);
757 object = amxd_dm_findf(dm,
"A");
758 assert_non_null(
object);
759 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"param_A", NULL), 2);
761 amxd_trans_select_pathf(&transaction,
"A.A_template.");
762 amxd_trans_add_inst(&transaction, 0, NULL);
763 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
764 amxd_trans_clean(&transaction);
766 while(amxp_signal_read() == 0) {
769 object = amxd_dm_findf(dm,
"B.B_template.1.");
770 assert_non_null(
object);
771 assert_int_equal(amxd_object_get_value(uint32_t,
object,
"uint_B", NULL), 1);
772 txt = amxd_object_get_value(cstring_t,
object,
"string_B", NULL);
773 assert_string_equal(txt,
"I am A");
776 amxd_trans_select_pathf(&transaction,
"B.B_template.1.");
777 amxd_trans_set_value(cstring_t, &transaction,
"string_B",
"Hello");
778 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
779 amxd_trans_clean(&transaction);
781 while(amxp_signal_read() == 0) {
784 object = amxd_dm_findf(dm,
"A.A_template.1.");
785 assert_non_null(
object);
786 txt = amxd_object_get_value(cstring_t,
object,
"string_A", NULL);
787 assert_string_equal(txt,
"I am A");
794 amxd_dm_t* dm = amxut_bus_dm();
796 amxd_object_t*
object = NULL;
797 amxd_trans_t transaction;
800 const char* file =
"./odl/valid_synchronize.odl";
804 " synchronize 'A.' <- 'B.' {"
805 " %batch parameter param_A <- param_B;"
806 " object 'A_template.' <- 'B_template.' {"
807 " %batch parameter uint_A <- uint_B;"
808 " %batch parameter ReadOnlyText <- ReadOnlyText;"
814 amxd_trans_init(&transaction);
823 object = amxd_dm_findf(dm,
"B");
824 assert_non_null(
object);
826 amxd_trans_select_pathf(&transaction,
"B.B_template.");
827 amxd_trans_add_inst(&transaction, 0, NULL);
828 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
829 amxd_trans_clean(&transaction);
831 while(amxp_signal_read() == 0) {
834 object = amxd_dm_findf(dm,
"A.A_template.1.");
835 assert_non_null(
object);
836 txt = amxd_object_get_value(cstring_t,
object,
"ReadOnlyText", NULL);
837 assert_string_equal(txt,
"5678");
844 amxd_dm_t* dm = amxut_bus_dm();
846 amxd_object_t*
object = NULL;
847 amxd_trans_t transaction;
849 amxs_sync_ctx_t* sync_ctx = NULL;
851 const char* file =
"./odl/valid_synchronize.odl";
855 " synchronize 'A.A_template.{i}.' <-> 'B.B_template.{i}.' as 'A2B'{"
856 " %batch parameter uint_A <-> uint_B;"
857 " %batch parameter string_A <-> string_B;"
862 amxd_trans_init(&transaction);
871 object = amxd_dm_findf(dm,
"A");
872 assert_non_null(
object);
874 amxd_trans_select_pathf(&transaction,
"A.A_template.");
875 amxd_trans_add_inst(&transaction, 0, NULL);
876 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
877 amxd_trans_clean(&transaction);
879 object = amxd_dm_findf(dm,
"B");
880 assert_non_null(
object);
882 amxd_trans_select_pathf(&transaction,
"B.B_template.");
883 amxd_trans_add_inst(&transaction, 0, NULL);
884 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
885 amxd_trans_clean(&transaction);
887 while(amxp_signal_read() == 0) {
891 assert_non_null(sync_ctx);
892 amxs_sync_ctx_start_sync(sync_ctx);
894 amxd_trans_select_pathf(&transaction,
"B.B_template.1.");
895 amxd_trans_set_value(cstring_t, &transaction,
"string_B",
"Hello");
896 assert_int_equal(amxd_trans_apply(&transaction, dm), 0);
897 amxd_trans_clean(&transaction);
899 while(amxp_signal_read() == 0) {
902 object = amxd_dm_findf(dm,
"A.A_template.1.");
903 assert_non_null(
object);
904 txt = amxd_object_get_value(cstring_t,
object,
"string_A", NULL);
905 assert_string_equal(txt,
"Hello");
908 amxs_sync_ctx_delete(&sync_ctx);
909 assert_null(sync_ctx);
914 amxd_dm_t* dm = amxut_bus_dm();
917 const char* file =
"./odl/valid_synchronize.odl";
921 " synchronize 'A.A_template.1.' <-> 'B.B_template.5.' as 'A1_2_B5'{"
922 " %batch parameter uint_A <-> uint_B;"
923 " %batch parameter string_A <-> string_B;"
928 " synchronize 'A.A_template.[Alias == \"test\"].' <-> 'B.B_template.[Alias == \"mapped\"].' as 'A2B'{"
929 " %batch parameter uint_A <-> uint_B;"
930 " %batch parameter string_A <-> string_B;"
935 " synchronize 'A.' <-> 'B.' as 'A2B_valid'{"
936 " %batch parameter param_A <-> param_B;"
Ambiorix ODL parser header file.
PRIVATE amxs_sync_entry_type_t amxo_parser_get_sync_type(amxo_parser_t *pctx)
int amxo_parser_start_synchronize(amxo_parser_t *parser)
Start all object and parameter synchronizations that were declared in the loaded odl files.
int amxo_parser_parse_string(amxo_parser_t *parser, const char *text, amxd_object_t *object)
Parses a string containing a valid ODL part.
void amxo_parser_clean(amxo_parser_t *parser)
Cleans up the odl parser instance.
int amxo_parser_parse_file(amxo_parser_t *parser, const char *file_path, amxd_object_t *object)
Parses an odl file.
amxs_sync_ctx_t * amxo_parser_new_sync_ctx(const char *sync_template, const char *object_a, const char *object_b)
Create a new synchronization context from a synchronization template.
int amxo_parser_init(amxo_parser_t *parser)
Initializes a new odl parser instance.
void amxo_parser_stop_synchronize(amxo_parser_t *parser)
Stop all object and parameter synchronizations that were declared in odl files.
int amxo_resolver_ftab_add(amxo_parser_t *parser, const char *fn_name, amxo_fn_ptr_t fn)
Adds a C function to the function table.
#define AMXO_FUNC(x)
Function ponter caster macro.
The ODL parser structure.
amxc_llist_t * sync_contexts
void test_synchronization_can_use_template(UNUSED void **state)
void test_can_parser_synchronize_definition(UNUSED void **state)
void test_parse_empty_synchronize_context_fails(UNUSED void **state)
void test_can_setup_synchronization_with_vars(UNUSED void **state)
static amxs_status_t translate_param(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED const amxc_var_t *input, UNUSED amxc_var_t *output, UNUSED void *priv)
void test_can_setup_synchronization(UNUSED void **state)
static amxs_status_t apply_object(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED amxc_var_t *data, UNUSED void *priv)
void test_synchronization_respects_direction(UNUSED void **state)
void test_synchronization_template_must_use_supported_path(UNUSED void **state)
void test_parser_sync_duplicates_fails(UNUSED void **state)
void test_synchronization_respects_direction_3(UNUSED void **state)
void test_parse_synchronize_with_invalid_action_fails(UNUSED void **state)
void test_can_parser_synchronize_definition_with_vars(UNUSED void **state)
void test_can_parser_synchronize_definition_with_cb(UNUSED void **state)
void test_synchronize_start_fails_when_no_bus_connections(UNUSED void **state)
void test_parse_synchronize_object_fails_without_entries(UNUSED void **state)
void test_parse_empty_synchronize_object_fails(UNUSED void **state)
void test_synchronization_respects_direction_2(UNUSED void **state)
void test_synchronization_can_set_readonly(UNUSED void **state)
void test_parse_sync_invalid_context_paths_fails(UNUSED void **state)
void test_can_parser_synchronize_definition_alternate(UNUSED void **state)
void test_create_sync_tree_fails_with_conflicting_directions(UNUSED void **state)
void test_parse_batch_parameter_with_cb_fails(UNUSED void **state)
static amxs_status_t apply_param(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED amxc_var_t *data, UNUSED void *priv)
static amxs_status_t translate_object(UNUSED const amxs_sync_entry_t *entry, UNUSED amxs_sync_direction_t direction, UNUSED const amxc_var_t *input, UNUSED amxc_var_t *output, UNUSED void *priv)