jm_status_enu_t fmi2_capi_free_dll(fmi2_capi_t* fmu) { if (fmu == NULL) { return jm_status_error; /* Return without writing any log message */ } if (fmu->dllHandle) { jm_status_enu_t status = (fmu->debugMode != 0) ? /* When running valgrind this may be convenient to track mem leaks */ jm_status_success: jm_portability_free_dll_handle(fmu->dllHandle); fmu->dllHandle = 0; if (status == jm_status_error) { /* Free the library handle */ jm_log(fmu->callbacks, FMI_CAPI_MODULE_NAME, jm_log_level_error, "Could not free the FMU binary: %s", jm_portability_get_last_dll_error()); return jm_status_error; } else { jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Successfully unloaded FMU binary"); return jm_status_success; } } return jm_status_success; }
/* Print msgIn into msgOut by expanding variable references of the form #<Type><VR># into variable names and replacing '##' with a single # */ void fmi1_import_expand_variable_references_impl(fmi1_import_t* fmu, const char* msgIn){ jm_vector(char)* msgOut = &fmu->logMessageBuffer; fmi1_xml_model_description_t* md = fmu->md; jm_callbacks* callbacks = fmu->callbacks; char curCh; const char* firstRef; size_t i; /* next char index after curCh in msgIn*/ size_t msgLen = strlen(msgIn)+1; /* original message length including terminating 0 */ if(jm_vector_reserve(char)(msgOut, msgLen + 100) < msgLen + 100) { jm_log(fmu->callbacks,"LOGGER", jm_log_level_warning, "Could not allocate memory for the log message"); jm_vector_resize(char)(msgOut, 6); memcpy(jm_vector_get_itemp(char)(msgOut,0),"ERROR",6); /* at least 16 chars are always there */ return; } /* check if there are any refs at all and copy the head of the string without references */ firstRef = strchr(msgIn, '#'); if(firstRef) { i = firstRef - msgIn; jm_vector_resize(char)(msgOut, i); if(i) { memcpy(jm_vector_get_itemp(char)(msgOut, 0), msgIn, i); } curCh = msgIn[i++]; } else { jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut, 0), msgIn, msgLen); return; } do { if (curCh!='#') { jm_vector_push_back(char)(msgOut, curCh); /* copy in to out */ } else if(msgIn[i] == '#') { jm_vector_push_back(char)(msgOut, '#'); i++; /* skip the second # */ } else { fmi1_value_reference_t vr = fmi1_undefined_value_reference; char typeChar = msgIn[i++]; size_t pastePos = jm_vector_get_size(char)(msgOut); fmi1_base_type_enu_t baseType; size_t num_digits; fmi1_xml_variable_t* var; const char* name; size_t nameLen; switch(typeChar) { case 'r': baseType = fmi1_base_type_real; break; case 'i': baseType = fmi1_base_type_int; break; case 'b': baseType = fmi1_base_type_bool; break; case 's': baseType = fmi1_base_type_str; break; default: jm_vector_push_back(char)(msgOut, 0); jm_log(callbacks,"LOGGER", jm_log_level_warning, "Expected type specification character 'r', 'i', 'b' or 's' in log message here: '%s'", jm_vector_get_itemp(char)(msgOut,0)); jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut,0),msgIn,msgLen); return; } curCh = msgIn[i++]; while( isdigit(curCh) ) { jm_vector_push_back(char)(msgOut, curCh); curCh = msgIn[i++]; } num_digits = jm_vector_get_size(char)(msgOut) - pastePos; jm_vector_push_back(char)(msgOut, 0); if(num_digits == 0) { jm_log(callbacks,"LOGGER", jm_log_level_warning, "Expected value reference in log message here: '%s'", jm_vector_get_itemp(char)(msgOut,0)); jm_vector_resize(char)(msgOut, msgLen); jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut,0),msgIn,msgLen); return; } else if(curCh != '#') { jm_log(callbacks,"LOGGER", jm_log_level_warning, "Expected terminating '#' in log message here: '%s'", jm_vector_get_itemp(char)(msgOut,0)); jm_vector_resize(char)(msgOut, msgLen); jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut,0),msgIn,msgLen); return; } if(sscanf(jm_vector_get_itemp(char)(msgOut, pastePos), "%u",&vr) != 1) { jm_log(callbacks,"LOGGER", jm_log_level_warning, "Could not decode value reference in log message here: '%s'", jm_vector_get_itemp(char)(msgOut,0)); jm_vector_resize(char)(msgOut, msgLen); jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut,0),msgIn,msgLen); return; } var = fmi1_xml_get_variable_by_vr(md,baseType,vr); if(!var) { jm_log(callbacks,"LOGGER", jm_log_level_warning, "Could not find variable referenced in log message here: '%s'", jm_vector_get_itemp(char)(msgOut,0)); jm_vector_resize(char)(msgOut, msgLen); jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut,0),msgIn,msgLen); return; } name = fmi1_xml_get_variable_name(var); nameLen = strlen(name); if(jm_vector_resize(char)(msgOut, pastePos + nameLen) != pastePos + nameLen) { jm_log(callbacks,"LOGGER", jm_log_level_warning, "Could not allocate memory for the log message"); jm_vector_resize(char)(msgOut, msgLen); jm_vector_resize(char)(msgOut, msgLen); memcpy(jm_vector_get_itemp(char)(msgOut,0),msgIn,msgLen); return; }; memcpy(jm_vector_get_itemp(char)(msgOut, pastePos), name, nameLen); } curCh = msgIn[i++]; } while (curCh); jm_vector_push_back(char)(msgOut, 0); }