From 7097ed6d2440f2548a001084bf41e4b4694e08e0 Mon Sep 17 00:00:00 2001 From: JKRT Date: Mon, 2 Mar 2026 17:39:21 +0100 Subject: [PATCH] Added several missing API functions --- src/api.jl | 670 +++++++++++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 233 ++++++++++++++++ 2 files changed, 903 insertions(+) diff --git a/src/api.jl b/src/api.jl index 99f8b37..07a9a56 100644 --- a/src/api.jl +++ b/src/api.jl @@ -280,3 +280,673 @@ function ModelicaStrings_length(string::String) (Cstring,), string) end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_getDer2Value(void* tableID, int icol, + double u, double der_u, double der2_u); +""" +function ModelicaStandardTables_CombiTable1D_getDer2Value( + tableID::Ptr{Cvoid}, + icol::Cint, + u::Cdouble, + der_u::Cdouble, + der2_u::Cdouble, + )::Cdouble +end + +""" +ModelicaStandardTables_CombiTable1D_getDer2Value( + tableID::ExternalCombiTable1D, + icol::Int64, + u::Float64, + der_u::Float64, + der2_u::Float64, + ) +""" +function ModelicaStandardTables_CombiTable1D_getDer2Value( + tableID::ExternalCombiTable1D, + icol::Int64, + u::Float64, + der_u::Float64, + der2_u::Float64, + ) + local res = 0.0 + try + res = ccall((:ModelicaStandardTables_CombiTable1D_getDer2Value, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cdouble, Cdouble, Cdouble), + tableID, icol, u, der_u, der2_u) + catch e + @error "Calling ModelicaStandardTables_CombiTable1D_getDer2Value. Check that icol is within the bounds of the table" icol + end + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_read(void* tableID, int force, int verbose); +""" +function ModelicaStandardTables_CombiTable1D_read(tableID::Ptr{Cvoid}, force::Cint, verbose::Cint)::Cdouble +end + +""" +ModelicaStandardTables_CombiTable1D_read(tableID::ExternalCombiTable1D, force::Int64, verbose::Int64) +""" +function ModelicaStandardTables_CombiTable1D_read(tableID::ExternalCombiTable1D, force::Int64, verbose::Int64) + res = ccall((:ModelicaStandardTables_CombiTable1D_read, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cint), + tableID, force, verbose) + return res +end + +#= ================================================================ =# +#= CombiTimeTable =# +#= ================================================================ =# + +const ExternalCombiTimeTable = Ptr{Nothing} + +""" +MODELICA_EXPORT void* ModelicaStandardTables_CombiTimeTable_init2( + _In_z_ const char* fileName, + _In_z_ const char* tableName, + _In_ double* table, + size_t nRow, + size_t nColumn, + double startTime, + _In_ int* columns, + size_t nCols, + int smoothness, + int extrapolation, + double shiftTime, + int timeEvents, + int verbose) MODELICA_NONNULLATTR; +""" +function ModelicaStandardTables_CombiTimeTable_init2( + fileName::Cstring, + tableName::Cstring, + table::Ptr{Cdouble}, + nRow::Csize_t, + nColumn::Csize_t, + startTime::Cdouble, + columns::Ptr{Cint}, + nCols::Csize_t, + smoothness::Cint, + extrapolation::Cint, + shiftTime::Cdouble, + timeEvents::Cint, + verbose::Cint)::Ptr{Cvoid} +end + +function ModelicaStandardTables_CombiTimeTable_init2( + fileName::String, + tableName::String, + table::Vector{Vector{Float64}}, + nRow::Int64, + nColumn::Int64, + startTime::Float64, + columns::Vector{Int64}, + nCols::Int64, + smoothness::Int64, + extrapolation::Int64, + shiftTime::Float64, + timeEvents::Int64, + verbose::Integer) + #= Requires Julia > 1.9 =# + local tableM = stack(table; dims=1) + ModelicaStandardTables_CombiTimeTable_init2( + fileName, tableName, tableM, + nRow, nColumn, startTime, + columns, nCols, + smoothness, extrapolation, shiftTime, timeEvents, verbose) +end + +function ModelicaStandardTables_CombiTimeTable_init2( + fileName::String, + tableName::String, + table::Matrix{Float64}, + nRow::Int64, + nColumn::Int64, + startTime::Float64, + columns::Vector{Int64}, + nCols::Int64, + smoothness::Int64, + extrapolation::Int64, + shiftTime::Float64, + timeEvents::Int64, + verbose::Integer) + #= Converts the table into the C format, that is double* =# + local tableCShape = reduce(vcat, [table[j,i] for i in 1:size(table,2), j in 1:size(table,1)]) + local res = ccall((:ModelicaStandardTables_CombiTimeTable_init2, installedLibPath), Ptr{Cvoid}, + (Cstring, Cstring, Ptr{Cdouble}, Csize_t, Csize_t, Cdouble, Ptr{Cint}, Csize_t, Cint, Cint, Cdouble, Cint, Cint), + fileName, tableName, tableCShape, nRow, nColumn, startTime, columns, nCols, smoothness, extrapolation, shiftTime, timeEvents, verbose) + res +end + +""" +void ModelicaStandardTables_CombiTimeTable_close(void* tableID) +""" +function ModelicaStandardTables_CombiTimeTable_close(_tableID::Ptr) +end + +function ModelicaStandardTables_CombiTimeTable_close(tableID::ExternalCombiTimeTable) + ccall( + (:ModelicaStandardTables_CombiTimeTable_close, installedLibPath), + Cvoid #= Returns =#, + (Ptr{Cvoid},), + tableID) +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_getValue(void* tableID, int icol, + double t, double nextTimeEvent, double preNextTimeEvent); +""" +function ModelicaStandardTables_CombiTimeTable_getValue( + tableID::Ptr{Cvoid}, + icol::Cint, + t::Cdouble, + nextTimeEvent::Cdouble, + preNextTimeEvent::Cdouble, + )::Cdouble +end + +function ModelicaStandardTables_CombiTimeTable_getValue( + tableID::ExternalCombiTimeTable, + icol::Int64, + t::Float64, + nextTimeEvent::Float64, + preNextTimeEvent::Float64, + )::Float64 + res = ccall((:ModelicaStandardTables_CombiTimeTable_getValue, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cdouble, Cdouble, Cdouble), + tableID, icol, t, nextTimeEvent, preNextTimeEvent) +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_getDerValue(void* tableID, int icol, + double t, double nextTimeEvent, double preNextTimeEvent, double der_t); +""" +function ModelicaStandardTables_CombiTimeTable_getDerValue( + tableID::Ptr{Cvoid}, + icol::Cint, + t::Cdouble, + nextTimeEvent::Cdouble, + preNextTimeEvent::Cdouble, + der_t::Cdouble, + )::Cdouble +end + +function ModelicaStandardTables_CombiTimeTable_getDerValue( + tableID::ExternalCombiTimeTable, + icol::Int64, + t::Float64, + nextTimeEvent::Float64, + preNextTimeEvent::Float64, + der_t::Float64, + ) + local res = 0.0 + try + res = ccall((:ModelicaStandardTables_CombiTimeTable_getDerValue, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cdouble, Cdouble, Cdouble, Cdouble), + tableID, icol, t, nextTimeEvent, preNextTimeEvent, der_t) + catch e + @error "Calling ModelicaStandardTables_CombiTimeTable_getDerValue. Check that icol is within the bounds of the table" icol + end + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_getDer2Value(void* tableID, int icol, + double t, double nextTimeEvent, double preNextTimeEvent, + double der_t, double der2_t); +""" +function ModelicaStandardTables_CombiTimeTable_getDer2Value( + tableID::Ptr{Cvoid}, + icol::Cint, + t::Cdouble, + nextTimeEvent::Cdouble, + preNextTimeEvent::Cdouble, + der_t::Cdouble, + der2_t::Cdouble, + )::Cdouble +end + +function ModelicaStandardTables_CombiTimeTable_getDer2Value( + tableID::ExternalCombiTimeTable, + icol::Int64, + t::Float64, + nextTimeEvent::Float64, + preNextTimeEvent::Float64, + der_t::Float64, + der2_t::Float64, + ) + local res = 0.0 + try + res = ccall((:ModelicaStandardTables_CombiTimeTable_getDer2Value, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble), + tableID, icol, t, nextTimeEvent, preNextTimeEvent, der_t, der2_t) + catch e + @error "Calling ModelicaStandardTables_CombiTimeTable_getDer2Value. Check that icol is within the bounds of the table" icol + end + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_minimumTime(void* tableID); +""" +function ModelicaStandardTables_CombiTimeTable_minimumTime(arg::Ptr) +end + +function ModelicaStandardTables_CombiTimeTable_minimumTime(tableID::ExternalCombiTimeTable)::Float64 + res = ccall((:ModelicaStandardTables_CombiTimeTable_minimumTime, installedLibPath), + #= Returns =# Cdouble, + (Ptr{Cvoid},), + tableID) + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_maximumTime(void* tableID); +""" +function ModelicaStandardTables_CombiTimeTable_maximumTime(arg::Ptr) +end + +function ModelicaStandardTables_CombiTimeTable_maximumTime(tableID::ExternalCombiTimeTable)::Float64 + res = ccall((:ModelicaStandardTables_CombiTimeTable_maximumTime, installedLibPath), + #= Returns =# Cdouble, + (Ptr{Cvoid},), + tableID) + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_nextTimeEvent(void* tableID, double t); +""" +function ModelicaStandardTables_CombiTimeTable_nextTimeEvent(arg::Ptr, t::Cdouble)::Cdouble +end + +function ModelicaStandardTables_CombiTimeTable_nextTimeEvent(tableID::ExternalCombiTimeTable, t::Float64)::Float64 + res = ccall((:ModelicaStandardTables_CombiTimeTable_nextTimeEvent, installedLibPath), + #= Returns =# Cdouble, + (Ptr{Cvoid}, Cdouble), + tableID, t) + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_read(void* tableID, int force, int verbose); +""" +function ModelicaStandardTables_CombiTimeTable_read(tableID::Ptr{Cvoid}, force::Cint, verbose::Cint)::Cdouble +end + +function ModelicaStandardTables_CombiTimeTable_read(tableID::ExternalCombiTimeTable, force::Int64, verbose::Int64) + res = ccall((:ModelicaStandardTables_CombiTimeTable_read, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cint), + tableID, force, verbose) + return res +end + +#= ================================================================ =# +#= CombiTable2D =# +#= ================================================================ =# + +const ExternalCombiTable2D = Ptr{Nothing} + +""" +MODELICA_EXPORT void* ModelicaStandardTables_CombiTable2D_init2( + _In_z_ const char* fileName, + _In_z_ const char* tableName, + _In_ double* table, + size_t nRow, + size_t nColumn, + int smoothness, + int extrapolation, + int verbose) MODELICA_NONNULLATTR; +""" +function ModelicaStandardTables_CombiTable2D_init2( + fileName::Cstring, + tableName::Cstring, + table::Ptr{Cdouble}, + nRow::Csize_t, + nColumn::Csize_t, + smoothness::Cint, + extrapolation::Cint, + verbose::Cint)::Ptr{Cvoid} +end + +function ModelicaStandardTables_CombiTable2D_init2( + fileName::String, + tableName::String, + table::Vector{Vector{Float64}}, + nRow::Int64, + nColumn::Int64, + smoothness::Int64, + extrapolation::Int64, + verbose::Integer) + #= Requires Julia > 1.9 =# + local tableM = stack(table; dims=1) + ModelicaStandardTables_CombiTable2D_init2( + fileName, tableName, tableM, + nRow, nColumn, + smoothness, extrapolation, verbose) +end + +function ModelicaStandardTables_CombiTable2D_init2( + fileName::String, + tableName::String, + table::Matrix{Float64}, + nRow::Int64, + nColumn::Int64, + smoothness::Int64, + extrapolation::Int64, + verbose::Integer) + #= Converts the table into the C format, that is double* =# + local tableCShape = reduce(vcat, [table[j,i] for i in 1:size(table,2), j in 1:size(table,1)]) + local res = ccall((:ModelicaStandardTables_CombiTable2D_init2, installedLibPath), Ptr{Cvoid}, + (Cstring, Cstring, Ptr{Cdouble}, Csize_t, Csize_t, Cint, Cint, Cint), + fileName, tableName, tableCShape, nRow, nColumn, smoothness, extrapolation, verbose) + res +end + +""" +void ModelicaStandardTables_CombiTable2D_close(void* tableID) +""" +function ModelicaStandardTables_CombiTable2D_close(_tableID::Ptr) +end + +function ModelicaStandardTables_CombiTable2D_close(tableID::ExternalCombiTable2D) + ccall( + (:ModelicaStandardTables_CombiTable2D_close, installedLibPath), + Cvoid #= Returns =#, + (Ptr{Cvoid},), + tableID) +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_getValue(void* tableID, double u1, double u2); +""" +function ModelicaStandardTables_CombiTable2D_getValue( + arg::Ptr, + u1::Cdouble, + u2::Cdouble, + )::Cdouble +end + +function ModelicaStandardTables_CombiTable2D_getValue( + tableID::ExternalCombiTable2D, + u1::Float64, + u2::Float64, + )::Float64 + res = ccall((:ModelicaStandardTables_CombiTable2D_getValue, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cdouble, Cdouble), + tableID, u1, u2) +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_getDerValue(void* tableID, + double u1, double u2, double der_u1, double der_u2); +""" +function ModelicaStandardTables_CombiTable2D_getDerValue( + arg::Ptr, + u1::Cdouble, + u2::Cdouble, + der_u1::Cdouble, + der_u2::Cdouble, + )::Cdouble +end + +function ModelicaStandardTables_CombiTable2D_getDerValue( + tableID::ExternalCombiTable2D, + u1::Float64, + u2::Float64, + der_u1::Float64, + der_u2::Float64, + ) + local res = 0.0 + try + res = ccall((:ModelicaStandardTables_CombiTable2D_getDerValue, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cdouble, Cdouble, Cdouble, Cdouble), + tableID, u1, u2, der_u1, der_u2) + catch e + @error "Calling ModelicaStandardTables_CombiTable2D_getDerValue" u1 u2 + end + return res +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_getDer2Value(void* tableID, + double u1, double u2, double der_u1, double der_u2, + double der2_u1, double der2_u2); +""" +function ModelicaStandardTables_CombiTable2D_getDer2Value( + arg::Ptr, + u1::Cdouble, + u2::Cdouble, + der_u1::Cdouble, + der_u2::Cdouble, + der2_u1::Cdouble, + der2_u2::Cdouble, + )::Cdouble +end + +function ModelicaStandardTables_CombiTable2D_getDer2Value( + tableID::ExternalCombiTable2D, + u1::Float64, + u2::Float64, + der_u1::Float64, + der_u2::Float64, + der2_u1::Float64, + der2_u2::Float64, + ) + local res = 0.0 + try + res = ccall((:ModelicaStandardTables_CombiTable2D_getDer2Value, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble, Cdouble), + tableID, u1, u2, der_u1, der_u2, der2_u1, der2_u2) + catch e + @error "Calling ModelicaStandardTables_CombiTable2D_getDer2Value" u1 u2 + end + return res +end + +""" +MODELICA_EXPORT void ModelicaStandardTables_CombiTable2D_minimumAbscissa(void* tableID, double* uMin); + Writes two doubles to uMin: uMin[0] = min of u1 axis, uMin[1] = min of u2 axis. +""" +function ModelicaStandardTables_CombiTable2D_minimumAbscissa(arg::Ptr) +end + +function ModelicaStandardTables_CombiTable2D_minimumAbscissa(tableID::ExternalCombiTable2D) + uMin = zeros(Cdouble, 2) + ccall((:ModelicaStandardTables_CombiTable2D_minimumAbscissa, installedLibPath), + Cvoid #= Returns =#, + (Ptr{Cvoid}, Ptr{Cdouble}), + tableID, uMin) + return (uMin[1], uMin[2]) +end + +""" +MODELICA_EXPORT void ModelicaStandardTables_CombiTable2D_maximumAbscissa(void* tableID, double* uMax); + Writes two doubles to uMax: uMax[0] = max of u1 axis, uMax[1] = max of u2 axis. +""" +function ModelicaStandardTables_CombiTable2D_maximumAbscissa(arg::Ptr) +end + +function ModelicaStandardTables_CombiTable2D_maximumAbscissa(tableID::ExternalCombiTable2D) + uMax = zeros(Cdouble, 2) + ccall((:ModelicaStandardTables_CombiTable2D_maximumAbscissa, installedLibPath), + Cvoid #= Returns =#, + (Ptr{Cvoid}, Ptr{Cdouble}), + tableID, uMax) + return (uMax[1], uMax[2]) +end + +""" +MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_read(void* tableID, int force, int verbose); +""" +function ModelicaStandardTables_CombiTable2D_read(tableID::Ptr{Cvoid}, force::Cint, verbose::Cint)::Cdouble +end + +function ModelicaStandardTables_CombiTable2D_read(tableID::ExternalCombiTable2D, force::Int64, verbose::Int64) + res = ccall((:ModelicaStandardTables_CombiTable2D_read, installedLibPath), + Cdouble #= Returns =#, + (Ptr{Cvoid}, Cint, Cint), + tableID, force, verbose) + return res +end + +#= ================================================================ =# +#= ModelicaStrings - Additional functions =# +#= ================================================================ =# + +""" +MODELICA_EXPORT const char* ModelicaStrings_substring(_In_z_ const char* string, int startIndex, int endIndex); +""" +function ModelicaStrings_substring(string::Ptr{Cchar}, startIndex::Cint, endIndex::Cint) +end + +""" +ModelicaStrings_substring(string::String, startIndex::Int64, endIndex::Int64) + Returns the substring from startIndex to endIndex (1-based, inclusive). +""" +function ModelicaStrings_substring(string::String, startIndex::Int64, endIndex::Int64) + res = ccall((:ModelicaStrings_substring, installedLibPathlibModelicaExternalC), + #= Returns =# Cstring, + (Cstring, Cint, Cint), + string, startIndex, endIndex) + return unsafe_string(res) +end + +""" +MODELICA_EXPORT int ModelicaStrings_compare(_In_z_ const char* string1, _In_z_ const char* string2, int caseSensitive); +""" +function ModelicaStrings_compare(string1::Ptr{Cchar}, string2::Ptr{Cchar}, caseSensitive::Cint) +end + +""" +ModelicaStrings_compare(string1::String, string2::String, caseSensitive::Int64) + Compares two strings. Returns 1 if string1 < string2, 2 if equal, 3 if string1 > string2. +""" +function ModelicaStrings_compare(string1::String, string2::String, caseSensitive::Int64) + res = ccall((:ModelicaStrings_compare, installedLibPathlibModelicaExternalC), + #= Returns =# Cint, + (Cstring, Cstring, Cint), + string1, string2, caseSensitive) + return Int64(res) +end + +""" +MODELICA_EXPORT void ModelicaStrings_scanIdentifier(_In_z_ const char* string, int startIndex, + int* nextIndex, const char** identifier); +""" +function ModelicaStrings_scanIdentifier(string::Ptr{Cchar}, startIndex::Cint) +end + +""" +ModelicaStrings_scanIdentifier(string::String, startIndex::Int64) + Scans for an identifier starting at startIndex. + Returns (nextIndex, identifier). +""" +function ModelicaStrings_scanIdentifier(string::String, startIndex::Int64) + nextIndex = Ref{Cint}(0) + identifier = Ref{Cstring}(C_NULL) + ccall((:ModelicaStrings_scanIdentifier, installedLibPathlibModelicaExternalC), + Cvoid, + (Cstring, Cint, Ref{Cint}, Ref{Cstring}), + string, startIndex, nextIndex, identifier) + local idStr = identifier[] == C_NULL ? "" : unsafe_string(identifier[]) + return (Int64(nextIndex[]), idStr) +end + +""" +MODELICA_EXPORT void ModelicaStrings_scanInteger(_In_z_ const char* string, int startIndex, + int unsignedNumber, int* nextIndex, int* integerNumber); +""" +function ModelicaStrings_scanInteger(string::Ptr{Cchar}, startIndex::Cint, unsignedNumber::Cint) +end + +""" +ModelicaStrings_scanInteger(string::String, startIndex::Int64, unsignedNumber::Int64) + Scans for an integer starting at startIndex. + If unsignedNumber != 0, only unsigned integers are recognized. + Returns (nextIndex, integerNumber). +""" +function ModelicaStrings_scanInteger(string::String, startIndex::Int64, unsignedNumber::Int64) + nextIndex = Ref{Cint}(0) + integerNumber = Ref{Cint}(0) + ccall((:ModelicaStrings_scanInteger, installedLibPathlibModelicaExternalC), + Cvoid, + (Cstring, Cint, Cint, Ref{Cint}, Ref{Cint}), + string, startIndex, unsignedNumber, nextIndex, integerNumber) + return (Int64(nextIndex[]), Int64(integerNumber[])) +end + +""" +MODELICA_EXPORT void ModelicaStrings_scanReal(_In_z_ const char* string, int startIndex, + int unsignedNumber, int* nextIndex, double* number); +""" +function ModelicaStrings_scanReal(string::Ptr{Cchar}, startIndex::Cint, unsignedNumber::Cint) +end + +""" +ModelicaStrings_scanReal(string::String, startIndex::Int64, unsignedNumber::Int64) + Scans for a real number starting at startIndex. + If unsignedNumber != 0, only unsigned numbers are recognized. + Returns (nextIndex, number). +""" +function ModelicaStrings_scanReal(string::String, startIndex::Int64, unsignedNumber::Int64) + nextIndex = Ref{Cint}(0) + number = Ref{Cdouble}(0.0) + ccall((:ModelicaStrings_scanReal, installedLibPathlibModelicaExternalC), + Cvoid, + (Cstring, Cint, Cint, Ref{Cint}, Ref{Cdouble}), + string, startIndex, unsignedNumber, nextIndex, number) + return (Int64(nextIndex[]), Float64(number[])) +end + +""" +MODELICA_EXPORT void ModelicaStrings_scanString(_In_z_ const char* string, int startIndex, + int* nextIndex, const char** result); +""" +function ModelicaStrings_scanString(string::Ptr{Cchar}, startIndex::Cint) +end + +""" +ModelicaStrings_scanString(string::String, startIndex::Int64) + Scans for a quoted string starting at startIndex. + Returns (nextIndex, result). +""" +function ModelicaStrings_scanString(string::String, startIndex::Int64) + nextIndex = Ref{Cint}(0) + result = Ref{Cstring}(C_NULL) + ccall((:ModelicaStrings_scanString, installedLibPathlibModelicaExternalC), + Cvoid, + (Cstring, Cint, Ref{Cint}, Ref{Cstring}), + string, startIndex, nextIndex, result) + local resStr = result[] == C_NULL ? "" : unsafe_string(result[]) + return (Int64(nextIndex[]), resStr) +end + +""" +MODELICA_EXPORT int ModelicaStrings_hashString(_In_z_ const char* str); +""" +function ModelicaStrings_hashString(string::Ptr{Cchar}) +end + +""" +ModelicaStrings_hashString(string::String) + Returns a hash value for the given string. +""" +function ModelicaStrings_hashString(string::String) + res = ccall((:ModelicaStrings_hashString, installedLibPathlibModelicaExternalC), + #= Returns =# Cint, + (Cstring,), + string) + return Int64(res) +end diff --git a/test/runtests.jl b/test/runtests.jl index 233f6b1..1bd4345 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -132,6 +132,192 @@ const ORC = OMRuntimeExternalC end end + @testset "CombiTable1D getDer2Value" begin + local table::Matrix{Float64} = [ + 1.0 10.0; + 2.0 20.0; + 3.0 30.0; + 4.0 40.0; + 5.0 50.0 + ] + local columns = [2] + local tableID = ORC.ModelicaStandardTables_CombiTable1D_init2( + "NoName", "NoName", + table, size(table, 1), size(table, 2), + columns, length(columns), + 1, 2, 1 + ) + #= For linear data, second derivative should be 0 =# + @test isapprox(ORC.ModelicaStandardTables_CombiTable1D_getDer2Value(tableID, 1, 2.5, 1.0, 0.0), 0.0, atol=1e-6) + ORC.ModelicaStandardTables_CombiTable1D_close(tableID) + end + + @testset "CombiTimeTable" begin + #= Time table: columns are [time, value]. Linear data: value = 10*time =# + local table::Matrix{Float64} = [ + 0.0 0.0; + 1.0 10.0; + 2.0 20.0; + 3.0 30.0; + 4.0 40.0; + 5.0 50.0 + ] + local columns = [2] + local smoothness = 1 #= LinearSegments =# + local extrapolation = 2 #= LastTwoPoints =# + + local tableID = ORC.ModelicaStandardTables_CombiTimeTable_init2( + "NoName", "NoName", + table, size(table, 1), size(table, 2), + 0.0, #= startTime =# + columns, length(columns), + smoothness, extrapolation, + 0.0, #= shiftTime =# + 1, #= timeEvents =# + 0 #= verbose =# + ) + + @testset "init2 returns valid pointer" begin + @test tableID isa Ptr{Nothing} + @test tableID != C_NULL + end + + @testset "minimumTime" begin + @test ORC.ModelicaStandardTables_CombiTimeTable_minimumTime(tableID) == 0.0 + end + + @testset "maximumTime" begin + @test ORC.ModelicaStandardTables_CombiTimeTable_maximumTime(tableID) == 5.0 + end + + @testset "getValue" begin + #= nextTimeEvent and preNextTimeEvent set to large values for simple interpolation =# + @test isapprox(ORC.ModelicaStandardTables_CombiTimeTable_getValue(tableID, 1, 0.0, 1e10, 1e10), 0.0, atol=1e-6) + @test isapprox(ORC.ModelicaStandardTables_CombiTimeTable_getValue(tableID, 1, 2.5, 1e10, 1e10), 25.0, atol=1e-6) + @test isapprox(ORC.ModelicaStandardTables_CombiTimeTable_getValue(tableID, 1, 5.0, 1e10, 1e10), 50.0, atol=1e-6) + end + + @testset "getDerValue" begin + #= For y = 10*t, derivative should be 10 everywhere =# + @test isapprox(ORC.ModelicaStandardTables_CombiTimeTable_getDerValue(tableID, 1, 2.0, 1e10, 1e10, 1.0), 10.0, atol=1e-6) + end + + @testset "nextTimeEvent" begin + #= For linear segments with no events, nextTimeEvent returns a large number =# + nte = ORC.ModelicaStandardTables_CombiTimeTable_nextTimeEvent(tableID, 0.0) + @test nte > 0.0 + end + + @testset "close" begin + @test begin + ORC.ModelicaStandardTables_CombiTimeTable_close(tableID) + true + end + end + end + + @testset "CombiTimeTable with Vector{Vector} input" begin + local vecVec::Vector{Vector{Float64}} = [ + [0.0, 100.0], + [1.0, 200.0], + [2.0, 300.0] + ] + local columns = [2] + + local tableID = ORC.ModelicaStandardTables_CombiTimeTable_init2( + "NoName", "NoName", + vecVec, 3, 2, + 0.0, columns, 1, + 1, 2, 0.0, 1, 0 + ) + + @test tableID isa Ptr{Nothing} + @test tableID != C_NULL + @test isapprox(ORC.ModelicaStandardTables_CombiTimeTable_getValue(tableID, 1, 0.5, 1e10, 1e10), 150.0, atol=1e-6) + ORC.ModelicaStandardTables_CombiTimeTable_close(tableID) + end + + @testset "CombiTable2D" begin + #= 2D table layout: + First row (after [0,0]) = u2 breakpoints: 1.0, 2.0, 3.0 + First column = u1 breakpoints: 10.0, 20.0 + Body = z(u1, u2) = u1 * u2 + =# + local table::Matrix{Float64} = [ + 0.0 1.0 2.0 3.0; + 10.0 10.0 20.0 30.0; + 20.0 20.0 40.0 60.0 + ] + local smoothness = 1 #= LinearSegments =# + local extrapolation = 2 #= LastTwoPoints =# + + local tableID = ORC.ModelicaStandardTables_CombiTable2D_init2( + "NoName", "NoName", + table, size(table, 1), size(table, 2), + smoothness, extrapolation, 0 + ) + + @testset "init2 returns valid pointer" begin + @test tableID isa Ptr{Nothing} + @test tableID != C_NULL + end + + @testset "getValue" begin + #= Exact grid point: z(10, 2) = 20 =# + @test isapprox(ORC.ModelicaStandardTables_CombiTable2D_getValue(tableID, 10.0, 2.0), 20.0, atol=1e-6) + #= Exact grid point: z(20, 3) = 60 =# + @test isapprox(ORC.ModelicaStandardTables_CombiTable2D_getValue(tableID, 20.0, 3.0), 60.0, atol=1e-6) + #= Interpolated: z(15, 2) should be 30 (midpoint between 20 and 40) =# + @test isapprox(ORC.ModelicaStandardTables_CombiTable2D_getValue(tableID, 15.0, 2.0), 30.0, atol=1e-6) + end + + @testset "minimumAbscissa" begin + (u1Min, u2Min) = ORC.ModelicaStandardTables_CombiTable2D_minimumAbscissa(tableID) + @test u1Min == 10.0 + @test u2Min == 1.0 + end + + @testset "maximumAbscissa" begin + (u1Max, u2Max) = ORC.ModelicaStandardTables_CombiTable2D_maximumAbscissa(tableID) + @test u1Max == 20.0 + @test u2Max == 3.0 + end + + @testset "getDerValue" begin + #= Partial derivative dz/du1 at (15, 2) with der_u1=1, der_u2=0 + dz/du1 = u2 = 2, so total = 2*1 + 0 = 2 =# + der = ORC.ModelicaStandardTables_CombiTable2D_getDerValue(tableID, 15.0, 2.0, 1.0, 0.0) + @test isapprox(der, 2.0, atol=1e-6) + end + + @testset "close" begin + @test begin + ORC.ModelicaStandardTables_CombiTable2D_close(tableID) + true + end + end + end + + @testset "CombiTable2D with Vector{Vector} input" begin + local vecVec::Vector{Vector{Float64}} = [ + [0.0, 1.0, 2.0], + [10.0, 10.0, 20.0], + [20.0, 20.0, 40.0] + ] + + local tableID = ORC.ModelicaStandardTables_CombiTable2D_init2( + "NoName", "NoName", + vecVec, 3, 3, + 1, 2, 0 + ) + + @test tableID isa Ptr{Nothing} + @test tableID != C_NULL + @test isapprox(ORC.ModelicaStandardTables_CombiTable2D_getValue(tableID, 10.0, 1.0), 10.0, atol=1e-6) + @test isapprox(ORC.ModelicaStandardTables_CombiTable2D_getValue(tableID, 15.0, 1.5), 22.5, atol=1e-6) + ORC.ModelicaStandardTables_CombiTable2D_close(tableID) + end + @testset "ModelicaStrings functions" begin @testset "ModelicaStrings_length" begin @test ORC.ModelicaStrings_length("") == 0 @@ -160,6 +346,53 @@ const ORC = OMRuntimeExternalC #= All whitespace =# @test ORC.ModelicaStrings_skipWhiteSpace(" ", 1) == 4 end + + @testset "ModelicaStrings_substring" begin + @test ORC.ModelicaStrings_substring("hello world", 1, 5) == "hello" + @test ORC.ModelicaStrings_substring("hello world", 7, 11) == "world" + @test ORC.ModelicaStrings_substring("abc", 2, 2) == "b" + end + + @testset "ModelicaStrings_compare" begin + #= 1 = Less, 2 = Equal, 3 = Greater (Modelica convention) =# + @test ORC.ModelicaStrings_compare("abc", "abc", 1) == 2 + @test ORC.ModelicaStrings_compare("abc", "def", 1) == 1 + @test ORC.ModelicaStrings_compare("def", "abc", 1) == 3 + #= Case insensitive =# + @test ORC.ModelicaStrings_compare("ABC", "abc", 0) == 2 + end + + @testset "ModelicaStrings_scanInteger" begin + (nextIdx, val) = ORC.ModelicaStrings_scanInteger("42 hello", 1, 0) + @test val == 42 + @test nextIdx == 3 + + (nextIdx2, val2) = ORC.ModelicaStrings_scanInteger("-123abc", 1, 0) + @test val2 == -123 + @test nextIdx2 == 5 + end + + @testset "ModelicaStrings_scanReal" begin + (nextIdx, val) = ORC.ModelicaStrings_scanReal("3.14 rest", 1, 0) + @test isapprox(val, 3.14, atol=1e-10) + @test nextIdx == 5 + + (nextIdx2, val2) = ORC.ModelicaStrings_scanReal("-2.5e3 rest", 1, 0) + @test isapprox(val2, -2500.0, atol=1e-6) + end + + @testset "ModelicaStrings_scanIdentifier" begin + (nextIdx, ident) = ORC.ModelicaStrings_scanIdentifier("myVar = 42", 1) + @test ident == "myVar" + @test nextIdx == 6 + end + + @testset "ModelicaStrings_hashString" begin + #= Same string should produce the same hash =# + @test ORC.ModelicaStrings_hashString("test") == ORC.ModelicaStrings_hashString("test") + #= Different strings should (very likely) produce different hashes =# + @test ORC.ModelicaStrings_hashString("abc") != ORC.ModelicaStrings_hashString("def") + end end end