From bdf4e0b0ddd8d144676ddaf52c37d34a5f1adf21 Mon Sep 17 00:00:00 2001
From: Thomas Beutlich <modelica@tbeu.de>
Date: Sun, 27 Oct 2024 13:34:14 +0100
Subject: [PATCH] Add abstraction layer for external function of Streams.error

This avoids that Modelica utility function ModelicaError has to be provided by library ModelicaExternalC.
---
 .../Resources/C-Sources/ModelicaInternal.c    | 62 +++----------------
 .../Resources/C-Sources/ModelicaInternal.h    | 54 ++++++++++++++++
 Modelica/Utilities/Streams.mo                 |  2 +-
 3 files changed, 63 insertions(+), 55 deletions(-)

diff --git a/Modelica/Resources/C-Sources/ModelicaInternal.c b/Modelica/Resources/C-Sources/ModelicaInternal.c
index 701cc0d3ed..a77c6f4d7b 100644
--- a/Modelica/Resources/C-Sources/ModelicaInternal.c
+++ b/Modelica/Resources/C-Sources/ModelicaInternal.c
@@ -30,6 +30,9 @@
 */
 
 /* Changelog:
+      Oct. 27, 2024: by Thomas Beutlich
+                     Added ModelicaInternal_error (ticket #4496)
+
       Jan. 15, 2024: by Thomas Beutlich
                      Utilized ModelicaDuplicateString and
                      ModelicaDuplicateStringWithErrorReturn (ticket #3686)
@@ -144,61 +147,8 @@
 #define _GNU_SOURCE 1
 #endif
 
-#include "ModelicaInternal.h"
 #include "ModelicaUtilities.h"
-
-/*
-  ModelicaNotExistError never returns to the caller. In order to compile
-  external Modelica C-code in most compilers, noreturn attributes need to
-  be present to avoid warnings or errors.
-
-  The following macros handle noreturn attributes according to the
-  C11/C++11 standard with fallback to GNU, Clang or MSVC extensions if using
-  an older compiler.
-*/
-#undef MODELICA_NORETURN
-#undef MODELICA_NORETURNATTR
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
-#define MODELICA_NORETURN _Noreturn
-#define MODELICA_NORETURNATTR
-#elif defined(__cplusplus) && __cplusplus >= 201103L
-#if (defined(__GNUC__) && __GNUC__ >= 5) || \
-    (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 8)
-#define MODELICA_NORETURN [[noreturn]]
-#define MODELICA_NORETURNATTR
-#elif (defined(__GNUC__) && __GNUC__ >= 3) || \
-      (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 8)
-#define MODELICA_NORETURN
-#define MODELICA_NORETURNATTR __attribute__((noreturn))
-#elif defined(__GNUC__)
-#define MODELICA_NORETURN
-#define MODELICA_NORETURNATTR
-#else
-#define MODELICA_NORETURN [[noreturn]]
-#define MODELICA_NORETURNATTR
-#endif
-#elif defined(__clang__)
-/* Encapsulated for Clang since GCC fails to process __has_attribute */
-#if __has_attribute(noreturn)
-#define MODELICA_NORETURN
-#define MODELICA_NORETURNATTR __attribute__((noreturn))
-#else
-#define MODELICA_NORETURN
-#define MODELICA_NORETURNATTR
-#endif
-#elif (defined(__GNUC__) && __GNUC__ >= 3) || \
-      (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 8) || \
-      (defined(__SUNPRO_C) && __SUNPRO_C >= 0x5110)
-#define MODELICA_NORETURN
-#define MODELICA_NORETURNATTR __attribute__((noreturn))
-#elif (defined(_MSC_VER) && _MSC_VER >= 1200) || \
-       defined(__BORLANDC__)
-#define MODELICA_NORETURN __declspec(noreturn)
-#define MODELICA_NORETURNATTR
-#else
-#define MODELICA_NORETURN
-#define MODELICA_NORETURNATTR
-#endif
+#include "ModelicaInternal.h"
 
 MODELICA_NORETURN static void ModelicaNotExistError(const char* name) MODELICA_NORETURNATTR;
 static void ModelicaNotExistError(const char* name) {
@@ -209,6 +159,10 @@ static void ModelicaNotExistError(const char* name) {
         "as for dSPACE or xPC systems)", name);
 }
 
+void ModelicaInternal_error(_In_z_ const char* string) {
+    ModelicaError(string);
+}
+
 #undef MODELICA_NORETURN
 #undef MODELICA_NORETURNATTR
 
