OMCompiler/SimulationRuntime/c/util/omc_error.c
| 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 | #include "setjmp.h" | ||
| 29 | #include <stdio.h> | ||
| 30 | #include "omc_error.h" | ||
| 31 | #include <string.h> | ||
| 32 | #include "omc_init.h" | ||
| 33 | #include "simulation_options.h" | ||
| 34 | |||
| 35 | const FILE_INFO omc_dummyFileInfo = omc_dummyFileInfo_val; | ||
| 36 | |||
| 37 | void (*omc_assert)(threadData_t*,FILE_INFO info,const char *msg,...) = omc_assert_function; | ||
| 38 | void (*omc_assert_warning)(FILE_INFO info,const char *msg,...) = omc_assert_warning_function; | ||
| 39 | void (*omc_terminate)(FILE_INFO info,const char *msg,...) = omc_terminate_function; | ||
| 40 | void (*omc_throw)(threadData_t*) __attribute__ ((noreturn)) = omc_throw_function; | ||
| 41 | |||
| 42 | /* An error raised from code that got no threadData (ModelicaError, an external | ||
| 43 | function's assert) finds it through mmc_thread_data_key. Without it there is no | ||
| 44 | jump buffer to leave through, so report and exit rather than crash. The key | ||
| 45 | comes up empty when the executable or an external library linked its own copy | ||
| 46 | of the pthread library: each copy keeps its own thread-specific values. */ | ||
| 47 | ✗ | threadData_t* omc_thread_data(threadData_t *threadData, const char *pendingMessage) | |
| 48 | { | ||
| 49 | ✗ | if (threadData) { | |
| 50 | return threadData; | ||
| 51 | } | ||
| 52 | ✗ | threadData = (threadData_t*)pthread_getspecific(mmc_thread_data_key); | |
| 53 | ✗ | if (threadData) { | |
| 54 | return threadData; | ||
| 55 | } | ||
| 56 | ✗ | if (pendingMessage) { | |
| 57 | ✗ | fprintf(stderr, "%s\n", pendingMessage); | |
| 58 | } | ||
| 59 | ✗ | fputs("Internal error: the calling thread has no OpenModelica thread data, so the error " | |
| 60 | "cannot be handled and the simulation is aborted.\n" | ||
| 61 | "This happens when the simulation executable or an external library links its " | ||
| 62 | "own copy of the pthread library (e.g. a static libwinpthread) instead of the " | ||
| 63 | "one the OpenModelica runtime uses.\n", stderr); | ||
| 64 | ✗ | fflush(NULL); | |
| 65 | ✗ | exit(1); | |
| 66 | } | ||
| 67 | |||
| 68 | |||
| 69 | const int firstOMCErrorStream = 1; | ||
| 70 | |||
| 71 | const char *OMC_LOG_STREAM_NAME[OMC_SIM_LOG_MAX] = { | ||
| 72 | "LOG_UNKNOWN", | ||
| 73 | "LOG_STDOUT", | ||
| 74 | "LOG_ASSERT", | ||
| 75 | |||
| 76 | "LOG_DASSL", | ||
| 77 | "LOG_DASSL_STATES", | ||
| 78 | "LOG_DEBUG", | ||
| 79 | "LOG_DELAY", | ||
| 80 | "LOG_DIVISION", | ||
| 81 | "LOG_DSS", | ||
| 82 | "LOG_DSS_JAC", | ||
| 83 | "LOG_DT", | ||
| 84 | "LOG_DT_CONS", | ||
| 85 | "LOG_EVENTS", | ||
| 86 | "LOG_EVENTS_V", | ||
| 87 | "LOG_GBODE", | ||
| 88 | "LOG_GBODE_V", | ||
| 89 | "LOG_GBODE_NLS", | ||
| 90 | "LOG_GBODE_NLS_V", | ||
| 91 | "LOG_GBODE_STATES", | ||
| 92 | "LOG_INIT", | ||
| 93 | "LOG_INIT_HOMOTOPY", | ||
| 94 | "LOG_INIT_V", | ||
| 95 | "LOG_IPOPT", | ||
| 96 | "LOG_IPOPT_FULL", | ||
| 97 | "LOG_IPOPT_JAC", | ||
| 98 | "LOG_IPOPT_HESSE", | ||
| 99 | "LOG_IPOPT_ERROR", | ||
| 100 | "LOG_JAC", | ||
| 101 | "LOG_LS", | ||
| 102 | "LOG_LS_V", | ||
| 103 | "LOG_MIXED", | ||
| 104 | "LOG_MOO", | ||
| 105 | "LOG_NLS", | ||
| 106 | "LOG_NLS_V", | ||
| 107 | "LOG_NLS_HOMOTOPY", | ||
| 108 | "LOG_NLS_JAC", | ||
| 109 | "LOG_NLS_JAC_TEST", | ||
| 110 | "LOG_NLS_JAC_SUMS", | ||
| 111 | "LOG_NLS_NEWTON_DIAGNOSTICS", | ||
| 112 | "LOG_NLS_DERIVATIVE_TEST", | ||
| 113 | "LOG_NLS_SVD", | ||
| 114 | "LOG_NLS_SVD_V", | ||
| 115 | "LOG_NLS_RES", | ||
| 116 | "LOG_NLS_EXTRAPOLATE", | ||
| 117 | "LOG_RES_INIT", | ||
| 118 | "LOG_RT", | ||
| 119 | "LOG_SIMULATION", | ||
| 120 | "LOG_SOLVER", | ||
| 121 | "LOG_SOLVER_V", | ||
| 122 | "LOG_SOLVER_CONTEXT", | ||
| 123 | "LOG_SOTI", | ||
| 124 | "LOG_SPATIALDISTR", | ||
| 125 | "LOG_STATS", | ||
| 126 | "LOG_STATS_V", | ||
| 127 | "LOG_SUCCESS", | ||
| 128 | "LOG_SYNCHRONOUS", | ||
| 129 | "LOG_ZEROCROSSINGS", | ||
| 130 | }; | ||
| 131 | |||
| 132 | const char *OMC_LOG_STREAM_DESC[OMC_SIM_LOG_MAX] = { | ||
| 133 | "unknown", | ||
| 134 | "this stream is always active, can be disabled with -lv=-LOG_STDOUT", /* OMC_LOG_STDOUT */ | ||
| 135 | "this stream is always active, can be disabled with -lv=-LOG_ASSERT", /* OMC_LOG_ASSERT */ | ||
| 136 | |||
| 137 | "additional information about dassl solver", /* OMC_LOG_DASSL */ | ||
| 138 | "outputs the states at every dassl call", /* OMC_LOG_DASSL_STATES */ | ||
| 139 | "additional debug information", /* OMC_LOG_DEBUG */ | ||
| 140 | "debug information for delay operator", /* OMC_LOG_DELAY */ | ||
| 141 | "Log division by zero", /* OMC_LOG_DIVISION */ | ||
| 142 | "outputs information about dynamic state selection", /* OMC_LOG_DSS */ | ||
| 143 | "outputs jacobian of the dynamic state selection", /* OMC_LOG_DSS_JAC */ | ||
| 144 | "additional information about dynamic tearing", /* OMC_LOG_DT */ | ||
| 145 | "additional information about dynamic tearing (local and global constraints)",/* OMC_LOG_DT_CONS */ | ||
| 146 | "additional information during event iteration", /* OMC_LOG_EVENTS */ | ||
| 147 | "verbose logging of event system", /* OMC_LOG_EVENTS_V */ | ||
| 148 | "information about GBODE solver", /* OMC_LOG_GBODE */ | ||
| 149 | "verbose information about GBODE solver", /* OMC_LOG_GBODE_V */ | ||
| 150 | "log non-linear solver process of GBODE solver", /* OMC_LOG_GBODE_NLS */ | ||
| 151 | "verbose log non-linear solver process of GBODE solver", /* OMC_LOG_GBODE_NLS_V */ | ||
| 152 | "output states at every GBODE call", /* OMC_LOG_GBODE_STATES */ | ||
| 153 | "additional information during initialization", /* OMC_LOG_INIT */ | ||
| 154 | "log homotopy initialization", /* OMC_LOG_INIT_HOMOTOPY */ | ||
| 155 | "verbose information during initialization", /* OMC_LOG_INIT_V */ | ||
| 156 | "information from Ipopt", /* OMC_LOG_IPOPT */ | ||
| 157 | "more information from Ipopt", /* OMC_LOG_IPOPT_FULL*/ | ||
| 158 | "check jacobian matrix with Ipopt", /* OMC_LOG_IPOPT_JAC*/ | ||
| 159 | "check hessian matrix with Ipopt", /* OMC_LOG_IPOPT_HESSE*/ | ||
| 160 | "print max error in the optimization", /* OMC_LOG_IPOPT_ERROR*/ | ||
| 161 | "outputs the jacobian matrix used by ODE solvers", /* OMC_LOG_JAC */ | ||
| 162 | "logging for linear systems", /* OMC_LOG_LS */ | ||
| 163 | "verbose logging of linear systems", /* OMC_LOG_LS_V */ | ||
| 164 | "logging for mixed systems", /* OMC_LOG_MIXED */ | ||
| 165 | "logging for dynamic optimization library MOO", /* OMC_LOG_MOO */ | ||
| 166 | "logging for nonlinear systems", /* OMC_LOG_NLS */ | ||
| 167 | "verbose logging of nonlinear systems", /* OMC_LOG_NLS_V */ | ||
| 168 | "logging of homotopy solver for nonlinear systems", /* OMC_LOG_NLS_HOMOTOPY */ | ||
| 169 | "outputs the jacobian of nonlinear systems", /* OMC_LOG_NLS_JAC */ | ||
| 170 | "tests the analytical jacobian of nonlinear systems", /* OMC_LOG_NLS_JAC_TEST */ | ||
| 171 | "tests the absolute sums of rows and cols in Kinsol Jacobian", /* OMC_LOG_NLS_JAC_SUMS */ | ||
| 172 | "newton diagnostics (see: https://doi.org/10.1016/j.amc.2021.125991)", /* OMC_LOG_NLS_NEWTON_DIAGNOSTICS */ | ||
| 173 | "test derivatives in KINSOL nonlinear systems", /* OMC_LOG_NLS_DERIVATIVE_TEST */ | ||
| 174 | "perform a SVD analysis in KINSOL nonlinear systems", /* OMC_LOG_NLS_SVD */ | ||
| 175 | "perform a SVD analysis in KINSOL nonlinear systems (verbose)", /* OMC_LOG_NLS_SVD_V */ | ||
| 176 | "outputs every evaluation of the residual function", /* OMC_LOG_NLS_RES */ | ||
| 177 | "outputs debug information about extrapolate process", /* OMC_LOG_NLS_EXTRAPOLATE */ | ||
| 178 | "outputs residuals of the initialization", /* OMC_LOG_RES_INIT */ | ||
| 179 | "additional information regarding real-time processes", /* OMC_LOG_RT */ | ||
| 180 | "additional information about simulation process", /* OMC_LOG_SIMULATION */ | ||
| 181 | "additional information about solver process", /* OMC_LOG_SOLVER */ | ||
| 182 | "verbose information about the integration process", /* OMC_LOG_SOLVER_V */ | ||
| 183 | "context information during the solver process", /* OMC_LOG_SOLVER_CONTEXT" */ | ||
| 184 | "final solution of the initialization", /* OMC_LOG_SOTI */ | ||
| 185 | "logging of internal operations for spatialDistribution", /* OMC_LOG_SPATIALDISTR */ | ||
| 186 | "additional statistics about timer/events/solver", /* OMC_LOG_STATS */ | ||
| 187 | "additional statistics for OMC_LOG_STATS", /* OMC_LOG_STATS_V */ | ||
| 188 | "this stream is always active, unless deactivated with -lv=-LOG_SUCCESS", /* OMC_LOG_SUCCESS */ | ||
| 189 | "log clocks and sub-clocks for synchronous features", /* OMC_LOG_SYNCHRONOUS */ | ||
| 190 | "additional information about the zerocrossings" /* OMC_LOG_ZEROCROSSINGS */ | ||
| 191 | }; | ||
| 192 | |||
| 193 | const char *OMC_LOG_TYPE_DESC[OMC_LOG_TYPE_MAX] = { | ||
| 194 | "unknown", | ||
| 195 | "info", | ||
| 196 | "warning", | ||
| 197 | "error", | ||
| 198 | "assert", | ||
| 199 | "debug" | ||
| 200 | }; | ||
| 201 | |||
| 202 | int omc_useStream[OMC_SIM_LOG_MAX]; /* 1 if LOG is enabled, otherwise 0 */ | ||
| 203 | static int backupUseStream[OMC_SIM_LOG_MAX]; /* Backup of omc_useStream */ | ||
| 204 | static int omc_level[OMC_SIM_LOG_MAX]; | ||
| 205 | static int omc_lastType[OMC_SIM_LOG_MAX]; | ||
| 206 | static int omc_lastStream = OMC_LOG_UNKNOWN; | ||
| 207 | int omc_showAllWarnings = 0; | ||
| 208 | static int streamsActive = 1; /* 1 if info streams from omc_useStream are active, 0 if deactivated */ | ||
| 209 | |||
| 210 | 1 | void initDumpSystem(void) | |
| 211 | { | ||
| 212 | int i; | ||
| 213 | |||
| 214 |
2/2✓ Branch 0 taken 57 times.
✓ Branch 1 taken 1 time.
|
58 | for(i=0; i<OMC_SIM_LOG_MAX; ++i) |
| 215 | { | ||
| 216 | 57 | omc_useStream[i] = 0; | |
| 217 | 57 | omc_level[i] = 0; | |
| 218 | 57 | omc_lastType[i] = 0; | |
| 219 | } | ||
| 220 | |||
| 221 | 1 | omc_useStream[OMC_LOG_STDOUT] = 1; | |
| 222 | 1 | omc_useStream[OMC_LOG_ASSERT] = 1; | |
| 223 | 1 | omc_useStream[OMC_LOG_SUCCESS] = 1; | |
| 224 | 1 | } | |
| 225 | |||
| 226 | /* Deactivates streams for logging except for stdout, assert and success. */ | ||
| 227 | ✗ | void deactivateLogging(void) | |
| 228 | { | ||
| 229 | int i; | ||
| 230 | |||
| 231 | ✗ | if (streamsActive == 0) | |
| 232 | { | ||
| 233 | return; /* Do nothing if already inactive */ | ||
| 234 | } | ||
| 235 | |||
| 236 | ✗ | for(i=0; i<OMC_SIM_LOG_MAX; ++i) | |
| 237 | { | ||
| 238 | ✗ | if (i != OMC_LOG_STDOUT && i != OMC_LOG_ASSERT && i != OMC_LOG_SUCCESS) | |
| 239 | { | ||
| 240 | ✗ | backupUseStream[i] = omc_useStream[i]; | |
| 241 | /* | ||
| 242 | if (omc_useStream[i] != 0) { | ||
| 243 | printf("Stream %s deactivated\n",LOG_STREAM_NAME[i]); | ||
| 244 | } | ||
| 245 | */ | ||
| 246 | ✗ | omc_useStream[i] = 0; | |
| 247 | } | ||
| 248 | } | ||
| 249 | |||
| 250 | ✗ | omc_useStream[OMC_LOG_STDOUT] = 1; | |
| 251 | ✗ | omc_useStream[OMC_LOG_ASSERT] = 1; | |
| 252 | ✗ | omc_useStream[OMC_LOG_SUCCESS] = 1; | |
| 253 | |||
| 254 | ✗ | streamsActive = 0; /* Deactivate info streams */ | |
| 255 | //infoStreamPrint(OMC_LOG_STDOUT,0,"Deactivated logging"); | ||
| 256 | } | ||
| 257 | |||
| 258 | /* Resets streams to backup after deactivateLogging() was used. */ | ||
| 259 | ✗ | void reactivateLogging(void) | |
| 260 | { | ||
| 261 | int i; | ||
| 262 | |||
| 263 | ✗ | if (streamsActive == 1) | |
| 264 | { | ||
| 265 | return; /* Do nothing if already active */ | ||
| 266 | } | ||
| 267 | |||
| 268 | ✗ | for(i=0; i<OMC_SIM_LOG_MAX; ++i) | |
| 269 | { | ||
| 270 | ✗ | if (i != OMC_LOG_STDOUT && i != OMC_LOG_ASSERT && i != OMC_LOG_SUCCESS) | |
| 271 | { | ||
| 272 | ✗ | omc_useStream[i] = backupUseStream[i]; | |
| 273 | /* | ||
| 274 | if (omc_useStream[i] != 0) { | ||
| 275 | printf("Stream %s reactivated\n",LOG_STREAM_NAME[i]); | ||
| 276 | } | ||
| 277 | */ | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | ✗ | streamsActive = 1; /* Activate info streams */ | |
| 282 | //infoStreamPrint(OMC_LOG_STDOUT,0,"Reactivated logging"); | ||
| 283 | } | ||
| 284 | |||
| 285 | ✗ | void printInfo(FILE *stream, FILE_INFO info) | |
| 286 | { | ||
| 287 | ✗ | fprintf(stream, "[%s:%d:%d-%d:%d:%s]", info.filename, info.lineStart, info.colStart, info.lineEnd, info.colEnd, info.readonly ? "readonly" : "writable"); | |
| 288 | ✗ | } | |
| 289 | |||
| 290 | static void (*omc_assert_reporter)(threadData_t*, FILE_INFO, const char*, va_list) = NULL; | ||
| 291 | static void (*omc_assert_warning_reporter)(FILE_INFO, const char*, va_list) = NULL; | ||
| 292 | |||
| 293 | 114 | void omc_set_assert_reporters(void (*err)(threadData_t*, FILE_INFO, const char*, va_list), | |
| 294 | void (*warn)(FILE_INFO, const char*, va_list)) | ||
| 295 | { | ||
| 296 | 114 | omc_assert_reporter = err; | |
| 297 | 114 | omc_assert_warning_reporter = warn; | |
| 298 | 114 | } | |
| 299 | |||
| 300 | ✗ | void omc_assert_function(threadData_t* threadData, FILE_INFO info, const char *msg, ...) | |
| 301 | { | ||
| 302 | va_list ap; | ||
| 303 | ✗ | va_start(ap,msg); | |
| 304 | ✗ | if (omc_assert_reporter) { | |
| 305 | ✗ | omc_assert_reporter(threadData, info, msg, ap); | |
| 306 | } else { | ||
| 307 | ✗ | printInfo(stderr, info); | |
| 308 | ✗ | fputs("Modelica Assert: ", stderr); | |
| 309 | ✗ | vfprintf(stderr,msg,ap); | |
| 310 | ✗ | fputs("!\n", stderr); | |
| 311 | } | ||
| 312 | ✗ | va_end(ap); | |
| 313 | ✗ | fflush(NULL); | |
| 314 | ✗ | threadData = omc_thread_data(threadData, NULL); | |
| 315 | ✗ | OMC_ERROR_RAISE(); | |
| 316 | ✗ | } | |
| 317 | |||
| 318 | ✗ | void omc_assert_warning_function(FILE_INFO info, const char *msg, ...) | |
| 319 | { | ||
| 320 | va_list ap; | ||
| 321 | ✗ | va_start(ap,msg); | |
| 322 | ✗ | if (omc_assert_warning_reporter) { | |
| 323 | ✗ | omc_assert_warning_reporter(info, msg, ap); | |
| 324 | } else { | ||
| 325 | ✗ | printInfo(stderr, info); | |
| 326 | ✗ | fputs("Warning, assertion triggered: ", stderr); | |
| 327 | ✗ | vfprintf(stderr,msg,ap); | |
| 328 | ✗ | fputs("!\n", stderr); | |
| 329 | } | ||
| 330 | ✗ | va_end(ap); | |
| 331 | ✗ | fflush(NULL); | |
| 332 | ✗ | } | |
| 333 | |||
| 334 | ✗ | void omc_throw_function(threadData_t *threadData) | |
| 335 | { | ||
| 336 | /* Unlike a model's assert this jumps: it ends the run, and no generated frame | ||
| 337 | is on the stack to owe a release. */ | ||
| 338 | ✗ | threadData = omc_thread_data(threadData, NULL); | |
| 339 | ✗ | OMC_THROW_INTERNAL(); | |
| 340 | } | ||
| 341 | |||
| 342 | ✗ | void omc_terminate_function(FILE_INFO info, const char *msg, ...) | |
| 343 | { | ||
| 344 | va_list ap; | ||
| 345 | ✗ | va_start(ap,msg); | |
| 346 | ✗ | printInfo(stderr, info); | |
| 347 | ✗ | fputs("Modelica Terminate: ", stderr); | |
| 348 | ✗ | vfprintf(stderr,msg,ap); | |
| 349 | ✗ | fputs("!\n", stderr); | |
| 350 | ✗ | va_end(ap); | |
| 351 | ✗ | fflush(NULL); | |
| 352 | ✗ | omc_throw_function(NULL); | |
| 353 | } | ||
| 354 | |||
| 355 | 65 | void messageText(int type, int stream, FILE_INFO info, int indentNext, char *msg, int subline, const int *indexes) | |
| 356 | { | ||
| 357 | int i; | ||
| 358 | int len; | ||
| 359 | |||
| 360 |
5/6✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 46 times.
|
65 | printf("%-17s | ", (subline || (omc_lastStream == stream && omc_level[stream] > 0)) ? "|" : OMC_LOG_STREAM_NAME[stream]); |
| 361 |
6/8✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 46 times.
|
65 | printf("%-7s | ", (subline || (omc_lastStream == stream && omc_lastType[stream] == type && omc_level[stream] > 0)) ? "|" : OMC_LOG_TYPE_DESC[type]); |
| 362 | 65 | omc_lastType[stream] = type; | |
| 363 | 65 | omc_lastStream = stream; | |
| 364 | |||
| 365 |
2/2✓ Branch 0 taken 74 times.
✓ Branch 1 taken 65 times.
|
139 | for(i=0; i<omc_level[stream]; ++i) |
| 366 | printf("| "); | ||
| 367 | |||
| 368 |
2/4✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 65 times.
|
65 | if (info.filename && strlen(info.filename) > 0) { |
| 369 | // Print to stdout because we are using printf down below as well. | ||
| 370 | ✗ | printInfo(stdout, info); | |
| 371 | printf("\n"); | ||
| 372 | |||
| 373 | printf("%-17s | ", "|"); | ||
| 374 | printf("%-7s | ", "|"); | ||
| 375 | } | ||
| 376 | |||
| 377 |
2/2✓ Branch 0 taken 2203 times.
✓ Branch 1 taken 65 times.
|
2268 | for(i=0; msg[i]; i++) |
| 378 | { | ||
| 379 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2203 times.
|
2203 | if(msg[i] == '\n') |
| 380 | { | ||
| 381 | ✗ | msg[i] = '\0'; | |
| 382 | printf("%s\n", msg); | ||
| 383 | ✗ | if (msg[i+1]) { | |
| 384 | ✗ | messageText(type, stream, omc_dummyFileInfo, 0, &msg[i+1], 1, indexes); | |
| 385 | } | ||
| 386 | ✗ | return; | |
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | 65 | len = strlen(msg); | |
| 391 |
2/4✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 65 times.
|
65 | if (len>0 && msg[len-1]=='\n') { |
| 392 | printf("%s", msg); | ||
| 393 | } else { | ||
| 394 | printf("%s\n", msg); | ||
| 395 | } | ||
| 396 | 65 | fflush(NULL); | |
| 397 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 48 times.
|
65 | if (indentNext) omc_level[stream]++; |
| 398 | } | ||
| 399 | |||
| 400 | /** | ||
| 401 | * @brief Close messages. | ||
| 402 | * | ||
| 403 | * Use for active streams to reduce level of indentation by one. | ||
| 404 | * | ||
| 405 | * @param stream Log stream. | ||
| 406 | */ | ||
| 407 | 177 | static void messageCloseText(int stream) | |
| 408 | { | ||
| 409 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 160 times.
|
177 | if(OMC_ACTIVE_STREAM(stream)) { |
| 410 | 17 | omc_level[stream]--; | |
| 411 | } | ||
| 412 | 177 | } | |
| 413 | |||
| 414 | /** | ||
| 415 | * @brief Close warning messages. | ||
| 416 | * | ||
| 417 | * Use for warning messages that indented the stream either because the stream is active | ||
| 418 | * or showAllWarnings is true. | ||
| 419 | * | ||
| 420 | * @param stream Log stream. | ||
| 421 | */ | ||
| 422 | ✗ | static void messageCloseTextWarning(int stream) | |
| 423 | { | ||
| 424 | ✗ | if (OMC_ACTIVE_WARNING_STREAM(stream)) { | |
| 425 | ✗ | omc_level[stream]--; | |
| 426 | } | ||
| 427 | ✗ | } | |
| 428 | |||
| 429 | void (*messageFunction)(int type, int stream, FILE_INFO info, int indentNext, char *msg, int subline, const int *indexes) = messageText; | ||
| 430 | /** | ||
| 431 | * @brief Close messages. | ||
| 432 | * See messageCloseText() for more info. | ||
| 433 | */ | ||
| 434 | void (*messageClose)(int stream) = messageCloseText; | ||
| 435 | /** | ||
| 436 | * @brief Close warning messages. | ||
| 437 | * See messageCloseTextWarning() for more info. | ||
| 438 | */ | ||
| 439 | void (*messageCloseWarning)(int stream) = messageCloseTextWarning; | ||
| 440 | |||
| 441 | #define SIZE_LOG_BUFFER 2048 | ||
| 442 | |||
| 443 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 444 | 27 | void va_infoStreamPrint(int stream, int indentNext, const char *format, va_list args) | |
| 445 | { | ||
| 446 |
1/2✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
|
27 | if (omc_useStream[stream]) { |
| 447 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 448 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 449 | 27 | messageFunction(OMC_LOG_TYPE_INFO, stream, omc_dummyFileInfo, indentNext, logBuffer, 0, NULL); | |
| 450 | } | ||
| 451 | 27 | } | |
| 452 | |||
| 453 | 9 | void infoStreamPrintWithEquationIndexes(int stream, FILE_INFO info, int indentNext, const int *indexes, const char *format, ...) | |
| 454 | { | ||
| 455 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (omc_useStream[stream]) { |
| 456 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 457 | va_list args; | ||
| 458 | 9 | va_start(args, format); | |
| 459 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 460 | 9 | va_end(args); | |
| 461 | 9 | messageFunction(OMC_LOG_TYPE_INFO, stream, info, indentNext, logBuffer, 0, indexes); | |
| 462 | } | ||
| 463 | 9 | } | |
| 464 | |||
| 465 | 29336980 | void infoStreamPrint(int stream, int indentNext, const char *format, ...) | |
| 466 | { | ||
| 467 |
2/2✓ Branch 0 taken 360 times.
✓ Branch 1 taken 29336620 times.
|
29336980 | if (omc_useStream[stream]) { |
| 468 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 469 | va_list args; | ||
| 470 | 360 | va_start(args, format); | |
| 471 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 472 | 360 | va_end(args); | |
| 473 | 360 | messageFunction(OMC_LOG_TYPE_INFO, stream, omc_dummyFileInfo, indentNext, logBuffer, 0, NULL); | |
| 474 | } | ||
| 475 | 29336980 | } | |
| 476 | |||
| 477 | 27 | void warningStreamPrintWithEquationIndexes(int stream, FILE_INFO info, int indentNext, const int *indexes, const char *format, ...) | |
| 478 | { | ||
| 479 |
2/4✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
|
27 | if (OMC_ACTIVE_WARNING_STREAM(stream)) { |
| 480 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 481 | va_list args; | ||
| 482 | ✗ | va_start(args, format); | |
| 483 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 484 | ✗ | va_end(args); | |
| 485 | ✗ | messageFunction(OMC_LOG_TYPE_WARNING, stream, info, indentNext, logBuffer, 0, indexes); | |
| 486 | } | ||
| 487 | 27 | } | |
| 488 | |||
| 489 | /** | ||
| 490 | * @brief Print warning to stream until limit is reached. | ||
| 491 | * | ||
| 492 | * If `nDisplayed` is larger than user specified display limit for warnings | ||
| 493 | * a info is displayed and no warning will be printed. | ||
| 494 | * | ||
| 495 | * @param stream Stream to print to. | ||
| 496 | * @param indentNext Will increase indentation level by one if true. | ||
| 497 | * @param nDisplayed Number of times this warning was displayed. | ||
| 498 | * @param maxWarnDisplays Maximum allowed warning displays. | ||
| 499 | * @param format Format string with message to print. | ||
| 500 | * @param ... Arguments for format string. | ||
| 501 | */ | ||
| 502 | ✗ | void warningStreamPrintWithLimit(int stream, int indentNext, unsigned long nDisplayed, unsigned long maxWarnDisplays, const char *format, ...) { | |
| 503 | |||
| 504 | ✗ | if (!OMC_ACTIVE_WARNING_STREAM(stream)) { | |
| 505 | ✗ | return; | |
| 506 | } | ||
| 507 | |||
| 508 | va_list args; | ||
| 509 | |||
| 510 | /* Display warning */ | ||
| 511 | ✗ | if (nDisplayed <= maxWarnDisplays) { | |
| 512 | ✗ | va_start(args, format); | |
| 513 | ✗ | va_warningStreamPrint(stream, indentNext, format, args); | |
| 514 | } | ||
| 515 | ✗ | if (nDisplayed == maxWarnDisplays) { | |
| 516 | ✗ | warningStreamPrintLimitReached(stream, indentNext, maxWarnDisplays); | |
| 517 | } | ||
| 518 | } | ||
| 519 | |||
| 520 | /** | ||
| 521 | * @brief Tell that a repeated warning reached its display limit. | ||
| 522 | * | ||
| 523 | * For a warning that is displayed with its own sublines, so it cannot use | ||
| 524 | * warningStreamPrintWithLimit. | ||
| 525 | * | ||
| 526 | * @param stream Stream of warning. | ||
| 527 | * @param indentNext Will increase indentation level by one if true. | ||
| 528 | * @param maxWarnDisplays Maximum allowed warning displays. | ||
| 529 | */ | ||
| 530 | ✗ | void warningStreamPrintLimitReached(int stream, int indentNext, unsigned long maxWarnDisplays) { | |
| 531 | ✗ | infoStreamPrint(stream, indentNext, "Too many warnings, reached display limit of %lu. " | |
| 532 | "Suppressing further warning messages of the same type.", maxWarnDisplays); | ||
| 533 | ✗ | infoStreamPrint(stream, indentNext, "Change limit with simulation flag -%s=<newLimit>", FLAG_NAME[FLAG_LV_MAX_WARN]); | |
| 534 | ✗ | } | |
| 535 | |||
| 536 | /** | ||
| 537 | * @brief Print warning to stream. | ||
| 538 | * | ||
| 539 | * Prints message only if stream is active or global variable showAllWarnings is true. | ||
| 540 | * | ||
| 541 | * Use messageCloseWarning to close message, if indentNext is true. | ||
| 542 | * | ||
| 543 | * @param stream Stream to print to. | ||
| 544 | * @param indentNext Will increase indentation level by one if true. | ||
| 545 | * @param format Format string with message to print. | ||
| 546 | * @param ... Arguments for format string. | ||
| 547 | */ | ||
| 548 | 6 | void warningStreamPrint(int stream, int indentNext, const char *format, ...) | |
| 549 | { | ||
| 550 |
3/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
|
6 | if (OMC_ACTIVE_WARNING_STREAM(stream)) { |
| 551 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 552 | va_list args; | ||
| 553 | 4 | va_start(args, format); | |
| 554 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 555 | 4 | va_end(args); | |
| 556 | 4 | messageFunction(OMC_LOG_TYPE_WARNING, stream, omc_dummyFileInfo, indentNext, logBuffer, 0, NULL); | |
| 557 | } | ||
| 558 | 6 | } | |
| 559 | |||
| 560 | ✗ | void va_warningStreamPrintWithEquationIndexes(int stream, FILE_INFO info, int indentNext, const int *indexes, const char *format, va_list args) | |
| 561 | { | ||
| 562 | ✗ | if (OMC_ACTIVE_WARNING_STREAM(stream)) { | |
| 563 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 564 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 565 | ✗ | messageFunction(OMC_LOG_TYPE_WARNING, stream, info, indentNext, logBuffer, 0, indexes); | |
| 566 | } | ||
| 567 | ✗ | } | |
| 568 | |||
| 569 | ✗ | void va_warningStreamPrint(int stream, int indentNext, const char *format, va_list args) | |
| 570 | { | ||
| 571 | ✗ | if (OMC_ACTIVE_WARNING_STREAM(stream)) { | |
| 572 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 573 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 574 | ✗ | messageFunction(OMC_LOG_TYPE_WARNING, stream, omc_dummyFileInfo, indentNext, logBuffer, 0, NULL); | |
| 575 | } | ||
| 576 | ✗ | } | |
| 577 | |||
| 578 | 3 | void errorStreamPrint(int stream, int indentNext, const char *format, ...) | |
| 579 | { | ||
| 580 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 581 | va_list args; | ||
| 582 | 3 | va_start(args, format); | |
| 583 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 584 | 3 | va_end(args); | |
| 585 | 3 | messageFunction(OMC_LOG_TYPE_ERROR, stream, omc_dummyFileInfo, indentNext, logBuffer, 0, NULL); | |
| 586 | 3 | } | |
| 587 | |||
| 588 | ✗ | void va_errorStreamPrint(int stream, int indentNext, const char *format, va_list args) | |
| 589 | { | ||
| 590 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 591 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 592 | ✗ | messageFunction(OMC_LOG_TYPE_ERROR, stream, omc_dummyFileInfo, indentNext, logBuffer, 0, NULL); | |
| 593 | ✗ | } | |
| 594 | |||
| 595 | ✗ | void va_errorStreamPrintWithEquationIndexes(int stream, FILE_INFO info, int indentNext, const int *indexes, const char *format, va_list args) | |
| 596 | { | ||
| 597 | |||
| 598 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 599 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 600 | ✗ | messageFunction(OMC_LOG_TYPE_ERROR, stream, info, indentNext, logBuffer, 0, indexes); | |
| 601 | ✗ | } | |
| 602 | #endif | ||
| 603 | |||
| 604 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 605 | /* A throw inside the nonlinear solver is a trial point it steps away from, so | ||
| 606 | * the message goes on OMC_LOG_NLS, as in omc_assert_simulation(). Not the | ||
| 607 | * integrator region: the failed-algebraic-solve throw is raised there. */ | ||
| 608 | static inline int throwPrintsMessage(threadData_t *threadData) | ||
| 609 | { | ||
| 610 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
|
7 | if (!omc_useStream[OMC_LOG_ASSERT]) { |
| 611 | return 0; | ||
| 612 | } | ||
| 613 |
4/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
|
57 | if (threadData->currentErrorStage == ERROR_NONLINEARSOLVER) { |
| 614 | 11 | return OMC_ACTIVE_STREAM(OMC_LOG_NLS); | |
| 615 | } | ||
| 616 | return 1; | ||
| 617 | } | ||
| 618 | #endif | ||
| 619 | |||
| 620 | #if defined(_MSC_VER) | ||
| 621 | static __declspec(thread) char lastSuppressedError[SIZE_LOG_BUFFER]; | ||
| 622 | #else | ||
| 623 | static __thread char lastSuppressedError[SIZE_LOG_BUFFER]; | ||
| 624 | #endif | ||
| 625 | |||
| 626 | 15 | void omc_note_suppressed_error(threadData_t *threadData, const char *format, va_list args) | |
| 627 | { | ||
| 628 |
2/4✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
|
15 | if (threadData && threadData->currentErrorStage == ERROR_NONLINEARSOLVER) { |
| 629 | vsnprintf(lastSuppressedError, SIZE_LOG_BUFFER, format, args); | ||
| 630 | } | ||
| 631 | 15 | } | |
| 632 | |||
| 633 | ✗ | const char* omc_last_suppressed_error(void) | |
| 634 | { | ||
| 635 | ✗ | return lastSuppressedError; | |
| 636 | } | ||
| 637 | |||
| 638 | 3740 | void omc_clear_last_suppressed_error(void) | |
| 639 | { | ||
| 640 | 3740 | lastSuppressedError[0] = '\0'; | |
| 641 | 3740 | } | |
| 642 | |||
| 643 | 7 | static inline jmp_buf* getBestJumpBuffer(threadData_t *threadData) | |
| 644 | { | ||
| 645 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (threadData->externalJumpBuffer) { |
| 646 | return threadData->externalJumpBuffer; | ||
| 647 | } | ||
| 648 | ✗ | switch (threadData->currentErrorStage) { | |
| 649 | ✗ | case ERROR_EVENTSEARCH: | |
| 650 | case ERROR_SIMULATION: | ||
| 651 | case ERROR_NONLINEARSOLVER: | ||
| 652 | case ERROR_INTEGRATOR: | ||
| 653 | case ERROR_OPTIMIZE: | ||
| 654 | #ifndef OMC_EMCC | ||
| 655 | ✗ | if (threadData->simulationJumpBuffer) { | |
| 656 | return threadData->simulationJumpBuffer; | ||
| 657 | } | ||
| 658 | ✗ | fprintf(stderr, "getBestJumpBuffer got simulationJumpBuffer=%p\n", (void*)threadData->simulationJumpBuffer); | |
| 659 | ✗ | abort(); | |
| 660 | #endif | ||
| 661 | ✗ | case ERROR_EVENTHANDLING: | |
| 662 | default: | ||
| 663 | ✗ | if (threadData->globalJumpBuffer) { | |
| 664 | return threadData->globalJumpBuffer; | ||
| 665 | } | ||
| 666 | ✗ | if (threadData->mmc_jumper) { | |
| 667 | return threadData->mmc_jumper; | ||
| 668 | } | ||
| 669 | ✗ | fprintf(stderr, "getBestJumpBuffer got mmc_jumper=%p, globalJumpBuffer=%p\n", (void*)threadData->mmc_jumper, (void*)threadData->globalJumpBuffer); | |
| 670 | ✗ | abort(); | |
| 671 | } | ||
| 672 | } | ||
| 673 | |||
| 674 | /* omc_thread_data() that reports the message being thrown, formatted only when | ||
| 675 | the lookup fails. */ | ||
| 676 | 61 | threadData_t* omc_thread_data_va(threadData_t *threadData, const char *format, va_list args) | |
| 677 | { | ||
| 678 |
3/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
|
61 | if (!threadData && !(threadData = (threadData_t*)pthread_getspecific(mmc_thread_data_key))) { |
| 679 | char msg[SIZE_LOG_BUFFER]; | ||
| 680 | va_list copy; | ||
| 681 | ✗ | va_copy(copy, args); | |
| 682 | vsnprintf(msg, SIZE_LOG_BUFFER, format, copy); | ||
| 683 | ✗ | va_end(copy); | |
| 684 | ✗ | threadData = omc_thread_data(NULL, msg); | |
| 685 | } | ||
| 686 | 61 | return threadData; | |
| 687 | } | ||
| 688 | |||
| 689 | /** | ||
| 690 | * @brief Variadic stream print and throw. | ||
| 691 | * | ||
| 692 | * Print message to OMC_LOG_ASSERT. | ||
| 693 | * | ||
| 694 | * @param threadData Thread data for throwing. | ||
| 695 | * @param format Format string. | ||
| 696 | * @param args Variadic argument list for format string | ||
| 697 | */ | ||
| 698 | 7 | void va_throwStreamPrint(threadData_t *threadData, const char *format, va_list args) | |
| 699 | { | ||
| 700 | 7 | threadData = omc_thread_data_va(threadData, format, args); | |
| 701 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 702 | ✗ | if (throwPrintsMessage(threadData)) { | |
| 703 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 704 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 705 | 3 | messageFunction(OMC_LOG_TYPE_DEBUG, OMC_LOG_ASSERT, omc_dummyFileInfo, 0, logBuffer, 0, NULL); | |
| 706 | } else { | ||
| 707 | 4 | omc_note_suppressed_error(threadData, format, args); | |
| 708 | } | ||
| 709 | #endif | ||
| 710 | 7 | longjmp(*getBestJumpBuffer(threadData), 1); | |
| 711 | } | ||
| 712 | |||
| 713 | /** | ||
| 714 | * @brief Print message to OMC_LOG_ASSERT and throw. | ||
| 715 | * | ||
| 716 | * @param threadData Thread data for throwing. | ||
| 717 | * @param format Format string. | ||
| 718 | * @param ... Additional arguments for format string. | ||
| 719 | */ | ||
| 720 | 4 | void throwStreamPrint(threadData_t *threadData, const char *format, ...) | |
| 721 | { | ||
| 722 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 723 | va_list args; | ||
| 724 | 4 | va_start(args, format); | |
| 725 | 4 | va_throwStreamPrint(threadData, format, args); | |
| 726 | va_end(args); | ||
| 727 | #else | ||
| 728 | threadData = omc_thread_data(threadData, format); | ||
| 729 | longjmp(*getBestJumpBuffer(threadData), 1); | ||
| 730 | #endif | ||
| 731 | } | ||
| 732 | |||
| 733 | #if !defined(OMC_METAMODELICA_RUNTIME) | ||
| 734 | /* A raise lands at the nearest checker, which retries the step. During event | ||
| 735 | handling there is nothing left to retry from, so jump to the stage's landing. */ | ||
| 736 | 7 | void omc_external_error(threadData_t *threadData) | |
| 737 | { | ||
| 738 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (threadData->currentErrorStage == ERROR_EVENTHANDLING) { |
| 739 | ✗ | longjmp(*getBestJumpBuffer(threadData), 1); | |
| 740 | } | ||
| 741 | 7 | OMC_ERROR_RAISE(); | |
| 742 | 7 | } | |
| 743 | #endif | ||
| 744 | |||
| 745 | 2251 | void omc_error_raise(threadData_t *threadData) | |
| 746 | { | ||
| 747 | 2251 | threadData->errorState = 1; | |
| 748 | 2251 | } | |
| 749 | |||
| 750 | 203729052 | int omc_error_take(threadData_t *threadData) | |
| 751 | { | ||
| 752 | 203729052 | int raised = threadData->errorState; | |
| 753 | 203729052 | threadData->errorState = 0; | |
| 754 | 203729052 | return raised; | |
| 755 | } | ||
| 756 | |||
| 757 | ✗ | jmp_buf *omc_external_jump_buffer(threadData_t *threadData) | |
| 758 | { | ||
| 759 | ✗ | return threadData->externalJumpBuffer; | |
| 760 | } | ||
| 761 | |||
| 762 | /* The raising counterparts of throwStreamPrint*, for generated code: they | ||
| 763 | return, so the caller leaves through its own _return: and runs its releases. */ | ||
| 764 | 14 | void raiseStreamPrint(threadData_t *threadData, const char *format, ...) | |
| 765 | { | ||
| 766 | va_list args; | ||
| 767 | 14 | va_start(args, format); | |
| 768 | 14 | threadData = omc_thread_data_va(threadData, format, args); | |
| 769 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | va_end(args); |
| 770 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 771 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if (throwPrintsMessage(threadData)) { |
| 772 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 773 | 3 | va_start(args, format); | |
| 774 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 775 | 3 | va_end(args); | |
| 776 | 3 | messageFunction(OMC_LOG_TYPE_DEBUG, OMC_LOG_ASSERT, omc_dummyFileInfo, 0, logBuffer, 0, NULL); | |
| 777 | } else { | ||
| 778 | 11 | va_start(args, format); | |
| 779 | 11 | omc_note_suppressed_error(threadData, format, args); | |
| 780 | 11 | va_end(args); | |
| 781 | } | ||
| 782 | #endif | ||
| 783 | 14 | OMC_ERROR_RAISE(); | |
| 784 | 14 | } | |
| 785 | |||
| 786 | 40 | void raiseStreamPrintWithEquationIndexes(threadData_t *threadData, FILE_INFO info, const int *indexes, const char *format, ...) | |
| 787 | { | ||
| 788 | va_list args; | ||
| 789 | 40 | va_start(args, format); | |
| 790 | 40 | threadData = omc_thread_data_va(threadData, format, args); | |
| 791 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | va_end(args); |
| 792 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 793 | ✗ | if (throwPrintsMessage(threadData)) { | |
| 794 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 795 | 40 | va_start(args, format); | |
| 796 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 797 | 40 | va_end(args); | |
| 798 | 40 | messageFunction(OMC_LOG_TYPE_DEBUG, OMC_LOG_ASSERT, info, 0, logBuffer, 0, indexes); | |
| 799 | } else { | ||
| 800 | ✗ | va_start(args, format); | |
| 801 | ✗ | omc_note_suppressed_error(threadData, format, args); | |
| 802 | ✗ | va_end(args); | |
| 803 | } | ||
| 804 | #endif | ||
| 805 | 40 | OMC_ERROR_RAISE(); | |
| 806 | 40 | } | |
| 807 | |||
| 808 | /** | ||
| 809 | * @brief Print message with equation indices to OMC_LOG_ASSERT stream and throw. | ||
| 810 | * | ||
| 811 | * @param threadData Thread data for throwing. | ||
| 812 | * @param info File info, can be omc_dummyFileInfo. | ||
| 813 | * @param indexes Equation indices. | ||
| 814 | * @param format Format string. | ||
| 815 | * @param ... Additional arguments for format string. | ||
| 816 | */ | ||
| 817 | ✗ | void throwStreamPrintWithEquationIndexes(threadData_t *threadData, FILE_INFO info, const int *indexes, const char *format, ...) | |
| 818 | { | ||
| 819 | va_list args; | ||
| 820 | ✗ | va_start(args, format); | |
| 821 | ✗ | threadData = omc_thread_data_va(threadData, format, args); | |
| 822 | ✗ | va_end(args); | |
| 823 | #if !defined(OMC_MINIMAL_LOGGING) | ||
| 824 | ✗ | if (throwPrintsMessage(threadData)) { | |
| 825 | char logBuffer[SIZE_LOG_BUFFER]; | ||
| 826 | ✗ | va_start(args, format); | |
| 827 | vsnprintf(logBuffer, SIZE_LOG_BUFFER, format, args); | ||
| 828 | ✗ | va_end(args); | |
| 829 | ✗ | messageFunction(OMC_LOG_TYPE_DEBUG, OMC_LOG_ASSERT, info, 0, logBuffer, 0, indexes); | |
| 830 | } else { | ||
| 831 | ✗ | va_start(args, format); | |
| 832 | ✗ | omc_note_suppressed_error(threadData, format, args); | |
| 833 | ✗ | va_end(args); | |
| 834 | } | ||
| 835 | #endif | ||
| 836 | ✗ | longjmp(*getBestJumpBuffer(threadData), 1); | |
| 837 | } | ||
| 838 |