OMCompiler/SimulationRuntime/c/simulation/options.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 "options.h" | ||
| 29 | #include "../util/omc_error.h" | ||
| 30 | #include "simulation_runtime.h" | ||
| 31 | |||
| 32 | #include <string.h> | ||
| 33 | #include <stdio.h> | ||
| 34 | |||
| 35 | static int flagSet(const char*, int, char**); /* -f */ | ||
| 36 | static int optionSet(const char *option, int argc, char** argv); /* -f=value */ | ||
| 37 | static const char* getOption(const char*, int, char **); /* -f=value; returns NULL if not found */ | ||
| 38 | static const char* getFlagValue(const char *, int , char **); /* -f value; returns NULL if not found */ | ||
| 39 | |||
| 40 | static int handle_repeated_option(int flag_index, char **argv_loc, int is_sticky); | ||
| 41 | static int handle_repeated_flag(int flag_index); | ||
| 42 | |||
| 43 | int omc_flag[FLAG_MAX]; | ||
| 44 | const char *omc_flagValue[FLAG_MAX]; | ||
| 45 | |||
| 46 | 1 | int helpFlagSet(int argc, char** argv) | |
| 47 | { | ||
| 48 |
2/4✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
|
1 | return flagSet("?", argc, argv) || flagSet("help", argc, argv); |
| 49 | } | ||
| 50 | |||
| 51 | #if !defined(OMC_MINIMAL_RUNTIME) | ||
| 52 | 1 | int setLogFormat(int argc, char** argv) | |
| 53 | { | ||
| 54 | 1 | const char* value = getOption(FLAG_NAME[FLAG_LOG_FORMAT], argc, argv); | |
| 55 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (NULL == value) { |
| 56 | 1 | value = getFlagValue(FLAG_NAME[FLAG_LOG_FORMAT], argc, argv); | |
| 57 | } | ||
| 58 | |||
| 59 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if (NULL != value) { |
| 60 | ✗ | if (0 == strcmp(value, "xml")) { | |
| 61 | ✗ | setStreamPrintXML(1); | |
| 62 | ✗ | } else if (0 == strcmp(value, "xmltcp")) { | |
| 63 | ✗ | setStreamPrintXML(2); | |
| 64 | ✗ | } else if (0 == strcmp(value, "text")) { | |
| 65 | ✗ | setStreamPrintXML(0); | |
| 66 | } else { | ||
| 67 | ✗ | warningStreamPrint(OMC_LOG_STDOUT, 0, "invalid command line option: -logFormat=%s, expected text, xml, or xmltcp", value); | |
| 68 | ✗ | return 1; | |
| 69 | } | ||
| 70 | } | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | #endif | ||
| 74 | |||
| 75 | 1 | int checkCommandLineArguments(int argc, char **argv) | |
| 76 | { | ||
| 77 | int i,j; | ||
| 78 | |||
| 79 | /* This works not that well - but is probably better than no check */ | ||
| 80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | assertStreamPrint(NULL, !strcmp(FLAG_NAME[FLAG_MAX], "FLAG_MAX"), "unbalanced command line flag structure: FLAG_NAME"); |
| 81 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | assertStreamPrint(NULL, !strcmp(FLAG_DESC[FLAG_MAX], "FLAG_MAX"), "unbalanced command line flag structure: FLAG_DESC"); |
| 82 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | assertStreamPrint(NULL, !strcmp(FLAG_DETAILED_DESC[FLAG_MAX], "FLAG_MAX"), "unbalanced command line flag structure: FLAG_DETAILED_DESC"); |
| 83 | |||
| 84 |
2/2✓ Branch 0 taken 156 times.
✓ Branch 1 taken 1 time.
|
157 | for(i=0; i<FLAG_MAX; ++i) |
| 85 | { | ||
| 86 | 156 | omc_flag[i] = 0; | |
| 87 | 156 | omc_flagValue[i] = NULL; | |
| 88 | } | ||
| 89 | |||
| 90 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
|
2 | for(i=1; i<argc; ++i) |
| 91 | { | ||
| 92 | int found=0; | ||
| 93 | |||
| 94 |
1/2✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
|
66 | for(j=1; j<FLAG_MAX; ++j) |
| 95 | { | ||
| 96 |
3/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
66 | if((FLAG_TYPE[j] == FLAG_TYPE_FLAG) && flagSet(FLAG_NAME[j], 1, argv+i)) |
| 97 | { | ||
| 98 | // Flag is not yet set. | ||
| 99 | ✗ | if(!omc_flag[j]) { | |
| 100 | ✗ | omc_flag[j] = 1; | |
| 101 | } | ||
| 102 | // Flag is already specified earlier. Check repetition policy. | ||
| 103 | ✗ | else if(!handle_repeated_flag(j)) { | |
| 104 | // repetition is invalid for this Flag | ||
| 105 | return 1; | ||
| 106 | } | ||
| 107 | |||
| 108 | // All good. | ||
| 109 | found=1; | ||
| 110 | |||
| 111 | break; | ||
| 112 | } | ||
| 113 |
3/6✓ Branch 0 taken 55 times.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 55 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
66 | else if((FLAG_TYPE[j] == FLAG_TYPE_OPTION) && flagSet(FLAG_NAME[j], 1, argv+i) && (i+1 < argc)) |
| 114 | { | ||
| 115 | // Option is not yet set. | ||
| 116 | ✗ | if(!omc_flag[j]) { | |
| 117 | ✗ | omc_flag[j] = 1; | |
| 118 | ✗ | omc_flagValue[j] = (char*)getFlagValue(FLAG_NAME[j], 1, argv+i); | |
| 119 | } | ||
| 120 | // Option is already specified earlier. Check repetition policy. | ||
| 121 | ✗ | else if(!handle_repeated_option(j, argv+i, 0 /*Not sticky*/)) { | |
| 122 | // repetition is invlaid for this option | ||
| 123 | return 1; | ||
| 124 | } | ||
| 125 | |||
| 126 | // All good. | ||
| 127 | found = 1; | ||
| 128 | i++; | ||
| 129 | |||
| 130 | break; | ||
| 131 | } | ||
| 132 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 11 times.
|
66 | else if((FLAG_TYPE[j] == FLAG_TYPE_OPTION) && optionSet(FLAG_NAME[j], 1, argv+i)) |
| 133 | { | ||
| 134 | |||
| 135 | // Option is not yet set. | ||
| 136 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if (!omc_flag[j]) { |
| 137 | 1 | omc_flag[j] = 1; | |
| 138 | 1 | omc_flagValue[j] = (char*)getOption(FLAG_NAME[j], 1, argv+i); | |
| 139 | } | ||
| 140 | // Option is already specified earlier. Check repetition policy. | ||
| 141 | ✗ | else if (!handle_repeated_option(j, argv+i, 1 /*Sticky*/)) { | |
| 142 | // repetition is invlaid for this option | ||
| 143 | return 1; | ||
| 144 | } | ||
| 145 | |||
| 146 | // All good. | ||
| 147 | found = 1; | ||
| 148 | |||
| 149 | break; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | |||
| 153 | if(!found) | ||
| 154 | { | ||
| 155 | ✗ | warningStreamPrint(OMC_LOG_STDOUT, 0, "invalid command line option: %s", argv[i]); | |
| 156 | ✗ | return 1; | |
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | ✗ | static int handle_repeated_flag(int flag_index) { | |
| 164 | |||
| 165 | ✗ | const char* flag_name = FLAG_NAME[flag_index]; | |
| 166 | ✗ | flag_repeat_policy repeat_policy = FLAG_REPEAT_POLICIES[flag_index]; | |
| 167 | |||
| 168 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_IGNORE) { | |
| 169 | ✗ | warningStreamPrint(OMC_LOG_STDOUT, 0, "Command line flag '%s' specified again. Ignoring." | |
| 170 | , flag_name); | ||
| 171 | ✗ | return 1; | |
| 172 | } | ||
| 173 | |||
| 174 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_FORBID) { | |
| 175 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Command line flag '%s' can be specified only once.", flag_name); | |
| 176 | ✗ | return 0; | |
| 177 | } | ||
| 178 | |||
| 179 | |||
| 180 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_REPLACE) { | |
| 181 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Command line flag %s is supposed to be replaced on repetition. This option does not apply for flags. Fix the repetition policy for the flag.", flag_name); | |
| 182 | ✗ | return 0; | |
| 183 | } | ||
| 184 | |||
| 185 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_COMBINE) { | |
| 186 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Command line flag %s is supposed to be combined on repetition. This option does not apply for flags. Fix the repetition policy for the flag.", flag_name); | |
| 187 | ✗ | return 0; | |
| 188 | } | ||
| 189 | |||
| 190 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Error: Unknow repetition policy for command line flag %s.", flag_name); | |
| 191 | ✗ | return 0; | |
| 192 | } | ||
| 193 | |||
| 194 | ✗ | static int handle_repeated_option(int flag_index, char **argv_loc, int is_sticky) { | |
| 195 | |||
| 196 | ✗ | const char* flag_name = FLAG_NAME[flag_index]; | |
| 197 | ✗ | flag_repeat_policy repeat_policy = FLAG_REPEAT_POLICIES[flag_index]; | |
| 198 | |||
| 199 | ✗ | const char* old_value = omc_flagValue[flag_index]; | |
| 200 | |||
| 201 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_IGNORE) { | |
| 202 | ✗ | warningStreamPrint(OMC_LOG_STDOUT, 0, "Command line option '%s' specified again. Keeping the first value '%s' and ignoring the rest." | |
| 203 | , flag_name, old_value); | ||
| 204 | ✗ | return 1; | |
| 205 | } | ||
| 206 | |||
| 207 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_FORBID) { | |
| 208 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Command line option '%s' can be specified only once.", flag_name); | |
| 209 | ✗ | return 0; | |
| 210 | } | ||
| 211 | |||
| 212 | |||
| 213 | const char* new_value; | ||
| 214 | |||
| 215 | ✗ | if(is_sticky) // lv=LOG_STATS | |
| 216 | ✗ | new_value = (char*)getOption(flag_name, 1, argv_loc); | |
| 217 | else // lv OMC_LOG_STATS | ||
| 218 | ✗ | new_value = (char*)getFlagValue(flag_name, 1, argv_loc); | |
| 219 | |||
| 220 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_REPLACE) { | |
| 221 | ✗ | omc_flagValue[flag_index] = new_value; | |
| 222 | ✗ | warningStreamPrint(OMC_LOG_STDOUT, 0, "Command line option '%s' specified again. Value has been overriden from '%s' to '%s'." | |
| 223 | , flag_name, old_value, new_value); | ||
| 224 | ✗ | return 1; | |
| 225 | } | ||
| 226 | |||
| 227 | ✗ | if(repeat_policy == FLAG_REPEAT_POLICY_COMBINE) { | |
| 228 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Command line option %s is supposed to be combined on repetition. This has not bee implemented yet", flag_name); | |
| 229 | ✗ | return 0; | |
| 230 | } | ||
| 231 | |||
| 232 | ✗ | errorStreamPrint(OMC_LOG_STDOUT, 0, "Error: Unknow repetition policy for command line option %s.", flag_name); | |
| 233 | ✗ | return 0; | |
| 234 | |||
| 235 | } | ||
| 236 | |||
| 237 | 68 | static int flagSet(const char *option, int argc, char** argv) | |
| 238 | { | ||
| 239 | int i; | ||
| 240 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 68 times.
|
138 | for(i=0; i<argc; i++) { |
| 241 |
3/4✓ Branch 0 taken 68 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 68 times.
✗ Branch 3 not taken.
|
70 | if((argv[i][0] == '-') && (0 == strcmp(option, argv[i]+1))) { |
| 242 | return 1; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | static int optionSet(const char *option, int argc, char** argv) | ||
| 249 | { | ||
| 250 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 54 times.
|
55 | return getOption(option, argc, argv) != NULL; |
| 251 | } | ||
| 252 | |||
| 253 | /* returns the value of a flag on the form -flagname=value */ | ||
| 254 | 57 | static const char* getOption(const char *option, int argc, char **argv) | |
| 255 | { | ||
| 256 | 57 | int optLen = strlen(option), i; | |
| 257 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 55 times.
|
113 | for(i=0; i<argc; i++) { |
| 258 |
6/6✓ Branch 0 taken 57 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 54 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 time.
|
58 | if((argv[i][0] == '-') && (0 == strncmp(option, argv[i]+1, optLen)) && (argv[i][optLen+1] == '=')) { |
| 259 | 2 | return argv[i] + optLen + 2; | |
| 260 | } | ||
| 261 | } | ||
| 262 | return NULL; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* returns the value of a flag on the form -flagname value */ | ||
| 266 | 1 | static const char* getFlagValue(const char *option, int argc, char **argv) | |
| 267 | { | ||
| 268 | int i; | ||
| 269 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
|
3 | for(i=0; i<argc; i++) { |
| 270 |
3/4✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
|
2 | if((argv[i][0] == '-') && (0 == strcmp(option, argv[i]+1))) { |
| 271 | ✗ | return argv[i+1]; | |
| 272 | } | ||
| 273 | } | ||
| 274 | return NULL; | ||
| 275 | } | ||
| 276 |