Changeset 65ed9dc2 in OpenModelica
- Timestamp:
- 2022-06-24T15:48:34+02:00 (22 months ago)
- Branches:
- maintenance/v1.20, maintenance/v1.21, maintenance/v1.22, maintenance/v1.23, master
- Children:
- b741403, ca0b89c7
- Parents:
- 897feb0
- git-author:
- Andreas <38031952+AnHeuermann@…> (06/24/22 15:48:34)
- git-committer:
- GitHub <noreply@…> (06/24/22 15:48:34)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
OMCompiler/SimulationRuntime/c/simulation/simulation_info_json.c
r8d9551a r65ed9dc2 41 41 #include "../util/omc_file.h" 42 42 43 /** 44 * @brief Skip whitespace. 45 * 46 * @param str Points to some locating inside JSON. 47 * @return const char* Points to next non-whitespace character. 48 */ 43 49 static inline const char* skipSpace(const char* str) 44 50 { … … 56 62 } 57 63 58 static const char* skipValue(const char* str); 59 60 static inline const char* skipObjectRest(const char* str, int first) 64 static const char* skipValue(const char* str, const char* fileName); 65 66 /** 67 * @brief Skip rest of JSON object. 68 * 69 * Move forward until next '}' is reached. 70 * 71 * @param str Points to some locating inside JSON object. 72 * @param first 1 if first location in JSON object, 0 otherwise. 73 * @param fileName Name of JSON to parse. Used for error messages. 74 * @return const char* Points to location directly after JSON obbject. 75 */ 76 static inline const char* skipObjectRest(const char* str, int first, const char* fileName) 61 77 { 62 78 str=skipSpace(str); … … 64 80 if (!first) { 65 81 if (*str != ',') { 66 fprintf(stderr, "JSON object expected ',' or '}', got: %.20s\n", str); 67 abort(); 82 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 83 errorStreamPrint(LOG_STDOUT, 0, "JSON object expected ',' or '}', got: %.20s\n", str); 84 messageClose(LOG_STDOUT); 85 omc_throw_function(NULL); 68 86 } 69 87 str++; … … 71 89 first = 0; 72 90 } 73 str = skipValue(str );91 str = skipValue(str, fileName); 74 92 str = skipSpace(str); 75 93 if (*str++ != ':') { 76 fprintf(stderr, "JSON object expected ':', got: %.20s\n", str); 77 abort(); 78 } 79 str = skipValue(str); 94 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 95 errorStreamPrint(LOG_STDOUT, 0, "JSON object expected ':', got: %.20s\n", str); 96 messageClose(LOG_STDOUT); 97 omc_throw_function(NULL); 98 } 99 str = skipValue(str, fileName); 80 100 str = skipSpace(str); 81 101 } … … 83 103 } 84 104 85 static const char* skipValue(const char* str) 105 /** 106 * @brief Skip JSON value. 107 * 108 * @param str Points to beginning of JSON value. 109 * @param fileName Name of JSON to parse. Used for error messages. 110 * @return const char* Points to location directly after JSON value. 111 */ 112 static const char* skipValue(const char* str, const char* fileName) 86 113 { 87 114 str = skipSpace(str); … … 89 116 case '{': 90 117 { 91 str = skipObjectRest(str+1, 1);118 str = skipObjectRest(str+1, 1, fileName); 92 119 return str; 93 120 } … … 98 125 while (*str != ']') { 99 126 if (!first && *str++ != ',') { 100 fprintf(stderr, "JSON array expected ',' or ']', got: %.20s\n", str); 101 abort(); 127 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 128 errorStreamPrint(LOG_STDOUT, 0, "JSON array expected ',' or ']', got: %.20s\n", str); 129 messageClose(LOG_STDOUT); 130 omc_throw_function(NULL); 102 131 } 103 132 first = 0; 104 str = skipValue(str );133 str = skipValue(str, fileName); 105 134 str = skipSpace(str); 106 135 } … … 111 140 do { 112 141 switch (*str) { 113 case '\0': fprintf(stderr, "Found end of file, expected end of string"); abort(); 142 case '\0': 143 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 144 errorStreamPrint(LOG_STDOUT, 0, "Found end of file, expected end of string"); 145 messageClose(LOG_STDOUT); 146 omc_throw_function(NULL); 114 147 case '\\': 115 148 if (*(str+1) == '\0') { 116 fprintf(stderr, "Found end of file, expected end of string"); abort(); 149 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 150 errorStreamPrint(LOG_STDOUT, 0, "Found end of file, expected end of string"); 151 messageClose(LOG_STDOUT); 152 omc_throw_function(NULL); 117 153 } 118 154 str+=2; … … 124 160 } 125 161 } while (1); 126 abort(); 162 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 163 errorStreamPrint(LOG_STDOUT, 0, "Reached state that should be impossible to reach."); 164 messageClose(LOG_STDOUT); 165 omc_throw_function(NULL); 127 166 case '-': 128 167 case '0': … … 140 179 om_strtod(str,&endptr); 141 180 if (str == endptr) { 142 fprintf(stderr, "Not a number, got %.20s\n", str); 143 abort(); 181 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 182 errorStreamPrint(LOG_STDOUT, 0, "Not a number, got %.20s\n", str); 183 messageClose(LOG_STDOUT); 184 omc_throw_function(NULL); 144 185 } 145 186 return endptr; 146 187 } 147 188 default: 148 fprintf(stderr, "JSON value expected, got: %.20s\n", str); 149 abort(); 150 } 151 } 152 153 /* Does not work for escaped strings. Returns the rest of the string to parse. */ 154 static inline const char* assertStringValue(const char *str, const char *value) 189 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 190 errorStreamPrint(LOG_STDOUT, 0, "JSON value expected, got: %.20s\n", str); 191 messageClose(LOG_STDOUT); 192 omc_throw_function(NULL); 193 } 194 } 195 196 /** 197 * @brief Assert str points to given string. 198 * 199 * Does not work for escaped strings. Returns the rest of the string to parse. 200 * 201 * @param str Points to beginning of string to assert. 202 * @param value Expected value of string. 203 * @param fileName Name of JSON to parse. Used for error messages. 204 * @return const char* Points to location directly after string. 205 */ 206 static inline const char* assertStringValue(const char *str, const char *value, const char* fileName) 155 207 { 156 208 int len = strlen(value); 157 209 str = skipSpace(str); 158 210 if ('\"' != *str || strncmp(str+1,value,len) || str[len+1] != '\"') { 159 fprintf(stderr, "JSON string value %s expected, got: %.20s\n", value, str); 160 abort(); 211 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 212 errorStreamPrint(LOG_STDOUT, 0, "JSON string value %s expected, got: %.20s\n", value, str); 213 messageClose(LOG_STDOUT); 214 omc_throw_function(NULL); 161 215 } 162 216 return str + len + 2; 163 217 } 164 218 165 static inline const char* assertChar(const char *str, char c) 219 /** 220 * @brief Assert str points to specific character. 221 * 222 * @param str Pointer to character to assert. 223 * @param c Character str should be equal to. 224 * @param fileName Name of JSON to parse. Used for error messages. 225 * @return const char* Point to next locatin after character. 226 */ 227 static inline const char* assertChar(const char *str, char c, const char *fileName) 166 228 { 167 229 str = skipSpace(str); 168 230 if (c != *str) { 169 fprintf(stderr, "Expected '%c', got: %.20s\n", c, str); 170 abort(); 231 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 232 errorStreamPrint(LOG_STDOUT, 0,"Expected '%c', got: %.20s\n", c, str); 233 messageClose(LOG_STDOUT); 234 omc_throw_function(NULL); 171 235 } 172 236 return str + 1; 173 237 } 174 238 175 static inline const char* assertNumber(const char *str, double expected) 239 /** 240 * @brief Assert str point to specific number. 241 * 242 * @param str Pointer to number to assert. 243 * @param expected Expected number. 244 * @param fileName Name of JSON to parse. Used for error messages. 245 * @return const char* Point to next locatin after number. 246 */ 247 static inline const char* assertNumber(const char *str, double expected, const char *fileName) 176 248 { 177 249 char *endptr = NULL; … … 180 252 d = om_strtod(str, &endptr); 181 253 if (str == endptr) { 182 fprintf(stderr, "Expected number, got: %.20s\n", str); 183 abort(); 254 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 255 errorStreamPrint(LOG_STDOUT, 0, "Expected number, got: %.20s\n", str); 256 messageClose(LOG_STDOUT); 257 omc_throw_function(NULL); 184 258 } 185 259 if (d != expected) { 186 fprintf(stderr, "Got number %f, expected: %f\n", d, expected); 187 abort(); 260 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", fileName); 261 errorStreamPrint(LOG_STDOUT, 0, "Got number %f, expected: %f\n", d, expected); 262 messageClose(LOG_STDOUT); 263 omc_throw_function(NULL); 188 264 } 189 265 return endptr; 190 266 } 191 267 192 static inline const char *skipFieldIfExist(const char *str,const char *name) 268 /** 269 * @brief Skipp JSON object if it exists. 270 * 271 * @param str Pointer to object/filed to skip. 272 * @param name Name of object to skip. 273 * @param fileName Name of JSON to parse. Used for error messages. 274 * @return const char* Point to next locatin after object. 275 */ 276 static inline const char *skipFieldIfExist(const char *str, const char *name, const char* fileName) 193 277 { 194 278 const char *s = str; … … 207 291 s += 2; 208 292 s = skipSpace(s); 209 s = skipValue(s );293 s = skipValue(s, fileName); 210 294 s = skipSpace(s); 211 295 s = skipSpace(s); … … 213 297 } 214 298 215 static const char* readEquation(const char *str,EQUATION_INFO *xml,int i) 299 /** 300 * @brief Parse single equation info from JSON. 301 * 302 * @param str Points to beginning of equation object. 303 * @param xml Equation info to fill 304 * @param i Index of equation inside "equations" array. 305 * @param fileName Name of JSON to parse. Used for error messages. 306 * @return const char* Point to next locatin after character. 307 */ 308 static const char* readEquation(const char *str, EQUATION_INFO *xml, int i, const char* fileName) 216 309 { 217 310 int n=0,j; 218 311 const char *str2; 219 str=assertChar(str,'{' );220 str=assertStringValue(str,"eqIndex" );221 str=assertChar(str,':' );222 str=assertNumber(str,i );312 str=assertChar(str,'{', fileName); 313 str=assertStringValue(str,"eqIndex", fileName); 314 str=assertChar(str,':', fileName); 315 str=assertNumber(str,i,fileName); 223 316 str=skipSpace(str); 224 317 xml->id = i; 225 str = skipFieldIfExist(str, "parent" );226 str = skipFieldIfExist(str, "section" );318 str = skipFieldIfExist(str, "parent", fileName); 319 str = skipFieldIfExist(str, "section", fileName); 227 320 if ((measure_time_flag & 1) && 0==strncmp(",\"tag\":\"system\"", str, 15)) { 228 321 xml->profileBlockIndex = -1; … … 234 327 xml->profileBlockIndex = 0; 235 328 } 236 str = skipFieldIfExist(str, "tag" );237 str = skipFieldIfExist(str, "display" );238 str = skipFieldIfExist(str, "unknowns" );329 str = skipFieldIfExist(str, "tag", fileName); 330 str = skipFieldIfExist(str, "display", fileName); 331 str = skipFieldIfExist(str, "unknowns", fileName); 239 332 if (strncmp(",\"defines\":[", str, 12)) { 240 333 xml->numVar = 0; 241 334 xml->vars = 0; 242 str = skipObjectRest(str,0 );335 str = skipObjectRest(str,0, fileName); 243 336 return str; 244 337 } … … 248 341 xml->numVar = 0; 249 342 xml->vars = 0; 250 return skipObjectRest(str-1,0 );343 return skipObjectRest(str-1,0, fileName); 251 344 } 252 345 str2 = skipSpace(str); 253 346 while (1) { 254 str=skipValue(str );347 str=skipValue(str, fileName); 255 348 n++; 256 349 str=skipSpace(str); … … 260 353 str++; 261 354 }; 262 assertChar(str, ']' );355 assertChar(str, ']', fileName); 263 356 xml->numVar = n; 264 357 xml->vars = malloc(sizeof(const char*)*n); … … 268 361 char *tmp; 269 362 int len=0; 270 str = assertChar(str, '\"' );363 str = assertChar(str, '\"', fileName); 271 364 while (*str != '\"' && *str) { 272 365 len++; 273 366 str++; 274 367 } 275 str = assertChar(str, '\"' );368 str = assertChar(str, '\"', fileName); 276 369 tmp = malloc(len+1); 277 370 strncpy(tmp, str3+1, len); … … 279 372 xml->vars[j] = tmp; 280 373 if (j != n-1) { 281 str = assertChar(str, ','); 282 } 283 } 284 str = assertChar(skipSpace(str), ']'); 285 return skipObjectRest(str,0); 286 } 287 288 static const char* readEquations(const char *str,MODEL_DATA_XML *xml) 374 str = assertChar(str, ',', fileName); 375 } 376 } 377 str = assertChar(skipSpace(str), ']', fileName); 378 return skipObjectRest(str,0, fileName); 379 } 380 381 /** 382 * @brief Parse equations from info.json. 383 * 384 * @param str Point to beginning of equation array at '['. 385 * @param xml Model data from xml 386 * @return const char* Point to end of equation array dirreclty after ']'. 387 */ 388 static const char* readEquations(const char *str, MODEL_DATA_XML *xml) 289 389 { 290 390 int i; 291 391 xml->nProfileBlocks = measure_time_flag & 2 ? 1 : 0; 292 str=assertChar(str,'[' );293 str = readEquation(str, xml->equationInfo,0);392 str=assertChar(str,'[', xml->fileName); 393 str = readEquation(str, xml->equationInfo, 0, xml->fileName); 294 394 for (i=1; i<xml->nEquations; i++) { 295 str = assertChar(str,','); 296 str = readEquation(str,xml->equationInfo+i,i); 395 if (*str != ',') { 396 errorStreamPrint(LOG_STDOUT, 1, "Failed to parse %s", xml->fileName); 397 errorStreamPrint(LOG_STDOUT, 0, "Expected %ld equations, but only found %i equations.", xml->nEquations, i-1); 398 messageClose(LOG_STDOUT); 399 omc_throw_function(NULL); 400 } else { 401 str = str + 1; 402 } 403 str = readEquation(str, xml->equationInfo+i, i, xml->fileName); 297 404 /* TODO: Odd, it seems there is 1 fewer equation than expected... */ 298 405 /* … … 305 412 } 306 413 } 307 str=assertChar(str,']' );414 str=assertChar(str,']', xml->fileName); 308 415 return str; 309 416 } 310 417 311 static const char* readFunction(const char *str, FUNCTION_INFO *xml,int i)418 static const char* readFunction(const char *str, FUNCTION_INFO *xml, int i, const char* fileName) 312 419 { 313 420 FILE_INFO info = omc_dummyFileInfo; … … 316 423 const char *str2; 317 424 str=skipSpace(str); 318 str2=assertChar(str,'"' );319 str=skipValue(str );425 str2=assertChar(str,'"', fileName); 426 str=skipValue(str, fileName); 320 427 xml->id = i; 321 428 len = str-str2; … … 328 435 } 329 436 330 static const char* readFunctions(const char *str, MODEL_DATA_XML *xml)437 static const char* readFunctions(const char *str, MODEL_DATA_XML *xml) 331 438 { 332 439 int i; 333 440 if (xml->nFunctions == 0) { 334 str=assertChar(str,'[' );335 str=assertChar(str,']' );441 str=assertChar(str,'[', xml->fileName); 442 str=assertChar(str,']', xml->fileName); 336 443 return str; 337 444 } 338 str=assertChar(str,'[' );445 str=assertChar(str,'[', xml->fileName); 339 446 for (i=0; i<xml->nFunctions; i++) { 340 str = readFunction(str, xml->functionNames+i,i);341 str=assertChar(str,xml->nFunctions==i+1 ? ']' : ',' );447 str = readFunction(str, xml->functionNames+i, i, xml->fileName); 448 str=assertChar(str,xml->nFunctions==i+1 ? ']' : ',', xml->fileName); 342 449 } 343 450 return str; 344 451 } 345 452 346 static void readInfoJson(const char *str, MODEL_DATA_XML *xml)347 { 348 str=assertChar(str,'{' );349 str=assertStringValue(str,"format" );350 str=assertChar(str,':' );351 str=assertStringValue(str,"Transformational debugger info" );352 str=assertChar(str,',' );353 str=assertStringValue(str,"version" );354 str=assertChar(str,':' );355 str=assertChar(str,'1' );356 str=assertChar(str,',' );357 str=assertStringValue(str,"info" );358 str=assertChar(str,':' );359 str=skipValue(str );360 str=assertChar(str,',' );361 str=assertStringValue(str,"variables" );362 str=assertChar(str,':' );363 str=skipValue(str );364 str=assertChar(str,',' );365 str=assertStringValue(str,"equations" );366 str=assertChar(str,':' );453 static void readInfoJson(const char *str, MODEL_DATA_XML *xml) 454 { 455 str=assertChar(str,'{', xml->fileName); 456 str=assertStringValue(str,"format", xml->fileName); 457 str=assertChar(str,':', xml->fileName); 458 str=assertStringValue(str,"Transformational debugger info", xml->fileName); 459 str=assertChar(str,',', xml->fileName); 460 str=assertStringValue(str,"version", xml->fileName); 461 str=assertChar(str,':', xml->fileName); 462 str=assertChar(str,'1', xml->fileName); 463 str=assertChar(str,',', xml->fileName); 464 str=assertStringValue(str,"info", xml->fileName); 465 str=assertChar(str,':', xml->fileName); 466 str=skipValue(str, xml->fileName); 467 str=assertChar(str,',', xml->fileName); 468 str=assertStringValue(str,"variables", xml->fileName); 469 str=assertChar(str,':', xml->fileName); 470 str=skipValue(str, xml->fileName); 471 str=assertChar(str,',', xml->fileName); 472 str=assertStringValue(str,"equations", xml->fileName); 473 str=assertChar(str,':', xml->fileName); 367 474 str=readEquations(str,xml); 368 str=assertChar(str,',' );369 str=assertStringValue(str,"functions" );370 str=assertChar(str,':' );475 str=assertChar(str,',', xml->fileName); 476 str=assertStringValue(str,"functions", xml->fileName); 477 str=assertChar(str,':', xml->fileName); 371 478 str=readFunctions(str,xml); 372 assertChar(str,'}'); 373 } 374 479 assertChar(str,'}', xml->fileName); 480 } 481 482 /** 483 * @brief Initialize model data xml structure by parsing info.json. 484 * 485 * @param xml Model info struct to initialize. 486 */ 375 487 void modelInfoInit(MODEL_DATA_XML* xml) 376 488 {
Note: See TracChangeset
for help on using the changeset viewer.