diff --git a/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp b/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp
index 20e7ec59..f3827ce5 100644
--- a/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp
+++ b/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp
@@ -28,6 +28,20 @@ TEST_CASE("Test parse terminals and icons") {
REQUIRE(xml != nullptr);
REQUIRE(fmi3_import_get_has_terminals_and_icons(xml) != 0);
+ SECTION("Testing graphicalRepresentation") {
+ // TODO: FMI2
+ // TODO
+ ;
+ SECTION("Testing coordinateSystem") {
+ // TODO:
+ ;
+ }
+ SECTION("Testing Icon") {
+ // TODO:
+ ;
+ }
+ }
+
SECTION("Testing getting terminal by name") {
fmi_import_terminal_t* term;
@@ -148,3 +162,67 @@ TEST_CASE("Test clearing of attribute buffer with invalid elements") {
REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3);
fmi3_testutil_import_free(tfmu);
}
+
+TEST_CASE("Empty graphical representation: Takes default") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/valid/empty_graphicalRepresentation";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ // TODO: Verify default coordinate system + scaling + no icon
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 0);
+ fmi3_testutil_import_free(tfmu);
+}
+
+TEST_CASE("Incomplete graphicaRepresentation->coordinateSystem: Takes default") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/incomplete_coordinateSystem";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'CoordinateSystem': required attribute 'x2' not found"));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'CoordinateSystem': required attribute 'y2' not found"));
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Failed to parse complete CoordinateSystem, using default system (-100, -100), (100, 100)."));
+
+ // TODO: Verify default coordinate system + no icon
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3);
+ fmi3_testutil_import_free(tfmu);
+}
+
+TEST_CASE("Not well-defined graphicaRepresentation->coordinateSystem") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/flipped_coordinateSystem";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "'CoordinateSystem' not well-defined, requires x1 = 100.000000 < x2 = -100.000000."));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "'CoordinateSystem' not well-defined, requires y1 = 100.000000 < y2 = -100.000000."));
+
+ // TODO: Verify coordinates are stored anyways
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 2);
+ fmi3_testutil_import_free(tfmu);
+}
+
+TEST_CASE("Incomplete graphicalRepresentation->Icon") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/incomplete_icon";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'Icon': required attribute 'x2' not found"));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'Icon': required attribute 'y2' not found"));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Failed to parse complete Icon."));
+
+ // TODO: Verify there is no icon
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3);
+ fmi3_testutil_import_free(tfmu);
+}
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..d58d0580
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..55ca3a4e
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..072bef7c
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml
index f14a6f37..1551ffeb 100644
--- a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..6ad178b9
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/XML/include/FMI/fmi_xml_terminals_and_icons.h b/src/XML/include/FMI/fmi_xml_terminals_and_icons.h
index 3d1f5ee7..99176e77 100644
--- a/src/XML/include/FMI/fmi_xml_terminals_and_icons.h
+++ b/src/XML/include/FMI/fmi_xml_terminals_and_icons.h
@@ -68,7 +68,22 @@ int fmi2_xml_terminals_and_icons_set_model_description(fmi_xml_terminals_and_ico
int fmi3_xml_terminals_and_icons_set_model_description(fmi_xml_terminals_and_icons_t* termIcon,
fmi3_xml_model_description_t* md);
+/* Top level */
int fmi_xml_get_has_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon);
+
+/* Graphical Representation */
+int fmi_xml_get_has_graphical_representation(fmi_xml_terminals_and_icons_t* termIcon);
+/* coordinateSystem*/
+int fmi_xml_get_graphical_representation_system_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2);
+int fmi_xml_get_graphical_representation_suggested_scaling(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* suggested_scaling);
+/* icon */
+int fmi_xml_get_graphical_representation_has_icon(fmi_xml_graphicalRepresentation_t* graphRepr);
+int fmi_xml_get_graphical_representation_icon_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2);
+
+/* Terminals */
fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name);
const char* fmi_xml_get_terminal_name(fmi_xml_terminal_t* term);
diff --git a/src/XML/src/FMI/fmi_xml_terminals_and_icons.c b/src/XML/src/FMI/fmi_xml_terminals_and_icons.c
index f910538f..959311e1 100644
--- a/src/XML/src/FMI/fmi_xml_terminals_and_icons.c
+++ b/src/XML/src/FMI/fmi_xml_terminals_and_icons.c
@@ -189,13 +189,26 @@ int fmi_xml_handle_CoordinateSystem(fmi3_xml_parser_context_t* context, const ch
ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(coordSys->y2), 100);
ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
- FMI_ATTR_TERMICON(fmi_termIcon_attr_id_suggestedScalingFactorTo_mm), 1, &(coordSys->suggestedScalingFactorTo_mm), 100);
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_suggestedScalingFactorTo_mm), 1, &(coordSys->suggestedScalingFactorTo_mm), 0.1);
if (ret) {
- // TODO: Log; clearly state that full coordinate system is discarded and default is taken instead?
+ fmi3_xml_parse_error(context, "Failed to parse complete CoordinateSystem, using default system (-100, -100), (100, 100).");
+ coordSys->x1 = -100;
+ coordSys->y1 = -100;
+ coordSys->x2 = 100;
+ coordSys->y2 = 100;
+ coordSys->suggestedScalingFactorTo_mm = 0.1;
return 1;
}
} else {
- // TODO: Error check; warning is
+ /* SPEC: [...] where the coordinates of the first point shall be less than the coordinates of the second point. */
+ if (coordSys->x1 >= coordSys->x2) {
+ fmi3_xml_parse_warning(context, "'CoordinateSystem' not well-defined, requires x1 = %f < x2 = %f.",
+ coordSys->x1, coordSys->x2);
+ }
+ if (coordSys->y1 >= coordSys->y2) {
+ fmi3_xml_parse_warning(context, "'CoordinateSystem' not well-defined, requires y1 = %f < y2 = %f.",
+ coordSys->y1, coordSys->y2);
+ }
}
return 0;
}
@@ -205,24 +218,26 @@ int fmi_xml_handle_Icon(fmi3_xml_parser_context_t* context, const char* data) {
fmi_xml_graphicalRepresentation_t* graphRepr = termIcon->graphicalRepresentation;
if (!data) {
int ret;
- graphRepr->icon = (fmi_xml_icon_t*)context->callbacks->calloc(1, sizeof(fmi_xml_icon_t));
- if (!(graphRepr->icon)) {
+ fmi_xml_icon_t* icon = (fmi_xml_icon_t*)context->callbacks->calloc(1, sizeof(fmi_xml_icon_t));
+ if (!icon) {
fmi3_xml_parse_fatal(context, "Could not allocate memory");
return 1;
}
ret = 0;
ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
- FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x1), 1, &(graphRepr->icon->x1), 0);
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x1), 1, &(icon->x1), 0);
ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
- FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y1), 1, &(graphRepr->icon->y1), 0);
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y1), 1, &(icon->y1), 0);
ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
- FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x2), 1, &(graphRepr->icon->x2), 0);
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x2), 1, &(icon->x2), 0);
ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
- FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(graphRepr->icon->y2), 0);
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(icon->y2), 0);
if (ret) {
- // TODO: Error message?
+ fmi3_xml_parse_error(context, "Failed to parse complete Icon.");
+ context->callbacks->free(icon); // Discard element
return 1;
}
+ graphRepr->icon = icon;
} else {
;
}
@@ -327,17 +342,69 @@ int fmi_xml_handle_TerminalGraphicalRepresentation(fmi3_xml_parser_context_t* co
return 0;
}
+
+/* Top level*/
int fmi_xml_get_has_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon) {
return termIcon ? 1 : 0;
}
-fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name){
- if (!name) return NULL;
+/* Graphical Representation */
+int fmi_xml_get_has_graphical_representation(fmi_xml_terminals_and_icons_t* termIcon) {
+ if (!termIcon) {
+ return 0;
+ }
+ return termIcon->graphicalRepresentation ? 1 : 0;
+}
+
+int fmi_xml_get_graphical_representation_system_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2) {
+ if (!graphRepr || (!graphRepr->coordinateSystem)) {
+ return 1;
+ }
+ *x1 = graphRepr->coordinateSystem->x1;
+ *y1 = graphRepr->coordinateSystem->y1;
+ *x2 = graphRepr->coordinateSystem->x2;
+ *y2 = graphRepr->coordinateSystem->y2;
+ return 0;
+}
+
+int fmi_xml_get_graphical_representation_suggested_scaling(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* suggested_scaling) {
+ if (!graphRepr || (!graphRepr->coordinateSystem)) {
+ return 1;
+ }
+ *suggested_scaling = graphRepr->coordinateSystem->suggestedScalingFactorTo_mm;
+ return 0;
+}
+
+int fmi_xml_get_graphical_representation_has_icon(fmi_xml_graphicalRepresentation_t* graphRepr) {
+ if (!graphRepr) {
+ return 0;
+ }
+ return graphRepr->icon ? 1 : 0;
+}
+
+int fmi_xml_get_graphical_representation_icon_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2) {
+ if (!graphRepr || (!graphRepr->icon)) {
+ return 1;
+ }
+ *x1 = graphRepr->icon->x1;
+ *y1 = graphRepr->icon->y1;
+ *x2 = graphRepr->icon->x2;
+ *y2 = graphRepr->icon->y2;
+ return 0;
+}
+
+/* Terminals*/
+fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name) {
+ if (!name) {
+ return NULL;
+ }
jm_named_ptr key, *found;
key.name = name;
found = jm_vector_bsearch(jm_named_ptr)(&termIcon->terminalsByName, &key, jm_compare_named);
- if (!found) return NULL;
- return found->ptr;
+ return found ? found->ptr : NULL;
}
const char* fmi_xml_get_terminal_name(fmi_xml_terminal_t* term) {
diff --git a/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h b/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h
index c06bd58a..53de2482 100644
--- a/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h
+++ b/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h
@@ -48,18 +48,12 @@ struct fmi_xml_graphicalRepresentation_t {
};
struct fmi_xml_coordinateSystem_t {
- double x1;
- double y1;
- double x2;
- double y2;
+ double x1, y1, x2, y2;
double suggestedScalingFactorTo_mm;
};
struct fmi_xml_icon_t {
- double x1;
- double y1;
- double x2;
- double y2;
+ double x1, y1, x2, y2;
};
struct fmi_xml_terminal_t {