OMCompiler/SimulationRuntime/cpp/SimCoreFactory/OMCFactory/OMCFactory.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file belongs to the OpenModelica Run-Time System | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings | ||
| 5 | * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights | ||
| 6 | * reserved. | ||
| 7 | * | ||
| 8 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE | ||
| 9 | * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY | ||
| 10 | * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S | ||
| 11 | * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL | ||
| 12 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 13 | * | ||
| 14 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License | ||
| 15 | * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs: | ||
| 16 | * http://www.openmodelica.org or https://github.com/OpenModelica/ or | ||
| 17 | * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU | ||
| 18 | * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW | ||
| 19 | * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause. | ||
| 20 | * | ||
| 21 | * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY | ||
| 23 | * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF | ||
| 24 | * OSMC-PL. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | /** @addtogroup simcorefactoryOMCFactory | ||
| 29 | * | ||
| 30 | * @{ | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifdef _WIN32 | ||
| 34 | #include <winsock2.h> | ||
| 35 | typedef SOCKET socket_t; | ||
| 36 | #define OMC_INVALID_SOCKET INVALID_SOCKET | ||
| 37 | #define omc_closesocket closesocket | ||
| 38 | #else | ||
| 39 | #include <arpa/inet.h> | ||
| 40 | #include <netinet/in.h> | ||
| 41 | #include <sys/socket.h> | ||
| 42 | #include <unistd.h> | ||
| 43 | typedef int socket_t; | ||
| 44 | #define OMC_INVALID_SOCKET (-1) | ||
| 45 | #define omc_closesocket close | ||
| 46 | #endif | ||
| 47 | #ifndef MSG_NOSIGNAL | ||
| 48 | #define MSG_NOSIGNAL 0 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | #include <Core/ModelicaDefine.h> | ||
| 52 | #include <Core/Modelica.h> | ||
| 53 | #include <SimCoreFactory/OMCFactory/OMCFactory.h> | ||
| 54 | #include <Core/SimController/ISimController.h> | ||
| 55 | #include <Core/System/FactoryExport.h> | ||
| 56 | #include <Core/Utils/extension/logger.hpp> | ||
| 57 | |||
| 58 | #include <cerrno> | ||
| 59 | #include <climits> | ||
| 60 | #include <cstdlib> | ||
| 61 | #include <cstring> | ||
| 62 | #include <filesystem> | ||
| 63 | #include <functional> | ||
| 64 | #include <optional> | ||
| 65 | |||
| 66 | namespace fs = std::filesystem; | ||
| 67 | |||
| 68 | ✗ | static std::string socketError() | |
| 69 | { | ||
| 70 | #ifdef _WIN32 | ||
| 71 | return "error " + std::to_string(WSAGetLastError()); | ||
| 72 | #else | ||
| 73 | ✗ | return strerror(errno); | |
| 74 | #endif | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Logger for XML messages through TCP port | ||
| 79 | */ | ||
| 80 | class LoggerXMLTCP: public LoggerXML | ||
| 81 | { | ||
| 82 | public: | ||
| 83 | ✗ | virtual ~LoggerXMLTCP() | |
| 84 | ✗ | { | |
| 85 | ✗ | omc_closesocket(_socket); | |
| 86 | #ifdef _WIN32 | ||
| 87 | WSACleanup(); | ||
| 88 | #endif | ||
| 89 | ✗ | } | |
| 90 | |||
| 91 | ✗ | static void initialize(int port, LogSettings &logSettings) | |
| 92 | { | ||
| 93 | ✗ | _instance = new LoggerXMLTCP(port, logSettings); | |
| 94 | ✗ | } | |
| 95 | |||
| 96 | protected: | ||
| 97 | ✗ | LoggerXMLTCP(int port, LogSettings &logSettings) | |
| 98 | ✗ | : LoggerXML(logSettings, true, _sstream) | |
| 99 | ✗ | , _socket(OMC_INVALID_SOCKET) | |
| 100 | { | ||
| 101 | ✗ | if (logSettings.format != LF_XML && logSettings.format != LF_XMLTCP) { | |
| 102 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, | |
| 103 | ✗ | "xmltcp logger requires log-format xml"); | |
| 104 | } | ||
| 105 | #ifdef _WIN32 | ||
| 106 | WSADATA wsaData; | ||
| 107 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) | ||
| 108 | throw std::runtime_error("WSAStartup failed"); | ||
| 109 | #endif | ||
| 110 | ✗ | _socket = socket(AF_INET, SOCK_STREAM, 0); | |
| 111 | ✗ | if (_socket == OMC_INVALID_SOCKET) { | |
| 112 | ✗ | std::string err = socketError(); | |
| 113 | #ifdef _WIN32 | ||
| 114 | WSACleanup(); | ||
| 115 | #endif | ||
| 116 | ✗ | throw std::runtime_error("socket: " + err); | |
| 117 | } | ||
| 118 | #ifdef SO_NOSIGPIPE | ||
| 119 | int on = 1; | ||
| 120 | setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); | ||
| 121 | #endif | ||
| 122 | sockaddr_in addr; | ||
| 123 | memset(&addr, 0, sizeof(addr)); | ||
| 124 | ✗ | addr.sin_family = AF_INET; | |
| 125 | ✗ | addr.sin_port = htons((unsigned short)port); | |
| 126 | ✗ | addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | |
| 127 | ✗ | if (connect(_socket, (sockaddr*)&addr, sizeof(addr)) != 0) { | |
| 128 | ✗ | std::string err = socketError(); | |
| 129 | ✗ | omc_closesocket(_socket); | |
| 130 | #ifdef _WIN32 | ||
| 131 | WSACleanup(); | ||
| 132 | #endif | ||
| 133 | ✗ | throw std::runtime_error("connect: " + err); | |
| 134 | } | ||
| 135 | ✗ | } | |
| 136 | |||
| 137 | ✗ | void sendString(const std::string& str) | |
| 138 | { | ||
| 139 | const char* p = str.data(); | ||
| 140 | size_t left = str.size(); | ||
| 141 | ✗ | while (left > 0) { | |
| 142 | ✗ | int n = send(_socket, p, (int)left, MSG_NOSIGNAL); | |
| 143 | ✗ | if (n <= 0) | |
| 144 | ✗ | throw std::runtime_error("send: " + socketError()); | |
| 145 | ✗ | p += n; | |
| 146 | ✗ | left -= n; | |
| 147 | } | ||
| 148 | ✗ | } | |
| 149 | |||
| 150 | ✗ | virtual void writeInternal(string msg, LogCategory cat, LogLevel lvl, | |
| 151 | LogStructure ls) | ||
| 152 | { | ||
| 153 | ✗ | _sstream.str(""); | |
| 154 | ✗ | LoggerXML::writeInternal(msg, cat, lvl, ls); | |
| 155 | ✗ | if (_logSettings.format == LF_XMLTCP) | |
| 156 | ✗ | sendString(_sstream.str()); | |
| 157 | else | ||
| 158 | ✗ | std::cout << _sstream.str(); | |
| 159 | ✗ | } | |
| 160 | |||
| 161 | ✗ | virtual void statusInternal(const char *phase, double currentTime, double currentStepSize) | |
| 162 | { | ||
| 163 | ✗ | int completion = _endTime <= _startTime? 0: | |
| 164 | ✗ | (int)((currentTime - _startTime) / (_endTime - _startTime) * 10000); | |
| 165 | ✗ | if (_logSettings.format == LF_XMLTCP) { | |
| 166 | ✗ | _sstream.str(""); | |
| 167 | _sstream << "<status phase=\"" << phase | ||
| 168 | ✗ | << "\" time=\"" << currentTime | |
| 169 | << "\" currentStepSize=\"" << currentStepSize | ||
| 170 | << "\" progress=\"" << completion | ||
| 171 | ✗ | << "\" />" << std::endl; | |
| 172 | ✗ | sendString(_sstream.str()); | |
| 173 | } | ||
| 174 | else { | ||
| 175 | // send status in old format for backwards compatibility | ||
| 176 | ✗ | _sstream.str(""); | |
| 177 | ✗ | _sstream << completion << " " << phase << std::endl; | |
| 178 | ✗ | sendString(_sstream.str()); | |
| 179 | } | ||
| 180 | ✗ | } | |
| 181 | |||
| 182 | socket_t _socket; | ||
| 183 | std::stringstream _sstream; | ||
| 184 | }; | ||
| 185 | |||
| 186 | namespace { | ||
| 187 | |||
| 188 | /** | ||
| 189 | * Command line parser: --name[=value] and -name[=value] for long names, | ||
| 190 | * -X[value] for short ones; a missing value is taken from the next argument. | ||
| 191 | */ | ||
| 192 | 40 | class CommandLine | |
| 193 | { | ||
| 194 | public: | ||
| 195 | enum Kind { FLAG, VALUE, VALUES }; | ||
| 196 | enum Type { STRING, REAL, INT, UINT }; | ||
| 197 | |||
| 198 | 1040 | void add(const string& name, char shortName, Kind kind, Type type, | |
| 199 | const string& help, std::optional<string> defaultValue = std::nullopt, | ||
| 200 | bool hidden = false) | ||
| 201 | { | ||
| 202 |
3/3✓ Branch 1 taken 1040 times.
✓ Branch 3 taken 160 times.
✓ Branch 4 taken 880 times.
|
2080 | Option o = {name, shortName, kind, type, help, defaultValue, hidden, {}}; |
| 203 |
2/2✓ Branch 0 taken 160 times.
✓ Branch 1 taken 880 times.
|
1040 | if (kind == FLAG) |
| 204 |
1/1✓ Branch 1 taken 160 times.
|
160 | o.defaultValue = "false"; |
| 205 |
1/1✓ Branch 1 taken 1040 times.
|
1040 | _options.push_back(o); |
| 206 | 1040 | } | |
| 207 | |||
| 208 | /** Returns the arguments that are not registered options. */ | ||
| 209 |
1/1✓ Branch 1 taken 40 times.
|
40 | vector<string> parse(int argc, const char* argv[], |
| 210 | const std::function<pair<string, string>(const string&)>& extraParser) | ||
| 211 | { | ||
| 212 | vector<string> unrecognized; | ||
| 213 |
1/1✓ Branch 1 taken 40 times.
|
40 | vector<string> args(argv + 1, argv + argc); |
| 214 |
2/2✓ Branch 0 taken 533 times.
✓ Branch 1 taken 40 times.
|
573 | for (size_t i = 0; i < args.size(); i++) { |
| 215 | const string& tok = args[i]; | ||
| 216 | Option* opt = nullptr; | ||
| 217 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 533 times.
|
533 | std::optional<string> value; |
| 218 | pair<string, string> replaced = extraParser(tok); | ||
| 219 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 481 times.
|
533 | if (!replaced.first.empty()) { |
| 220 | opt = findLong(replaced.first); | ||
| 221 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 41 times.
|
52 | if (!replaced.second.empty()) |
| 222 |
1/1✓ Branch 1 taken 11 times.
|
11 | value = replaced.second; |
| 223 | } | ||
| 224 |
5/6✓ Branch 0 taken 41 times.
✓ Branch 1 taken 440 times.
✓ Branch 2 taken 41 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
✓ Branch 5 taken 1 time.
|
481 | else if (tok.size() >= 3 && tok[0] == '-' && tok[1] == '-') { |
| 225 |
1/1✓ Branch 2 taken 40 times.
|
40 | opt = findLong(tok.substr(2, tok.find('=') - 2)); |
| 226 |
1/1✓ Branch 1 taken 40 times.
|
80 | value = adjacentValue(tok); |
| 227 | } | ||
| 228 |
2/4✓ Branch 0 taken 441 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 441 times.
✗ Branch 3 not taken.
|
441 | else if (tok.size() >= 2 && tok[0] == '-') { |
| 229 |
2/3✓ Branch 2 taken 441 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 441 times.
|
882 | if ((opt = findLong(tok.substr(1, tok.find('=') - 1)))) |
| 230 | ✗ | value = adjacentValue(tok); | |
| 231 |
3/4✓ Branch 0 taken 440 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 440 times.
|
882 | else if ((opt = findShort(tok[1])) && tok.size() > 2) |
| 232 | ✗ | value = tok.substr(tok[2] == '=' ? 3 : 2); | |
| 233 | } | ||
| 234 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 532 times.
|
533 | if (!opt) { |
| 235 |
1/1✓ Branch 1 taken 1 time.
|
1 | unrecognized.push_back(tok); |
| 236 | continue; | ||
| 237 | } | ||
| 238 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 531 times.
|
532 | if (opt->kind == FLAG) { |
| 239 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (value) |
| 240 | ✗ | throw std::invalid_argument("option '--" + opt->name + "' does not take any arguments"); | |
| 241 |
1/1✓ Branch 1 taken 1 time.
|
1 | value = "true"; |
| 242 | } | ||
| 243 |
2/2✓ Branch 0 taken 520 times.
✓ Branch 1 taken 11 times.
|
531 | else if (!value) { |
| 244 |
3/5✓ Branch 0 taken 520 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 520 times.
✓ Branch 5 taken 520 times.
✗ Branch 6 not taken.
|
520 | if (i + 1 == args.size() || isOption(args[i + 1])) |
| 245 | ✗ | throw std::invalid_argument("the required argument for option '--" + opt->name + "' is missing"); | |
| 246 |
1/1✓ Branch 1 taken 520 times.
|
520 | value = args[++i]; |
| 247 | } | ||
| 248 |
1/1✓ Branch 1 taken 532 times.
|
532 | store(*opt, *value); |
| 249 | 533 | } | |
| 250 | 40 | return unrecognized; | |
| 251 | 40 | } | |
| 252 | |||
| 253 | size_t count(const string& name) const | ||
| 254 | { | ||
| 255 |
11/11✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 10 taken 40 times.
✓ Branch 13 taken 40 times.
✓ Branch 16 taken 40 times.
✓ Branch 19 taken 40 times.
✓ Branch 22 taken 40 times.
✓ Branch 25 taken 40 times.
✓ Branch 28 taken 40 times.
✓ Branch 31 taken 40 times.
|
440 | const Option& o = get(name); |
| 256 |
20/44✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 40 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 40 times.
✓ Branch 12 taken 40 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 40 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 40 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 40 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 40 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 40 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 32 times.
✓ Branch 29 taken 8 times.
✓ Branch 30 taken 32 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 40 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 39 times.
✓ Branch 37 taken 1 time.
✗ Branch 38 not taken.
✓ Branch 39 taken 39 times.
✓ Branch 40 taken 39 times.
✓ Branch 41 taken 1 time.
✓ Branch 42 taken 39 times.
✗ Branch 43 not taken.
|
440 | return !o.values.empty() || o.defaultValue ? 1 : 0; |
| 257 | } | ||
| 258 | |||
| 259 | const string& str(const string& name) const | ||
| 260 | { | ||
| 261 |
10/14✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 10 taken 40 times.
✓ Branch 13 taken 40 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 22 taken 40 times.
✓ Branch 25 taken 40 times.
✓ Branch 28 taken 40 times.
✓ Branch 31 taken 40 times.
✓ Branch 34 taken 40 times.
|
400 | const Option& o = get(name); |
| 262 |
18/32✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 40 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 40 times.
✓ Branch 18 taken 32 times.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 40 times.
✓ Branch 22 taken 39 times.
✓ Branch 23 taken 1 time.
✓ Branch 24 taken 159 times.
✓ Branch 25 taken 1 time.
✓ Branch 26 taken 40 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 40 times.
✓ Branch 29 taken 48 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 160 times.
|
848 | return o.values.empty() ? *o.defaultValue : o.values.front(); |
| 263 | } | ||
| 264 | |||
| 265 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 1 time.
|
41 | const vector<string>& values(const string& name) const { return get(name).values; } |
| 266 | 320 | double real(const string& name) const { return std::strtod(str(name).c_str(), nullptr); } | |
| 267 | 176 | int integer(const string& name) const { return (int)std::strtol(str(name).c_str(), nullptr, 10); } | |
| 268 | 80 | unsigned int uinteger(const string& name) const { return (unsigned int)std::strtoul(str(name).c_str(), nullptr, 10); } | |
| 269 | 160 | bool flag(const string& name) const { return str(name) == "true"; } | |
| 270 | |||
| 271 | ✗ | void printHelp(std::ostream& os) const | |
| 272 | { | ||
| 273 | vector<string> left; | ||
| 274 | ✗ | size_t width = 0; | |
| 275 | ✗ | for (const Option& o : _options) { | |
| 276 | ✗ | string l = o.shortName ? string("-") + o.shortName + " [ --" + o.name + " ]" : "--" + o.name; | |
| 277 | ✗ | if (o.kind != FLAG) | |
| 278 | ✗ | l += o.defaultValue ? " arg (=" + *o.defaultValue + ")" : " arg"; | |
| 279 | ✗ | width = (std::max)(width, l.size()); | |
| 280 | ✗ | left.push_back(l); | |
| 281 | } | ||
| 282 | os << "Allowed options:" << std::endl; | ||
| 283 | ✗ | for (size_t i = 0; i < _options.size(); i++) | |
| 284 | ✗ | if (!_options[i].hidden) | |
| 285 | ✗ | os << " " << left[i] << string(width - left[i].size() + 2, ' ') << _options[i].help << std::endl; | |
| 286 | ✗ | } | |
| 287 | |||
| 288 | private: | ||
| 289 | struct Option | ||
| 290 | { | ||
| 291 | string name; | ||
| 292 | char shortName; | ||
| 293 | Kind kind; | ||
| 294 | Type type; | ||
| 295 | string help; | ||
| 296 | std::optional<string> defaultValue; | ||
| 297 | bool hidden; | ||
| 298 | vector<string> values; | ||
| 299 | }; | ||
| 300 | |||
| 301 | Option* findLong(const string& name) | ||
| 302 | { | ||
| 303 |
4/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 522 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1040 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11466 times.
✓ Branch 7 taken 441 times.
|
13469 | for (Option& o : _options) |
| 304 |
5/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 470 times.
✓ Branch 3 taken 52 times.
✓ Branch 4 taken 1000 times.
✓ Branch 5 taken 40 times.
✓ Branch 6 taken 11466 times.
✗ Branch 7 not taken.
|
13028 | if (o.name == name) |
| 305 | return &o; | ||
| 306 | return nullptr; | ||
| 307 | } | ||
| 308 | |||
| 309 | Option* findShort(char c) | ||
| 310 | { | ||
| 311 |
2/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 5146 times.
✓ Branch 3 taken 1 time.
|
5147 | for (Option& o : _options) |
| 312 |
2/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4706 times.
✓ Branch 3 taken 440 times.
|
5146 | if (o.shortName == c) |
| 313 | return &o; | ||
| 314 | return nullptr; | ||
| 315 | } | ||
| 316 | |||
| 317 | 1329 | const Option& get(const string& name) const | |
| 318 | { | ||
| 319 |
1/2✓ Branch 0 taken 18529 times.
✗ Branch 1 not taken.
|
18529 | for (const Option& o : _options) |
| 320 |
2/2✓ Branch 0 taken 1329 times.
✓ Branch 1 taken 17200 times.
|
18529 | if (o.name == name) |
| 321 | 1329 | return o; | |
| 322 | ✗ | throw std::logic_error("unknown option " + name); | |
| 323 | } | ||
| 324 | |||
| 325 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 487 times.
|
520 | bool isOption(const string& tok) |
| 326 | { | ||
| 327 |
3/4✓ Branch 0 taken 33 times.
✓ Branch 1 taken 487 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
|
520 | if (tok.size() == 2 && tok[0] == '-') |
| 328 | ✗ | return findShort(tok[1]) != nullptr; | |
| 329 |
4/10✓ Branch 0 taken 443 times.
✓ Branch 1 taken 77 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 443 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 520 times.
|
520 | return tok.size() > 2 && tok[0] == '-' && tok[1] == '-' && findLong(tok.substr(2, tok.find('=') - 2)); |
| 330 | } | ||
| 331 | |||
| 332 | 40 | std::optional<string> adjacentValue(const string& tok) | |
| 333 | { | ||
| 334 | 40 | size_t eq = tok.find('='); | |
| 335 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (eq == string::npos) |
| 336 | 40 | return std::nullopt; | |
| 337 | ✗ | if (eq + 1 == tok.size()) | |
| 338 | ✗ | throw std::invalid_argument("the argument for option '" + tok + "' should follow immediately after the equal sign"); | |
| 339 | ✗ | return tok.substr(eq + 1); | |
| 340 | } | ||
| 341 | |||
| 342 | 532 | void store(Option& o, const string& value) | |
| 343 | { | ||
| 344 |
3/4✓ Branch 0 taken 450 times.
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450 times.
|
532 | if (o.kind != VALUES && !o.values.empty()) |
| 345 | ✗ | throw std::invalid_argument("option '--" + o.name + "' cannot be specified more than once"); | |
| 346 | const char* begin = value.c_str(); | ||
| 347 | 532 | char* end = nullptr; | |
| 348 | 532 | errno = 0; | |
| 349 |
3/4✓ Branch 0 taken 160 times.
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 292 times.
|
532 | switch (o.type) { |
| 350 | 160 | case REAL: std::strtod(begin, &end); break; | |
| 351 | 80 | case INT: { | |
| 352 | 80 | long l = std::strtol(begin, &end, 10); | |
| 353 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
|
80 | if (l < INT_MIN || l > INT_MAX) |
| 354 | ✗ | errno = ERANGE; | |
| 355 | break; | ||
| 356 | } | ||
| 357 | ✗ | case UINT: std::strtoul(begin, &end, 10); break; | |
| 358 | case STRING: break; | ||
| 359 | } | ||
| 360 |
5/8✓ Branch 0 taken 240 times.
✓ Branch 1 taken 292 times.
✓ Branch 2 taken 240 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 240 times.
✗ Branch 7 not taken.
|
532 | if (o.type != STRING && (value.empty() || *end != '\0' || errno == ERANGE)) |
| 361 | ✗ | throw std::invalid_argument("the argument ('" + value + "') for option '--" + o.name + "' is invalid"); | |
| 362 | 532 | o.values.push_back(value); | |
| 363 | 532 | } | |
| 364 | |||
| 365 | vector<Option> _options; | ||
| 366 | }; | ||
| 367 | |||
| 368 | 2 | vector<string> split(const string& str, char sep) | |
| 369 | { | ||
| 370 | vector<string> parts; | ||
| 371 | size_t start = 0, pos; | ||
| 372 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | while ((pos = str.find(sep, start)) != string::npos) { |
| 373 | ✗ | parts.push_back(str.substr(start, pos - start)); | |
| 374 | ✗ | start = pos + 1; | |
| 375 | } | ||
| 376 |
1/1✓ Branch 1 taken 2 times.
|
2 | parts.push_back(str.substr(start)); |
| 377 | 2 | return parts; | |
| 378 | ✗ | } | |
| 379 | |||
| 380 | } | ||
| 381 | |||
| 382 |
1/2✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
|
80 | inline void normalizePath(std::string& path) |
| 383 | { | ||
| 384 |
2/4✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
|
80 | if (path.length() > 0 && path[path.length() - 1] != '/') |
| 385 | path += "/"; | ||
| 386 | 80 | } | |
| 387 | |||
| 388 | /** | ||
| 389 | * Implementation of OMCFactory | ||
| 390 | */ | ||
| 391 | 200 | OMCFactory::OMCFactory(PATH library_path, PATH modelicasystem_path) | |
| 392 | 200 | : _library_path(library_path) | |
| 393 |
1/1✓ Branch 1 taken 200 times.
|
200 | , _modelicasystem_path(modelicasystem_path) |
| 394 |
1/1✓ Branch 1 taken 200 times.
|
200 | , _defaultLinSolver("dgesvSolver") |
| 395 |
8/15✓ Branch 1 taken 200 times.
✓ Branch 4 taken 200 times.
✓ Branch 7 taken 200 times.
✓ Branch 10 taken 200 times.
✓ Branch 12 taken 400 times.
✓ Branch 13 taken 200 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 400 times.
✓ Branch 17 taken 200 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
800 | , _defaultNonLinSolvers({"newton", "kinsol"}) |
| 396 | { | ||
| 397 |
1/1✓ Branch 1 taken 200 times.
|
200 | fillArgumentsToIgnore(); |
| 398 |
1/1✓ Branch 1 taken 200 times.
|
200 | fillArgumentsToReplace(); |
| 399 | 200 | } | |
| 400 | |||
| 401 | 40 | OMCFactory::OMCFactory() | |
| 402 | 80 | : _library_path("") | |
| 403 |
2/4✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
40 | , _modelicasystem_path("") |
| 404 |
1/1✓ Branch 1 taken 40 times.
|
40 | , _defaultLinSolver("dgesvSolver") |
| 405 |
8/15✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 10 taken 40 times.
✓ Branch 12 taken 80 times.
✓ Branch 13 taken 40 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 80 times.
✓ Branch 17 taken 40 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
160 | , _defaultNonLinSolvers({"newton", "kinsol"}) |
| 406 | { | ||
| 407 |
1/1✓ Branch 1 taken 40 times.
|
40 | fillArgumentsToIgnore(); |
| 408 |
1/1✓ Branch 1 taken 40 times.
|
40 | fillArgumentsToReplace(); |
| 409 | 40 | } | |
| 410 | |||
| 411 | 480 | OMCFactory::~OMCFactory() | |
| 412 | { | ||
| 413 | 480 | } | |
| 414 | |||
| 415 | 200 | void OMCFactory::UnloadAllLibs(void) | |
| 416 | { | ||
| 417 | map<string,shared_library>::iterator iter; | ||
| 418 |
2/2✓ Branch 0 taken 413 times.
✓ Branch 1 taken 200 times.
|
613 | for(iter = _modules.begin(); iter!=_modules.end(); ++iter) { |
| 419 |
1/1✓ Branch 2 taken 413 times.
|
413 | UnloadLibrary(iter->second); |
| 420 | } | ||
| 421 | 200 | } | |
| 422 | |||
| 423 | 533 | pair<string, string> OMCFactory::replaceCRuntimeArguments(const string &arg) | |
| 424 | { | ||
| 425 | string key = arg; | ||
| 426 |
1/3✓ Branch 1 taken 533 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
533 | string value = ""; |
| 427 | 533 | int sep = arg.find("="); | |
| 428 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 529 times.
|
533 | if (sep > 0) { |
| 429 |
1/1✓ Branch 1 taken 4 times.
|
4 | key = arg.substr(0, sep); |
| 430 |
1/1✓ Branch 1 taken 4 times.
|
8 | value = arg.substr(sep + 1); |
| 431 | } | ||
| 432 | // check for replacement | ||
| 433 | map<string,string>::iterator iter = _argumentsToReplace.find(key); | ||
| 434 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 481 times.
|
533 | if (iter != _argumentsToReplace.end()) { |
| 435 |
1/1✓ Branch 1 taken 52 times.
|
52 | key = iter->second; |
| 436 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 49 times.
|
52 | if (sep > 0) { |
| 437 | // check for replacements of value, depending on key | ||
| 438 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (key == "lin-solver") { |
| 439 | ✗ | if (value == "lapack" || value == "default") | |
| 440 | value = "dgesvSolver"; | ||
| 441 | ✗ | else if (value == "klu") | |
| 442 | value = "linearSolver"; // contains klu for sparse | ||
| 443 | } | ||
| 444 | } | ||
| 445 | else { | ||
| 446 | // check for space in replacement, separating a value | ||
| 447 | 49 | int ssep = key.find(" "); | |
| 448 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 41 times.
|
49 | if (ssep > 0) { |
| 449 |
1/1✓ Branch 1 taken 8 times.
|
8 | value = key.substr(ssep + 1); |
| 450 |
1/1✓ Branch 1 taken 8 times.
|
16 | key = key.substr(0, ssep); |
| 451 | sep = ssep; | ||
| 452 | } | ||
| 453 | } | ||
| 454 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 41 times.
|
52 | if (sep > 0) |
| 455 | return make_pair(key, value); // rename arg and provide value | ||
| 456 | else | ||
| 457 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
41 | return make_pair(key, string()); // rename arg |
| 458 | } | ||
| 459 | 481 | return make_pair(string(), string());// don't touch arg | |
| 460 | } | ||
| 461 | |||
| 462 | 40 | static LogSettings initializeLogger(const CommandLine& vm) | |
| 463 | { | ||
| 464 | map<string, LogCategory> logCatMap = MAP_LIST_OF | ||
| 465 | "init", LC_INIT MAP_LIST_SEP "nls", LC_NLS MAP_LIST_SEP | ||
| 466 | "ls", LC_LS MAP_LIST_SEP "solver", LC_SOLVER MAP_LIST_SEP | ||
| 467 | "output", LC_OUTPUT MAP_LIST_SEP "events", LC_EVENTS MAP_LIST_SEP | ||
| 468 |
3/8✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 320 times.
✓ Branch 6 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
400 | "model", LC_MODEL MAP_LIST_SEP "other", LC_OTHER MAP_LIST_END; |
| 469 | map<string, LogLevel> logLvlMap = MAP_LIST_OF | ||
| 470 | "error", LL_ERROR MAP_LIST_SEP "warning", LL_WARNING MAP_LIST_SEP | ||
| 471 |
3/8✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 160 times.
✓ Branch 6 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
240 | "info", LL_INFO MAP_LIST_SEP "debug", LL_DEBUG MAP_LIST_END; |
| 472 | map<string, LogFormat> logFormatMap = MAP_LIST_OF | ||
| 473 | "txt", LF_TXT MAP_LIST_SEP "xml", LF_XML MAP_LIST_SEP | ||
| 474 |
3/8✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 120 times.
✓ Branch 6 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
200 | "xmltcp", LF_XMLTCP MAP_LIST_END; |
| 475 | enum LogOMEdit {LOG_STDOUT, LOG_ASSERT, LOG_EVENTS, LOG_INIT, LOG_LS, LOG_NLS, LOG_SOLVER, LOG_STATS}; | ||
| 476 | map<string, LogOMEdit> logOMEditMap = MAP_LIST_OF | ||
| 477 | "LOG_STDOUT", LOG_STDOUT MAP_LIST_SEP "LOG_ASSERT", LOG_ASSERT MAP_LIST_SEP | ||
| 478 | "LOG_EVENTS", LOG_EVENTS MAP_LIST_SEP "LOG_INIT", LOG_INIT MAP_LIST_SEP | ||
| 479 | "LOG_LS", LOG_LS MAP_LIST_SEP "LOG_NLS", LOG_NLS MAP_LIST_SEP | ||
| 480 |
2/7✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 320 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
360 | "LOG_SOLVER", LOG_SOLVER MAP_LIST_SEP "LOG_STATS", LOG_STATS MAP_LIST_END; |
| 481 | |||
| 482 |
1/1✓ Branch 1 taken 40 times.
|
40 | LogSettings logSettings; |
| 483 | std::string logWarning; | ||
| 484 | bool logUsingOMEdit = false; | ||
| 485 |
3/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 39 times.
|
80 | if (vm.count("log-settings")) { |
| 486 |
1/1✓ Branch 1 taken 1 time.
|
1 | const vector<string>& log_vec = vm.values("log-settings"); |
| 487 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
|
2 | for (int i = 0; i < log_vec.size(); i++) { |
| 488 | // each log setting may be a comma separated list of options | ||
| 489 |
1/1✓ Branch 1 taken 1 time.
|
1 | vector<string> opt_vec = split(log_vec[i], ','); |
| 490 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
|
2 | for (int j = 0; j < opt_vec.size(); j++) { |
| 491 | // check for option with level, like "-V ls=warning" (default for "-V ls": LL_DEBUG) | ||
| 492 |
1/1✓ Branch 1 taken 1 time.
|
1 | vector<string> cat_lvl = split(opt_vec[j], '='); |
| 493 |
2/4✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
|
2 | if (!logUsingOMEdit && opt_vec[j].rfind("LOG_", 0) == 0) |
| 494 | logUsingOMEdit = true; | ||
| 495 |
1/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
|
1 | if (logUsingOMEdit && logOMEditMap.find(opt_vec[j]) != logOMEditMap.end()) { |
| 496 | // OMEdit option | ||
| 497 |
1/1✓ Branch 1 taken 1 time.
|
1 | LogOMEdit logOMEdit = logOMEditMap[opt_vec[j]]; |
| 498 |
1/7✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
|
1 | switch (logOMEdit) { |
| 499 | case LOG_STDOUT: | ||
| 500 | // that's given | ||
| 501 | break; | ||
| 502 | case LOG_ASSERT: | ||
| 503 | // that's given | ||
| 504 | break; | ||
| 505 | ✗ | case LOG_EVENTS: | |
| 506 | ✗ | logSettings.modes[LC_EVENTS] = LL_DEBUG; | |
| 507 | ✗ | break; | |
| 508 | ✗ | case LOG_INIT: | |
| 509 | ✗ | logSettings.modes[LC_INIT] = LL_DEBUG; | |
| 510 | ✗ | break; | |
| 511 | ✗ | case LOG_LS: | |
| 512 | ✗ | logSettings.modes[LC_LS] = LL_DEBUG; | |
| 513 | ✗ | break; | |
| 514 | ✗ | case LOG_NLS: | |
| 515 | ✗ | logSettings.modes[LC_NLS] = LL_DEBUG; | |
| 516 | ✗ | break; | |
| 517 | ✗ | case LOG_SOLVER: | |
| 518 | ✗ | logSettings.modes[LC_SOLVER] = LL_DEBUG; | |
| 519 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | case LOG_STATS: |
| 520 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (logSettings.modes[LC_SOLVER] < LL_INFO) |
| 521 | 1 | logSettings.modes[LC_SOLVER] = LL_INFO; | |
| 522 | break; | ||
| 523 | } | ||
| 524 | } | ||
| 525 | ✗ | else if (cat_lvl[0] == "all" || logCatMap.find(cat_lvl[0]) != logCatMap.end()) { | |
| 526 | // native option | ||
| 527 | LogLevel logLevel = LL_DEBUG; | ||
| 528 | ✗ | if (cat_lvl.size() > 1 && logLvlMap.find(cat_lvl[1]) != logLvlMap.end()) | |
| 529 | ✗ | logLevel = logLvlMap[cat_lvl[1]]; | |
| 530 | ✗ | if (cat_lvl[0] == "all") | |
| 531 | logSettings.setAll(logLevel); | ||
| 532 | else | ||
| 533 | ✗ | logSettings.modes[logCatMap[cat_lvl[0]]] = logLevel; | |
| 534 | } | ||
| 535 | else { | ||
| 536 | ✗ | if (logWarning.size() > 0) | |
| 537 | logWarning += ","; | ||
| 538 | logWarning += opt_vec[j]; | ||
| 539 | } | ||
| 540 | 1 | } | |
| 541 | 1 | } | |
| 542 | } | ||
| 543 | |||
| 544 |
4/4✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 39 times.
|
80 | if (vm.flag("warn-all")) { |
| 545 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 time.
|
9 | for (int i = 0; i < logSettings.modes.size(); i++) |
| 546 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 time.
|
8 | if (logSettings.modes[i] < LL_WARNING) |
| 547 | 7 | logSettings.modes[i] = LL_WARNING; | |
| 548 | } | ||
| 549 | |||
| 550 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("log-format")) { |
| 551 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | string logFormat_str = vm.str("log-format"); |
| 552 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (logFormatMap.find(logFormat_str) != logFormatMap.end()) |
| 553 |
2/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
40 | logSettings.format = logFormatMap[logFormat_str]; |
| 554 | else | ||
| 555 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, | |
| 556 | ✗ | "Unknown log-format " + logFormat_str); | |
| 557 | } | ||
| 558 | |||
| 559 | // make sure other infos get issued and initialize logger | ||
| 560 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (logSettings.modes[LC_OTHER] < LL_INFO) |
| 561 | 40 | logSettings.modes[LC_OTHER] = LL_INFO; | |
| 562 | |||
| 563 | // initialize logger if it has been enabled | ||
| 564 | if (Logger::isEnabled()) { | ||
| 565 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | int port = vm.integer("log-port"); |
| 566 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if (port > 0) { |
| 567 | try { | ||
| 568 | ✗ | LoggerXMLTCP::initialize(port, logSettings); | |
| 569 | } | ||
| 570 | ✗ | catch (std::exception &ex) { | |
| 571 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, | |
| 572 | ✗ | "Failed to start logger with port " + to_string(port) + ": " | |
| 573 | ✗ | + ex.what() + '\n'); | |
| 574 | ✗ | } | |
| 575 | } | ||
| 576 | else | ||
| 577 |
1/1✓ Branch 1 taken 40 times.
|
80 | Logger::initialize(logSettings); |
| 578 | } | ||
| 579 | |||
| 580 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if (logWarning.size() > 0) { |
| 581 | ✗ | LOGGER_WRITE("Unrecognized logging: " + logWarning, LC_OTHER, LL_WARNING); | |
| 582 | ✗ | if (logUsingOMEdit) { | |
| 583 | ✗ | ostringstream os; | |
| 584 | ✗ | os << "Supported are: "; | |
| 585 | map<std::string, LogOMEdit>::const_iterator it; | ||
| 586 | ✗ | for (it = logOMEditMap.begin(); it != logOMEditMap.end(); ++it) { | |
| 587 | ✗ | if (it != logOMEditMap.begin()) | |
| 588 | ✗ | os << ","; | |
| 589 | os << it->first; | ||
| 590 | } | ||
| 591 | ✗ | LOGGER_WRITE(os.str(), LC_OTHER, LL_INFO); | |
| 592 | ✗ | } | |
| 593 | } | ||
| 594 | |||
| 595 | 40 | return logSettings; | |
| 596 | } | ||
| 597 | |||
| 598 | 40 | SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[]) | |
| 599 | { | ||
| 600 | int opt; | ||
| 601 | int portnum; | ||
| 602 | map<string, OutputPointType> outputPointTypeMap = MAP_LIST_OF | ||
| 603 | "all", OPT_ALL MAP_LIST_SEP "step", OPT_STEP MAP_LIST_SEP | ||
| 604 |
3/8✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 120 times.
✓ Branch 6 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
200 | "none", OPT_NONE MAP_LIST_END; |
| 605 | map<string, OutputFormat> outputFormatMap = MAP_LIST_OF | ||
| 606 | "csv", CSV MAP_LIST_SEP "mat", MAT MAP_LIST_SEP | ||
| 607 |
3/8✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 160 times.
✓ Branch 6 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
240 | "buffer", BUFFER MAP_LIST_SEP "empty", EMPTY MAP_LIST_END; |
| 608 | map<string, EmitResults> emitResultsMap = MAP_LIST_OF | ||
| 609 | "all", EMIT_ALL MAP_LIST_SEP "hidden", EMIT_HIDDEN MAP_LIST_SEP | ||
| 610 | "protected", EMIT_PROTECTED MAP_LIST_SEP "public", EMIT_PUBLIC MAP_LIST_SEP | ||
| 611 |
3/8✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 200 times.
✓ Branch 6 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
280 | "none", EMIT_NONE MAP_LIST_END; |
| 612 | CommandLine vm; | ||
| 613 | |||
| 614 | //program options that can be overwritten by OMEdit must be declared as VALUES | ||
| 615 | //so that the same value can be set multiple times | ||
| 616 | //(e.g. 'executable -F arg1 -r=arg2' -> 'executable -F arg1 -F=arg2') | ||
| 617 | //the variables of OMEdit are always the first elements of the result vectors, if they are set | ||
| 618 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("help", 0, CommandLine::FLAG, CommandLine::STRING, "produce help message"); |
| 619 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("nls-continue", 0, CommandLine::FLAG, CommandLine::STRING, "non linear solver will continue if it can not reach the given precision"); |
| 620 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("runtime-library", 'R', CommandLine::VALUE, CommandLine::STRING, "path to cpp runtime libraries"); |
| 621 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("modelica-system-library", 'M', CommandLine::VALUE, CommandLine::STRING, "path to Modelica library"); |
| 622 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("input-path", 0, CommandLine::VALUE, CommandLine::STRING, "directory with input files, like init xml (defaults to modelica-system-library)"); |
| 623 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("output-path", 0, CommandLine::VALUE, CommandLine::STRING, "directory for output files, like results (defaults to modelica-system-library)"); |
| 624 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("results-file", 'F', CommandLine::VALUES, CommandLine::STRING, "name of results file"); |
| 625 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("start-time", 'S', CommandLine::VALUE, CommandLine::REAL, "simulation start time", "0"); |
| 626 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("stop-time", 'E', CommandLine::VALUE, CommandLine::REAL, "simulation stop time", "1"); |
| 627 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("step-size", 'H', CommandLine::VALUE, CommandLine::REAL, "simulation step size", "0"); |
| 628 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40 times.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
80 | vm.add("solver", 'I', CommandLine::VALUE, CommandLine::STRING, "solver method", "euler"); |
| 629 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("lin-solver", 'L', CommandLine::VALUE, CommandLine::STRING, "linear solver method", _defaultLinSolver); |
| 630 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("non-lin-solver", 'N', CommandLine::VALUE, CommandLine::STRING, "non linear solver method", _defaultNonLinSolvers[0]); |
| 631 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("number-of-intervals", 'G', CommandLine::VALUE, CommandLine::INT, "number of intervals in equidistant grid", "500"); |
| 632 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("tolerance", 'T', CommandLine::VALUE, CommandLine::REAL, "solver tolerance", "1e-06"); |
| 633 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("warn-all", 'W', CommandLine::FLAG, CommandLine::STRING, "issue all warning messages"); |
| 634 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("log-settings", 'V', CommandLine::VALUES, CommandLine::STRING, "cat[=lvl][,cat[=lvl]]... with cat: all, init, nls, ls, solver, output, events, model, other and lvl: error, warning, info, debug"); |
| 635 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("log-format", 'X', CommandLine::VALUE, CommandLine::STRING, "log format: txt, xml, xmltcp", "txt"); |
| 636 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("log-port", 0, CommandLine::VALUE, CommandLine::INT, "tcp port for log messages (default 0 meaning stdout/stderr)", "0"); |
| 637 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("alarm", 'A', CommandLine::VALUE, CommandLine::UINT, "sets timeout in seconds for simulation", "360"); |
| 638 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("output-type", 'O', CommandLine::VALUE, CommandLine::STRING, "the points in time written to result file: all (output steps + events), step (just output points), none", "all"); |
| 639 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("output-format", 'P', CommandLine::VALUE, CommandLine::STRING, "simulation results output format: csv, mat, buffer, empty", "mat"); |
| 640 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("emit-results", 'U', CommandLine::VALUE, CommandLine::STRING, "emit results: all, hidden, protected, public, none", "public"); |
| 641 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("ignore-hide-result", 0, CommandLine::FLAG, CommandLine::STRING, "ignore HideResult annotations"); |
| 642 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("variable-filter", 'B', CommandLine::VALUE, CommandLine::STRING, "only write variables that match filter", ".*"); |
| 643 |
5/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
120 | vm.add("solver-threads", 0, CommandLine::VALUE, CommandLine::INT, "number of threads that can be used by the solver", "1", true); |
| 644 | |||
| 645 | vector<string> unrecognized; | ||
| 646 | try { | ||
| 647 |
2/3✓ Branch 2 taken 40 times.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
|
573 | unrecognized = vm.parse(argc, argv, [this](const string& arg) { return replaceCRuntimeArguments(arg); }); |
| 648 | } | ||
| 649 | ✗ | catch (std::exception& ex) { | |
| 650 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, ex.what()); | |
| 651 | ✗ | } | |
| 652 |
3/4✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 40 times.
|
80 | if (vm.flag("help")) { |
| 653 | ✗ | vm.printHelp(cout); | |
| 654 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, "Cannot parse command line arguments correctly, because the help message was requested.", "",true); | |
| 655 | } | ||
| 656 | |||
| 657 |
1/1✓ Branch 1 taken 40 times.
|
40 | LogSettings logSettings = initializeLogger(vm); |
| 658 | |||
| 659 | // warn about unrecognized command line options | ||
| 660 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 39 times.
|
40 | if (unrecognized.size() > 0) { |
| 661 |
1/1✓ Branch 1 taken 1 time.
|
1 | ostringstream os; |
| 662 |
1/1✓ Branch 1 taken 1 time.
|
1 | os << "Warning: unrecognized command line options "; |
| 663 | copy(unrecognized.begin(), unrecognized.end(), ostream_iterator<string>(os, " ")); | ||
| 664 |
1/1✓ Branch 1 taken 1 time.
|
2 | LOGGER_WRITE(os.str(), LC_OTHER, LL_WARNING); |
| 665 | 1 | } | |
| 666 | |||
| 667 | string runtime_lib_path; | ||
| 668 | string modelica_lib_path; | ||
| 669 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | double starttime = vm.real("start-time"); |
| 670 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | double stoptime = vm.real("stop-time"); |
| 671 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | double stepsize =vm.real("step-size"); |
| 672 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | bool nlsContinueOnError = vm.flag("nls-continue"); |
| 673 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | int solverThreads = vm.integer("solver-threads"); |
| 674 | |||
| 675 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 32 times.
|
40 | if (!(stepsize > 0.0)) |
| 676 |
3/4✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
16 | stepsize = (stoptime - starttime) / vm.integer("number-of-intervals"); |
| 677 | |||
| 678 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | double tolerance = vm.real("tolerance"); |
| 679 |
2/4✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
80 | string solver = vm.str("solver"); |
| 680 | std::vector<string> nonLinSolvers; | ||
| 681 |
3/4✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 40 times.
|
120 | nonLinSolvers.push_back(vm.str("non-lin-solver")); |
| 682 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
|
40 | nonLinSolvers.push_back(nonLinSolvers[0] != _defaultNonLinSolvers[1]? _defaultNonLinSolvers[1]: _defaultNonLinSolvers[0]); |
| 683 |
1/1✓ Branch 1 taken 40 times.
|
40 | string linSolver = vm.str("lin-solver"); |
| 684 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
40 | unsigned int timeOut = vm.uinteger("alarm"); |
| 685 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("runtime-library")) |
| 686 | { | ||
| 687 |
1/1✓ Branch 1 taken 40 times.
|
40 | runtime_lib_path = vm.str("runtime-library"); |
| 688 |
1/1✓ Branch 1 taken 40 times.
|
40 | normalizePath(runtime_lib_path); |
| 689 | } | ||
| 690 | else | ||
| 691 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY,"runtime libraries path is not set"); | |
| 692 | |||
| 693 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("modelica-system-library")) |
| 694 | { | ||
| 695 |
1/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
40 | modelica_lib_path = vm.str("modelica-system-library"); |
| 696 |
1/1✓ Branch 1 taken 40 times.
|
40 | normalizePath(modelica_lib_path); |
| 697 | } | ||
| 698 | else | ||
| 699 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY,"Modelica library path is not set"); | |
| 700 | |||
| 701 | string inputPath, outputPath; | ||
| 702 |
2/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
80 | if (vm.count("input-path")) { |
| 703 | ✗ | inputPath = vm.str("input-path"); | |
| 704 | ✗ | normalizePath(inputPath); | |
| 705 | } | ||
| 706 | else | ||
| 707 | inputPath = modelica_lib_path; | ||
| 708 |
2/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
80 | if (vm.count("output-path")) { |
| 709 | ✗ | outputPath = vm.str("output-path"); | |
| 710 | ✗ | normalizePath(outputPath); | |
| 711 | } | ||
| 712 | else | ||
| 713 | outputPath = modelica_lib_path; | ||
| 714 | |||
| 715 | string resultsFileName; | ||
| 716 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("results-file")) |
| 717 | { | ||
| 718 |
1/1✓ Branch 1 taken 40 times.
|
40 | resultsFileName = vm.values("results-file").front(); |
| 719 | } | ||
| 720 | else | ||
| 721 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY,"results-filename is not set"); | |
| 722 | |||
| 723 | OutputPointType outputPointType; | ||
| 724 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("output-type")) |
| 725 | { | ||
| 726 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | string outputType_str = vm.str("output-type"); |
| 727 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (outputPointTypeMap.find(outputType_str) != outputPointTypeMap.end()) |
| 728 |
2/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
40 | outputPointType = outputPointTypeMap[outputType_str]; |
| 729 | else | ||
| 730 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, | |
| 731 | ✗ | "Unknown output-type " + outputType_str); | |
| 732 | } | ||
| 733 | else | ||
| 734 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, "output-type is not set"); | |
| 735 | |||
| 736 | OutputFormat outputFormat; | ||
| 737 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("output-format")) |
| 738 | { | ||
| 739 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | string outputFormat_str = vm.str("output-format"); |
| 740 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (outputFormatMap.find(outputFormat_str) != outputFormatMap.end()) |
| 741 |
1/1✓ Branch 1 taken 40 times.
|
40 | outputFormat = outputFormatMap[outputFormat_str]; |
| 742 | else | ||
| 743 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, | |
| 744 | ✗ | "Unknown output-format " + outputFormat_str); | |
| 745 | |||
| 746 | // adapt resultsFileName to match selected format | ||
| 747 | // (this is needed if outputFormat differs from value at compilation time) | ||
| 748 | size_t idx = resultsFileName.find_last_of('.'); | ||
| 749 |
4/9✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 40 times.
✗ Branch 10 not taken.
|
80 | if (idx > 0 && outputFormatMap.find(resultsFileName.substr(idx + 1)) != outputFormatMap.end()) |
| 750 |
3/6✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
80 | resultsFileName = resultsFileName.substr(0, idx + 1) + outputFormat_str; |
| 751 | } | ||
| 752 | else | ||
| 753 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, "output-format is not set"); | |
| 754 | |||
| 755 | EmitResults emitResults = EMIT_PUBLIC; // emit public per default for OMC use | ||
| 756 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("emit-results")) |
| 757 | { | ||
| 758 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | string emitResults_str = vm.str("emit-results"); |
| 759 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (emitResultsMap.find(emitResults_str) != emitResultsMap.end()) |
| 760 |
2/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
|
40 | emitResults = emitResultsMap[emitResults_str]; |
| 761 | else | ||
| 762 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY, | |
| 763 | ✗ | "Unknown emit-results " + emitResults_str); | |
| 764 | } | ||
| 765 |
3/4✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 40 times.
|
80 | if (vm.flag("ignore-hide-result")) |
| 766 | { | ||
| 767 | ✗ | switch (emitResults) { | |
| 768 | ✗ | case EMIT_NONE: | |
| 769 | case EMIT_PUBLIC: | ||
| 770 | emitResults = EMIT_HIDDEN; | ||
| 771 | ✗ | break; | |
| 772 | ✗ | case EMIT_PROTECTED: | |
| 773 | emitResults = EMIT_ALL; | ||
| 774 | default: | ||
| 775 | break; | ||
| 776 | } | ||
| 777 | } | ||
| 778 | |||
| 779 |
1/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
40 | string variableFilter = ".*"; |
| 780 |
2/3✓ Branch 1 taken 40 times.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | if (vm.count("variable-filter")) |
| 781 | { | ||
| 782 |
1/3✓ Branch 1 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
80 | variableFilter = vm.str("variable-filter"); |
| 783 | } | ||
| 784 | |||
| 785 |
1/1✓ Branch 1 taken 40 times.
|
80 | fs::path libraries_path = fs::path( runtime_lib_path) ; |
| 786 |
1/1✓ Branch 1 taken 40 times.
|
40 | fs::path modelica_path = fs::path( modelica_lib_path) ; |
| 787 | |||
| 788 | libraries_path.make_preferred(); | ||
| 789 | modelica_path.make_preferred(); | ||
| 790 | |||
| 791 |
8/8✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
✓ Branch 7 taken 40 times.
✓ Branch 10 taken 40 times.
✓ Branch 13 taken 40 times.
✓ Branch 16 taken 40 times.
✓ Branch 19 taken 40 times.
✓ Branch 22 taken 40 times.
|
240 | SimSettings settings = {solver, linSolver, nonLinSolvers, starttime, stoptime, stepsize, 1e-24, 0.01, tolerance, resultsFileName, timeOut, outputPointType, logSettings, nlsContinueOnError, solverThreads, outputFormat, emitResults, variableFilter, inputPath, outputPath}; |
| 792 | |||
| 793 |
1/1✓ Branch 2 taken 40 times.
|
80 | _library_path = libraries_path.string(); |
| 794 | 80 | _modelicasystem_path = modelica_path.string(); | |
| 795 | |||
| 796 | 40 | return settings; | |
| 797 | 80 | } | |
| 798 | |||
| 799 | 40 | vector<const char *> OMCFactory::handleOverrides(int argc, const char* argv[], map<string, string> &opts) | |
| 800 | { | ||
| 801 | map<string, string> mapOMEdit = MAP_LIST_OF | ||
| 802 | "-startTime", "-S" MAP_LIST_SEP "-stopTime", "-E" MAP_LIST_SEP | ||
| 803 | "-stepSize", "-H" MAP_LIST_SEP "-numberOfIntervals", "-G" MAP_LIST_SEP | ||
| 804 | "-s", "-I" MAP_LIST_SEP "-tolerance", "-T" MAP_LIST_SEP | ||
| 805 |
1/3✓ Branch 10 taken 40 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
400 | "-outputFormat", "-P" MAP_LIST_SEP "-variableFilter", "-B" MAP_LIST_END; |
| 806 | map<string, string>::const_iterator oit, mit; | ||
| 807 | vector<const char *> optv; | ||
| 808 | |||
| 809 |
1/1✓ Branch 2 taken 40 times.
|
40 | optv.push_back(strdup(argv[0])); |
| 810 |
2/2✓ Branch 0 taken 459 times.
✓ Branch 1 taken 40 times.
|
499 | for (int i = 1; i < argc; i++) { |
| 811 |
3/3✓ Branch 1 taken 459 times.
✓ Branch 3 taken 419 times.
✓ Branch 4 taken 40 times.
|
459 | string arg = argv[i]; |
| 812 | int j; | ||
| 813 | // Cpp overrides with = | ||
| 814 |
3/4✓ Branch 0 taken 419 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 409 times.
|
419 | if (arg[0] == '-' && arg[1] != '-' && (j = arg.find('=')) > 0 |
| 815 |
7/9✓ Branch 0 taken 419 times.
✓ Branch 1 taken 40 times.
✓ Branch 3 taken 10 times.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 449 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 459 times.
|
898 | && (oit = opts.find(arg.substr(0, j))) != opts.end()) |
| 816 | ✗ | opts[oit->first] = arg.substr(j + 1); // split at = and override | |
| 817 | // Cpp overrides with space | ||
| 818 |
3/4✓ Branch 0 taken 360 times.
✓ Branch 1 taken 99 times.
✓ Branch 2 taken 360 times.
✗ Branch 3 not taken.
|
459 | else if ((oit = opts.find(arg)) != opts.end() && i < argc - 1) |
| 819 |
1/1✓ Branch 1 taken 360 times.
|
360 | opts[oit->first] = argv[++i]; // regular override |
| 820 | // OMEdit options | ||
| 821 |
3/4✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 49 times.
|
59 | else if (arg[0] == '-' && arg[1] != '-' && (j = arg.find('=')) > 0 |
| 822 |
9/9✓ Branch 0 taken 59 times.
✓ Branch 1 taken 40 times.
✓ Branch 3 taken 10 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 89 times.
✓ Branch 9 taken 6 times.
✓ Branch 10 taken 93 times.
|
172 | && (mit = mapOMEdit.find(arg.substr(0, j))) != mapOMEdit.end()) { |
| 823 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if ((oit = opts.find(mit->second)) != opts.end()) |
| 824 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
|
12 | opts[oit->first] = arg.substr(j + 1); // split at = and override value |
| 825 | else | ||
| 826 | ✗ | optv.push_back(strdup(argv[i])); // pass through | |
| 827 | } | ||
| 828 | else | ||
| 829 |
1/3✓ Branch 2 taken 93 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
93 | optv.push_back(strdup(argv[i])); // pass through |
| 830 | } | ||
| 831 |
2/2✓ Branch 0 taken 480 times.
✓ Branch 1 taken 40 times.
|
520 | for (oit = opts.begin(); oit != opts.end(); oit++) { |
| 832 |
1/1✓ Branch 2 taken 480 times.
|
480 | optv.push_back(strdup(oit->first.c_str())); |
| 833 |
1/3✓ Branch 2 taken 480 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
480 | optv.push_back(strdup(oit->second.c_str())); |
| 834 | } | ||
| 835 | |||
| 836 | 40 | return optv; | |
| 837 | } | ||
| 838 | |||
| 839 | 240 | void OMCFactory::fillArgumentsToIgnore() | |
| 840 | { | ||
| 841 | 240 | _argumentsToIgnore.insert("-abortSlowSimulation"); // used by nightly tests | |
| 842 | 240 | } | |
| 843 | |||
| 844 | 240 | void OMCFactory::fillArgumentsToReplace() | |
| 845 | { | ||
| 846 | 480 | _argumentsToReplace.insert(pair<string,string>("-r", "results-file")); | |
| 847 | 480 | _argumentsToReplace.insert(pair<string,string>("-ls", "lin-solver")); | |
| 848 | 480 | _argumentsToReplace.insert(pair<string,string>("-nls", "non-lin-solver")); | |
| 849 | 480 | _argumentsToReplace.insert(pair<string,string>("-lv", "log-settings")); | |
| 850 | 480 | _argumentsToReplace.insert(pair<string,string>("-w", "warn-all")); | |
| 851 | 480 | _argumentsToReplace.insert(pair<string,string>("-logFormat", "log-format")); | |
| 852 | 480 | _argumentsToReplace.insert(pair<string,string>("-port", "log-port")); | |
| 853 | 480 | _argumentsToReplace.insert(pair<string,string>("-alarm", "alarm")); | |
| 854 | 480 | _argumentsToReplace.insert(pair<string,string>("-emit_protected", "emit-results protected")); | |
| 855 | 480 | _argumentsToReplace.insert(pair<string,string>("-ignoreHideResult", "ignore-hide-result")); | |
| 856 | 480 | _argumentsToReplace.insert(pair<string,string>("-inputPath", "input-path")); | |
| 857 | 480 | _argumentsToReplace.insert(pair<string,string>("-outputPath", "output-path")); | |
| 858 | 240 | } | |
| 859 | |||
| 860 | pair<shared_ptr<ISimController>,SimSettings> | ||
| 861 | 40 | OMCFactory::createSimulation(int argc, const char* argv[], | |
| 862 | map<string, string> &opts) | ||
| 863 | { | ||
| 864 | 40 | vector<const char *> optv = handleOverrides(argc, argv, opts); | |
| 865 | |||
| 866 |
1/1✓ Branch 1 taken 40 times.
|
40 | SimSettings settings = readSimulationParameter(optv.size(), &optv[0]); |
| 867 | type_map simcontroller_type_map; | ||
| 868 |
1/1✓ Branch 1 taken 40 times.
|
40 | fs::path simcontroller_path = _library_path; |
| 869 |
1/1✓ Branch 1 taken 40 times.
|
40 | fs::path simcontroller_name(SIMCONTROLLER_LIB); |
| 870 |
1/1✓ Branch 1 taken 40 times.
|
40 | simcontroller_path/=simcontroller_name; |
| 871 | |||
| 872 |
2/2✓ Branch 1 taken 40 times.
✓ Branch 4 taken 40 times.
|
120 | shared_ptr<ISimController> simcontroller = loadSimControllerLib(simcontroller_path.string(), simcontroller_type_map); |
| 873 | |||
| 874 |
2/2✓ Branch 0 taken 1093 times.
✓ Branch 1 taken 40 times.
|
1133 | for(int i = 0; i < optv.size(); i++) |
| 875 | 1093 | free((char*)optv[i]); | |
| 876 | |||
| 877 | optv.clear(); | ||
| 878 | |||
| 879 | 40 | return make_pair(simcontroller, settings); | |
| 880 | 80 | } | |
| 881 | |||
| 882 |
1/1✓ Branch 1 taken 558 times.
|
558 | LOADERRESULT OMCFactory::LoadLibrary(string libName,type_map& current_map) |
| 883 | { | ||
| 884 | |||
| 885 | shared_library lib; | ||
| 886 |
2/3✓ Branch 1 taken 558 times.
✓ Branch 3 taken 558 times.
✗ Branch 4 not taken.
|
558 | if(!load_single_library(current_map,libName,lib)) |
| 887 | return LOADER_ERROR; | ||
| 888 | 558 | _modules.insert(make_pair(libName,lib)); | |
| 889 | 558 | return LOADER_SUCCESS; | |
| 890 | 558 | } | |
| 891 | |||
| 892 |
1/2✓ Branch 0 taken 413 times.
✗ Branch 1 not taken.
|
413 | LOADERRESULT OMCFactory::UnloadLibrary(shared_library lib) |
| 893 | { | ||
| 894 |
1/2✓ Branch 0 taken 413 times.
✗ Branch 1 not taken.
|
413 | if(lib.is_open()) |
| 895 | { | ||
| 896 |
1/2✓ Branch 0 taken 413 times.
✗ Branch 1 not taken.
|
413 | if(!lib.close()) |
| 897 | return LOADER_ERROR; | ||
| 898 | else | ||
| 899 | 413 | return LOADER_SUCCESS; | |
| 900 | } | ||
| 901 | return LOADER_SUCCESS; | ||
| 902 | } | ||
| 903 | |||
| 904 | 40 | shared_ptr<ISimController> OMCFactory::loadSimControllerLib(PATH simcontroller_path, type_map simcontroller_type_map) | |
| 905 | { | ||
| 906 |
1/1✓ Branch 2 taken 40 times.
|
40 | LOADERRESULT result = LoadLibrary(simcontroller_path, simcontroller_type_map); |
| 907 | |||
| 908 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if (result != LOADER_SUCCESS) |
| 909 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY,string("Failed loading SimController library from path ") + simcontroller_path); | |
| 910 | |||
| 911 | map<string, factory<ISimController,PATH,PATH> >::iterator iter; | ||
| 912 | 40 | map<string, factory<ISimController,PATH,PATH> >& factories(simcontroller_type_map.get()); | |
| 913 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
|
80 | iter = factories.find("SimController"); |
| 914 | |||
| 915 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | if (iter ==factories.end()) |
| 916 | ✗ | throw ModelicaSimulationError(MODEL_FACTORY,"No such SimController library"); | |
| 917 | |||
| 918 |
2/5✓ Branch 2 taken 40 times.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
160 | return shared_ptr<ISimController>(iter->second.create(_library_path, _modelicasystem_path)); |
| 919 | } | ||
| 920 | /** @} */ // end of simcorefactoryOMCFactory | ||
| 921 |