diff --git a/cmake/sspschemafiles.cmake b/cmake/sspschemafiles.cmake index 30b54b2..19b92f7 100644 --- a/cmake/sspschemafiles.cmake +++ b/cmake/sspschemafiles.cmake @@ -41,6 +41,8 @@ set(OUT_DIR "${INCLUDE_DIR}/reader/ssp/schema") add_library(ssp_headers INTERFACE) +find_package(Python3 REQUIRED) + # process schema files file(GLOB_RECURSE SCHEMA_FILES "${SSP_ROOT}/*.xsd") foreach(SCHEMA_FILE ${SCHEMA_FILES}) @@ -61,7 +63,7 @@ foreach(SCHEMA_FILE ${SCHEMA_FILES}) add_custom_command( OUTPUT "${OUT_DIR}/${SUB_DIR}/${SCHEMA_FILE_NAME}.h" - COMMAND python "${PYTHON_SCRIPT}" "${SCHEMA_FILE}" -o "${OUT_DIR}/${SUB_DIR}" -p "${SUB_DIR}" + COMMAND "${Python3_EXECUTABLE}" "${PYTHON_SCRIPT}" "${SCHEMA_FILE}" -o "${OUT_DIR}/${SUB_DIR}" -p "${SUB_DIR}" DEPENDS "${SCHEMA_FILE}" COMMENT "${CMD_COMMENT}") @@ -77,7 +79,7 @@ foreach(SCHEMA_FILE ${SCHEMA_FILES}) add_custom_command( OUTPUT "${OUT_DIR}/${SCHEMA_FILE_NAME}.h" - COMMAND python "${PYTHON_SCRIPT}" "${SCHEMA_FILE}" -o "${OUT_DIR}" + COMMAND "${Python3_EXECUTABLE}" "${PYTHON_SCRIPT}" "${SCHEMA_FILE}" -o "${OUT_DIR}" DEPENDS "${SCHEMA_FILE}" COMMENT "${CMD_COMMENT}") diff --git a/libs/util/include/util/os.h b/libs/util/include/util/os.h index b192042..41972da 100644 --- a/libs/util/include/util/os.h +++ b/libs/util/include/util/os.h @@ -40,11 +40,11 @@ McxStatus mcx_os_set_env_var(const char * name, const char * value); * %VAR%, $(VAR) or ${VAR} in path with their respective values and * returns the result. */ -char * mcx_resolve_env_var(char * path); +char * mcx_resolve_env_var(const char * path); -int mcx_parse_win_env_var(char * path, char ** res); -int mcx_parse_linux_par_env_var(char * path, char ** res); -int mcx_parse_linux_bra_env_var(char * path, char ** res); +int mcx_parse_win_env_var(const char * path, char ** res); +int mcx_parse_linux_par_env_var(const char * path, char ** res); +int mcx_parse_linux_bra_env_var(const char * path, char ** res); /** * Get string description of errno. diff --git a/libs/util/include/util/paths.h b/libs/util/include/util/paths.h index dff145f..0c89137 100644 --- a/libs/util/include/util/paths.h +++ b/libs/util/include/util/paths.h @@ -40,6 +40,8 @@ extern "C" { char * mcx_path_dir_name(const char * path); char * mcx_path_file_name(const char * path); +void mcx_path_strip_ext(char * path); + char * mcx_path_get_absolute(const char * path); int mcx_path_is_absolute(const char * path); diff --git a/libs/util/include/util/string.h b/libs/util/include/util/string.h index 44bd74a..9d8c4f0 100644 --- a/libs/util/include/util/string.h +++ b/libs/util/include/util/string.h @@ -19,8 +19,11 @@ extern "C" { char * mcx_string_dup(const char * s); +char * mcx_string_decode(const char * str, char _escape_char); char * mcx_string_encode(const char * str, char _escape_char, const char _chars_to_escape[]); +char* mcx_string_encode_special_characters_except_hash(const char* str); char * mcx_string_encode_filename(const char * str); +char * mcx_string_encode_filename_result_files(const char* str); wchar_t * mcx_string_to_widechar(const char * str); char * mcx_string_to_utf8(const wchar_t * wstr); @@ -38,6 +41,7 @@ char * mcx_string_merge_array_with_spaces(char * args[]); char * mcx_string_merge_quoted_array_with_spaces(char * strs[]); char* mcx_string_sep(char** stringp, const char* delim); +void mcx_string_replace_char(char * str, char searched_char, char replacement_char); #ifdef __cplusplus } /* closing brace for extern "C" */ diff --git a/libs/util/src/common/os.c b/libs/util/src/common/os.c index 035aedc..f0db6d6 100644 --- a/libs/util/src/common/os.c +++ b/libs/util/src/common/os.c @@ -13,6 +13,7 @@ #include #include "common/memory.h" +#include "common/logging.h" #include "util/os.h" #include "util/paths.h" @@ -84,7 +85,7 @@ int mcx_os_fprintf(FILE *stream, const char *format, ...) { return ret; } -int mcx_parse_win_env_var(char * path, char ** res) { +int mcx_parse_win_env_var(const char * path, char ** res) { size_t i = 0; *res = NULL; @@ -119,7 +120,7 @@ int mcx_parse_win_env_var(char * path, char ** res) { return (int)i; } -static int input_parse_linux_env_var(char * path, char ** res, char open, char close) { +static int input_parse_linux_env_var(const char * path, char ** res, char open, char close) { size_t i = 0; *res = NULL; @@ -160,11 +161,11 @@ static int input_parse_linux_env_var(char * path, char ** res, char open, char c return (int)i; } -int mcx_parse_linux_par_env_var(char * path, char ** res) { +int mcx_parse_linux_par_env_var(const char * path, char ** res) { return input_parse_linux_env_var(path, res, '(', ')'); } -int mcx_parse_linux_bra_env_var(char * path, char ** res) { +int mcx_parse_linux_bra_env_var(const char * path, char ** res) { return input_parse_linux_env_var(path, res, '{', '}'); } @@ -183,7 +184,7 @@ int mcx_parse_linux_bra_env_var(char * path, char ** res) { * If path does not start with an environment variable, *res is set to * NULL and 0 is returned. */ -static int mcx_parse_env_var(char * path, char ** res) { +static int mcx_parse_env_var(const char * path, char ** res) { int num; if (num = mcx_parse_win_env_var(path, res)) { @@ -200,7 +201,7 @@ static int mcx_parse_env_var(char * path, char ** res) { return 0; } -static int mcx_parse_escaped_env_delimiter_win(char * path) { +static int mcx_parse_escaped_env_delimiter_win(const char * path) { if (strlen(path) > 1 && path[0] == '%' && path[1] == '%') { return (int)'%'; } else { @@ -208,7 +209,7 @@ static int mcx_parse_escaped_env_delimiter_win(char * path) { } } -static int mcx_parse_escaped_env_delimiter_linux(char * path) { +static int mcx_parse_escaped_env_delimiter_linux(const char * path) { if (strlen(path) > 1 && path[0] == '$' && path[1] == '$') { return (int)'$'; } else { @@ -216,7 +217,7 @@ static int mcx_parse_escaped_env_delimiter_linux(char * path) { } } -static int mcx_parse_escaped_env_delimiter(char * path) { +static int mcx_parse_escaped_env_delimiter(const char * path) { int num; if (num = mcx_parse_escaped_env_delimiter_win(path)) { @@ -229,7 +230,7 @@ static int mcx_parse_escaped_env_delimiter(char * path) { return 0; } -char * mcx_resolve_env_var(char * path) { +char * mcx_resolve_env_var(const char * path) { int i = 0; int resolved_len = 1; // for '\0' @@ -239,9 +240,9 @@ char * mcx_resolve_env_var(char * path) { } while (path[i]) { - char * name; - char quote; - int num; + char * name = NULL; + char quote = 0; + int num = 0; // skip over chars until we find a variable or a quote while (path[i] && @@ -281,9 +282,7 @@ char * mcx_resolve_env_var(char * path) { // copy env-var value if (name) { - char * value; - - value = mcx_os_get_env_var(name); + char * value = mcx_os_get_env_var(name); if (value) { resolved_len += (int)strlen(value); resolved = mcx_realloc(resolved, resolved_len); @@ -296,6 +295,20 @@ char * mcx_resolve_env_var(char * path) { strcat(resolved, value); mcx_free(value); + + if (path[i] == '%') { + mcx_log(LOG_WARNING, "Defining environment variables via '%%env_var%%' (%s) is deprecated. Please switch to the '${env_var}' construct instead", path); + } + } else { + resolved_len += num; + resolved = mcx_realloc(resolved, resolved_len); + if (!resolved) { + mcx_free(name); + return NULL; + } + + strncat(resolved, path + i, num); + resolved[resolved_len - 1] = '\0'; } mcx_free(name); diff --git a/libs/util/src/common/paths.c b/libs/util/src/common/paths.c index 83d2dd7..bbb9207 100644 --- a/libs/util/src/common/paths.c +++ b/libs/util/src/common/paths.c @@ -17,6 +17,9 @@ #include "util/paths.h" +#define LOCATION_PREFIX "file://" + + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -60,6 +63,14 @@ char * mcx_path_file_name(const char * path) { return dir; } +void mcx_path_strip_ext(char * path) { + char * dot = strrchr(path, '.'); + + if (dot) { + *dot = '\0'; + } +} + char ** mcx_path_split(char * path) { size_t partsNum = 0; size_t pos = 0; @@ -247,60 +258,6 @@ char * mcx_path_get_relative(const char * fileName, const char * path) { return mergedPath; } -char * mcx_path_from_uri(const char * uri) { - char * buffer = NULL; - size_t i = 0; - size_t j = 0; -#if defined (OS_WINDOWS) - /* use of PathCreateFromUrl was considered, dismissed because of - needed effort */ -#define LOCATION_PREFIX "file:///" -#define LOCATION_PREFIX_2SLASHES "file://" - if (0 == strncmp(uri, LOCATION_PREFIX, strlen(LOCATION_PREFIX))) { - uri += strlen(LOCATION_PREFIX); - } else if (0 == strncmp(uri, LOCATION_PREFIX_2SLASHES, strlen(LOCATION_PREFIX_2SLASHES))) { - uri += strlen(LOCATION_PREFIX_2SLASHES); - } -#else -#define LOCATION_PREFIX "file://" - /* check if this is file uri */ - if (strncmp(uri, LOCATION_PREFIX, strlen(LOCATION_PREFIX))) { - /* not a file uri */ - return NULL; - } - - /* check if uri has authority component */ - if (uri[strlen(LOCATION_PREFIX)] == '/') { - /* no authority component */ - uri += strlen(LOCATION_PREFIX); - } else { - /* skip over authority component */ - uri += strlen(LOCATION_PREFIX); - while (*uri != '\0' && *uri != '/') { - uri++; - } - } -#endif /* OS_WINDOWS */ - buffer = (char *)mcx_calloc(strlen(uri) + 1, sizeof(char)); - if (!buffer) { return NULL; } - - /* convert escaped characters back */ - while (uri[i]) { - if (uri[i] == '%') { - char str[3] = {uri[i+1], uri[i+2], 0}; - buffer[j] = (char) strtol(str, NULL, 16); - i += 3; - j += 1; - } else { - buffer[j] = uri[i]; - i += 1; - j += 1; - } - } - buffer[j] = '\0'; - - return buffer; -} char * mcx_path_to_uri(const char * path) { char * uri = NULL; diff --git a/libs/util/src/common/string.c b/libs/util/src/common/string.c index 64d27bc..87132a9 100644 --- a/libs/util/src/common/string.c +++ b/libs/util/src/common/string.c @@ -11,8 +11,10 @@ #include #include #include +#include #include "common/memory.h" +#include "common/logging.h" #include "util/string.h" @@ -44,6 +46,37 @@ static int mcx_string_contains_char(const char * str, char c) { return 0; } +char * mcx_string_decode(const char * str, char _escape_char) { + int i = 0; + int j = 0; + char * buffer = NULL; + + buffer = (char *) mcx_calloc(strlen(str) + 1, sizeof(char)); + if (!buffer) { + return NULL; + } + + while (str[i]) { + if (str[i] == _escape_char) { + if (!str[i+1] || !str[i+2]) { + mcx_log(LOG_ERROR, "Invalid escape sequence encountered in string: %s", str); + return NULL; + } + char escape_sequence[3] = {str[i+1], str[i+2], 0}; + buffer[j] = (char) strtol(escape_sequence, NULL, 16); + i += 3; + j += 1; + } else { + buffer[j] = str[i]; + i += 1; + j += 1; + } + } + buffer[j] = '\0'; + + return buffer; +} + char * mcx_string_encode(const char * str, char _escape_char, const char _chars_to_escape[]) { size_t len = strlen(str); size_t num = 0; @@ -78,6 +111,17 @@ char * mcx_string_encode_filename(const char * str) { return mcx_string_encode(str, '%', "\\\"<>|!#$&'()*+,/:;=?@[]%"); } +char* mcx_string_encode_special_characters_except_hash(const char* str) { + return mcx_string_encode(str, '%', "\\\"<>|!$&'()*+,/:;=?@[]%._`*{}"); +} + +char* mcx_string_encode_filename_result_files(const char* str) { + char* str_encoded = mcx_string_encode_special_characters_except_hash(str); + mcx_string_replace_char(str_encoded, ' ', '_'); + mcx_string_replace_char(str_encoded, '#', '.'); + return str_encoded; +} + int mcx_string_ends_with(const char * str, const char * suffix) { if ( *str ) { char * pos = strstr(str, suffix); @@ -243,6 +287,18 @@ char* mcx_string_sep(char** stringp, const char* delim) return start; } +void mcx_string_replace_char(char* str, char searched_char, char replacement_char) { + size_t len = strlen(str); + size_t i = 0; + + for (i = 0; i < len; i++) { + if (searched_char == str[i]) { + str[i] = replacement_char; + } + } +} + + #ifdef __cplusplus } /* closing brace for extern "C" */ #endif /* __cplusplus */ \ No newline at end of file diff --git a/libs/util/src/linux/paths.c b/libs/util/src/linux/paths.c index 107728b..679d386 100644 --- a/libs/util/src/linux/paths.c +++ b/libs/util/src/linux/paths.c @@ -12,12 +12,16 @@ #include #include "common/memory.h" +#include "common/logging.h" #include "util/os.h" #include "util/paths.h" #include "util/string.h" +#define LOCATION_PREFIX "file://" + + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -49,6 +53,35 @@ int mcx_path_is_absolute(const char * path) { return 0; } +char * mcx_path_from_uri(const char * uri) { + char * buffer = NULL; + + /* check if this is file uri */ + if (strncmp(uri, LOCATION_PREFIX, strlen(LOCATION_PREFIX))) { + /* not a file uri */ + return NULL; + } + + /* check if uri has authority component */ + if (uri[strlen(LOCATION_PREFIX)] == '/') { + /* no authority component */ + uri += strlen(LOCATION_PREFIX); + } else { + /* skip over authority component */ + uri += strlen(LOCATION_PREFIX); + while (*uri != '\0' && *uri != '/') { + uri++; + } + } + + buffer = mcx_string_decode(uri, '%'); + if (buffer == NULL) { + mcx_log(LOG_ERROR, "Cannot URL decode string"); + return NULL; + } + + return buffer; +} #ifdef __cplusplus } /* closing brace for extern "C" */ diff --git a/libs/util/src/win/libs.c b/libs/util/src/win/libs.c index 7f6bc34..f03df8b 100644 --- a/libs/util/src/win/libs.c +++ b/libs/util/src/win/libs.c @@ -10,6 +10,7 @@ #define _WINSOCKAPI_ // stops windows.h including winsock.h #include +#undef OS_WINDOWS // gets redefinied in shlwapi.h #include #include "common/logging.h" @@ -19,6 +20,10 @@ #include "util/string.h" +#define LONG_PATH_PREFIX L"\\\\?\\" +#define LONG_UNC_PATH_PREFIX L"\\\\?\\UNC\\" + + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -49,41 +54,171 @@ static void print_last_error() { } -McxStatus mcx_dll_load(DllHandle * handle, const char * dllPath) { - DllHandleCheck compValue; +static wchar_t * normalize_unc_path(const wchar_t * src) { + if (!src) { + return NULL; + } - wchar_t * wDllPath = mcx_string_to_widechar(dllPath); + if (*src != L'\\' || *(src + 1) != L'\\') { + return NULL; // not an UNC path + } - McxStatus retVal = RETURN_OK; + wchar_t * norm_path = (wchar_t *) mcx_calloc(wcslen(src) + 1, sizeof(wchar_t)); + if (!norm_path) { + return NULL; + } + + wcscpy(norm_path, src); + + // replace forward slashes with backward slashes + { + wchar_t * proc = norm_path; + while (*proc) { + if (*proc == L'/') { + *proc = L'\\'; + } + + proc++; + } + } - if (PathIsRelativeW(wDllPath)) { - wchar_t * wFullDllPath = NULL; - DWORD length = GetFullPathNameW(wDllPath, 0, NULL, NULL); + // remove duplicate backslashes (except the starting one) + { + wchar_t * proc = norm_path + 2; + while (*proc) { + if (*proc == L'\\' && *(proc + 1) == L'\\') { + wcscpy(proc, proc + 1); + continue; + } + + proc++; + } + } + + // resolve '.' and '..' + { + wchar_t * dest = norm_path; + wchar_t * path_segment = dest; + + wchar_t * proc = wcsstr(path_segment, L"\\."); + while (proc) { + if (proc[2] == '.' && (proc[3] == L'\\' || proc[3] == L'\0')) { + // parent folder -> revert 1 path segment + wcsncpy(dest, path_segment, proc - path_segment); + dest += proc - path_segment; + if (dest - 1 >= norm_path) { + while (*dest != L'\\') + dest--; + } + path_segment = proc + 3; + } else if (proc[2] == L'\\' || proc[2] == L'\0') { + // current folder -> ignore path segment + wcsncpy(dest, path_segment, proc - path_segment); + dest += proc - path_segment; + path_segment = proc + 2; + } + + proc = wcsstr(path_segment, L"\\."); + } + + wcscpy(dest, path_segment); + } + + return norm_path; +} + + +static McxStatus adapt_long_path(const wchar_t * path, wchar_t ** adapted_path) { + *adapted_path = NULL; + + if (wcslen(path) < (MAX_PATH - 12)) { + return RETURN_OK; + } + + if (wcslen(path) >= 2 && path[0] == L'\\' && path[1] == L'\\') { + // UNC path + wchar_t * norm_path = normalize_unc_path(path); + if (!norm_path) { + mcx_log(LOG_ERROR, "Util: UNC path normalization failed"); + return RETURN_ERROR; + } + + wchar_t * prefixed_norm_path = (wchar_t *) mcx_calloc(wcslen(LONG_UNC_PATH_PREFIX) + wcslen(norm_path) + 1, sizeof(wchar_t)); + if (!prefixed_norm_path) { + mcx_log(LOG_ERROR, "Util: Extending UNC path failed"); + mcx_free(norm_path); + return RETURN_ERROR; + } + + wcscpy(prefixed_norm_path, LONG_UNC_PATH_PREFIX); + wcscat(prefixed_norm_path, norm_path); + + mcx_free(norm_path); + + *adapted_path = prefixed_norm_path; + } else { + wchar_t * full_path = NULL; + DWORD length = GetFullPathNameW(path, 0, NULL, NULL); if (length == 0) { - mcx_log(LOG_ERROR, "Util: Error retrieving length of absolute path of Dll (%s)", dllPath); + mcx_log(LOG_ERROR, "Util: Retrieving absolute path length failed"); print_last_error(); - retVal = RETURN_ERROR; - goto relpath_cleanup; + return RETURN_ERROR; + } + + full_path = (wchar_t *) mcx_malloc(sizeof(wchar_t) * length); + if (!full_path) { + mcx_log(LOG_ERROR, "Util: Absolute path memory allocation failed"); + return RETURN_ERROR; } - wFullDllPath = (wchar_t *) mcx_malloc(sizeof(wchar_t) * length); - length = GetFullPathNameW(wDllPath, length, wFullDllPath, NULL); + + length = GetFullPathNameW(path, length, full_path, NULL); if (length == 0) { - mcx_log(LOG_ERROR, "Util: Error creating absolute path for Dll (%s)", dllPath); + mcx_log(LOG_ERROR, "Util: Absolute path creation failed"); print_last_error(); - retVal = RETURN_ERROR; - goto relpath_cleanup; + return RETURN_ERROR; } -relpath_cleanup: - if (wDllPath) { - mcx_free(wDllPath); - } - if (retVal != RETURN_OK) { - goto cleanup; + + wchar_t * prefixed_norm_path = (wchar_t *) mcx_calloc(wcslen(LONG_PATH_PREFIX) + wcslen(full_path) + 1, sizeof(wchar_t)); + if (!prefixed_norm_path) { + mcx_log(LOG_ERROR, "Util: Extending absolute path failed"); + mcx_free(full_path); + return RETURN_ERROR; } - wDllPath = wFullDllPath; + + wcscpy(prefixed_norm_path, LONG_PATH_PREFIX); + wcscat(prefixed_norm_path, full_path); + + mcx_free(full_path); + + *adapted_path = prefixed_norm_path; + } + + return RETURN_OK; +} + + +McxStatus mcx_dll_load(DllHandle * handle, const char * dllPath) { + DllHandleCheck compValue; + + wchar_t * wDllPath = mcx_string_to_widechar(dllPath); + wchar_t * wNormDllPath = NULL; + + McxStatus retVal = RETURN_OK; + + mcx_log(LOG_DEBUG, "Util: Loading dll: %ls", wDllPath); + + retVal = adapt_long_path(wDllPath, &wNormDllPath); + if (RETURN_ERROR == retVal) { + mcx_log(LOG_ERROR, "Util: Adapting dll path failed"); + goto cleanup; + } + + if (wNormDllPath) { + mcx_free(wDllPath); + wDllPath = wNormDllPath; } - mcx_log(LOG_DEBUG, "Util: Loading Dll %S", wDllPath); + mcx_log(LOG_DEBUG, "Util: Adapted dll path: %ls", wDllPath); * handle = LoadLibraryExW(wDllPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); diff --git a/libs/util/src/win/paths.c b/libs/util/src/win/paths.c index 9c881d0..d80f586 100644 --- a/libs/util/src/win/paths.c +++ b/libs/util/src/win/paths.c @@ -11,7 +11,11 @@ #define _WINSOCKAPI_ // stops windows.h including winsock.h #include +#undef OS_WINDOWS // gets redefined in Shlwapi.h +#include + #include "common/memory.h" +#include "common/logging.h" #include "util/paths.h" #include "util/string.h" @@ -65,6 +69,35 @@ int mcx_path_is_absolute(const char * path) { return 0; } +char * mcx_path_from_uri(const char * uri) { + wchar_t * wchar_uri = NULL; + wchar_t wchar_path[4096] = { 0 }; + DWORD buffer_len = sizeof(wchar_path) / sizeof(wchar_path[0]); + char * path = NULL; + HRESULT hres = S_OK; + + wchar_uri = mcx_string_to_widechar(uri); + if (wchar_uri == NULL) { + mcx_log(LOG_ERROR, "Cannot convert UTF-8 string to wide string"); + return NULL; + } + + hres = PathCreateFromUrlW(wchar_uri, wchar_path, &buffer_len, 0); + mcx_free(wchar_uri); + if (hres != S_OK) { + mcx_log(LOG_ERROR, "PathCreateFromUrlW returned with HRESULT error: %d", hres); + return NULL; + } + + path = mcx_string_to_utf8(wchar_path); + if (path == NULL) { + mcx_log(LOG_ERROR, "Cannot convert wide string to UTF-8"); + return NULL; + } + + return path; +} + #ifdef __cplusplus } /* closing brace for extern "C" */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5808f1e..b123ead 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,3 +99,7 @@ if(UNIX) set_target_properties(mcx_common PROPERTIES LINK_OPTIONS -Wl,--exclude-libs,ALL) endif() +if(MSVC) + target_link_options(mcx_common PUBLIC /ignore:4099) # disable LNK4099: "PDB 'XYZ.pdb' was not found with 'XYZ.lib'" warning +endif() + diff --git a/src/components/comp_fmu.c b/src/components/comp_fmu.c index 8b8cfff..f495b1b 100644 --- a/src/components/comp_fmu.c +++ b/src/components/comp_fmu.c @@ -1167,6 +1167,9 @@ static void CompFMUDestructor(CompFMU * compFmu) { Fmu2CommonStruct * fmu2 = & compFmu->fmu2; FmuCommon * common = & compFmu->common; + Component * comp = (Component *) compFmu; + mcx_signal_handler_set_name(comp->GetName(comp)); + // TOOD: Move this to the common struct destructors if (fmu1->fmiImport) { if (fmi1_true == fmu1->runOk) { @@ -1200,6 +1203,8 @@ static void CompFMUDestructor(CompFMU * compFmu) { Fmu2CommonStructDestructor(fmu2); FmuCommonDestructor(common); + + mcx_signal_handler_unset_name(); } static Component * CompFMUCreate(Component * comp) { diff --git a/src/core/Component.c b/src/core/Component.c index 305fee5..2cbbdd9 100644 --- a/src/core/Component.c +++ b/src/core/Component.c @@ -458,6 +458,18 @@ McxStatus ComponentExitInitializationMode(Component * comp) { return RETURN_OK; } +McxStatus ComponentEnterEventMode(Component * comp) { + return RETURN_OK; +} + +McxStatus ComponentExitEventMode(Component * comp) { + return RETURN_OK; +} + +int ComponentInEventMode(Component * comp) { + return FALSE; +} + static McxStatus ComponentUpdateInitialOutChannels(Component * comp) { return RETURN_OK; } @@ -878,6 +890,14 @@ static int ComponentHasOwnTime(const Component * comp) { return comp->data->hasOwnTime; } +static void ComponentSetIsShadowComponent(Component * comp) { + comp->data->isShadowComponent = 1; +} + +static int ComponentIsShadowComponent(const Component * comp) { + return comp->data->isShadowComponent; +} + static void ComponentSetHasOwnTime(Component * comp) { comp->data->hasOwnTime = 1; } @@ -1200,6 +1220,10 @@ static Component * ComponentCreate(Component * comp) { comp->UpdateOutChannels = NULL; comp->UpdateInChannels = NULL; + comp->EnterEventMode = ComponentEnterEventMode; + comp->InEventMode = ComponentInEventMode; + comp->ExitEventMode = ComponentExitEventMode; + comp->RegisterStorage = ComponentRegisterStorage; comp->GetStorage = ComponentGetStorage; comp->Store = ComponentStore; @@ -1232,6 +1256,9 @@ static Component * ComponentCreate(Component * comp) { comp->HasOwnTime = ComponentHasOwnTime; comp->SetHasOwnTime = ComponentSetHasOwnTime; + comp->IsShadowComponent = ComponentIsShadowComponent; + comp->SetIsShadowComponent = ComponentSetIsShadowComponent; + comp->GetFinishState = ComponentGetFinishState; comp->SetIsFinished = ComponentSetIsFinished; @@ -1441,6 +1468,8 @@ static ComponentData * ComponentDataCreate(ComponentData * data) { data->input = NULL; + data->isShadowComponent = 0; + rtData = &data->rtData; rtData->defined = FALSE; rtData->enabled = FALSE; diff --git a/src/core/Component.h b/src/core/Component.h index 997d330..402ef0a 100644 --- a/src/core/Component.h +++ b/src/core/Component.h @@ -48,6 +48,10 @@ typedef McxStatus (* fComponentExitInitializationMode)(Component * comp); typedef McxStatus (* fComponentUpdateInitialOutChannels)(Component * comp); typedef McxStatus (* fComponentUpdateOutChannels)(Component * comp); +typedef McxStatus (*fComponentEnterEventMode)(Component * comp); +typedef McxStatus (*fComponentExitEventMode)(Component * comp); +typedef int (*fComponentInEventMode)(Component * comp); + typedef McxStatus (* fComponentUpdateInChannels)(Component * comp); typedef int (* fComponentContainsComponent)(Component * comp, const Component * otherComp); @@ -71,6 +75,9 @@ typedef int (* fComponentHasOwnTime)(const Component * comp); typedef void(* fComponentSetHasOwnTime)(Component * comp); typedef void (* fComponentUpdateTime)(Component * comp); +typedef int (* fComponentIsShadowComponent)(const Component * comp); +typedef void (*fComponentSetIsShadowComponent)(Component * comp); + typedef int (* fComponentOneOutputOneGroup)(Component * comp); typedef ComponentFinishState (* fComponentGetFinishState)(const Component * comp); @@ -125,6 +132,10 @@ struct Component { fComponentInitialize Initialize; fComponentExitInitializationMode ExitInitializationMode; + fComponentEnterEventMode EnterEventMode; + fComponentExitEventMode ExitEventMode; + fComponentInEventMode InEventMode; + /** * Updates the initial values of the output channels depending on the * internal parameters and the input channels. @@ -185,6 +196,9 @@ struct Component { fComponentSetHasOwnTime SetHasOwnTime; + fComponentIsShadowComponent IsShadowComponent; + fComponentSetIsShadowComponent SetIsShadowComponent; + fComponentPredicate IsPartOfInitCalculation; fComponentSetIsPartOfInitCalculation SetIsPartOfInitCalculation; diff --git a/src/core/Component_impl.h b/src/core/Component_impl.h index 4eb5098..8225054 100644 --- a/src/core/Component_impl.h +++ b/src/core/Component_impl.h @@ -147,6 +147,9 @@ struct ComponentData { struct ComponentStorage * storage; ComponentInput * input; + + int isShadowComponent; + }; #ifdef __cplusplus diff --git a/src/core/Conversion.c b/src/core/Conversion.c index cb1677d..17f76b1 100644 --- a/src/core/Conversion.c +++ b/src/core/Conversion.c @@ -36,7 +36,7 @@ OBJECT_CLASS(Conversion, Object); // ---------------------------------------------------------------------- // Range Conversion -static int RangeConversionElemwiseLeq(void * first, void * second, ChannelType * type) { +static int RangeConversionElemwiseLeq(const void * first, const void * second, ChannelType * type) { switch (type->con) { case CHANNEL_DOUBLE: return *(double *) first <= *(double *) second; @@ -47,7 +47,7 @@ static int RangeConversionElemwiseLeq(void * first, void * second, ChannelType * } } -static int RangeConversionElemwiseGeq(void * first, void * second, ChannelType * type) { +static int RangeConversionElemwiseGeq(const void * first, const void * second, ChannelType * type) { switch (type->con) { case CHANNEL_DOUBLE: return *(double *) first >= *(double *) second; @@ -229,7 +229,7 @@ McxStatus ConvertRange(ChannelValue * min, ChannelValue * max, ChannelValue * va retVal = RangeConversionConvertValueRef(rangeConv, ref); DestroyChannelValueReference(ref); } else { - retVal = RangeConversionConvert(rangeConv, value); + retVal = RangeConversionConvert((Conversion *) rangeConv, value); } if (retVal == RETURN_ERROR) { @@ -387,7 +387,7 @@ static McxStatus UnitConversionConvert(Conversion * conversion, ChannelValue * v return RETURN_ERROR; } - *elem = UnitConversionConvertValue(conversion, *elem); + *elem = UnitConversionConvertValue(unitConversion, *elem); } } else { double val = UnitConversionConvertValue(unitConversion, *(double *) ChannelValueDataPointer(value)); @@ -485,7 +485,7 @@ McxStatus ConvertUnit(const char * fromUnit, const char * toUnit, ChannelValue * retVal = UnitConversionConvertValueRef(unitConv, ref); DestroyChannelValueReference(ref); } else { - retVal = UnitConversionConvert(unitConv, value); + retVal = UnitConversionConvert((Conversion *) unitConv, value); } if (retVal == RETURN_ERROR) { @@ -754,7 +754,7 @@ McxStatus ConvertLinear(ChannelValue * factor, ChannelValue * offset, ChannelVal retVal = LinearConversionConvertValueRef(linearConv, ref); DestroyChannelValueReference(ref); } else { - retVal = LinearConversionConvert(linearConv, value); + retVal = LinearConversionConvert((Conversion *) linearConv, value); } if (RETURN_OK != retVal) { @@ -843,8 +843,8 @@ McxStatus ConvertType(ChannelValue * dest, ChannelDimension * destSlice, Channel return retVal; } -static McxStatus CheckTypesValidForConversion(ChannelType * destType, - ChannelType * expectedDestType) +static McxStatus CheckTypesValidForConversion(const ChannelType * destType, + const ChannelType * expectedDestType) { if (!ChannelTypeEq(destType, expectedDestType)) { mcx_log(LOG_ERROR, @@ -914,7 +914,7 @@ static McxStatus ArraysValidForConversion(ChannelValueReference * dest, return RETURN_OK; } -static McxStatus TypeConversionConvertIntDouble(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertIntDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -924,7 +924,7 @@ static McxStatus TypeConversionConvertIntDouble(Conversion * conversion, Channel return RETURN_OK; } -static McxStatus TypeConversionConvertDoubleInt(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertDoubleInt(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -934,7 +934,7 @@ static McxStatus TypeConversionConvertDoubleInt(Conversion * conversion, Channel return RETURN_OK; } -static McxStatus TypeConversionConvertBoolDouble(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertBoolDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -944,7 +944,7 @@ static McxStatus TypeConversionConvertBoolDouble(Conversion * conversion, Channe return RETURN_OK; } -static McxStatus TypeConversionConvertDoubleBool(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertDoubleBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeBool)) { return RETURN_ERROR; } @@ -954,7 +954,7 @@ static McxStatus TypeConversionConvertDoubleBool(Conversion * conversion, Channe return RETURN_OK; } -static McxStatus TypeConversionConvertBoolInteger(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertBoolInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -964,7 +964,7 @@ static McxStatus TypeConversionConvertBoolInteger(Conversion * conversion, Chann return RETURN_OK; } -static McxStatus TypeConversionConvertIntegerBool(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertIntegerBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeBool)) { return RETURN_ERROR; } @@ -974,7 +974,7 @@ static McxStatus TypeConversionConvertIntegerBool(Conversion * conversion, Chann return RETURN_OK; } -static McxStatus TypeConversionConvertArrayDoubleToDouble(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayDoubleToDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -988,7 +988,7 @@ static McxStatus TypeConversionConvertArrayDoubleToDouble(TypeConversion * conve return RETURN_OK; } -static McxStatus TypeConversionConvertArrayIntegerToDouble(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayIntegerToDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -1002,7 +1002,7 @@ static McxStatus TypeConversionConvertArrayIntegerToDouble(TypeConversion * conv return RETURN_OK; } -static McxStatus TypeConversionConvertArrayBoolToDouble(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayBoolToDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -1016,7 +1016,7 @@ static McxStatus TypeConversionConvertArrayBoolToDouble(TypeConversion * convers return RETURN_OK; } -static McxStatus TypeConversionConvertArrayDoubleToInteger(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayDoubleToInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -1030,7 +1030,7 @@ static McxStatus TypeConversionConvertArrayDoubleToInteger(TypeConversion * conv return RETURN_OK; } -static McxStatus TypeConversionConvertArrayIntegerToInteger(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayIntegerToInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -1044,7 +1044,7 @@ static McxStatus TypeConversionConvertArrayIntegerToInteger(TypeConversion * con return RETURN_OK; } -static McxStatus TypeConversionConvertArrayBoolToInteger(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayBoolToInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -1058,7 +1058,7 @@ static McxStatus TypeConversionConvertArrayBoolToInteger(TypeConversion * conver return RETURN_OK; } -static McxStatus TypeConversionConvertArrayDoubleToBool(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayDoubleToBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeBool)) { return RETURN_ERROR; } @@ -1072,7 +1072,7 @@ static McxStatus TypeConversionConvertArrayDoubleToBool(TypeConversion * convers return RETURN_OK; } -static McxStatus TypeConversionConvertArrayIntegerToBool(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayIntegerToBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeBool)) { return RETURN_ERROR; } @@ -1086,7 +1086,7 @@ static McxStatus TypeConversionConvertArrayIntegerToBool(TypeConversion * conver return RETURN_OK; } -static McxStatus TypeConversionConvertArrayBoolToBool(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayBoolToBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckTypesValidForConversion(ChannelValueReferenceGetType(dest), &ChannelTypeBool)) { return RETURN_ERROR; } @@ -1100,7 +1100,7 @@ static McxStatus TypeConversionConvertArrayBoolToBool(TypeConversion * conversio return RETURN_OK; } -static McxStatus TypeConversionConvertDoubleToArrayDouble(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertDoubleToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -1115,7 +1115,7 @@ static McxStatus TypeConversionConvertDoubleToArrayDouble(Conversion * conversio return RETURN_OK; } -static McxStatus TypeConversionConvertIntegerToArrayDouble(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertIntegerToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -1130,7 +1130,7 @@ static McxStatus TypeConversionConvertIntegerToArrayDouble(Conversion * conversi return RETURN_OK; } -static McxStatus TypeConversionConvertBoolToArrayDouble(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertBoolToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeDouble)) { return RETURN_ERROR; } @@ -1145,7 +1145,7 @@ static McxStatus TypeConversionConvertBoolToArrayDouble(Conversion * conversion, return RETURN_OK; } -static McxStatus TypeConversionConvertDoubleToArrayInteger(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertDoubleToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -1160,7 +1160,7 @@ static McxStatus TypeConversionConvertDoubleToArrayInteger(Conversion * conversi return RETURN_OK; } -static McxStatus TypeConversionConvertIntegerToArrayInteger(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertIntegerToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -1175,7 +1175,7 @@ static McxStatus TypeConversionConvertIntegerToArrayInteger(Conversion * convers return RETURN_OK; } -static McxStatus TypeConversionConvertBoolToArrayInteger(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertBoolToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeInteger)) { return RETURN_ERROR; } @@ -1190,7 +1190,7 @@ static McxStatus TypeConversionConvertBoolToArrayInteger(Conversion * conversion return RETURN_OK; } -static McxStatus TypeConversionConvertDoubleToArrayBool(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertDoubleToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeBool)) { return RETURN_ERROR; } @@ -1205,7 +1205,7 @@ static McxStatus TypeConversionConvertDoubleToArrayBool(Conversion * conversion, return RETURN_OK; } -static McxStatus TypeConversionConvertIntegerToArrayBool(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertIntegerToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeBool)) { return RETURN_ERROR; } @@ -1220,7 +1220,7 @@ static McxStatus TypeConversionConvertIntegerToArrayBool(Conversion * conversion return RETURN_OK; } -static McxStatus TypeConversionConvertBoolToArrayBool(Conversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertBoolToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_ERROR == CheckArrayReferencingOnlyOneElement(dest, &ChannelTypeBool)) { return RETURN_ERROR; } @@ -1235,7 +1235,7 @@ static McxStatus TypeConversionConvertBoolToArrayBool(Conversion * conversion, C return RETURN_OK; } -static size_t IndexOfElemInSrcArray(size_t dest_idx, mcx_array * src_array, ChannelDimension * src_dim, ChannelValueReference * dest) { +static size_t IndexOfElemInSrcArray(size_t dest_idx, const mcx_array * src_array, const ChannelDimension * src_dim, const ChannelValueReference * dest) { if (src_dim) { if (dest->type == CHANNEL_VALUE_REF_VALUE) { return ChannelDimensionGetIndex(src_dim, dest_idx, src_array->dims); @@ -1253,13 +1253,13 @@ static size_t IndexOfElemInSrcArray(size_t dest_idx, mcx_array * src_array, Chan } typedef struct Array2ArrayCtx { - mcx_array * src_array; - ChannelDimension * src_dim; + const mcx_array * src_array; + const ChannelDimension * src_dim; ChannelValueReference * dest; } Array2ArrayCtx; -static McxStatus IntegerArrayToDouble(void * element, size_t idx, ChannelType * type, void * ctx) { - Array2ArrayCtx * context = (Array2ArrayCtx *) ctx; +static McxStatus IntegerArrayToDouble(void * element, size_t idx, ChannelType * type, const void * ctx) { + const Array2ArrayCtx * context = (const Array2ArrayCtx *) ctx; size_t i = IndexOfElemInSrcArray(idx, context->src_array, context->src_dim, context->dest); void * src_elem = mcx_array_get_elem_reference(context->src_array, i); @@ -1272,8 +1272,8 @@ static McxStatus IntegerArrayToDouble(void * element, size_t idx, ChannelType * return RETURN_OK; } -static McxStatus BoolArrayToDouble(void * element, size_t idx, ChannelType * type, void * ctx) { - Array2ArrayCtx * context = (Array2ArrayCtx *) ctx; +static McxStatus BoolArrayToDouble(void * element, size_t idx, ChannelType * type, const void * ctx) { + const Array2ArrayCtx * context = (const Array2ArrayCtx *) ctx; size_t i = IndexOfElemInSrcArray(idx, context->src_array, context->src_dim, context->dest); void * src_elem = mcx_array_get_elem_reference(context->src_array, i); @@ -1286,8 +1286,8 @@ static McxStatus BoolArrayToDouble(void * element, size_t idx, ChannelType * typ return RETURN_OK; } -static McxStatus BoolArrayToInteger(void * element, size_t idx, ChannelType * type, void * ctx) { - Array2ArrayCtx * context = (Array2ArrayCtx *) ctx; +static McxStatus BoolArrayToInteger(void * element, size_t idx, ChannelType * type, const void * ctx) { + const Array2ArrayCtx * context = (const Array2ArrayCtx *) ctx; size_t i = IndexOfElemInSrcArray(idx, context->src_array, context->src_dim, context->dest); void * src_elem = mcx_array_get_elem_reference(context->src_array, i); @@ -1300,8 +1300,8 @@ static McxStatus BoolArrayToInteger(void * element, size_t idx, ChannelType * ty return RETURN_OK; } -static McxStatus DoubleArrayToInteger(void * element, size_t idx, ChannelType * type, void * ctx) { - Array2ArrayCtx * context = (Array2ArrayCtx *) ctx; +static McxStatus DoubleArrayToInteger(void * element, size_t idx, ChannelType * type, const void * ctx) { + const Array2ArrayCtx * context = (const Array2ArrayCtx *) ctx; size_t i = IndexOfElemInSrcArray(idx, context->src_array, context->src_dim, context->dest); void * src_elem = mcx_array_get_elem_reference(context->src_array, i); @@ -1314,8 +1314,8 @@ static McxStatus DoubleArrayToInteger(void * element, size_t idx, ChannelType * return RETURN_OK; } -static McxStatus DoubleArrayToBool(void * element, size_t idx, ChannelType * type, void * ctx) { - Array2ArrayCtx * context = (Array2ArrayCtx *) ctx; +static McxStatus DoubleArrayToBool(void * element, size_t idx, ChannelType * type, const void * ctx) { + const Array2ArrayCtx * context = (const Array2ArrayCtx *) ctx; size_t i = IndexOfElemInSrcArray(idx, context->src_array, context->src_dim, context->dest); void * src_elem = mcx_array_get_elem_reference(context->src_array, i); @@ -1328,8 +1328,8 @@ static McxStatus DoubleArrayToBool(void * element, size_t idx, ChannelType * typ return RETURN_OK; } -static McxStatus IntegerArrayToBool(void * element, size_t idx, ChannelType * type, void * ctx) { - Array2ArrayCtx * context = (Array2ArrayCtx *) ctx; +static McxStatus IntegerArrayToBool(void * element, size_t idx, ChannelType * type, const void * ctx) { + const Array2ArrayCtx * context = (const Array2ArrayCtx *) ctx; size_t i = IndexOfElemInSrcArray(idx, context->src_array, context->src_dim, context->dest); void * src_elem = mcx_array_get_elem_reference(context->src_array, i); @@ -1342,7 +1342,7 @@ static McxStatus IntegerArrayToBool(void * element, size_t idx, ChannelType * ty return RETURN_OK; } -static McxStatus TypeConversionConvertArrayIntegerToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayIntegerToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_OK != ArraysValidForConversion(dest, &ChannelTypeDouble, (mcx_array *) src, conversion->sourceSlice)) { return RETURN_ERROR; } @@ -1351,7 +1351,7 @@ static McxStatus TypeConversionConvertArrayIntegerToArrayDouble(TypeConversion * return ChannelValueReferenceElemMap(dest, IntegerArrayToDouble, &ctx); } -static McxStatus TypeConversionConvertArrayBoolToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayBoolToArrayDouble(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_OK != ArraysValidForConversion(dest, &ChannelTypeDouble, (mcx_array *) src, conversion->sourceSlice)) { return RETURN_ERROR; } @@ -1360,7 +1360,7 @@ static McxStatus TypeConversionConvertArrayBoolToArrayDouble(TypeConversion * co return ChannelValueReferenceElemMap(dest, BoolArrayToDouble, &ctx); } -static McxStatus TypeConversionConvertArrayDoubleToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayDoubleToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_OK != ArraysValidForConversion(dest, &ChannelTypeInteger, (mcx_array *) src, conversion->sourceSlice)) { return RETURN_ERROR; } @@ -1369,7 +1369,7 @@ static McxStatus TypeConversionConvertArrayDoubleToArrayInteger(TypeConversion * return ChannelValueReferenceElemMap(dest, DoubleArrayToInteger, &ctx); } -static McxStatus TypeConversionConvertArrayBoolToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayBoolToArrayInteger(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_OK != ArraysValidForConversion(dest, &ChannelTypeInteger, (mcx_array *) src, conversion->sourceSlice)) { return RETURN_ERROR; } @@ -1378,7 +1378,7 @@ static McxStatus TypeConversionConvertArrayBoolToArrayInteger(TypeConversion * c return ChannelValueReferenceElemMap(dest, BoolArrayToInteger, &ctx); } -static McxStatus TypeConversionConvertArrayDoubleToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayDoubleToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_OK != ArraysValidForConversion(dest, &ChannelTypeBool, (mcx_array *) src, conversion->sourceSlice)) { return RETURN_ERROR; } @@ -1387,7 +1387,7 @@ static McxStatus TypeConversionConvertArrayDoubleToArrayBool(TypeConversion * co return ChannelValueReferenceElemMap(dest, DoubleArrayToBool, &ctx); } -static McxStatus TypeConversionConvertArrayIntegerToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertArrayIntegerToArrayBool(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { if (RETURN_OK != ArraysValidForConversion(dest, &ChannelTypeBool, (mcx_array *) src, conversion->sourceSlice)) { return RETURN_ERROR; } @@ -1396,7 +1396,7 @@ static McxStatus TypeConversionConvertArrayIntegerToArrayBool(TypeConversion * c return ChannelValueReferenceElemMap(dest, IntegerArrayToBool, &ctx); } -static McxStatus TypeConversionConvertId(TypeConversion * conversion, ChannelValueReference * dest, void * src) { +static McxStatus TypeConversionConvertId(TypeConversion * conversion, ChannelValueReference * dest, const void * src) { return ChannelValueReferenceSetFromPointer(dest, src, conversion->sourceSlice, NULL); } diff --git a/src/core/Conversion.h b/src/core/Conversion.h index 1c2d3ed..149b51e 100644 --- a/src/core/Conversion.h +++ b/src/core/Conversion.h @@ -121,14 +121,14 @@ McxStatus ConvertLinear(ChannelValue * factor, ChannelValue * offset, ChannelVal typedef struct TypeConversion TypeConversion; typedef McxStatus (*fTypeConversionSetup)(TypeConversion * conversion, - const ChannelType * fromType, + ChannelType * fromType, ChannelDimension * fromDimension, - const ChannelType * toType, + ChannelType * toType, ChannelDimension * toDimension); // TODO: Ideally the `src` argument would also be ChannelValueReference, but that requires quite of lot of changes // in the API of databus definition (i.e. DatabusSetIn(Out)Reference) -typedef McxStatus (*fTypeConversionConvert)(TypeConversion * conversion, ChannelValueReference * dest, void * src); +typedef McxStatus (*fTypeConversionConvert)(TypeConversion * conversion, ChannelValueReference * dest, const void * src); extern const struct ObjectClass _TypeConversion; diff --git a/src/core/Databus.c b/src/core/Databus.c index 7e920e7..cb51959 100644 --- a/src/core/Databus.c +++ b/src/core/Databus.c @@ -273,8 +273,8 @@ static ChannelInfo * DatabusReadPortInput(PortInput * input) { return info; } -static int ChannelInfoSameNamePred(void * elem, const char * name) { - ChannelInfo * info = (ChannelInfo *) elem; +static int ChannelInfoSameNamePred(const void * elem, const char * name) { + const ChannelInfo * info = (const ChannelInfo *) elem; return 0 == strcmp(ChannelInfoGetName(info), name); } @@ -372,8 +372,8 @@ McxStatus DatabusInfoRead(DatabusInfo * dbInfo, return retVal; } -static int IsWriteResults(void * elem, void * ignore) { - ChannelInfo * info = (ChannelInfo *) elem; +static int IsWriteResults(const void * elem, const void * ignore) { + const ChannelInfo * info = (const ChannelInfo *) elem; return info->writeResult; } @@ -1419,7 +1419,7 @@ OBJECT_CLASS(Databus, Object); char * CreateChannelID(const char * compName, const char * channelName) { - const char separator = '.'; + const char separator = '#'; size_t len = strlen(compName) + strlen(channelName) + 2; char * id = (char *) mcx_calloc(len, sizeof(char)); if (id) { diff --git a/src/core/Model.c b/src/core/Model.c index e89be67..f7fc60d 100644 --- a/src/core/Model.c +++ b/src/core/Model.c @@ -59,24 +59,24 @@ static ChannelInfo * GetSourceChannelInfo(ConnectionInfo * info) { return DatabusGetOutChannelInfo(srcDb, srcId); } -static int ConnInfoWithSrc(void * elem, void * arg) { +static int ConnInfoWithSrc(const void * elem, const void * arg) { /* * TRUE if obj (ConnectionInfo) has ctx as its source ChannelInfo */ - ChannelInfo * chInfo = (ChannelInfo *) arg; + const ChannelInfo * chInfo = (const ChannelInfo *) arg; ConnectionInfo * info = *((ConnectionInfo **) elem); ChannelInfo * srcInfo = GetSourceChannelInfo(info); return srcInfo == chInfo; } -static int IsBinaryConn(void * elem, void * args) { +static int IsBinaryConn(const void * elem, const void * args) { /* * TRUE if both source and target channel infos of obj (ConnectionInfo) are binary */ ConnectionInfo * info = (ConnectionInfo *) elem; - ChannelInfo * srcInfo = GetSourceChannelInfo(info); - ChannelInfo * trgInfo = GetTargetChannelInfo(info); + const ChannelInfo * srcInfo = GetSourceChannelInfo(info); + const ChannelInfo * trgInfo = GetTargetChannelInfo(info); return ChannelInfoIsBinary(srcInfo) && ChannelInfoIsBinary(trgInfo); } @@ -295,9 +295,9 @@ static McxStatus ModelPreprocessConstConnections(Model * model) { return RETURN_OK; } -static int ConnInfoContained(void * elem, void * arg) { - ConnectionInfo * info = *(ConnectionInfo **) elem; - return info == (ConnectionInfo *) arg; +static int ConnInfoContained(const void * elem, const void * arg) { + const ConnectionInfo * info = *(const ConnectionInfo **) elem; + return info == (const ConnectionInfo *) arg; } static McxStatus ModelPreprocessBinaryConnections(Model * model) { @@ -313,7 +313,8 @@ static McxStatus ModelPreprocessBinaryConnections(Model * model) { McxStatus retVal = RETURN_OK; - if (task->stepTypeType != STEP_TYPE_SEQUENTIAL) { + if (task->stepTypeType != STEP_TYPE_SEQUENTIAL + ) { return RETURN_OK; } @@ -733,13 +734,14 @@ static void DestroyOneComponent(Component * comp) { static void ModelDestructor(void * self) { Model * model = (Model *) self; ObjectContainer * comps = model->components; - size_t i = 0; + int i = 0; if (0 == model) return; - for (i = 0; i < comps->Size(comps); i++) { - Component * comp = (Component *) comps->At(comps, i); + // Delete components in the reverse order they were created. + for (i = (int) comps->Size(comps) - 1; i >= 0; i--) { + Component* comp = (Component*)comps->At(comps, i); DestroyOneComponent(comp); } @@ -880,7 +882,8 @@ static McxStatus ModelMakeConnections(Model * model) { InterExtrapolatingType isInterExtrapolating = INTERPOLATING; - if (STEP_TYPE_SEQUENTIAL == type) { + if (STEP_TYPE_SEQUENTIAL == type + ) { isInterExtrapolating = INTERPOLATING; } else { isInterExtrapolating = EXTRAPOLATING; diff --git a/src/core/Model.h b/src/core/Model.h index a0fefb5..c75a92b 100644 --- a/src/core/Model.h +++ b/src/core/Model.h @@ -65,7 +65,6 @@ struct Model { Task * task; Vector * connections; - ObjectContainer * components; ComponentFactory * factory; diff --git a/src/core/SubModel.c b/src/core/SubModel.c index e2e64d8..1e258f4 100644 --- a/src/core/SubModel.c +++ b/src/core/SubModel.c @@ -869,7 +869,9 @@ StringContainer * SubModelGetAllObservableChannelsContainer(SubModel * subModel) for (i = 0; i < comps->Size(comps); i++) { Component * comp = (Component *) comps->At(comps, i); // TODO: make composable - comp->AddObservableChannels(comp, container, &count); + if (!comp->IsShadowComponent(comp)) { + comp->AddObservableChannels(comp, container, &count); + } } StringContainerResize(container, count); diff --git a/src/core/Task.c b/src/core/Task.c index fa63a9f..380b2c2 100644 --- a/src/core/Task.c +++ b/src/core/Task.c @@ -137,7 +137,7 @@ static McxStatus TaskInitialize(Task * task, Model * model) { task->storage->StoreModelLocal(task->storage, model->subModel, stepParams->time, STORE_SYNCHRONIZATION); task->storage->StoreModelRTFactor(task->storage, model->subModel, stepParams->time, STORE_SYNCHRONIZATION); - task->stepType->Configure(task->stepType, stepParams, subModel); + task->stepType->Configure(task->stepType, stepParams, subModel, model); return RETURN_OK; } diff --git a/src/core/channels/ChannelInfo.c b/src/core/channels/ChannelInfo.c index ff93130..cbef73f 100644 --- a/src/core/channels/ChannelInfo.c +++ b/src/core/channels/ChannelInfo.c @@ -272,6 +272,10 @@ void ChannelInfoDestroy(ChannelInfo * info) { object_destroy(info->dimension); } + if (info->connectionStatus) { + DestroyConnectionStatus(info->connectionStatus); + } + info->channel = NULL; info->initialValueIsExact = FALSE; info->type = ChannelTypeClone(&ChannelTypeUnknown); @@ -305,6 +309,8 @@ McxStatus ChannelInfoInit(ChannelInfo * info) { info->channel = NULL; + info->connectionStatus = NULL; + return RETURN_OK; } diff --git a/src/core/channels/ChannelInfo.h b/src/core/channels/ChannelInfo.h index adad36d..8e55e4c 100644 --- a/src/core/channels/ChannelInfo.h +++ b/src/core/channels/ChannelInfo.h @@ -14,6 +14,7 @@ #include "core/channels/ChannelValue.h" #include "CentralParts.h" #include "core/channels/ChannelDimension.h" +#include "core/channels/ConnectionStatus.h" #include "common/status.h" @@ -51,6 +52,8 @@ typedef struct ChannelInfo { int connected; int initialValueIsExact; + + ConnectionStatus * connectionStatus; } ChannelInfo; diff --git a/src/core/channels/ChannelValue.c b/src/core/channels/ChannelValue.c index 9386b73..1f22f76 100644 --- a/src/core/channels/ChannelValue.c +++ b/src/core/channels/ChannelValue.c @@ -23,8 +23,6 @@ ChannelType ChannelTypeBool = { CHANNEL_BOOL, NULL}; ChannelType ChannelTypeString = { CHANNEL_STRING, NULL}; ChannelType ChannelTypeBinary = { CHANNEL_BINARY, NULL}; ChannelType ChannelTypeBinaryReference = { CHANNEL_BINARY_REFERENCE, NULL}; - - char * CreateIndexedName(const char * name, unsigned i) { size_t len = 0; char * buffer = NULL; @@ -42,7 +40,7 @@ char * CreateIndexedName(const char * name, unsigned i) { } -ChannelType * ChannelTypeClone(ChannelType * type) { +ChannelType * ChannelTypeClone(const ChannelType * type) { switch (type->con) { case CHANNEL_UNKNOWN: case CHANNEL_INTEGER: @@ -52,7 +50,7 @@ ChannelType * ChannelTypeClone(ChannelType * type) { case CHANNEL_BINARY: case CHANNEL_BINARY_REFERENCE: // Scalar types are used statically (&ChannelTypeDouble, etc) - return type; + return (ChannelType *) type; case CHANNEL_ARRAY: { ChannelType * clone = (ChannelType *) mcx_calloc(sizeof(ChannelType), 1); if (!clone) { return NULL; } @@ -169,7 +167,7 @@ int ChannelTypeIsBinary(const ChannelType * a) { return a->con == CHANNEL_BINARY || a->con == CHANNEL_BINARY_REFERENCE; } -ChannelType * ChannelTypeBaseType(const ChannelType * a) { +const ChannelType * ChannelTypeBaseType(const ChannelType * a) { if (ChannelTypeIsArray(a)) { return ChannelTypeBaseType(a->ty.a.inner); } else { @@ -204,7 +202,7 @@ int ChannelTypeConformable(ChannelType * a, ChannelDimension * sliceA, ChannelTy return ChannelTypeEq(a, b); } } else { - if (sliceA || sliceB) { + if (a->con != CHANNEL_ARRAY && sliceA || b->con != CHANNEL_ARRAY && sliceB) { mcx_log(LOG_ERROR, "ChannelTypeConformable: Slice dimensions defined for non-array channels"); return 0; } @@ -486,8 +484,8 @@ ChannelType * ChannelTypeFromDimension(ChannelType * base_type, ChannelDimension } } -void ChannelValueInit(ChannelValue * value, ChannelType * type) { - value->type = type; +void ChannelValueInit(ChannelValue * value, const ChannelType * type) { + value->type = (ChannelType *) type; ChannelValueDataInit(&value->value, type); } @@ -755,7 +753,7 @@ void * ChannelValueDataPointer(ChannelValue * value) { } } -void ChannelValueDataInit(ChannelValueData * data, ChannelType * type) { +void ChannelValueDataInit(ChannelValueData * data, const ChannelType * type) { switch (type->con) { case CHANNEL_DOUBLE: data->d = 0.0; @@ -936,7 +934,7 @@ McxStatus ChannelValueSet(ChannelValue * value, const ChannelValue * source) { return RETURN_OK; } -McxStatus ChannelValueDataSetToReference(ChannelValueData * value, ChannelType * type, void * reference) { +McxStatus ChannelValueDataSetToReference(ChannelValueData * value, const ChannelType * type, void * reference) { if (!reference) { mcx_log(LOG_ERROR, "ChannelValueDataSetToReference: Reference not defined"); return RETURN_ERROR; @@ -1024,7 +1022,7 @@ McxStatus ChannelValueSetToReference(ChannelValue * value, void * reference) { } #ifdef __cplusplus -size_t ChannelValueTypeSize(ChannelType * type) { +size_t ChannelValueTypeSize(const ChannelType * type) { switch (type->con) { case CHANNEL_DOUBLE: return sizeof(ChannelValueData::d); @@ -1043,7 +1041,7 @@ size_t ChannelValueTypeSize(ChannelType * type) { return 0; } #else //__cplusplus -size_t ChannelValueTypeSize(ChannelType * type) { +size_t ChannelValueTypeSize(const ChannelType * type) { ChannelValueData value; switch (type->con) { case CHANNEL_DOUBLE: @@ -1068,7 +1066,7 @@ int ChannelTypeMatch(ChannelType * a, ChannelType * b) { return ChannelTypeEq(a, b); } -const char * ChannelTypeToString(ChannelType * type) { +const char * ChannelTypeToString(const ChannelType * type) { switch (type->con) { case CHANNEL_UNKNOWN: return "Unknown"; diff --git a/src/core/channels/ChannelValue.h b/src/core/channels/ChannelValue.h index 9647c62..bad2dbc 100644 --- a/src/core/channels/ChannelValue.h +++ b/src/core/channels/ChannelValue.h @@ -33,7 +33,7 @@ typedef enum ChannelTypeConstructor { CHANNEL_STRING = 4, CHANNEL_BINARY = 5, CHANNEL_BINARY_REFERENCE = 6, - CHANNEL_ARRAY = 7, + CHANNEL_ARRAY = 7 } ChannelTypeConstructor; typedef struct ChannelTypeArrayType { @@ -60,7 +60,7 @@ extern ChannelType ChannelTypeBinaryReference; ChannelType * ChannelTypeArray(ChannelType * inner, size_t numDims, size_t * dims); ChannelType * ChannelTypeArrayUInt64Dims(ChannelType * inner, size_t numDims, uint64_t * dims); -ChannelType * ChannelTypeClone(ChannelType * type); +ChannelType * ChannelTypeClone(const ChannelType * type); void ChannelTypeDestructor(ChannelType * type); ChannelType * ChannelTypeArrayInner(ChannelType * array); @@ -74,7 +74,7 @@ size_t ChannelTypeNumElements(const ChannelType * type); ChannelType * ChannelTypeFromDimension(ChannelType * base_type, ChannelDimension * dimension); -ChannelType * ChannelTypeBaseType(const ChannelType * a); +const ChannelType * ChannelTypeBaseType(const ChannelType * a); int ChannelTypeEq(const ChannelType * a, const ChannelType * b); int ChannelTypeConformable(ChannelType * a, ChannelDimension * sliceA, ChannelType * b, ChannelDimension * sliceB); @@ -142,7 +142,7 @@ struct ChannelValue { }; // Takes ownership of type -void ChannelValueInit(ChannelValue * value, ChannelType * type); +void ChannelValueInit(ChannelValue * value, const ChannelType * type); void ChannelValueDestructor(ChannelValue * value); char * ChannelValueToString(ChannelValue * value); McxStatus ChannelValueDataToStringBuffer(const ChannelValueData * value, ChannelType * type, char * buffer, size_t len); @@ -152,21 +152,21 @@ ChannelType * ChannelValueType(ChannelValue * value); void * ChannelValueDataPointer(ChannelValue * value); void ChannelValueDataDestructor(ChannelValueData * data, ChannelType * type); -void ChannelValueDataInit(ChannelValueData * data, ChannelType * type); +void ChannelValueDataInit(ChannelValueData * data, const ChannelType * type); McxStatus ChannelValueDataSetFromReference(ChannelValueData * data, ChannelType * type, const void * reference); -typedef int (*fChannelValueDataSetterPredicate)(void * first, void * second, ChannelType * type); +typedef int (*fChannelValueDataSetterPredicate)(const void * first, const void * second, ChannelType * type); McxStatus ChannelValueDataSetFromReferenceIfElemwisePred(ChannelValueData * data, ChannelType * type, const void * reference, fChannelValueDataSetterPredicate predicate); -McxStatus ChannelValueDataSetToReference(ChannelValueData * value, ChannelType * type, void * reference); +McxStatus ChannelValueDataSetToReference(ChannelValueData * value, const ChannelType * type, void * reference); McxStatus ChannelValueSetFromReference(ChannelValue * value, const void * reference); McxStatus ChannelValueSetToReference(ChannelValue * value, void * reference); McxStatus ChannelValueSet(ChannelValue * value, const ChannelValue * source); -size_t ChannelValueTypeSize(ChannelType * type); +size_t ChannelValueTypeSize(const ChannelType * type); int ChannelTypeMatch(ChannelType * a, ChannelType * b); ChannelValue * ChannelValueNewScalar(ChannelType * type, void * data); @@ -179,7 +179,7 @@ ChannelValue ** ArrayToChannelValueArray(void * values, size_t num, ChannelType * Returns a string representation of ChannelType for use in log * messages. */ -const char * ChannelTypeToString(ChannelType * type); +const char * ChannelTypeToString(const ChannelType * type); /* * Creates a copy of value. Allocates memory if needed, e.g. when diff --git a/src/core/channels/ConnectionStatus.c b/src/core/channels/ConnectionStatus.c new file mode 100644 index 0000000..316892b --- /dev/null +++ b/src/core/channels/ConnectionStatus.c @@ -0,0 +1,113 @@ +/******************************************************************************** + * Copyright (c) 2021 AVL List GmbH and others + * + * This program and the accompanying materials are made available under the + * terms of the Apache Software License 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "core/channels/ChannelDimension.h" +#include "core/channels/ConnectionStatus.h" +#include "util/stdlib.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +ConnectionStatus * CreateConnectionStatus(ChannelDimension * dimension) { + size_t i; + ConnectionStatus * connectionStatusNew = (ConnectionStatus *) mcx_calloc(1, sizeof(ConnectionStatus)); + if (!connectionStatusNew) { + return NULL; + } + + if (!dimension) { + connectionStatusNew->num = 0; + connectionStatusNew->startIdxs = NULL; + connectionStatusNew->endIdxs = NULL; + connectionStatusNew->connected.scalar = 0; + return connectionStatusNew; + } + + connectionStatusNew->num = dimension->num; + + connectionStatusNew->startIdxs = (size_t *) mcx_calloc(connectionStatusNew->num, sizeof(size_t)); + if (!connectionStatusNew->startIdxs) { + goto error_cleanup; + } + + connectionStatusNew->endIdxs = (size_t *) mcx_calloc(connectionStatusNew->num, sizeof(size_t)); + if (!connectionStatusNew->endIdxs) { + goto error_cleanup; + } + + memcpy(connectionStatusNew->startIdxs, dimension->startIdxs, connectionStatusNew->num * sizeof(size_t)); + memcpy(connectionStatusNew->endIdxs, dimension->endIdxs, connectionStatusNew->num * sizeof(size_t)); + + connectionStatusNew->connected.array = (int **) mcx_calloc(connectionStatusNew->num, sizeof(int *)); + if (!connectionStatusNew->connected.array) { + goto error_cleanup; + } + + for (i = 0; i < connectionStatusNew->num; i++) { + connectionStatusNew->connected.array[i] = (int *) + mcx_calloc(connectionStatusNew->endIdxs[i] - connectionStatusNew->startIdxs[i] + 1, sizeof(int)); + if (!connectionStatusNew->connected.array[i]) { + goto error_cleanup; + } + } + return connectionStatusNew; + +error_cleanup: + if (connectionStatusNew->startIdxs) { + mcx_free(connectionStatusNew->startIdxs); + } + if (connectionStatusNew->endIdxs) { + mcx_free(connectionStatusNew->endIdxs); + } + if (connectionStatusNew->num > 0 && connectionStatusNew->connected.array) { + for (i = 0; i < connectionStatusNew->num; i++) { + if (connectionStatusNew->connected.array[i]) { + mcx_free(connectionStatusNew->connected.array[i]); + } + } + mcx_free(connectionStatusNew->connected.array); + } + + if (connectionStatusNew) { + mcx_free(connectionStatusNew); + } + return NULL; +} + +void DestroyConnectionStatus(ConnectionStatus * connectionStatus) { + size_t i; + for (i = 0; i < connectionStatus->num; i++) { + if (connectionStatus->connected.array[i]) { + mcx_free(connectionStatus->connected.array[i]); + } + } + + if (connectionStatus->num > 0 && connectionStatus->connected.array) { + mcx_free(connectionStatus->connected.array); + } + + if (connectionStatus->endIdxs) { + mcx_free(connectionStatus->endIdxs); + } + if (connectionStatus->startIdxs) { + mcx_free(connectionStatus->startIdxs); + } + if (connectionStatus) { + mcx_free(connectionStatus); + } + +} + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ \ No newline at end of file diff --git a/src/core/channels/ConnectionStatus.h b/src/core/channels/ConnectionStatus.h new file mode 100644 index 0000000..109a1e5 --- /dev/null +++ b/src/core/channels/ConnectionStatus.h @@ -0,0 +1,43 @@ +/******************************************************************************** + * Copyright (c) 2021 AVL List GmbH and others + * + * This program and the accompanying materials are made available under the + * terms of the Apache Software License 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#ifndef MCX_CORE_CHANNELS_CONNECTION_STATUS_H +#define MCX_CORE_CHANNELS_CONNECTION_STATUS_H + +#include "CentralParts.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +typedef struct ConnectionStatus { + size_t num; + size_t * startIdxs; + size_t * endIdxs; + + union { + int scalar; + int ** array; + } connected; +} ConnectionStatus; + +ConnectionStatus * CreateConnectionStatus(ChannelDimension * dimension); +void DestroyConnectionStatus(ConnectionStatus * connectionStatus); + + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif /* __cplusplus */ + +#endif // MCX_CORE_CHANNELS_CONNECTION_STATUS_H +#pragma once \ No newline at end of file diff --git a/src/core/connections/Connection.c b/src/core/connections/Connection.c index 01bc80a..073469c 100644 --- a/src/core/connections/Connection.c +++ b/src/core/connections/Connection.c @@ -928,7 +928,7 @@ static size_t MemoryFilterHistorySize(Component * sourceComp, Component * target return size + model->config->memFilterHistoryExtra; } -static MemoryFilter * SetMemoryFilter(int reverseSearch, ChannelType * sourceType, size_t historySize) { +static MemoryFilter * SetMemoryFilter(int reverseSearch, const ChannelType * sourceType, size_t historySize) { McxStatus retVal = RETURN_OK; MemoryFilter * filter = (MemoryFilter *)object_create(MemoryFilter); @@ -953,11 +953,13 @@ static MemoryFilter * SetMemoryFilter(int reverseSearch, ChannelType * sourceTyp ChannelFilter * FilterFactory(ConnectionState * state, InterExtrapolationType extrapolation_type, InterExtrapolationParams * extrapolation_params, - ChannelType * channel_type, + const ChannelType * channel_type, InterExtrapolatingType inter_extrapolating_type, int is_decoupled, Component * sourceComp, + int source, Component * targetComp, + int target, const char * connString) { ChannelFilter * filter = NULL; McxStatus retVal; diff --git a/src/core/connections/Connection.h b/src/core/connections/Connection.h index 1e54b67..35b76c4 100644 --- a/src/core/connections/Connection.h +++ b/src/core/connections/Connection.h @@ -229,11 +229,13 @@ McxStatus ConnectionSetup(Connection * connection, struct ChannelOut * out, stru struct ChannelFilter *FilterFactory(ConnectionState *state, InterExtrapolationType extrapolation_type, InterExtrapolationParams *extrapolation_params, - ChannelType *channel_type, + const ChannelType *channel_type, InterExtrapolatingType inter_extrapolating_type, int is_decoupled, Component * sourceComp, + int source, Component * targetComp, + int target, const char * connString); diff --git a/src/core/connections/ConnectionInfoFactory.c b/src/core/connections/ConnectionInfoFactory.c index 9f0ef0b..b75fc3b 100644 --- a/src/core/connections/ConnectionInfoFactory.c +++ b/src/core/connections/ConnectionInfoFactory.c @@ -11,6 +11,8 @@ #include "core/connections/ConnectionInfoFactory.h" #include "core/connections/ConnectionInfo.h" #include "core/channels/ChannelDimension.h" +#include "core/channels/ConnectionStatus.h" + #include "core/Databus.h" #include "objects/Vector.h" @@ -272,6 +274,7 @@ static McxStatus ConnectionInfoFactoryInitConnectionInfo(ConnectionInfo * info, int tmp = info->sourceChannel; Component * tmpCmp = info->sourceComponent; ChannelDimension * tmpDim = info->sourceDimension; + char * tmpStr = strFromChannel; info->sourceChannel = info->targetChannel; info->targetChannel = tmp; @@ -284,6 +287,9 @@ static McxStatus ConnectionInfoFactoryInitConnectionInfo(ConnectionInfo * info, mcx_log(LOG_DEBUG, "Connection: Inverted connection (%s, %s) -- (%s, %s)", info->targetComponent->GetName(info->targetComponent), strFromChannel, info->sourceComponent->GetName(info->sourceComponent), strToChannel); + + strFromChannel = strToChannel; + strToChannel = tmpStr; } { @@ -301,6 +307,68 @@ static McxStatus ConnectionInfoFactoryInitConnectionInfo(ConnectionInfo * info, } } + { // check if ports are already occupied + Databus * databus = info->targetComponent->GetDatabus(info->targetComponent); + DatabusInfo * databusInfo = NULL; + databusInfo = DatabusGetInInfo(databus); + ChannelInfo * targetInfo = NULL; + targetInfo = DatabusInfoGetChannel(databusInfo, info->targetChannel); + + if (!targetInfo->connectionStatus) { + targetInfo->connectionStatus = CreateConnectionStatus(targetInfo->dimension); + if (targetInfo->connectionStatus == NULL) { + mcx_log( + LOG_ERROR, + "Could not create ConnectionStatus for input %s of element %s", + strToChannel, + info->targetComponent->GetName(info->targetComponent) + ); + retVal = RETURN_ERROR; + goto cleanup; + } + } + + if (info->targetDimension) { + size_t num_targetDimension = info->targetDimension->num; + for (size_t i = 0; i < num_targetDimension; i++) { + size_t startIdxs_targetDimension = info->targetDimension->startIdxs[i]; + size_t endIdxs_targetDimension = info->targetDimension->endIdxs[i]; + size_t startIdxs = startIdxs_targetDimension - targetInfo->dimension->startIdxs[i]; + size_t endIdxs = endIdxs_targetDimension - targetInfo->dimension->startIdxs[i]; + for (size_t j = startIdxs; j <= endIdxs; j++) { + if (targetInfo->connectionStatus->connected.array[i][j] != 0) { + mcx_log( + LOG_ERROR, + "Same input port vector component (port: %s, dimension: %zu, idx: %zu) of element %s cannot be connected more " + "than once", + strToChannel, + i + 1, + j + targetInfo->dimension->startIdxs[i], + info->targetComponent->GetName(info->targetComponent) + ); + retVal = RETURN_ERROR; + goto cleanup; + } else { + targetInfo->connectionStatus->connected.array[i][j] = 1; + } + } + } + } else { + if (targetInfo->connectionStatus->connected.scalar == 0) { + targetInfo->connectionStatus->connected.scalar = 1; + } else { + mcx_log( + LOG_ERROR, + "Same input port %s of element %s cannot be connected more than once", + strToChannel, + info->targetComponent->GetName(info->targetComponent) + ); + retVal = RETURN_ERROR; + goto cleanup; + } + } + } + // extrapolation if (connInput->interExtrapolationType.defined) { info->interExtrapolationType = connInput->interExtrapolationType.value; diff --git a/src/core/connections/FilteredConnection.c b/src/core/connections/FilteredConnection.c index dfa516a..df63b24 100644 --- a/src/core/connections/FilteredConnection.c +++ b/src/core/connections/FilteredConnection.c @@ -241,7 +241,7 @@ static McxStatus FilteredConnectionUpdateToOutput(Connection * connection, TimeI } else { size_t i = 0; size_t numFilters = FilteredConnectionGetNumFilters(filteredConnection); - ChannelType * type = info->type; + const ChannelType * type = info->type; mcx_array * elements = (mcx_array *) ChannelValueDataPointer(&filteredConnection->data.updateBuffer); char * dest = (char *) elements->data; @@ -302,7 +302,9 @@ static McxStatus AddFilter(Connection * connection) { info->isInterExtrapolating, ConnectionInfoIsDecoupled(info), info->sourceComponent, + info->sourceChannel, info->targetComponent, + info->targetChannel, connString); if (NULL == filteredConnection->data.filters[i]) { mcx_log(LOG_DEBUG, "Connection: Array filter creation failed for index %zu", i); @@ -319,7 +321,9 @@ static McxStatus AddFilter(Connection * connection) { info->isInterExtrapolating, ConnectionInfoIsDecoupled(info), info->sourceComponent, + info->sourceChannel, info->targetComponent, + info->targetChannel, connString); if (NULL == filteredConnection->data._filter) { mcx_log(LOG_DEBUG, "Connection: No Filter created"); @@ -330,7 +334,7 @@ static McxStatus AddFilter(Connection * connection) { } cleanup: - mcx_free(connString); + mcx_free((void *) connString); if (retVal != RETURN_OK) { return retVal; } diff --git a/src/core/connections/filters/DiscreteFilter.c b/src/core/connections/filters/DiscreteFilter.c index 2ad8241..d2f24a7 100644 --- a/src/core/connections/filters/DiscreteFilter.c +++ b/src/core/connections/filters/DiscreteFilter.c @@ -46,7 +46,7 @@ static McxStatus DiscreteFilterEnterCommunicationMode(ChannelFilter * filter, do return RETURN_OK; } -static McxStatus DiscreteFilterSetup(DiscreteFilter * filter, ChannelType * type) { +static McxStatus DiscreteFilterSetup(DiscreteFilter * filter, const ChannelType * type) { ChannelValueInit(&filter->lastSynchronizationStepValue, ChannelTypeClone(type)); ChannelValueInit(&filter->lastCouplingStepValue, ChannelTypeClone(type)); diff --git a/src/core/connections/filters/DiscreteFilter.h b/src/core/connections/filters/DiscreteFilter.h index cca3e6e..d5d981e 100644 --- a/src/core/connections/filters/DiscreteFilter.h +++ b/src/core/connections/filters/DiscreteFilter.h @@ -19,7 +19,7 @@ extern "C" { typedef struct DiscreteFilter DiscreteFilter; -typedef McxStatus (* fDiscreteFilterSetup)(DiscreteFilter * filter, ChannelType * type); +typedef McxStatus (* fDiscreteFilterSetup)(DiscreteFilter * filter, const ChannelType * type); extern const struct ObjectClass _DiscreteFilter; diff --git a/src/core/connections/filters/MemoryFilter.c b/src/core/connections/filters/MemoryFilter.c index ac14fa0..4a982ab 100644 --- a/src/core/connections/filters/MemoryFilter.c +++ b/src/core/connections/filters/MemoryFilter.c @@ -206,7 +206,7 @@ static McxStatus MemoryFilterEnterCommunicationMode(ChannelFilter * filter, doub return RETURN_OK; } -static McxStatus MemoryFilterSetup(MemoryFilter * filter, ChannelType * type, size_t historySize, int reverseSearch) { +static McxStatus MemoryFilterSetup(MemoryFilter * filter, const ChannelType * type, size_t historySize, int reverseSearch) { ChannelFilter * channelFilter = (ChannelFilter *)filter; size_t i = 0; diff --git a/src/core/connections/filters/MemoryFilter.h b/src/core/connections/filters/MemoryFilter.h index 1561fe6..db29796 100644 --- a/src/core/connections/filters/MemoryFilter.h +++ b/src/core/connections/filters/MemoryFilter.h @@ -19,7 +19,7 @@ extern "C" { typedef struct MemoryFilter MemoryFilter; -typedef McxStatus (* fMemoryFilterSetup)(MemoryFilter * filter, ChannelType * type, size_t historySize, int reverseSearch); +typedef McxStatus (* fMemoryFilterSetup)(MemoryFilter * filter, const ChannelType * type, size_t historySize, int reverseSearch); extern const struct ObjectClass _MemoryFilter; diff --git a/src/fmu/Fmu1Value.c b/src/fmu/Fmu1Value.c index 7f2818a..e43896c 100644 --- a/src/fmu/Fmu1Value.c +++ b/src/fmu/Fmu1Value.c @@ -117,7 +117,7 @@ static Fmu1ValueData * Fmu1ValueDataArrayMake(size_t numDims, size_t dims[], fmi } for (i = 0; i < num; i++) { - data->vr.array.values[i] = fmi2_import_get_variable_vr(data->var.array.values[i]); + data->vr.array.values[i] = fmi1_import_get_variable_vr(data->var.array.values[i]); } } return data; @@ -265,7 +265,7 @@ Fmu1Value * Fmu1ValueReadArray(const char * logPrefix, ChannelType * type, Chann } for (i = startIdx; i <= endIdx; i++) { - char * indexedChannelName = CreateIndexedName(channelName, i); + char * indexedChannelName = CreateIndexedName(channelName, (unsigned int) i); fmi1_import_variable_t * var = fmi1_import_get_variable_by_name(fmiImport, indexedChannelName); if (!var) { mcx_log(LOG_ERROR, "%s: Could not get variable %s", logPrefix, indexedChannelName); diff --git a/src/fmu/Fmu2Value.c b/src/fmu/Fmu2Value.c index cf2e0e5..b6d0571 100644 --- a/src/fmu/Fmu2Value.c +++ b/src/fmu/Fmu2Value.c @@ -50,7 +50,7 @@ Fmu2VariableInfo * Fmu2VariableInfoMake(fmi2_import_variable_t * var) { ChannelValueData max = { 0 }; int maxDefined = FALSE; - char * xmlDesc = fmi2_import_get_variable_description(var); + char * xmlDesc = (char *) fmi2_import_get_variable_description(var); info->desc = mcx_string_copy(xmlDesc); if (xmlDesc && !info->desc) { goto cleanup; @@ -501,7 +501,7 @@ Fmu2Value * Fmu2ReadFmu2ArrayValue(const char * logPrefix, ChannelType * type, c } for (i = startIdx; i <= endIdx; i++) { - char * indexedChannelName = CreateIndexedName(channelName, i); + char * indexedChannelName = CreateIndexedName(channelName, (unsigned int) i); fmi2_import_variable_t * var = fmi2_import_get_variable_by_name(fmiImport, indexedChannelName); if (!var) { mcx_log(LOG_ERROR, "%s: Could not get variable %s", logPrefix, indexedChannelName); diff --git a/src/fmu/common_fmu2.c b/src/fmu/common_fmu2.c index d801886..4d6d472 100644 --- a/src/fmu/common_fmu2.c +++ b/src/fmu/common_fmu2.c @@ -274,7 +274,9 @@ void Fmu2CommonStructDestructor(Fmu2CommonStruct * fmu) { } if (fmu->fmiImport) { + mcx_signal_handler_set_function("fmi2_import_free"); fmi2_import_free(fmu->fmiImport); + mcx_signal_handler_unset_function(); fmu->fmiImport = NULL; } } @@ -366,6 +368,7 @@ static ObjectContainer* Fmu2ReadArrayParamValues(const char * name, Fmu2Value * val = NULL; char * varName = (char *) mcx_calloc(stringBufferLength, sizeof(char)); fmi2_import_variable_t * var = NULL; + const char * unitName = NULL; ChannelValue chVal; if (!varName) { @@ -386,7 +389,14 @@ static ObjectContainer* Fmu2ReadArrayParamValues(const char * name, goto fmu2_read_array_param_values_for_cleanup; } - val = Fmu2ValueScalarMake(varName, var, NULL, NULL); + if (fmi2_base_type_real == fmi2_import_get_variable_base_type(var)) { + fmi2_import_unit_t * unit = fmi2_import_get_real_variable_unit(fmi2_import_get_variable_as_real(var)); + if (unit) { + unitName = fmi2_import_get_unit_name(unit); + } + } + + val = Fmu2ValueScalarMake(varName, var, unitName, NULL); if (!val) { retVal = RETURN_ERROR; goto fmu2_read_array_param_values_for_cleanup; @@ -520,7 +530,22 @@ McxStatus Fmu2ReadParams(ObjectContainer * params, ObjectContainer * arrayParams goto cleanup_1; } - retVal = proxy->Setup(proxy, name, parameterInput->parameter.arrayParameter->numDims, parameterInput->parameter.arrayParameter->dims); + size_t numDims = parameterInput->parameter.arrayParameter->numDims; + size_t * dims = mcx_malloc(sizeof(size_t) * numDims); + if (!dims) { + mcx_log(LOG_ERROR, "FMU: Copying parameter array dimensions failed: No memory"); + retVal = RETURN_ERROR; + goto cleanup_1; + } + size_t start, end; + for (size_t idx = 0; idx < numDims; idx++) { + start = parameterInput->parameter.arrayParameter->dims[idx]->start; + end = parameterInput->parameter.arrayParameter->dims[idx]->end; + dims[idx] = end - start + 1; + } + + retVal = proxy->Setup(proxy, name, numDims, dims); + mcx_free(dims); if (RETURN_ERROR == retVal) { mcx_log(LOG_ERROR, "FMU Array parameter %s: Array proxy setup failed", name); goto cleanup_1; @@ -778,7 +803,7 @@ McxStatus Fmu2SetDependencies(Fmu2CommonStruct * fmu2, Databus * db, Dependencie if (ChannelTypeIsArray(info->type)) { in_channel_connectivity[i].is_connected = TRUE; in_channel_connectivity[i].num_elems = 0; - in_channel_connectivity[i].elems = (int *) mcx_calloc(ChannelDimensionNumElements(info->dimension), sizeof(size_t)); + in_channel_connectivity[i].elems = (size_t *) mcx_calloc(ChannelDimensionNumElements(info->dimension), sizeof(size_t)); if (!in_channel_connectivity[i].elems) { mcx_log(LOG_ERROR, "SetDependenciesFMU2: Input connectivity element container allocation failed"); ret_val = RETURN_ERROR; @@ -801,7 +826,7 @@ McxStatus Fmu2SetDependencies(Fmu2CommonStruct * fmu2, Databus * db, Dependencie in_channel_connectivity[i].is_connected = TRUE; // scalar channels are treated like they have 1 element (equal to zero) in_channel_connectivity[i].num_elems = 1; - in_channel_connectivity[i].elems = (int*)mcx_calloc(1, sizeof(size_t)); + in_channel_connectivity[i].elems = (size_t *) mcx_calloc(1, sizeof(size_t)); if (!in_channel_connectivity[i].elems) { mcx_log(LOG_ERROR, "SetDependenciesFMU2: Input connectivity element allocation failed"); ret_val = RETURN_ERROR; diff --git a/src/objects/ObjectContainer.c b/src/objects/ObjectContainer.c index c7c9cdc..48304d1 100644 --- a/src/objects/ObjectContainer.c +++ b/src/objects/ObjectContainer.c @@ -476,7 +476,7 @@ static McxStatus ObjectContainerSetElementName(ObjectContainer * container, size_t pos, const char * name) { if (pos >= container->size) { - mcx_log(LOG_ERROR, "ObjectContainer: SetElementName: Position %u out of bounds, max is %u", pos, container->size); + mcx_log(LOG_ERROR, "ObjectContainer: SetElementName: Position %zu out of bounds, max is %zu", pos, container->size); return RETURN_ERROR; } diff --git a/src/objects/Vector.c b/src/objects/Vector.c index 49915e3..6bbf66d 100644 --- a/src/objects/Vector.c +++ b/src/objects/Vector.c @@ -85,7 +85,7 @@ static McxStatus VectorSetAt(Vector * vector, size_t pos, void * elem) { return RETURN_OK; } -static size_t VectorFindIdx(const Vector * vector, fVectorElemPredicate pred, void * args) { +static size_t VectorFindIdx(const Vector * vector, fVectorElemPredicate pred, const void * args) { size_t i = 0; char * it = NULL; @@ -98,7 +98,7 @@ static size_t VectorFindIdx(const Vector * vector, fVectorElemPredicate pred, vo return SIZE_T_ERROR; } -static void * VectorFind(const Vector * vector, fVectorElemPredicate pred, void * args) { +static void * VectorFind(const Vector * vector, fVectorElemPredicate pred, const void * args) { size_t idx = vector->FindIdx(vector, pred, args); if (idx == SIZE_T_ERROR) { diff --git a/src/objects/Vector.h b/src/objects/Vector.h index 5572555..43d943e 100644 --- a/src/objects/Vector.h +++ b/src/objects/Vector.h @@ -29,9 +29,9 @@ typedef void (*fVectorElemDestructor)(void * elem); typedef void (*fVectorSetup)(Vector * vector, size_t elemSize, fVectorElemInitializer elemInitializer, fVectorElemSetter elemSetter, fVectorElemDestructor elemDestructor); typedef size_t (*fVectorSize)(const Vector * vector); -typedef int (*fVectorElemPredicate)(void * elem, void * args); -typedef void * (*fVectorFind)(const Vector * vector, fVectorElemPredicate pred, void * args); -typedef size_t (*fVectorFindIdx)(const Vector * vector, fVectorElemPredicate pred, void * args); +typedef int (*fVectorElemPredicate)(const void * elem, const void * args); +typedef void * (*fVectorFind)(const Vector * vector, fVectorElemPredicate pred, const void * args); +typedef size_t (*fVectorFindIdx)(const Vector * vector, fVectorElemPredicate pred, const void * args); typedef void * (*fVectorAt)(const Vector * vector, size_t idx); typedef McxStatus (*fVectorSetAt)(Vector * vector, size_t pos, void * elem); typedef McxStatus (*fVectorReserve)(Vector * vector, size_t newCapacity); diff --git a/src/reader/EnumMapping.c b/src/reader/EnumMapping.c index be08854..3198806 100644 --- a/src/reader/EnumMapping.c +++ b/src/reader/EnumMapping.c @@ -20,7 +20,6 @@ extern "C" { MapStringInt storeLevelMapping[] = { {"none", STORE_NONE}, - {"micro", STORE_MICRO}, {"coupling", STORE_COUPLING}, {"synchronization", STORE_SYNCHRONIZATION}, {NULL, 0} diff --git a/src/reader/ssp/Ports.c b/src/reader/ssp/Ports.c index 93c4b08..bc06ebc 100644 --- a/src/reader/ssp/Ports.c +++ b/src/reader/ssp/Ports.c @@ -26,12 +26,12 @@ extern "C" { #endif /* __cplusplus */ static MapStringChannelType _typeMapping[] = { - {"Real", &ChannelTypeDouble}, - {"Integer", &ChannelTypeInteger}, - {"Boolean", &ChannelTypeBool}, - {"String", &ChannelTypeString}, - {"Binary", &ChannelTypeBinary}, - {NULL, &ChannelTypeUnknown}, + { "Real", &ChannelTypeDouble}, + {"Integer", &ChannelTypeInteger}, + {"Boolean", &ChannelTypeBool}, + { "String", &ChannelTypeString}, + { "Binary", &ChannelTypeBinary}, + { NULL, &ChannelTypeUnknown}, }; static MapStringChannelType _vectorTypeMapping[] = { diff --git a/src/steptypes/StepType.c b/src/steptypes/StepType.c index 0a1a39d..2e13f50 100644 --- a/src/steptypes/StepType.c +++ b/src/steptypes/StepType.c @@ -82,9 +82,10 @@ McxStatus ComponentDoCommunicationStep(Component * comp, size_t group, StepTypeP while ( comp->GetFinishState(comp) != COMP_IS_FINISHED && - comp->syncHints.stepSizesAreMultiples ? + (comp->syncHints.stepSizesAreMultiples ? double_cmp_eps_abs(comp->GetTime(comp), stepEndTime, comp->syncHints.eps) == CMP_LT : double_lt(comp->GetTime(comp), stepEndTime) + ) ) { if (comp->HasOwnTime(comp)) { interval.startTime = comp->GetTime(comp); @@ -154,7 +155,7 @@ McxStatus ComponentDoCommunicationStep(Component * comp, size_t group, StepTypeP } interval.startTime = comp->GetTime(comp); - interval.endTime = comp->GetTime(comp); + interval.endTime = interval.startTime; retVal = ComponentUpdateOutChannels(comp, &interval); if (RETURN_ERROR == retVal) { mcx_log(LOG_ERROR, "%s: Updating outports failed", comp->GetName(comp)); @@ -316,7 +317,7 @@ int IsStepTypeMultiThreading(StepTypeType type) { ); } -static McxStatus StepTypeConfigure(StepType * stepType, StepTypeParams * params, SubModel * subModel) { +static McxStatus StepTypeConfigure(StepType * stepType, StepTypeParams * params, SubModel * subModel, Model * model) { return RETURN_OK; } diff --git a/src/steptypes/StepType.h b/src/steptypes/StepType.h index b0676d0..3e1f851 100644 --- a/src/steptypes/StepType.h +++ b/src/steptypes/StepType.h @@ -20,6 +20,7 @@ extern "C" { typedef struct StepType StepType; typedef struct StepTypeParams StepTypeParams; typedef struct Component Component; +typedef struct Model Model; typedef struct SubModel SubModel; typedef struct CompAndGroup CompAndGroup; @@ -49,7 +50,7 @@ int IsStepTypeMultiThreading(StepTypeType type); typedef McxStatus (* fStepTypeDoStep)(StepType * stepType, StepTypeParams * params, SubModel * subModel); typedef McxStatus (* fStepTypeFinish)(StepType * stepType, StepTypeParams * params, SubModel * subModel, FinishState * finishState); -typedef McxStatus (* fStepTypeConfigure)(StepType * stepType, StepTypeParams * params, SubModel * subModel); +typedef McxStatus (* fStepTypeConfigure)(StepType * stepType, StepTypeParams * params, SubModel * subModel, Model * model); typedef StepTypeType (* fStepTypeGetType)(StepType * type); diff --git a/src/steptypes/StepTypeParallelMT.c b/src/steptypes/StepTypeParallelMT.c index ee43557..9ebc983 100644 --- a/src/steptypes/StepTypeParallelMT.c +++ b/src/steptypes/StepTypeParallelMT.c @@ -203,7 +203,7 @@ static McxStatus ParallelMTDoStep(StepType * stepType, StepTypeParams * params, return RETURN_OK; } -static McxStatus ParallelMTConfigure(StepType * stepType, StepTypeParams * params, SubModel * subModel) { +static McxStatus ParallelMTConfigure(StepType * stepType, StepTypeParams * params, SubModel * subModel, Model * model) { StepTypeParallelMT * parallelMTType = (StepTypeParallelMT *) stepType; DoStepThreadCounter * counter = parallelMTType->counter; diff --git a/src/storage/ChannelStorage.c b/src/storage/ChannelStorage.c index 65ca204..4adcab6 100644 --- a/src/storage/ChannelStorage.c +++ b/src/storage/ChannelStorage.c @@ -358,7 +358,7 @@ char ** ExpandedChannelNames(const char * name, size_t start, size_t end) { } for (i = start; i <= end; i++) { - names[i-start] = CreateIndexedName(name, i); + names[i-start] = CreateIndexedName(name, (unsigned int) i); } names[i-start] = NULL; diff --git a/src/storage/PPD.c b/src/storage/PPD.c index e90dfe0..4c11a44 100644 --- a/src/storage/PPD.c +++ b/src/storage/PPD.c @@ -171,7 +171,7 @@ static McxStatus PpdFolderAddElement(PpdFolder * folder, PpdElement * element) { return elements->SetElementName(elements, elements->Size(elements) - 1, element->GetName(element)); } -static char PPD_SEP = '.'; +static char PPD_SEP = '#'; static PpdFolder * PpdFolderInsertComponent(PpdFolder * folder, const char * linkType, const char * compName, const char * fileNameOut, const char * fileNameIn, const char * fileNameLocal, const char * fileNameRTFactor) { const char * sep = strchr(compName, PPD_SEP); diff --git a/src/storage/StorageBackendCsv.c b/src/storage/StorageBackendCsv.c index 67e216b..4f6aaff 100644 --- a/src/storage/StorageBackendCsv.c +++ b/src/storage/StorageBackendCsv.c @@ -208,7 +208,6 @@ static McxStatus SetupComponentFilesCsv(StorageBackend * backend) { size_t j = 0; char * localName = mcx_string_encode_filename(comp->GetName(comp)); - size_t numberOfPorts[CHANNEL_STORE_NUM] = { 0 }; //avoid empty result files numberOfPorts[CHANNEL_STORE_IN] = comp->GetNumWriteInChannels(comp); numberOfPorts[CHANNEL_STORE_OUT] = comp->GetNumWriteOutChannels(comp); diff --git a/src/util/win/time.c b/src/util/win/time.c index 990c9af..ba0f74f 100644 --- a/src/util/win/time.c +++ b/src/util/win/time.c @@ -58,7 +58,7 @@ double mcx_time_to_micro_s(McxTime * time) { micro_secs.QuadPart = time->QuadPart * 1000000; micro_secs.QuadPart /= freq.QuadPart; - return micro_secs.QuadPart; + return (double) micro_secs.QuadPart; } McxTime mcx_seconds_to_time(int seconds) {