diff --git a/Modelica/Resources/C-Sources/ModelicaInternal.h b/Modelica/Resources/C-Sources/ModelicaInternal.h
index d81b354e08..2475fb632c 100644
--- a/Modelica/Resources/C-Sources/ModelicaInternal.h
+++ b/Modelica/Resources/C-Sources/ModelicaInternal.h
@@ -54,6 +54,59 @@
 #endif
 #endif
 
+/*
+  Some of the functions never return to the caller. In order to compile
+  external Modelica C-code in most compilers, noreturn attributes need to
+  be present to avoid warnings or errors.
+
+  The following macros handle noreturn attributes according to the
+  C11/C++11 standard with fallback to GNU, Clang or MSVC extensions if using
+  an older compiler.
+*/
+#undef MODELICA_NORETURN
+#undef MODELICA_NORETURNATTR
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#define MODELICA_NORETURN _Noreturn
+#define MODELICA_NORETURNATTR
+#elif defined(__cplusplus) && __cplusplus >= 201103L
+#if (defined(__GNUC__) && __GNUC__ >= 5) || \
+    (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+#define MODELICA_NORETURN [[noreturn]]
+#define MODELICA_NORETURNATTR
+#elif (defined(__GNUC__) && __GNUC__ >= 3) || \
+      (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+#define MODELICA_NORETURN
+#define MODELICA_NORETURNATTR __attribute__((noreturn))
+#elif defined(__GNUC__)
+#define MODELICA_NORETURN
+#define MODELICA_NORETURNATTR
+#else
+#define MODELICA_NORETURN [[noreturn]]
+#define MODELICA_NORETURNATTR
+#endif
+#elif defined(__clang__)
+/* Encapsulated for Clang since GCC fails to process __has_attribute */
+#if __has_attribute(noreturn)
+#define MODELICA_NORETURN
+#define MODELICA_NORETURNATTR __attribute__((noreturn))
+#else
+#define MODELICA_NORETURN
+#define MODELICA_NORETURNATTR
+#endif
+#elif (defined(__GNUC__) && __GNUC__ >= 3) || \
+      (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 8) || \
+      (defined(__SUNPRO_C) && __SUNPRO_C >= 0x5110)
+#define MODELICA_NORETURN
+#define MODELICA_NORETURNATTR __attribute__((noreturn))
+#elif (defined(_MSC_VER) && _MSC_VER >= 1200) || \
+       defined(__BORLANDC__)
+#define MODELICA_NORETURN __declspec(noreturn)
+#define MODELICA_NORETURNATTR
+#else
+#define MODELICA_NORETURN
+#define MODELICA_NORETURNATTR
+#endif
+
 /*
  * Non-null pointers and esp. null-terminated strings need to be passed to
  * external functions.
@@ -87,6 +140,7 @@
 #define _Ret_z_
 #endif
 
+MODELICA_EXPORT MODELICA_NORETURN void ModelicaInternal_error(_In_z_ const char* string) MODELICA_NORETURNATTR MODELICA_NONNULLATTR;
 MODELICA_EXPORT void ModelicaInternal_mkdir(_In_z_ const char* directoryName) MODELICA_NONNULLATTR;
 MODELICA_EXPORT void ModelicaInternal_rmdir(_In_z_ const char* directoryName) MODELICA_NONNULLATTR;
 MODELICA_EXPORT int ModelicaInternal_stat(_In_z_ const char* name) MODELICA_NONNULLATTR;
diff --git a/Modelica/Utilities/Streams.mo b/Modelica/Utilities/Streams.mo
index ceed866f44..1ac605c644 100644
--- a/Modelica/Utilities/Streams.mo
+++ b/Modelica/Utilities/Streams.mo
@@ -120,7 +120,7 @@ separated by LF or CR-LF.
   pure function error "Print error message and cancel all actions - in case of an unrecoverable error"
     extends Modelica.Icons.Function;
     input String string "String to be printed to error message window";
-    external "C" ModelicaError(string) annotation(Include="#include \"ModelicaUtilities.h\"", Library="ModelicaExternalC");
+    external "C" ModelicaInternal_error(string) annotation(IncludeDirectory="modelica://Modelica/Resources/C-Sources", Include="#include \"ModelicaInternal.h\"", Library="ModelicaExternalC");
     annotation (Documentation(info="<html>
 <h4>Syntax</h4>
 <blockquote><pre>