Bug Summary

File:OMCompiler/Compiler/runtime/./systemimpl.c
Warning:line 3044, column 7
Value stored to 'j' is never read

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2010, Linköpings University,
5 * Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THIS OSMC PUBLIC
11 * LICENSE (OSMC-PL). ANY USE, REPRODUCTION OR DISTRIBUTION OF
12 * THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THE OSMC
13 * PUBLIC LICENSE.
14 *
15 * The OpenModelica software and the Open Source Modelica
16 * Consortium (OSMC) Public License (OSMC-PL) are obtained
17 * from Linköpings University, either from the above address,
18 * from the URL: http://www.ida.liu.se/projects/OpenModelica
19 * and in the OpenModelica distribution.
20 *
21 * This program is distributed WITHOUT ANY WARRANTY; without
22 * even the implied warranty of MERCHANTABILITY or FITNESS
23 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
24 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
25 * OF OSMC-PL.
26 *
27 * See the full OSMC Public License conditions for more details.
28 *
29 */
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#include "systemimpl.h"
36#include "is_utf8.h"
37
38/*
39 * Common includes
40 */
41#if !defined(_MSC_VER)
42#include <libgen.h>
43#include <dirent.h>
44#include <unistd.h>
45#endif
46
47#include "meta_modelica.h"
48#include <limits.h>
49#include "ModelicaUtilities.h"
50
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <time.h>
55#include <math.h>
56
57#include "rtclock.h"
58#include "omc_config.h"
59#include "errorext.h"
60#include "settingsimpl.h"
61#include "printimpl.h"
62
63#if defined(_MSC_VER) /* no iconv for VS! */
64
65typedef void* iconv_t;
66#define iconv_open(tocode, fromcode) (0)
67#define iconv_close(cd) (0)
68#define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) (0)
69
70#else /* real compilers */
71
72#include "iconv.h"
73
74#endif
75
76
77#if defined(__MINGW32__) || defined(_MSC_VER)
78#include <rpc.h>
79#define getFunctionPointerFromDLLdlsym GetProcAddress
80#define FreeLibraryFromHandledlclose !FreeLibrary
81
82#else /* *nix / Mac */
83
84#include <signal.h>
85
86#define getFunctionPointerFromDLLdlsym dlsym
87#define FreeLibraryFromHandledlclose dlclose
88#define GetLastError(X)1L 1L
89#include <fcntl.h>
90
91#endif
92
93
94/*
95 * Platform specific includes and defines
96 */
97#if defined(__MINGW32__) || defined(_MSC_VER)
98/* includes/defines specific for Windows*/
99#include <assert.h>
100#include <direct.h>
101#include <process.h>
102
103#define MAXPATHLEN4096 MAX_PATH
104#define S_IFLNK0120000 0120000 /* symbolic link */
105
106#include <sys/types.h>
107
108#else
109/* includes/defines specific for LINUX/OS X */
110#include <ctype.h>
111#include <dirent.h>
112#include <sys/ioctl.h>
113#include <sys/param.h> /* MAXPATHLEN */
114#include <sys/unistd.h>
115#include <sys/wait.h> /* only available in Linux, not windows */
116#include <unistd.h>
117#include <stdlib.h>
118#include <spawn.h>
119
120#include <dlfcn.h>
121extern char **environ;
122
123#define HAVE_SCANDIR
124
125#ifndef _IFDIR0040000
126# ifdef S_IFDIR0040000
127# define _IFDIR0040000 S_IFDIR0040000
128# else
129# error "Neither _IFDIR nor S_IFDIR is defined."
130# endif
131#endif
132#endif
133
134#if defined(_MSC_VER)
135#define strncasecmp strnicmp
136#endif
137
138#define MAX_PTR_INDEX10000 10000
139static struct modelica_ptr_s ptr_vector[MAX_PTR_INDEX10000];
140static modelica_integer last_ptr_index = -1;
141
142static inline__inline__ modelica_integer alloc_ptr(void);
143static inline__inline__ void free_ptr(modelica_integer index);
144static void free_library(modelica_ptr_t lib, modelica_integer printDebug);
145static void free_function(modelica_ptr_t func);
146
147static const char def_cc[] = DEFAULT_CC"/usr/share/clang/scan-build-6.0/bin/../libexec/ccc-analyzer";
148static const char def_cxx[] = DEFAULT_CXX"/usr/share/clang/scan-build-6.0/bin/../libexec/c++-analyzer";
149static const char def_ompcc[] = DEFAULT_OMPCC"/usr/share/clang/scan-build-6.0/bin/../libexec/ccc-analyzer -fopenmp";
150static const char def_linker[] = DEFAULT_LINKER"/usr/share/clang/scan-build-6.0/bin/../libexec/ccc-analyzer -shared";
151static const char def_cflags[] = DEFAULT_CFLAGS"-fPIC -falign-functions -mfpmath=sse -fno-dollars-in-identifiers ${MODELICAUSERCFLAGS}";
152static const char def_ldflags[]= DEFAULT_LDFLAGS"";
153
154static char *cc = (char *)def_cc;
155static char *cxx = (char *)def_cxx;
156static char *omp_cc = (char *)def_ompcc;
157static char *linker = (char *)def_linker;
158static char *cflags = (char *)def_cflags;
159static char *ldflags= (char *)def_ldflags;
160
161/* TODO! FIXME!
162 * we need to move these to threadData if we are to run things in parallel in OMC!
163 */
164static int hasExpandableConnectors = 0;
165static int hasOverconstrainedConnectors = 0;
166static int hasInnerOuterDefinitions = 0;
167static int hasStreamConnectors = 0;
168static int isPartialInstantiation = 0;
169static int usesCardinality = 1;
170static char* class_names_for_simulation = NULL((void*)0);
171static const char *select_from_dir = NULL((void*)0);
172
173/*
174 * Common implementations
175 */
176
177static inline__inline__ int intMax(int a, int b)
178{
179 return a > b ? a : b;
180}
181
182static int str_contain_char(const char* chars, const char chr)
183{
184 int i = 0;
185 while(chars[i] != '\0') {
186 if(chr == chars[i]) {
187 return 1;
188 }
189 i++;
190 }
191 return 0;
192}
193
194static int filterString(char* buf,char* bufRes)
195{
196 int i,bufPointer = 0,slen,isNumeric=0,numericEncounter=0;
197 char preChar;
198 char filterChars[] = "0123456789.\0";
199 char numeric[] = "0123456789\0";
200 slen = strlen(buf);
201 preChar = '\0';
202 for(i=0;i<slen;++i) {
203 if((str_contain_char(filterChars,buf[i]))) {
204 if(buf[i]=='.') {
205 if(str_contain_char(numeric,preChar) || (( i < slen+1) && str_contain_char(numeric,buf[i+1])) ) {
206 if(isNumeric == 0) {isNumeric=1; numericEncounter++;}
207 //printf("skipping_1: '%c'\n",buf[i]);
208 } else {
209 bufRes[bufPointer++] = buf[i];
210 isNumeric=0;
211 }
212 } else {
213 if(isNumeric == 0){isNumeric=1;numericEncounter++;}
214 //printf("skipping_2: '%c'\n",buf[i]);
215 }
216 } else {
217 bufRes[bufPointer++] = buf[i];
218 isNumeric=0;
219 }
220 preChar = buf[i];
221 //isNumeric=0;
222 }
223 bufRes[bufPointer++] = '\0';
224 return numericEncounter;
225}
226
227extern int SystemImpl__setCCompiler(const char *str)
228{
229 cc = omc_alloc_interface.malloc_strdup(str);
230 if (cc == NULL((void*)0)) return -1;
231 return 0;
232}
233
234extern int SystemImpl__setCXXCompiler(const char *str)
235{
236 cxx = omc_alloc_interface.malloc_strdup(str);
237 if (cxx == NULL((void*)0)) return -1;
238 return 0;
239}
240
241extern int SystemImpl__setLinker(const char *str)
242{
243 linker = omc_alloc_interface.malloc_strdup(str);
244 if (linker == NULL((void*)0)) return -1;
245 return 0;
246}
247
248extern int SystemImpl__setCFlags(const char *str)
249{
250 cflags = omc_alloc_interface.malloc_strdup(str);
251 if (cflags == NULL((void*)0)) return -1;
252 return 0;
253}
254
255extern int SystemImpl__setLDFlags(const char *str)
256{
257 ldflags = omc_alloc_interface.malloc_strdup(str);
258 if (ldflags == NULL((void*)0)) return -1;
259 return 0;
260}
261
262#if defined(__MINGW32__) || defined(_MSC_VER)
263/* Make sure windows paths use frontslash and not backslash */
264void SystemImpl__toWindowsSeperators(char* buffer, int bufferLength)
265{
266 int i;
267 for (i=0; i<bufferLength && buffer[i]; i++) {
268 if (buffer[i] == '\\') buffer[i] = '/';
269 }
270}
271#endif
272
273int SystemImpl__chdir(const char* path)
274{
275#if defined(__MINGW32__) || defined(_MSC_VER)
276 MULTIBYTE_TO_WIDECHAR_LENGTH(path, unicodePathLength);
277 MULTIBYTE_TO_WIDECHAR_VAR(path, unicodePath, unicodePathLength);
278
279 if (!SetCurrentDirectoryW(unicodePath)) {
280 MULTIBYTE_OR_WIDECHAR_VAR_FREE(unicodePath);
281 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("SetCurrentDirectoryW failed.")dcgettext (((void*)0), "SetCurrentDirectoryW failed.", 5),NULL((void*)0),0);
282 return -1;
283 }
284 MULTIBYTE_OR_WIDECHAR_VAR_FREE(unicodePath);
285 return 0;
286#else
287 if (chdir(path) != 0) {
288 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("chdir failed.")dcgettext (((void*)0), "chdir failed.", 5),NULL((void*)0),0);
289 return -1;
290 }
291 return 0;
292#endif
293}
294
295extern char* SystemImpl__pwd(void)
296{
297#if defined(__MINGW32__) || defined(_MSC_VER)
298 DWORD bufLen = 0;
299 bufLen = GetCurrentDirectoryW(bufLen, 0);
300 if (!bufLen) {
301 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("GetCurrentDirectoryW failed.")dcgettext (((void*)0), "GetCurrentDirectoryW failed.", 5),NULL((void*)0),0);
302 return NULL((void*)0);
303 }
304
305 WCHAR unicodePath[bufLen];
306 if (!GetCurrentDirectoryW(bufLen, unicodePath)) {
307 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("GetCurrentDirectoryW failed.")dcgettext (((void*)0), "GetCurrentDirectoryW failed.", 5),NULL((void*)0),0);
308 return NULL((void*)0);
309 }
310 WIDECHAR_TO_MULTIBYTE_LENGTH(unicodePath, bufferLength);
311 WIDECHAR_TO_MULTIBYTE_VAR(unicodePath, buffer, bufferLength);
312 SystemImpl__toWindowsSeperators(buffer, bufferLength);
313 char *res = omc_alloc_interface.malloc_strdup(buffer);
314 MULTIBYTE_OR_WIDECHAR_VAR_FREE(buffer);
315 return res;
316#else
317 char buf[MAXPATHLEN4096];
318 if (NULL((void*)0) == getcwd(buf,MAXPATHLEN4096)) {
319 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("System.pwd failed.")dcgettext (((void*)0), "System.pwd failed.", 5),NULL((void*)0),0);
320 return NULL((void*)0);
321 }
322 return omc_alloc_interface.malloc_strdup(buf);
323#endif
324}
325
326extern int SystemImpl__regularFileExists(const char* str)
327{
328#if defined(__MINGW32__) || defined(_MSC_VER)
329 WIN32_FIND_DATAW FileData;
330 HANDLE sh;
331
332 MULTIBYTE_TO_WIDECHAR_LENGTH(str, unicodeFilenameLength);
333 MULTIBYTE_TO_WIDECHAR_VAR(str, unicodeFilename, unicodeFilenameLength);
334
335 sh = FindFirstFileW(unicodeFilename, &FileData);
336
337 MULTIBYTE_OR_WIDECHAR_VAR_FREE(unicodeFilename);
338
339 if (sh == INVALID_HANDLE_VALUE) {
340 if (strlen(str) >= MAXPATHLEN4096)
341 {
342 const char *c_tokens[1]={str};
343 c_add_message(NULL((void*)0),85, /* error opening file */
344 ErrorType_scripting,
345 ErrorLevel_error,
346 gettext("Error opening file: %s.")dcgettext (((void*)0), "Error opening file: %s.", 5),
347 c_tokens,
348 1);
349 }
350 return 0;
351 }
352 FindClose(sh);
353 return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);
354#else
355 struct stat buf;
356 /* adrpo: TODO: check if str leads to a path > PATH_MAX, maybe use realpath impl. from below */
357 if (stat(str, &buf)) return 0;
358 return (buf.st_mode & S_IFREG0100000) != 0;
359#endif
360}
361
362extern int SystemImpl__regularFileWritable(const char* str)
363{
364 FILE *f;
365 if (!SystemImpl__regularFileExists(str))
366 return 0;
367 f = omc_fopen(str, "a");
368 if (f == NULL((void*)0))
369 return 0;
370 fclose(f);
371 return 1;
372}
373
374static char* SystemImpl__readFile(const char* filename)
375{
376 char* buf;
377 int res;
378 FILE * file = NULL((void*)0);
379#if defined(__MINGW32__) || defined(_MSC_VER)
380 struct _stat statstr;
381#else
382 struct stat statstr;
383#endif
384 res = omc_stat(filename, &statstr);
385
386 if (res != 0) {
387 const char *c_tokens[2]={strerror(errno(*__errno_location ())),filename};
388 c_add_message(NULL((void*)0),85, /* ERROR_OPENING_FILE */
389 ErrorType_scripting,
390 ErrorLevel_error,
391 gettext("Error opening file: %s: %s.")dcgettext (((void*)0), "Error opening file: %s: %s.", 5),
392 c_tokens,
393 2);
394 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
395 }
396
397 /* adrpo: if size is larger than the max string, return a different string */
398#if !(defined(_LP641) || defined(_LLP64) || defined(_WIN64) || defined(__MINGW64__))
399 if (statstr.st_size > (pow((double)2, (double)22) * 4)) {
400 const char *c_tokens[1]={filename};
401 c_add_message(NULL((void*)0),85, /* ERROR_OPENING_FILE */
402 ErrorType_scripting,
403 ErrorLevel_error,
404 gettext("File too large to fit into a MetaModelica string: %s.")dcgettext (((void*)0), "File too large to fit into a MetaModelica string: %s."
, 5)
,
405 c_tokens,
406 1);
407 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
408 }
409#endif
410
411 file = omc_fopen(filename,"rb");
412 if (file == NULL((void*)0)) {
413 const char *c_tokens[2]={strerror(errno(*__errno_location ())),filename};
414 c_add_message(NULL((void*)0), 85, /* ERROR_OPENING_FILE */
415 ErrorType_scripting,
416 ErrorLevel_error,
417 gettext("Error opening file: %s (its size is known, but failed to open it): %s")dcgettext (((void*)0), "Error opening file: %s (its size is known, but failed to open it): %s"
, 5)
,
418 c_tokens,
419 2);
420 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
421 }
422 buf = (char*) omc_alloc_interface.malloc_atomic(statstr.st_size+1);
423
424 if( (res = fread(buf, sizeof(char), statstr.st_size, file)) != statstr.st_size) {
425 const char *c_tokens[2]={strerror(errno(*__errno_location ())),filename};
426 c_add_message(NULL((void*)0),85, /* ERROR_OPENING_FILE */
427 ErrorType_scripting,
428 ErrorLevel_error,
429 gettext("Failed to read the entire file: %s: %s")dcgettext (((void*)0), "Failed to read the entire file: %s: %s"
, 5)
,
430 c_tokens,
431 2);
432 fclose(file);
433 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
434 }
435 buf[statstr.st_size] = '\0';
436 fclose(file);
437 return buf;
438}
439
440/* returns 0 on success */
441int SystemImpl__removeFile(const char* filename)
442{
443 return omc_unlink(filename);
444}
445
446/* returns 0 on success */
447int SystemImpl__writeFile(const char* filename, const char* data)
448{
449#if defined(__MINGW32__) || defined(_MSC_VER)
450 const char *fileOpenMode = "wt"; /* on Windows do translation so that \n becomes \r\n */
451#else
452 const char *fileOpenMode = "wb"; /* on Unixes don't bother, do it binary mode */
453#endif
454 FILE * file = NULL((void*)0);
455 int len = strlen(data); /* MMC_HDRSTRLEN(MMC_GETHDR(rmlA1)); */
456#if defined(__APPLE_CC__)||defined(__MINGW32__)||defined(__MINGW64__)
457 SystemImpl__removeFile(filename);
458#endif
459 /* adrpo: 2010-09-22 open the file in BINARY mode as otherwise \r\n becomes \r\r\n! */
460 file = omc_fopen(filename,fileOpenMode);
461 if (file == NULL((void*)0)) {
462 const char *c_tokens[1]={filename};
463 c_add_message(NULL((void*)0),21, /* WRITING_FILE_ERROR */
464 ErrorType_scripting,
465 ErrorLevel_error,
466 gettext("Error writing to file %s.")dcgettext (((void*)0), "Error writing to file %s.", 5),
467 c_tokens,
468 1);
469 return 1;
470 }
471 /* nothing to write to file! just close it and return */
472 if (len == 0)
473 {
474 fclose(file);
475 return 0;
476 }
477 /* write 1 element of size len to file and check for errors */
478 if (1 != fwrite(data, len, 1, file))
479 {
480 const char *c_tokens[1]={filename};
481 c_add_message(NULL((void*)0),21, /* WRITING_FILE_ERROR */
482 ErrorType_scripting,
483 ErrorLevel_error,
484 gettext("Error writing to file %s.")dcgettext (((void*)0), "Error writing to file %s.", 5),
485 c_tokens,
486 1);
487 fclose(file);
488 return 1;
489 }
490 if (fflush(file) != 0)
491 {
492 fprintf(stderrstderr, "System.writeFile: error flushing file: %s!\n", filename);
493 }
494 fclose(file);
495 return 0;
496}
497
498/* returns 0 on success */
499int SystemImpl__appendFile(const char* filename, const char *data)
500{
501 FILE *file = NULL((void*)0);
502 file = fopen(filename, "a");
503
504 if(file == NULL((void*)0)) {
505 const char *c_tokens[1] = {filename};
506 c_add_message(NULL((void*)0),21, /* WRITING_FILE_ERROR */
507 ErrorType_scripting, ErrorLevel_error,
508 gettext("Error appending to file %s.")dcgettext (((void*)0), "Error appending to file %s.", 5),
509 c_tokens,
510 1);
511 return 1;
512 }
513
514 fwrite(data, strlen(data), 1, file);
515 fflush(file);
516 fclose(file);
517 return 0;
518}
519
520// Trim left (step -1) or right (step +1)
521static const char* trimStep(const char* str, const char* chars_to_be_removed, int step)
522{
523 while ( *str && str_contain_char(chars_to_be_removed,*str) ) {
524 str += step;
525 }
526 return str;
527}
528
529static char* SystemImpl__trim(const char* str, const char* chars_to_be_removed)
530{
531 int length;
532 char *res;
533 const char *str2;
534
535 //fprintf(stderr, "trimming '%s' with '%s'\n", str, chars_to_be_removed);
536 str = trimStep(str, chars_to_be_removed, 1);
537 //fprintf(stderr, "trim left '%s'\n", str);
538 length = strlen(str);
539 if (length) // It is safe to go backwards in the string because we know there is at least 1 char that stops it
540 str2 = trimStep(str+length-1, chars_to_be_removed, -1);
541 else
542 str2 = str;
543 //fprintf(stderr, "trim right '%s'\n", str2);
544 length = str2 - str + 1;
545 res = (char*) omc_alloc_interface.malloc_atomic(length+1);
546 strncpy(res,str,length);
547 res[length] = '\0';
548 return res;
549}
550
551void* SystemImpl__trimChar(const char* str, char char_to_be_trimmed)
552{
553 int start_pos = 0;
554 char* res;
555
556 while(str[start_pos] == char_to_be_trimmed) {
557 start_pos++;
558 }
559 if(str[start_pos] != '\0') {
560 void *rmlRes;
561 int end_pos = strlen(str) - 1;
562
563 while(str[end_pos] == char_to_be_trimmed) {
564 end_pos--;
565 }
566 res = (char*)omc_alloc_interface.malloc_atomic(end_pos - start_pos +2);
567 strncpy(res,&str[start_pos],end_pos - start_pos+1);
568 res[end_pos - start_pos+1] = '\0';
569 rmlRes = (void*) mmc_mk_scon(res);
570 return rmlRes;
571 } else {
572 return mmc_mk_scon("");
573 }
574}
575
576const char* SystemImpl__basename(const char *str)
577{
578 const char* res = NULL((void*)0);
579#if defined(__MINGW32__) || defined(_MSC_VER)
580 res = strrchr(str, '\\');
581#endif
582 if (res == NULL((void*)0)) { res = strrchr(str, '/'); }
583 if (res == NULL((void*)0)) { res = str; } else { ++res; }
584 return res;
585}
586
587#if defined(__MINGW32__) || defined(_MSC_VER)
588int runProcess(const char* cmd)
589{
590 STARTUPINFOW si;
591 PROCESS_INFORMATION pi;
592 char *c = "cmd /c";
593 char *command = (char *)omc_alloc_interface.malloc_atomic(strlen(cmd) + strlen(c) + 4);
594 DWORD exitCode = 1;
595
596 ZeroMemory(&si, sizeof(si));
597 si.cb = sizeof(si);
598 ZeroMemory(&pi, sizeof(pi));
599
600
601 sprintf(command, "%s \"%s\"", c, cmd);
602
603 /* fprintf(stderr, "%s\n", command); fflush(NULL); */
604
605 MULTIBYTE_TO_WIDECHAR_LENGTH(command, unicodeCommandLength);
606 MULTIBYTE_TO_WIDECHAR_VAR(command, unicodeCommand, unicodeCommandLength);
607
608 if (CreateProcessW(NULL((void*)0), unicodeCommand, NULL((void*)0), NULL((void*)0), FALSE0, CREATE_NO_WINDOW, NULL((void*)0), NULL((void*)0), &si, &pi))
609 {
610 WaitForSingleObject(pi.hProcess, INFINITE);
611 // Get the exit code.
612 GetExitCodeProcess(pi.hProcess, &exitCode);
613 CloseHandle(pi.hProcess);
614 CloseHandle(pi.hThread);
615 }
616 MULTIBYTE_OR_WIDECHAR_VAR_FREE(unicodeCommand);
617 GC_free(command);
618 return (int)exitCode;
619}
620#endif
621
622int SystemImpl__systemCall(const char* str, const char* outFile)
623{
624 int status = -1,ret_val = -1;
625 const int debug = 0;
626 if (debug) {
627 fprintf(stderrstderr, "System.systemCall: %s\n", str); fflush(NULL((void*)0));
628 }
629
630 fflush(NULL((void*)0)); /* flush output so the testsuite is deterministic */
631#if defined(__MINGW32__) || defined(_MSC_VER)
632 if (*outFile) {
633 char *command = (char *)omc_alloc_interface.malloc_atomic(strlen(str) + strlen(outFile) + 10);
634 sprintf(command, "%s >> %s 2>&1", str, outFile);
635 status = runProcess(command);
636 GC_free((void*)command);
637 } else {
638 status = runProcess(str);
639 }
640#else
641 pid_t pID = vfork();
642 if (pID == 0) { // child
643 if (*outFile) {
644 /* redirect stdout, stderr in the fork'ed process */
645 int fd = open(outFile, O_RDWR02 | O_CREAT0100, S_IRUSR0400 | S_IWUSR0200);
646 if (fd < 0) {
647 _exit(1);
648 }
649 dup2(fd, 1);
650 dup2(fd, 2);
651#if defined(__APPLE_CC__)
652 /* OSX likes to not redirect the Segmentation Fault: messages unless the command is in a subshell */
653 char command[strlen(str)+3];
654 sprintf(command, "(%s)", str);
655 execl("/bin/sh", "/bin/sh", "-c", command, NULL((void*)0));
656#else
657 execl("/bin/sh", "/bin/sh", "-c", str, NULL((void*)0));
658#endif
659 } else {
660 execl("/bin/sh", "/bin/sh", "-c", str, NULL((void*)0));
661 }
662 if (debug) {
663 fprintf(stderrstderr, "System.systemCall: execl failed %s\n", strerror(errno(*__errno_location ())));
664 fflush(NULL((void*)0));
665 }
666 _exit(1);
667 } else if (pID < 0) {
668 const char *tokens[2] = {strerror(errno(*__errno_location ())),str};
669 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("system(%s) failed: %s")dcgettext (((void*)0), "system(%s) failed: %s", 5),tokens,2);
670 return -1;
671 } else {
672
673 while (waitpid(pID, &status, 0) == -1) {
674 if (errno(*__errno_location ()) == EINTR4) {
675 continue;
676 } else {
677 const char *tokens[2] = {strerror(errno(*__errno_location ())),str};
678 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error, gettext("system(%s) failed: %s")dcgettext (((void*)0), "system(%s) failed: %s", 5),tokens,2);
679 break;
680 }
681 }
682 }
683#endif
684 fflush(NULL((void*)0)); /* flush output so the testsuite is deterministic */
685
686 if (debug) {
687 fprintf(stderrstderr, "System.systemCall: returned\n"); fflush(NULL((void*)0));
688 }
689
690#if defined(__MINGW32__) || defined(_MSC_VER)
691 ret_val = status;
692#else
693 if (WIFEXITED(status)(((status) & 0x7f) == 0)) /* Did the process exit normally? */
694 ret_val = WEXITSTATUS(status)(((status) & 0xff00) >> 8); /* Fetch the actual exit status */
695 else
696 ret_val = -1;
697#endif
698
699 if (debug) {
700 fprintf(stderrstderr, "System.systemCall: returned value: %d\n", ret_val); fflush(NULL((void*)0));
701 }
702
703 return ret_val;
704}
705
706char* System_popen(threadData_t *threadData, const char* command, int *status)
707{
708 int ret_val = -1;
709 const int debug = 0;
710 if (debug) {
711 fprintf(stderrstderr, "System.popen: %s\n", command); fflush(NULL((void*)0));
712 }
713
714#if defined(__MINGW32__) || defined(_MSC_VER)
715 *status = 1;
716 return "Windows does not have popen";
717#else
718 FILE *pipe = popen(command, "r");
719 if (pipe == NULL((void*)0)) {
720 *status = 1;
721 return "popen returned NULL";
722 }
723 long handle = Print_saveAndClearBuf(threadData);
724 char buf[4096];
725 while (fgets(buf, 4096, pipe) != NULL((void*)0)){
726 Print_printBuf(threadData, buf);
727 }
728
729 if (debug) {
730 fprintf(stderrstderr, "System.pipe: returned\n"); fflush(NULL((void*)0));
731 }
732
733 char *res = omc_alloc_interface.malloc_strdup(-1 == pclose(pipe) ? strerror(errno(*__errno_location ())) : Print_getString(threadData));
734 Print_restoreBuf(threadData, handle);
735
736 if (debug) {
737 fprintf(stderrstderr, "System.systemCall: returned value: %d\n", ret_val); fflush(NULL((void*)0));
738 }
739
740 return res;
741#endif
742}
743
744#if WITH_HWLOC0==1
745#include <hwloc.h>
746#endif
747
748int System_numProcessors(void)
749{
750#if WITH_HWLOC0==1
751 hwloc_topology_t topology;
752 if (0==hwloc_topology_init(&topology) && 0==hwloc_topology_load(topology)) {
753 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_CORE);
754 if(depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
755 int res = hwloc_get_nbobjs_by_depth(topology, depth);
756 hwloc_topology_destroy(topology);
757 return intMax(res,1);
758 }
759 }
760#endif
761#if defined(__MINGW32__) || defined(_MSC_VER)
762 SYSTEM_INFO sysinfo;
763 GetSystemInfo( &sysinfo );
764 return intMax(sysinfo.dwNumberOfProcessors, 1);
765#else
766 return intMax(sysconf(_SC_NPROCESSORS_ONLN_SC_NPROCESSORS_ONLN), 1);
767#endif
768}
769
770struct systemCallWorkerThreadArgs {
771 pthread_mutex_t *mutex;
772 int *current;
773 int size;
774 char **calls;
775 int *results;
776};
777
778static void* systemCallWorkerThread(void *argVoid)
779{
780 struct systemCallWorkerThreadArgs *arg = (struct systemCallWorkerThreadArgs *) argVoid;
781 while (1) {
782 int i;
783 pthread_mutex_lock(arg->mutex);
784 i = (*arg->current);
785 *arg->current+=1;
786 pthread_mutex_unlock(arg->mutex);
787 if (i >= arg->size) break;
788 arg->results[i] = SystemImpl__systemCall(arg->calls[i],"");
789 };
790 return NULL((void*)0);
791}
792
793void* SystemImpl__systemCallParallel(void *lst, int numThreads)
794{
795 void *tmp = lst;
796 int sz = 0, i = 0;
797 char **calls;
798 int *results;
799 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(tmp)(*(mmc_uint_t*)((void*)((char*)(tmp) - 3)))) {
800 sz++;
801 tmp = MMC_CDR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
2)))))
;
802 }
803 if (sz == 0) return mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3));
804 calls = (char**) omc_alloc_interface.malloc(sz*sizeof(char*));
805 assert(calls)((void) sizeof ((calls) ? 1 : 0), __extension__ ({ if (calls)
; else __assert_fail ("calls", "./systemimpl.c", 805, __extension__
__PRETTY_FUNCTION__); }))
;
806 results = (int*) omc_alloc_interface.malloc_atomic(sz*sizeof(int));
807 assert(results)((void) sizeof ((results) ? 1 : 0), __extension__ ({ if (results
) ; else __assert_fail ("results", "./systemimpl.c", 807, __extension__
__PRETTY_FUNCTION__); }))
;
808 tmp = lst;
809 if (numThreads > sz) {
810 numThreads = sz;
811 }
812 sz=0;
813 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(tmp)(*(mmc_uint_t*)((void*)((char*)(tmp) - 3)))) {
814 calls[sz++] = MMC_STRINGDATA(MMC_CAR(tmp))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(tmp) - 3))) + (1)))))) - 3)))->data)
;
815 tmp = MMC_CDR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
2)))))
;
816 }
817 if (sz == 1) {
818 results[i] = SystemImpl__systemCall(calls[0],"");
819 } else {
820 int index = 0;
821 pthread_mutex_t mutex;
822 struct systemCallWorkerThreadArgs args = {&mutex,&index,sz,calls,results};
823 pthread_t *th = NULL((void*)0);
824 pthread_mutex_init(&mutex,NULL((void*)0));
825 th = omc_alloc_interface.malloc(sizeof(pthread_t)*numThreads);
826 /* Last element is NULL from GC_malloc */
827 for (i=0; i<numThreads; i++) {
828 GC_pthread_create(&th[i],NULL((void*)0),systemCallWorkerThread,&args);
829 }
830 for (i=0; i<numThreads; i++) {
831 GC_pthread_join(th[i], NULL((void*)0));
832 }
833 GC_free(th);
834 pthread_mutex_destroy(&mutex);
835 }
836 GC_free(calls);
837 tmp = mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3));
838 for (i=sz-1; i>=0; i--) {
839 tmp = mmc_mk_cons(mmc_mk_icon(results[i]),tmp);
840 }
841 GC_free(results);
842 return tmp;
843}
844
845int SystemImpl__spawnCall(const char* path, const char* str)
846{
847 int ret_val = -1;
848 const int debug = 0;
849 if (debug) {
850 fprintf(stderrstderr, "System.spawnCall: %s\n", str); fflush(NULL((void*)0));
851 }
852
853 fflush(NULL((void*)0)); /* flush output so the testsuite is deterministic */
854#if defined(__MINGW32__) || defined(_MSC_VER)
855 ret_val = spawnl(P_DETACH, path, str, "", NULL((void*)0));
856#else
857 pid_t pid;
858 int status;
859 const char * argv[4] = {"/bin/sh","-c",str,NULL((void*)0)};
860 ret_val = (0 == posix_spawn(&pid, "/bin/sh", NULL((void*)0), NULL((void*)0), (char * const *) argv, environ));
861#endif
862 fflush(NULL((void*)0)); /* flush output so the testsuite is deterministic */
863
864 if (debug) {
865 fprintf(stderrstderr, "System.spawnCall: returned value: %d\n", ret_val); fflush(NULL((void*)0));
866 }
867
868 return ret_val;
869}
870
871int SystemImpl__plotCallBackDefined(threadData_t *threadData)
872{
873 if (threadData->plotClassPointer && threadData->plotCB) {
874 return 1;
875 } else {
876 return 0;
877 }
878}
879
880void SystemImpl__plotCallBack(threadData_t *threadData, int externalWindow, const char* filename, const char* title, const char* grid, const char* plotType,
881 const char* logX, const char* logY, const char* xLabel, const char* yLabel, const char* x1, const char* x2, const char* y1,
882 const char* y2, const char* curveWidth, const char* curveStyle, const char* legendPosition, const char* footer, const char* autoScale,
883 const char* variables)
884{
885 if (threadData->plotClassPointer && threadData->plotCB) {
886 PlotCallback pcb = threadData->plotCB;
887 pcb(threadData->plotClassPointer, externalWindow, filename, title, grid, plotType, logX, logY, xLabel, yLabel, x1, x2, y1, y2, curveWidth, curveStyle,
888 legendPosition, footer, autoScale, variables);
889 }
890}
891
892extern double SystemImpl__time(void)
893{
894 clock_t cl = clock();
895 return (double)cl / (double)CLOCKS_PER_SEC((__clock_t) 1000000);
896}
897
898extern int SystemImpl__directoryExists(const char *str)
899{
900 /* if the string is NULL return 0 */
901 if (!str) return 0;
902#if defined(__MINGW32__) || defined(_MSC_VER)
903 WIN32_FIND_DATA FileData;
904 HANDLE sh;
905 char* path = strdup(str);
906 int last = strlen(path)-1;
907 /* adrpo: RTFM! the path cannot end in a slash??!! https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx */
908 if (last > 0 && (path[last] == '\\' || path[last] == '/')) path[last] = '\0';
909 sh = FindFirstFile(path, &FileData);
910 free(path);
911 if (sh == INVALID_HANDLE_VALUE)
912 return 0;
913 FindClose(sh);
914 return (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
915#else
916 struct stat buf;
917 if (stat(str, &buf))
918 return 0;
919 return (buf.st_mode & S_IFDIR0040000) != 0;
920#endif
921}
922
923extern int SystemImpl__createDirectory(const char *str)
924{
925 int rv;
926
927#if defined(__MINGW32__) || defined(_MSC_VER)
928 rv = mkdir(str);
929#else
930 rv = mkdir(str, S_IRWXU(0400|0200|0100));
931#endif
932 if (rv == -1)
933 {
934 return 0;
935 }
936 else
937 {
938 return 1;
939 }
940}
941
942extern int SystemImpl__copyFile(const char *str_1, const char *str_2)
943{
944 int rv = 1;
945 size_t n;
946 char buf[8192];
947 FILE *source, *target;
948
949 source = fopen(str_1, "r");
950 if (source==0) {
951 const char *msg[2] = {strerror(errno(*__errno_location ())), str_1};
952 c_add_message(NULL((void*)0),85,
953 ErrorType_scripting,
954 ErrorLevel_error,
955 gettext("Error opening file for reading %s: %s")dcgettext (((void*)0), "Error opening file for reading %s: %s"
, 5)
,
956 msg,
957 2);
958 return 0;
959 }
960 target = fopen(str_2, "w");
961 if (target==0) {
962 const char *msg[2] = {strerror(errno(*__errno_location ())), str_2};
963 c_add_message(NULL((void*)0),85,
964 ErrorType_scripting,
965 ErrorLevel_error,
966 gettext("Error opening file for writing %s: %s")dcgettext (((void*)0), "Error opening file for writing %s: %s"
, 5)
,
967 msg,
968 2);
969 fclose(source);
970 return 0;
971 }
972
973 while ( n = fread(buf, 1, 8192, source) ) {
974 if (n != fwrite(buf, 1, n, target)) {
975 rv = 0;
976 break;
977 }
978 }
979 if (rv == 0) {
980 const char *msg[3] = {strerror(errno(*__errno_location ())), str_2, str_1};
981 c_add_message(NULL((void*)0),85,
982 ErrorType_scripting,
983 ErrorLevel_error,
984 gettext("Error copying file contents %s to %s: %s")dcgettext (((void*)0), "Error copying file contents %s to %s: %s"
, 5)
,
985 msg,
986 3);
987 }
988 if (!feof(source)) {
989 rv = 0;
990 }
991
992 fclose(source);
993 fclose(target);
994 return rv;
995}
996
997static char * SystemImpl__NextDir(const char * path)
998{
999 char * res = NULL((void*)0);
1000
1001#if defined(__MINGW32__) || defined(_MSC_VER)
1002 res = strchr(path, '\\');
1003#endif
1004 if (res == NULL((void*)0))
1005 {
1006 res = strchr(path, '/');
1007 }
1008 if (res != NULL((void*)0))
1009 {
1010 res++;
1011 }
1012 return res;
1013}
1014
1015static int SystemImpl__removeDirectoryItem(const char *path)
1016{
1017 int retval;
1018 DIR * d = opendir(path);
1019
1020 if (d != NULL((void*)0))
1021 {
1022 struct dirent * p;
1023 size_t path_len = strlen(path);
1024
1025 retval = 0;
1026 while ((retval == 0) && (p = readdir(d)))
1027 {
1028 int r2 = -1;
1029 char * buf;
1030 size_t len;
1031
1032 /* Do not recurse on "." and ".." */
1033 if ((p->d_name[0] == '.') && ( (p->d_name[1] == 0) || ((p->d_name[1] == '.') && (p->d_name[2] == 0))))
1034 {
1035 continue;
1036 }
1037
1038 len = path_len + strlen(p->d_name) + 2;
1039 buf = (char *)omc_alloc_interface.malloc_atomic(len);
1040 if (buf != NULL((void*)0))
1041 {
1042 struct stat statbuf;
1043
1044 snprintf(buf, len, "%s/%s", path, p->d_name);
1045 if (stat(buf, &statbuf) == 0)
1046 {
1047 if (S_ISDIR(statbuf.st_mode)((((statbuf.st_mode)) & 0170000) == (0040000)))
1048 {
1049 r2 = 0==SystemImpl__removeDirectory(buf);
1050 }
1051 else
1052 {
1053 r2 = unlink(buf);
1054 }
1055 }
1056 }
1057 retval = r2;
1058 }
1059 closedir(d);
1060
1061 if (retval == 0)
1062 {
1063 /* if everything is ok, then dir should be empty now */
1064 retval = rmdir(path);
1065 }
1066 }
1067 else
1068 {
1069 /* Could not open path as dir, try to handle as file */
1070 retval = unlink(path);
1071 }
1072
1073 return retval;
1074}
1075
1076extern int SystemImpl__removeDirectory(const char *path)
1077{
1078 int retval = -1;
1079 char * wild = strchr(path, '*');
1080
1081 if (wild == NULL((void*)0))
1082 {
1083 retval = SystemImpl__removeDirectoryItem(path);
1084 }
1085 else
1086 {
1087 /* [ basepath '/' ] [pat_pre] '*' [pat_post] [ '/' sub ] */
1088 /* replace first wildcard item */
1089 char * basepath;
1090 char * ctmp = NULL((void*)0);
1091 const char * str = path;
1092 DIR * d;
1093 char * pattern;
1094 char * pat_pre = NULL((void*)0);
1095 char * pat_post = NULL((void*)0);
1096 char * sub = NULL((void*)0);
1097 size_t len_sub = 0;
1098
1099 do
1100 {
1101 char * res = SystemImpl__NextDir(str);
1102
1103 if (res == NULL((void*)0))
1104 {
1105 /* basepath is finally found */
1106 pattern = omc_alloc_interface.malloc_strdup(str);
1107 break;
1108 }
1109 else
1110 {
1111 if (res <= wild)
1112 {
1113 /* found new constituent of basepath */
1114 ctmp = res;
1115 str = res;
1116 }
1117 else
1118 {
1119 /* basepath is finally found */
1120 pattern = omc_alloc_interface.malloc_strdup(str);
1121 sub = res;
1122 len_sub = strlen(sub);
1123 break;
1124 }
1125 }
1126 } while(1);
1127
1128 /* prepare basepath */
1129 if (ctmp == NULL((void*)0)) {
1130 basepath = ".";
1131 } else {
1132 size_t len = ctmp-path;
1133 basepath = (char *)omc_alloc_interface.malloc_atomic(len);
1134 strncpy(basepath, path, len);
1135 basepath[len-1] = 0;
1136 }
1137
1138 /* prepare pattern */
1139 ctmp = SystemImpl__NextDir(pattern);
1140 if (ctmp != NULL((void*)0))
1141 {
1142 ctmp--;
1143 *ctmp = 0;
1144 }
1145 pat_pre = pattern;
1146 pat_post = strchr(pattern, '*');
1147 *pat_post = 0;
1148 pat_post++;
1149
1150 d = opendir(basepath);
1151 if (d != NULL((void*)0))
1152 {
1153 struct dirent * p;
1154
1155 size_t len_base = strlen(basepath);
1156 size_t len_pre = strlen(pat_pre);
1157 size_t len_post = strlen(pat_post);
1158
1159 while ((p = readdir(d)) != NULL((void*)0))
1160 {
1161 size_t len;
1162
1163 /* Do not recurse on "." and ".." */
1164 if ((p->d_name[0] == '.') && ( (p->d_name[1] == 0) || ((p->d_name[1] == '.') && (p->d_name[2] == 0))))
1165 {
1166 continue;
1167 }
1168
1169 len = strlen(p->d_name);
1170 if ((len >= (len_pre+len_post)) && (strncmp(p->d_name, pat_pre, len_pre) == 0))
1171 {
1172 if (strcmp(p->d_name+(len-len_post), pat_post) == 0)
1173 {
1174 /* pre and post pattern do match */
1175 struct stat statbuf;
1176 char * newdir = (char *)omc_alloc_interface.malloc_atomic(len_base+len+len_sub+3);
1177
1178 strcpy(newdir, basepath);
1179 strcat(newdir, "/");
1180 strcat(newdir, p->d_name);
1181 if (stat(newdir, &statbuf) == 0)
1182 {
1183 if (S_ISDIR(statbuf.st_mode)((((statbuf.st_mode)) & 0170000) == (0040000)))
1184 {
1185 if (sub != NULL((void*)0))
1186 {
1187 strcat(newdir, "/");
1188 strcat(newdir, sub);
1189 }
1190 SystemImpl__removeDirectory(newdir);
1191 }
1192 else
1193 {
1194 if (sub == NULL((void*)0))
1195 {
1196 unlink(newdir);
1197 }
1198 else
1199 {
1200 /* we have more paths, but this is no directory, skip */
1201 }
1202 }
1203 }
1204 }
1205 }
1206 }
1207 closedir(d);
1208 retval = 0;
1209 }
1210 else
1211 {
1212 retval = -1;
1213 }
1214 }
1215
1216 return retval==0;
1217}
1218
1219extern const char* SystemImpl__readFileNoNumeric(const char* filename)
1220{
1221 char* buf, *bufRes;
1222 int res,numCount;
1223 FILE * file = NULL((void*)0);
1224#if defined(__MINGW32__) || defined(_MSC_VER)
1225 struct _stat statstr;
1226#else
1227 struct stat statstr;
1228#endif
1229 res = omc_stat(filename, &statstr);
1230
1231 if(res!=0) {
1232 const char *c_tokens[1]={filename};
1233 c_add_message(NULL((void*)0),85, /* ERROR_OPENING_FILE */
1234 ErrorType_scripting,
1235 ErrorLevel_error,
1236 gettext("Error opening file %s.")dcgettext (((void*)0), "Error opening file %s.", 5),
1237 c_tokens,
1238 1);
1239 return "No such file";
1240 }
1241
1242 file = omc_fopen(filename,"rb");
1243 buf = (char*) omc_alloc_interface.malloc_atomic(statstr.st_size+1);
1244 bufRes = (char*) omc_alloc_interface.malloc_atomic((statstr.st_size+70)*sizeof(char));
1245 if( (res = fread(buf, sizeof(char), statstr.st_size, file)) != statstr.st_size) {
1246 fclose(file);
1247 return "Failed while reading file";
1248 }
1249 buf[statstr.st_size] = '\0';
1250 numCount = filterString(buf,bufRes);
1251 fclose(file);
1252 sprintf(bufRes,"%s\nFilter count from number domain: %d",bufRes,numCount);
1253 return bufRes;
1254}
1255
1256extern double SystemImpl__getCurrentTime(void)
1257{
1258 time_t t;
1259 time( &t );
1260 return difftime(t, 0); // the current time
1261}
1262
1263#if !defined(__MINGW32__) && !defined(_MSC_VER)
1264
1265typedef const struct dirent* direntry;
1266
1267static int file_select_mo(direntry entry)
1268{
1269 char* ptr;
1270 if ((strcmp(entry->d_name, ".") == 0) ||
1271 (strcmp(entry->d_name, "..") == 0) ||
1272 (strcmp(entry->d_name, "package.mo") == 0)) {
1273 return (0);
1274 } else {
1275 ptr = (char*)rindex(entry->d_name, '.');
1276 if ((ptr != NULL((void*)0)) &&
1277 ((strcmp(ptr, ".mo") == 0))) {
1278 return (1);
1279 } else {
1280 return (0);
1281 }
1282 }
1283}
1284
1285static int file_select_moc(direntry entry)
1286{
1287 char* ptr;
1288 if ((strcmp(entry->d_name, ".") == 0) ||
1289 (strcmp(entry->d_name, "..") == 0) ||
1290 (strcmp(entry->d_name, "package.moc") == 0)) {
1291 return (0);
1292 } else {
1293 ptr = (char*)rindex(entry->d_name, '.');
1294 if ((ptr != NULL((void*)0)) &&
1295 ((strcmp(ptr, ".moc") == 0))) {
1296 return (1);
1297 } else {
1298 return (0);
1299 }
1300 }
1301}
1302
1303#endif
1304
1305#if defined(__MINGW32__) || defined(_MSC_VER)
1306int setenv(const char* envname, const char* envvalue, int overwrite)
1307{
1308 int res;
1309 char *temp = (char*)omc_alloc_interface.malloc_atomic(strlen(envname)+strlen(envvalue)+2);
1310 sprintf(temp,"%s=%s", envname, envvalue);
1311 res = _putenv(temp);
1312 return res;
1313}
1314#endif
1315
1316#if defined(WITH_LIBUUID1)
1317#include <uuid/uuid.h>
1318#endif
1319
1320// Do not free the result
1321static const char* SystemImpl__getUUIDStr(void)
1322{
1323 static char uuidStr[37] = "8c4e810f-3df3-4a00-8276-176fa3c9f9e0";
1324#if defined(__MINGW32__) || defined(_MSC_VER)
1325 unsigned char *tmp;
1326 UUID uuid;
1327 if (UuidCreate(&uuid) == RPC_S_OK)
1328 UuidToString(&uuid, &tmp);
1329 tmp[36] = '\0';
1330 memcpy(uuidStr, strlwr((char*)tmp), 36);
1331 RpcStringFree(&tmp);
1332#elif defined(WITH_LIBUUID1)
1333 uuid_t uu;
1334 uuid_generate(uu);
1335 uuid_unparse_lower(uu, uuidStr);
1336#endif
1337 return uuidStr;
1338}
1339
1340typedef void (*mmc_GC_function_set_gc_state)(mmc_GC_state_type*);
1341
1342#if defined(__MINGW32__) || defined(_MSC_VER)
1343int SystemImpl__loadLibrary(const char *str, int printDebug)
1344{
1345 char libname[MAXPATHLEN4096];
1346 char currentDirectory[MAXPATHLEN4096];
1347 DWORD bufLen = MAXPATHLEN4096;
1348 modelica_ptr_t lib = NULL((void*)0);
1349 modelica_integer libIndex;
1350 HMODULE h;
1351 const char* ctokens[2];
1352 mmc_GC_function_set_gc_state mmc_GC_set_state_lib_function = NULL((void*)0);
1353 /* adrpo: use BACKSLASH here as specified here: http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx */
1354 GetCurrentDirectory(bufLen,currentDirectory);
1355#if defined(_MSC_VER)
1356 _snprintf(libname, MAXPATHLEN4096, "%s\\%s.dll", currentDirectory, str);
1357#else
1358 snprintf(libname, MAXPATHLEN4096, "%s\\%s.dll", currentDirectory, str);
1359#endif
1360
1361 h = LoadLibrary(libname);
1362 if (h == NULL((void*)0)) {
1363 LPVOID lpMsgBuf;
1364 FormatMessage(
1365 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1366 FORMAT_MESSAGE_FROM_SYSTEM |
1367 FORMAT_MESSAGE_IGNORE_INSERTS,
1368 NULL((void*)0),
1369 GetLastError()1L,
1370 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1371 (LPTSTR) &lpMsgBuf,
1372 0, NULL((void*)0) );
1373 ctokens[0] = lpMsgBuf;
1374 ctokens[1] = libname;
1375 c_add_message(NULL((void*)0),-1, ErrorType_runtime,ErrorLevel_error, gettext("OMC unable to load `%s': %s.\n")dcgettext (((void*)0), "OMC unable to load `%s': %s.\n", 5), ctokens, 2);
1376 LocalFree(lpMsgBuf);
1377 return -1;
1378 }
1379
1380 /* adrpo, pass the mmc_GC_state pointer from the current process!
1381 mmc_GC_set_state_lib_function = (mmc_GC_function_set_gc_state)getFunctionPointerFromDLL(h, "mmc_GC_set_state");
1382 if (mmc_GC_set_state_lib_function == NULL) {
1383 fprintf(stderr, "Unable to get pointer for mmc_GC_set_state in %s!\n", libname);
1384 fflush(stderr);
1385 return -1;
1386 }
1387 mmc_GC_set_state_lib_function(mmc_GC_state);
1388 */
1389
1390 libIndex = alloc_ptr();
1391 if (libIndex < 0) {
1392 //fprintf(stderr, "Error loading library %s!\n", libname); fflush(stderr);
1393 FreeLibrary(h);
1394 h = NULL((void*)0);
1395 return -1;
1396 }
1397 lib = lookup_ptr(libIndex); // lib->cnt = 1
1398 lib->data.lib = h;
1399 if (printDebug) { fprintf(stderrstderr, "LIB LOAD name[%s] index[%d] handle[%lu].\n", libname, libIndex, h); fflush(stderrstderr); }
1400 return libIndex;
1401}
1402
1403#else
1404int SystemImpl__loadLibrary(const char *str, int printDebug)
1405{
1406 char libname[MAXPATHLEN4096];
1407 modelica_ptr_t lib = NULL((void*)0);
1408 modelica_integer libIndex;
1409 void *h = NULL((void*)0);
1410 mmc_GC_function_set_gc_state mmc_GC_set_state_lib_function = NULL((void*)0);
1411 const char* ctokens[2];
1412 snprintf(libname, MAXPATHLEN4096, "./%s" CONFIG_DLL_EXT".so", str);
1413#if defined(RTLD_DEEPBIND0x00008)
1414 h = dlopen(libname, RTLD_LOCAL0 | RTLD_NOW0x00002 | RTLD_DEEPBIND0x00008);
1415#else
1416 h = dlopen(libname, RTLD_LOCAL0 | RTLD_NOW0x00002);
1417#endif
1418 if (h == NULL((void*)0)) {
1419 ctokens[0] = dlerror();
1420 ctokens[1] = libname;
1421 c_add_message(NULL((void*)0),-1, ErrorType_runtime,ErrorLevel_error, gettext("OMC unable to load `%s': %s.\n")dcgettext (((void*)0), "OMC unable to load `%s': %s.\n", 5), ctokens, 2);
1422 return -1;
1423 }
1424
1425 /* adrpo, pass the mmc_GC_state pointer from the current process!
1426 mmc_GC_set_state_lib_function = (mmc_GC_function_set_gc_state)getFunctionPointerFromDLL(h, "mmc_GC_set_state");
1427 if (mmc_GC_set_state_lib_function == NULL) {
1428 fprintf(stderr, "Unable to get pointer for mmc_GC_set_state in %s!\n", libname);
1429 fflush(stderr);
1430 return -1;
1431 }
1432 mmc_GC_set_state_lib_function(mmc_GC_state);
1433 */
1434
1435 libIndex = alloc_ptr();
1436 if (libIndex < 0) {
1437 fprintf(stderrstderr, "Error loading library %s!\n", libname); fflush(stderrstderr);
1438 dlclose(h);
1439 return -1;
1440 }
1441 lib = lookup_ptr(libIndex);
1442 lib->data.lib = h;
1443 if (printDebug)
1444 {
1445 fprintf(stderrstderr, "LIB LOAD [%s].\n", libname); fflush(stderrstderr);
1446 }
1447 return libIndex;
1448}
1449#endif
1450
1451static inline__inline__ modelica_integer alloc_ptr(void)
1452{
1453 const modelica_integer start = last_ptr_index;
1454 modelica_integer index;
1455 index = start;
1456 for (;;) {
1457 ++index;
1458 if (index >= MAX_PTR_INDEX10000)
1459 index = 0;
1460 if (index == start)
1461 return -1;
1462 if (ptr_vector[index].cnt == 0)
1463 break;
1464 }
1465 ptr_vector[index].cnt = 1;
1466 return index;
1467}
1468
1469modelica_ptr_t lookup_ptr(modelica_integer index)
1470{
1471 assert(index < MAX_PTR_INDEX)((void) sizeof ((index < 10000) ? 1 : 0), __extension__ ({
if (index < 10000) ; else __assert_fail ("index < MAX_PTR_INDEX"
, "./systemimpl.c", 1471, __extension__ __PRETTY_FUNCTION__);
}))
;
1472 return ptr_vector + index;
1473}
1474
1475static inline__inline__ void free_ptr(modelica_integer index)
1476{
1477 assert(index < MAX_PTR_INDEX)((void) sizeof ((index < 10000) ? 1 : 0), __extension__ ({
if (index < 10000) ; else __assert_fail ("index < MAX_PTR_INDEX"
, "./systemimpl.c", 1477, __extension__ __PRETTY_FUNCTION__);
}))
;
1478 ptr_vector[index].cnt = 0;
1479 memset(&(ptr_vector[index].data), 0, sizeof(ptr_vector[index].data));
1480}
1481
1482#if !defined(__MINGW32__) && !defined(_MSC_VER)
1483
1484int file_select_directories(direntry entry)
1485{
1486 char fileName[MAXPATHLEN4096];
1487 int res;
1488 struct stat fileStatus;
1489 if ((strcmp(entry->d_name, ".") == 0) ||
1490 (strcmp(entry->d_name, "..") == 0)) {
1491 return (0);
1492 } else {
1493 sprintf(fileName,"%s/%s",select_from_dir,entry->d_name);
1494 res = stat(fileName,&fileStatus);
1495 if (res!=0) return 0;
1496 if ((fileStatus.st_mode & _IFDIR0040000))
1497 return (1);
1498 else
1499 return (0);
1500 }
1501}
1502
1503#endif
1504
1505int SystemImpl__lookupFunction(int libIndex, const char *str)
1506{
1507 modelica_ptr_t lib = NULL((void*)0), func = NULL((void*)0);
1508 function_t funcptr;
1509 int funcIndex;
1510
1511 lib = lookup_ptr(libIndex);
1512
1513 if (lib == NULL((void*)0))
1514 return -1;
1515
1516 funcptr = (int (*)(threadData_t*, type_description*, type_description*)) getFunctionPointerFromDLLdlsym(lib->data.lib, str);
1517
1518 if (funcptr == NULL((void*)0)) {
1519 fprintf(stderrstderr, "Unable to find `%s': %lu.\n", str, GetLastError()1L);
1520 return -1;
1521 }
1522
1523 funcIndex = alloc_ptr();
1524 func = lookup_ptr(funcIndex);
1525 func->data.func.handle = funcptr;
1526 func->data.func.lib = libIndex;
1527 ++(lib->cnt); // lib->cnt = 2
1528 /* fprintf(stderr, "LOOKUP LIB index[%d]/count[%d]/handle[%lu] function %s[%d].\n", libIndex, lib->cnt, lib->data.lib, str, funcIndex); fflush(stderr); */
1529 return funcIndex;
1530}
1531
1532static int SystemImpl__freeFunction(int funcIndex, int printDebug)
1533{
1534 modelica_ptr_t func = NULL((void*)0), lib = NULL((void*)0);
1535
1536 //fprintf(stderr,"freeFunction(%d,%d)\n", funcIndex, printDebug);
1537
1538 func = lookup_ptr(funcIndex);
1539
1540 //fprintf(stderr,"freeFunction(%d,%d) lookup: func: %p\n", func);
1541
1542 if (func == NULL((void*)0)) return 1;
1543
1544 lib = lookup_ptr(func->data.func.lib);
1545
1546 //fprintf(stderr,"freeFunction(%d,%d) lookup: lib %p\n", lib);
1547
1548 if (lib == NULL((void*)0)) {
1549 free_function(func);
1550 free_ptr(funcIndex);
1551 return 1;
1552 }
1553
1554
1555 if (lib->cnt <= 1) {
1556 free_library(lib, printDebug);
1557 free_ptr(func->data.func.lib);
1558 // fprintf(stderr, "library count %u, after unloading!\n", lib->cnt); fflush(stderr);
1559 } else {
1560 --(lib->cnt);
1561 // fprintf(stderr, "library count %u, no unloading!\n", lib->cnt); fflush(stderr);
1562 }
1563
1564 free_function(func);
1565 free_ptr(funcIndex);
1566 return 0;
1567}
1568
1569static int SystemImpl__freeLibrary(int libIndex, int printDebug)
1570{
1571 modelica_ptr_t lib = NULL((void*)0);
1572
1573 lib = lookup_ptr(libIndex);
1574
1575 if (lib == NULL((void*)0)) return 1;
1576
1577 if (lib->cnt <= 1) {
1578 free_library(lib, printDebug);
1579 free_ptr(libIndex);
1580 /* fprintf(stderr, "LIB UNLOAD index[%d]/count[%d]/handle[%ul].\n", libIndex, lib->cnt, lib->data.lib); fflush(stderr); */
1581 } else {
1582 --(lib->cnt);
1583 /* fprintf(stderr, "LIB *NO* UNLOAD index[%d]/count[%d]/handle[%ul].\n", libIndex, lib->cnt, lib->data.lib); fflush(stderr); */
1584 }
1585 return 0;
1586}
1587
1588static void free_library(modelica_ptr_t lib, modelica_integer printDebug)
1589{
1590 if (printDebug) { fprintf(stderrstderr, "LIB UNLOAD handle[%" PRINT_MMC_UINT_T"lu" "].\n", (mmc_uint_t) lib->data.lib); fflush(stderrstderr); }
1591 if (FreeLibraryFromHandledlclose(lib->data.lib))
1592 {
1593 fprintf(stderrstderr,"System.freeLibrary error code: %lu while unloading dll.\n", GetLastError()1L);
1594 fflush(stderrstderr);
1595 }
1596 lib->data.lib = NULL((void*)0);
1597}
1598
1599static void free_function(modelica_ptr_t func)
1600{
1601 /* noop */
1602 lookup_ptr(func->data.func.lib);
1603 /* fprintf(stderr, "FUNCTION FREE LIB index[%d]/count[%d]/handle[%ul].\n", (lib-ptr_vector),((modelica_ptr_t)(lib-ptr_vector))->cnt, lib->data.lib); fflush(stderr); */
1604}
1605
1606static int SystemImpl__getVariableValue(double timeStamp, void* timeValues, void *varValues, double *returnValue)
1607{
1608 // values to find the correct range
1609 double preValue = 0.0;
1610 double preTime = 0.0;
1611 double nowValue = 0.0;
1612 double nowTime = 0.0;
1613
1614 // linjear interpolation data
1615 double timedif = 0.0;
1616 double valuedif = 0.0;
1617 double valueSlope = 0.0;
1618 double timeDifTimeStamp = 0.0;
1619
1620 // break loop and return value
1621 int valueFound = 0;
1622
1623 for(; MMC_GETHDR(timeValues)(*(mmc_uint_t*)((void*)((char*)(timeValues) - 3))) == MMC_CONSHDR(((2) << 10) + (((1) & 255) << 2)) && valueFound == 0; timeValues = MMC_CDR(timeValues)(*(void**)(((void*)((void**)(((void*)((char*)(timeValues) - 3
))) + (2)))))
, varValues = MMC_CDR(varValues)(*(void**)(((void*)((void**)(((void*)((char*)(varValues) - 3)
)) + (2)))))
) {
1624 nowValue = mmc_prim_get_real(MMC_CAR(varValues)(*(void**)(((void*)((void**)(((void*)((char*)(varValues) - 3)
)) + (1)))))
);
1625 nowTime = mmc_prim_get_real(MMC_CAR(timeValues)(*(void**)(((void*)((void**)(((void*)((char*)(timeValues) - 3
))) + (1)))))
);
1626
1627 if(timeStamp == nowTime){
1628 valueFound = 1;
1629 *returnValue = nowValue;
1630 } else if (timeStamp >= preTime && timeStamp <= nowTime) { // need to do interpolation
1631 valueFound = 1;
1632 timedif = nowTime - preTime;
1633 valuedif = nowValue - preValue;
1634 valueSlope = valuedif / timedif;
1635 timeDifTimeStamp = timeStamp - preTime;
1636 *returnValue = preValue + (valueSlope*timeDifTimeStamp);
1637 } else {
1638 preValue = nowValue;
1639 preTime = nowTime;
1640 }
1641 }
1642
1643 if(valueFound == 0){
1644 // value could not be found in the dataset, what do we do?
1645 printf("\n WARNING: timestamp(%f) outside simulation timeline \n", timeStamp);
1646 return 1;
1647 }
1648 return 0;
1649}
1650
1651/* If the Modelica string is used as a C string literal, this
1652 * calculates the string length of that string. */
1653extern int SystemImpl__unescapedStringLength(const char* str)
1654{
1655 int i=0;
1656 while (*str) {
1657 if (str[0] == '\\') {
1658 switch (str[1]) {
1659 case '\'':
1660 case '"':
1661 case '?':
1662 case '\\':
1663 case 'a':
1664 case 'b':
1665 case 'f':
1666 case 'n':
1667 case 'r':
1668 case 't':
1669 case 'v':
1670 str++; break;
1671 }
1672 }
1673 i++;
1674 str++;
1675 }
1676 return i;
1677}
1678
1679extern char* SystemImpl__unescapedString(const char* str)
1680{
1681 int len1,len2;
1682 char *res;
1683 int i=0;
1684 len1 = strlen(str);
1685 len2 = SystemImpl__unescapedStringLength(str);
1686 if (len1 == len2) return NULL((void*)0);
1687 res = (char*) omc_alloc_interface.malloc_atomic(len2+1);
1688 while (*str) {
1689 res[i] = str[0];
1690 if (str[0] == '\\') {
1691 switch (str[1]) {
1692 case '\'':
1693 str++; res[i]='\''; break;
1694 case '"':
1695 str++; res[i]='\"'; break;
1696 case '?':
1697 str++; res[i]='\?'; break;
1698 case '\\':
1699 str++; res[i]='\\'; break;
1700 case 'a':
1701 str++; res[i]='\a'; break;
1702 case 'b':
1703 str++; res[i]='\b'; break;
1704 case 'f':
1705 str++; res[i]='\f'; break;
1706 case 'n':
1707 str++; res[i]='\n'; break;
1708 case 'r':
1709 str++; res[i]='\r'; break;
1710 case 't':
1711 str++; res[i]='\t'; break;
1712 case 'v':
1713 str++; res[i]='\v'; break;
1714 }
1715 }
1716 i++;
1717 str++;
1718 }
1719 res[i] = '\0';
1720 return res;
1721}
1722
1723
1724static int compute_sanitized_string_size(const char* str) {
1725 int i, count;
1726
1727 for (i=0, count=0; str[i]; i++, count++) {
1728 char c = str[i];
1729 // Each non-alphanum character needs one more char for its
1730 // two char ascii representation.
1731 if (!isalnum(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalnum
)
&& c != '_') {
1732 count++;
1733 }
1734 }
1735
1736 return count;
1737}
1738
1739static char* sanitize_string(const char* src, char* dst, int nrchars) {
1740 const char lookupTbl[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1741
1742 int i;
1743 for (i = 0; i < nrchars; i++) {
1744 unsigned char c = src[i];
1745 if (isalnum(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalnum
)
|| c == '_') {
1746 *dst = c;
1747 dst++;
1748 }
1749 else {
1750 *dst = lookupTbl[c/16];
1751 dst++;
1752 *dst = lookupTbl[c%16];
1753 dst++;
1754 }
1755 }
1756
1757 return dst;
1758}
1759
1760// This function assumes the input is actually a quoted string e.g 'gb' or 'ab[!%'
1761extern char* System_sanitizeQuotedIdentifier(const char* str)
1762{
1763 char *res,*cur;
1764
1765 const char openquote[]="Q_";
1766 const char closequote[]="_Q";
1767 const int qsize = sizeof(openquote) - 1;
1768
1769 int nrchars_org = strlen(str);
1770
1771 // Each non-alphanum character needs one more char for its
1772 // two char ascii representation.
1773 int nrchars_needed = compute_sanitized_string_size(str);
1774
1775 // ignore the count for opening and closing quotes in the original string
1776 nrchars_needed = nrchars_needed - 4;
1777 nrchars_org = nrchars_org - 2;
1778
1779 nrchars_needed += 2*qsize; // opening and closing quoute rep.
1780 nrchars_needed++; /*null terminator*/
1781 res = (char*) omc_alloc_interface.malloc_atomic(nrchars_needed * sizeof(char));
1782
1783 cur = res;
1784 cur += sprintf(cur, "%s", openquote);
1785 cur = sanitize_string(str + 1, cur, nrchars_org);
1786 cur += sprintf(cur,"%s", closequote);
1787 *cur = '\0';
1788
1789 ++cur;
1790 assert((cur == res + nrchars_needed) && "Allocated memory does not exactly fit the unquoted string output")((void) sizeof (((cur == res + nrchars_needed) && "Allocated memory does not exactly fit the unquoted string output"
) ? 1 : 0), __extension__ ({ if ((cur == res + nrchars_needed
) && "Allocated memory does not exactly fit the unquoted string output"
) ; else __assert_fail ("(cur == res + nrchars_needed) && \"Allocated memory does not exactly fit the unquoted string output\""
, "./systemimpl.c", 1790, __extension__ __PRETTY_FUNCTION__);
}))
;
1791
1792 return res;
1793}
1794
1795extern char* System_sanitizeIdentifier(const char* str)
1796{
1797 char *res,*cur;
1798
1799 int nrchars_org = strlen(str);
1800
1801 // Each non-alphanum character needs one more char for its
1802 // two char ascii representation.
1803 int nrchars_needed = compute_sanitized_string_size(str);
1804
1805 // if the first char is not alphanum then the result will start with a number(ascii)
1806 // we do not want that. So make it always start with a char.
1807 const char openquote[]="D_";
1808 const int qsize = sizeof(openquote) - 1;
1809 nrchars_needed += qsize;
1810
1811 nrchars_needed++; /*null terminator*/
1812 res = (char*) omc_alloc_interface.malloc_atomic(nrchars_needed * sizeof(char));
1813
1814 cur = res;
1815 cur += sprintf(cur, "%s", openquote);
1816 cur = sanitize_string(str, cur, nrchars_org);
1817 *cur = '\0';
1818
1819 ++cur;
1820 assert((cur == res + nrchars_needed) && "Allocated memory does not exactly fit the unquoted string output")((void) sizeof (((cur == res + nrchars_needed) && "Allocated memory does not exactly fit the unquoted string output"
) ? 1 : 0), __extension__ ({ if ((cur == res + nrchars_needed
) && "Allocated memory does not exactly fit the unquoted string output"
) ; else __assert_fail ("(cur == res + nrchars_needed) && \"Allocated memory does not exactly fit the unquoted string output\""
, "./systemimpl.c", 1820, __extension__ __PRETTY_FUNCTION__);
}))
;
1821
1822 return res;
1823}
1824
1825extern char* SystemImpl__unquoteIdentifier(char* str)
1826{
1827
1828 if (str[0] == '\'') {
1829 return System_sanitizeQuotedIdentifier(str);
1830 }
1831
1832#if !defined(OPENMODELICA_BOOTSTRAPPING_STAGE_1)
1833 if (strstr(str, "$")) {
1834 return System_sanitizeIdentifier(str);
1835 }
1836#endif
1837
1838 return str;
1839}
1840
1841#define TIMER_MAX_STACK1000 1000
1842static double timerIntervalTime = 0;
1843static double timerCummulatedTime = 0;
1844static double timerTime = 0;
1845static long int timerStackIdx = 0;
1846static double timerStack[TIMER_MAX_STACK1000] = {0};
1847
1848static void pushTimerStack(void)
1849{
1850 if (timerStackIdx < TIMER_MAX_STACK1000)
1851 {
1852 timerStack[timerStackIdx] = rt_tock(RT_CLOCK_SPECIAL_STOPWATCH32);
1853 /* increase the stack */
1854 timerStackIdx++;
1855 }
1856 else
1857 {
1858 fprintf(stderrstderr, "System.pushStartTime -> timerStack overflow %ld\n", timerStackIdx);
1859 }
1860}
1861
1862static void popTimerStack(void)
1863{
1864 if (timerStackIdx >= 1)
1865 {
1866 /* how much time passed since we last called startTime? */
1867 timerIntervalTime = rt_tock(RT_CLOCK_SPECIAL_STOPWATCH32) - timerStack[timerStackIdx-1];
1868 timerCummulatedTime += timerIntervalTime;
1869 /* decrease the stack */
1870 timerStackIdx--;
1871 }
1872 else
1873 {
1874 fprintf(stderrstderr, "System.popStartTime -> timerStack underflow %ld\n", timerStackIdx);
1875 }
1876}
1877
1878static void decodeUri2(const char *src, char *dest, int breakCh)
1879{
1880 char *tmp = dest;
1881 while (*src) {
1882 if (*src == '+') *(tmp++) = ' ';
1883 else if (*src == '%' && src[1]) {
1884 char buf[3];
1885 int i;
1886 buf[0] = src[1];
1887 buf[1] = src[2];
1888 buf[2] = '\0';
1889 errno(*__errno_location ()) = 0;
1890 i = strtol(buf,NULL((void*)0),16);
1891 if (errno(*__errno_location ())) {
1892 *(tmp++) = *src;
1893 errno(*__errno_location ()) = 0;
1894 } else {
1895 *(tmp++) = i;
1896 *tmp = 0;
1897 src += 2;
1898 }
1899 } else if (*src == breakCh) {
1900 break;
1901 } else *(tmp++) = *src;
1902 src++;
1903 }
1904 *tmp = '\0';
1905}
1906
1907static void decodeUri(const char *src, char **name, char **path)
1908{
1909 const char *srcPath = strchr(src,'/');
1910 const char *srcName = src;
1911 int len = strlen(src);
1912 int lenPath = srcPath ? strlen(srcPath+1) : 0;
1913 *name = (char*) omc_alloc_interface.malloc_atomic(len - lenPath + 2);
1914 decodeUri2(src,*name,'/');
1915 *path = (char*) omc_alloc_interface.malloc_atomic(lenPath+2);
1916 **path = '\0';
1917 if (srcPath == NULL((void*)0)) {
1918 return;
1919 }
1920 decodeUri2(srcPath,*path,-1);
1921}
1922
1923static int SystemImpl__uriToClassAndPath(const char *uri, const char **scheme, char **name, char **path)
1924{
1925 const char *modelicaUri = "modelica://";
1926 const char *fileUri = "file://";
1927 const char *msg[2];
1928 *scheme = NULL((void*)0);
1929 *name = NULL((void*)0);
1930 *path = NULL((void*)0);
1931 if (0 == strncasecmp(uri, modelicaUri, strlen(modelicaUri))) {
1932 *scheme = modelicaUri;
1933 decodeUri(uri+strlen(modelicaUri),name,path);
1934 if (!**name) {
1935 msg[0] = uri;
1936 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("Modelica URI lacks classname: %s")dcgettext (((void*)0), "Modelica URI lacks classname: %s", 5),msg,1);
1937 return 1;
1938 }
1939 return 0;
1940 } else if (0 == strncasecmp(uri, fileUri, strlen(fileUri))) {
1941 *scheme = fileUri;
1942 decodeUri(uri+strlen(fileUri),name,path);
1943 if (!**path) {
1944 msg[0] = uri;
1945 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("File URI has no path: %s")dcgettext (((void*)0), "File URI has no path: %s", 5),msg,1);
1946 return 1;
1947 } else if (**name) {
1948 msg[0] = uri;
1949 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("File URI using hostnames is not supported: %s")dcgettext (((void*)0), "File URI using hostnames is not supported: %s"
, 5)
,msg,1);
1950 return 1;
1951 }
1952 return 0;
1953 }
1954 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("Unknown uri: %s")dcgettext (((void*)0), "Unknown uri: %s", 5),&uri,1);
1955 return 1;
1956}
1957
1958#ifdef NO_LAPACK
1959int SystemImpl__dgesv(void *lA, void *lB, void **res)
1960{
1961 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
1962}
1963#else
1964/* adrpo 2011-06-23
1965 * extern definition to dgesv_ from -llapack
1966 * as we do not link with -lsim and the one
1967 * in matrix.h got renamed to _omc_dgesv_ to
1968 * avoid name clashes!
1969 */
1970extern int dgesv_(integer *n, integer *nrhs, doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer *ldb, integer *info);
1971
1972int SystemImpl__dgesv(void *lA, void *lB, void **res)
1973{
1974 integer sz = 0, i = 0, j = 0;
1975 void *tmp = lB;
1976 double *A,*B;
1977 integer *ipiv;
1978 integer info = 0,nrhs=1,lda,ldb;
1979 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(tmp)(*(mmc_uint_t*)((void*)((char*)(tmp) - 3)))) {
1980 sz++;
1981 tmp = MMC_CDR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
2)))))
;
1982 }
1983 A = (double*) omc_alloc_interface.malloc_atomic(sz*sz*sizeof(double));
1984 assert(A != NULL)((void) sizeof ((A != ((void*)0)) ? 1 : 0), __extension__ ({ if
(A != ((void*)0)) ; else __assert_fail ("A != NULL", "./systemimpl.c"
, 1984, __extension__ __PRETTY_FUNCTION__); }))
;
1985 B = (double*) omc_alloc_interface.malloc_atomic(sz*sizeof(double));
1986 assert(B != NULL)((void) sizeof ((B != ((void*)0)) ? 1 : 0), __extension__ ({ if
(B != ((void*)0)) ; else __assert_fail ("B != NULL", "./systemimpl.c"
, 1986, __extension__ __PRETTY_FUNCTION__); }))
;
1987 for (i=0; i<sz; i++) {
1988 tmp = MMC_CAR(lA)(*(void**)(((void*)((void**)(((void*)((char*)(lA) - 3))) + (1
)))))
;
1989 for (j=0; j<sz; j++) {
1990 A[j*sz+i] = mmc_prim_get_real(MMC_CAR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
1)))))
);
1991 tmp = MMC_CDR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
2)))))
;
1992 }
1993 B[i] = mmc_prim_get_real(MMC_CAR(lB)(*(void**)(((void*)((void**)(((void*)((char*)(lB) - 3))) + (1
)))))
);
1994 lA = MMC_CDR(lA)(*(void**)(((void*)((void**)(((void*)((char*)(lA) - 3))) + (2
)))))
;
1995 lB = MMC_CDR(lB)(*(void**)(((void*)((void**)(((void*)((char*)(lB) - 3))) + (2
)))))
;
1996 }
1997 ipiv = (integer*) omc_alloc_interface.malloc_atomic(sz*sizeof(integer));
1998 memset(ipiv,0,sz*sizeof(integer));
1999 assert(ipiv != 0)((void) sizeof ((ipiv != 0) ? 1 : 0), __extension__ ({ if (ipiv
!= 0) ; else __assert_fail ("ipiv != 0", "./systemimpl.c", 1999
, __extension__ __PRETTY_FUNCTION__); }))
;
2000 lda = sz;
2001 ldb = sz;
2002 dgesv_(&sz,&nrhs,A,&lda,ipiv,B,&ldb,&info);
2003
2004 tmp = mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3));
2005 while (sz--) {
2006 tmp = mmc_mk_cons(mmc_mk_rcon(B[sz]),tmp);
2007 }
2008 *res = tmp;
2009 return info;
2010}
2011#endif
2012
2013#ifdef NO_LPLIB
2014int SystemImpl__lpsolve55(void *lA, void *lB, void *ix, void **res)
2015{
2016 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("Not compiled with lpsolve support")dcgettext (((void*)0), "Not compiled with lpsolve support", 5
)
,NULL((void*)0),0);
2017 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
2018}
2019#else
2020
2021#include CONFIG_LPSOLVEINC"lpsolve/lp_lib.h"
2022
2023int SystemImpl__lpsolve55(void *lA, void *lB, void *ix, void **res)
2024{
2025 int i = 0, j = 0, info, sz = 0;
2026 void *tmp = lB;
2027 lprec *lp;
2028 double inf,*vres;
2029
2030 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(tmp)(*(mmc_uint_t*)((void*)((char*)(tmp) - 3)))) {
2031 sz++;
2032 tmp = MMC_CDR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
2)))))
;
2033 }
2034 vres = (double*)omc_alloc_interface.malloc_atomic(sz*sizeof(double));
2035 memset(vres,0,sz*sizeof(double));
2036 lp = make_lp(sz, sz);
2037 set_verbose(lp, 1);
2038 inf = get_infinite(lp);
2039
2040 for (i=0; i<sz; i++) {
2041 set_lowbo(lp, i+1, -inf);
2042 set_constr_type(lp, i+1, EQ3);
2043 tmp = MMC_CAR(lA)(*(void**)(((void*)((void**)(((void*)((char*)(lA) - 3))) + (1
)))))
;
2044 for (j=0; j<sz; j++) {
2045 set_mat(lp, i+1, j+1, mmc_prim_get_real(MMC_CAR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
1)))))
));
2046 tmp = MMC_CDR(tmp)(*(void**)(((void*)((void**)(((void*)((char*)(tmp) - 3))) + (
2)))))
;
2047 }
2048 set_rh(lp, i+1, mmc_prim_get_real(MMC_CAR(lB)(*(void**)(((void*)((void**)(((void*)((char*)(lB) - 3))) + (1
)))))
));
2049 lA = MMC_CDR(lA)(*(void**)(((void*)((void**)(((void*)((char*)(lA) - 3))) + (2
)))))
;
2050 lB = MMC_CDR(lB)(*(void**)(((void*)((void**)(((void*)((char*)(lB) - 3))) + (2
)))))
;
2051 }
2052 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(ix)(*(mmc_uint_t*)((void*)((char*)(ix) - 3)))) {
2053 if (MMC_UNTAGFIXNUM(MMC_CAR(ix))(((mmc_sint_t) ((*(void**)(((void*)((void**)(((void*)((char*)
(ix) - 3))) + (1))))))) >> 1)
!= -1) set_int(lp, MMC_UNTAGFIXNUM(MMC_CAR(ix))(((mmc_sint_t) ((*(void**)(((void*)((void**)(((void*)((char*)
(ix) - 3))) + (1))))))) >> 1)
, 1);
2054 ix = MMC_CDR(ix)(*(void**)(((void*)((void**)(((void*)((char*)(ix) - 3))) + (2
)))))
;
2055 }
2056 info=solve(lp);
2057 //print_lp(lp);
2058 if (info==0 || info==1) get_ptr_variables(lp,&vres);
2059 *res = mmc_mk_nil()((void*)((char*)(&(mmc_nil).header) + 3));
2060 while (sz--) {
2061 *res = mmc_mk_cons(mmc_mk_rcon(vres[sz]),*res);
2062 }
2063 delete_lp(lp);
2064 return info;
2065}
2066#endif
2067
2068#define MODELICAPATH_LEVELS6 6
2069typedef struct {
2070 const char *dir;
2071 char *file;
2072 long version[MODELICAPATH_LEVELS6];
2073 char *versionExtra;
2074 int fileIsDir;
2075} modelicaPathEntry;
2076
2077void splitVersion(const char *version, long *versionNum, char **versionExtra)
2078{
2079 const char *buf = version;
2080 char *next;
2081 long l;
2082 int cont,i=0,len;
2083 memset(versionNum,0,sizeof(long)*MODELICAPATH_LEVELS6);
2084 do {
2085 /* fprintf(stderr, "look versionNum %s\n", buf); */
2086 l = strtol(buf,&next,10);
2087 cont = buf != next && l >= 0;
2088 if (cont) {
2089 versionNum[i] = l;
2090 /* fprintf(stderr, "versionNum %lx\n", *versionNum); */
2091 if (*next == '.') next++;
2092 }
2093 buf = next;
2094 } while (cont && ++i < MODELICAPATH_LEVELS6);
2095 if (*buf == ' ') buf++;
2096 *versionExtra = omc_alloc_interface.malloc_strdup(buf);
2097 len = strlen(*versionExtra);
2098 /* fprintf(stderr, "have len %ld versionExtra %s\n", len, *versionExtra); */
2099 if (len >= 2 && 0==strcmp("mo", *versionExtra+len-2)) {
2100 (*versionExtra)[len-2] = '\0';
2101 }
2102}
2103
2104static int regularFileExistsInDirectory(const char *dir1, const char *dir2, const char *file)
2105{
2106 char *str;
2107 int res;
2108 str = (char*) omc_alloc_interface.malloc_atomic(strlen(dir1) + strlen(dir2) + strlen(file) + 3);
2109 sprintf(str,"%s/%s/%s", dir1, dir2, file);
2110 res = SystemImpl__regularFileExists(str);
2111 return res;
2112}
2113
2114static modelicaPathEntry* getAllModelicaPaths(const char *name, size_t nlen, void *mps, int *numMatches)
2115{
2116 int i = 0;
2117 modelicaPathEntry* res;
2118 void *save_mps = mps;
2119 *numMatches = 0;
2120 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(mps)(*(mmc_uint_t*)((void*)((char*)(mps) - 3)))) {
2121 const char *mp = MMC_STRINGDATA(MMC_CAR(mps))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(mps) - 3))) + (1)))))) - 3)))->data)
;
2122 DIR *dir = opendir(mp);
2123 struct dirent *ent;
2124 mps = MMC_CDR(mps)(*(void**)(((void*)((void**)(((void*)((char*)(mps) - 3))) + (
2)))))
;
2125 if (!dir) continue;
2126 while ((ent = readdir(dir))) {
2127 if (0 == strncmp(name, ent->d_name, nlen) && (ent->d_name[nlen] == '\0' || ent->d_name[nlen] == ' ' || ent->d_name[nlen] == '.')) {
2128 int entlen,mightbedir;
2129#ifdef DT_DIRDT_DIR
2130 mightbedir = (ent->d_type==DT_DIRDT_DIR || ent->d_type==DT_UNKNOWNDT_UNKNOWN || ent->d_type==DT_LNKDT_LNK);
2131#else
2132 mightbedir = 1;
2133#endif
2134 if (mightbedir && (regularFileExistsInDirectory(mp,ent->d_name,"package.mo") || regularFileExistsInDirectory(mp,ent->d_name,"package.moc"))) {
2135 /* fprintf(stderr, "found match %d %s\n", *numMatches, ent->d_name); */
2136 (*numMatches)++;
2137 continue;
2138 }
2139 entlen = strlen(ent->d_name);
2140 if (((entlen > 3 && 0==strcmp(ent->d_name+entlen-3,".mo")) || (entlen > 4 && 0==strcmp(ent->d_name+entlen-4,".moc"))) && regularFileExistsInDirectory(mp,"",ent->d_name)) {
2141 /* fprintf(stderr, "found match %d %s\n", *numMatches, ent->d_name); */
2142 (*numMatches)++;
2143 }
2144 }
2145 }
2146 closedir(dir);
2147 }
2148 /* fprintf(stderr, "numMatches: %ld\n", *numMatches); */
2149 /*** NOTE: Doing the same thing again. It is very important the same (number of) entries are match as in the loop above ***/
2150 res = (modelicaPathEntry*) omc_alloc_interface.malloc(*numMatches*sizeof(modelicaPathEntry));
2151 mps = save_mps;
2152 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(mps)(*(mmc_uint_t*)((void*)((char*)(mps) - 3)))) {
2153 const char *mp = MMC_STRINGDATA(MMC_CAR(mps))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(mps) - 3))) + (1)))))) - 3)))->data)
;
2154 DIR *dir = opendir(mp);
2155 struct dirent *ent;
2156 mps = MMC_CDR(mps)(*(void**)(((void*)((void**)(((void*)((char*)(mps) - 3))) + (
2)))))
;
2157 if (!dir) continue;
2158 while ((ent = readdir(dir))) {
2159 if (0 == strncmp(name, ent->d_name, nlen) && (ent->d_name[nlen] == '\0' || ent->d_name[nlen] == ' ' || ent->d_name[nlen] == '.')) {
2160 int entlen,ok=0,maybeDir;
2161#ifdef DT_DIRDT_DIR
2162 maybeDir = (ent->d_type==DT_DIRDT_DIR || ent->d_type==DT_UNKNOWNDT_UNKNOWN || ent->d_type==DT_LNKDT_LNK);
2163#else
2164 maybeDir = 1;
2165#endif
2166 if (maybeDir && (regularFileExistsInDirectory(mp,ent->d_name,"package.mo") || regularFileExistsInDirectory(mp,ent->d_name,"package.moc"))) {
2167 ok=1;
2168 res[i].fileIsDir=1;
2169 /* fprintf(stderr, "found dir match: %ld %s - ok=%d\n", i, ent->d_name, ok); */
2170 }
2171 entlen = strlen(ent->d_name);
2172 if (!ok && ((entlen > 3 && 0==strcmp(ent->d_name+entlen-3,".mo")) || (entlen > 4 && 0==strcmp(ent->d_name+entlen-4,".moc"))) && regularFileExistsInDirectory(mp,"",ent->d_name)) {
2173 /* fprintf(stderr, "found match file: %ld %s - ok=%d\n", i, ent->d_name, ok); */
2174 res[i].fileIsDir=0;
2175 ok=1;
2176 }
2177 if (!ok)
2178 continue;
2179 res[i].dir = mp;
2180 res[i].file = omc_alloc_interface.malloc_strdup(ent->d_name);
2181 if (res[i].file[nlen] == ' ') {
2182 splitVersion(res[i].file+nlen+1, res[i].version, &res[i].versionExtra);
2183 } else {
2184 memset(res[i].version,0,sizeof(long)*MODELICAPATH_LEVELS6);
2185 res[i].versionExtra = "";
2186 }
2187 assert(i<*numMatches)((void) sizeof ((i<*numMatches) ? 1 : 0), __extension__ ({
if (i<*numMatches) ; else __assert_fail ("i<*numMatches"
, "./systemimpl.c", 2187, __extension__ __PRETTY_FUNCTION__);
}))
;
2188 i++;
2189 }
2190 }
2191 closedir(dir);
2192 }
2193 return res;
2194}
2195
2196static int modelicaPathEntryVersionEqual(long *ver1, long *ver2, int numToTest)
2197{
2198 int i;
2199 for (i=0; i<numToTest; i++) {
2200 if (ver1[i] != ver2[i]) return 0;
2201 }
2202 return 1;
2203}
2204
2205static int modelicaPathEntryVersionGreater(long *ver1, long *ver2, int numToTest)
2206{
2207 int i;
2208 for (i=0; i<numToTest; i++) {
2209 if (ver1[i] > ver2[i]) return 1;
2210 if (ver1[i] < ver2[i]) return 0;
2211 }
2212 return 1;
2213}
2214
2215static int getLoadModelPathFromSingleTarget(const char *searchTarget, modelicaPathEntry *entries, int numEntries, int exactVersion, const char **outDir, char **outName, int *isDir)
2216{
2217 int i, j, foundIndex = -1;
2218 long version[MODELICAPATH_LEVELS6] = {0}, foundVersion[MODELICAPATH_LEVELS6] = {0};
2219 char *versionExtra;
2220 splitVersion(searchTarget,version,&versionExtra);
2221 /* fprintf(stderr, "expected %ld.%ld.%ld.%ld %s ; exact=%d\n", version[0], version[1], version[2], version[3], versionExtra, exactVersion); */
2222 if (version > 0 && !*versionExtra) {
2223 /* Makes us load 3.2.1 if 3.2.0.0 is not available.
2224 * Note that all 4 levels are present and 3.2 is equivalent to 3.2.0.0
2225 * Search one additional level for each time we fail.
2226 */
2227 for (j=MODELICAPATH_LEVELS6; j>=(exactVersion ? MODELICAPATH_LEVELS6 : 0); j--) {
2228 for (i=0; i<numEntries; i++) {
2229 /* fprintf(stderr, "entry %s/%s\n", entries[i].dir, entries[i].file);
2230 fprintf(stderr, "expected %ld.%ld.%ld.%ld %s\n", entries[i].version[0], entries[i].version[1], entries[i].version[2], entries[i].version[3], entries[i].versionExtra); */
2231
2232 if (modelicaPathEntryVersionEqual(entries[i].version,version,j)
2233 && (j==MODELICAPATH_LEVELS6 || modelicaPathEntryVersionGreater(entries[i].version,version,MODELICAPATH_LEVELS6))
2234 && entries[i].versionExtra[0] == '\0') {
2235 if (modelicaPathEntryVersionGreater(entries[i].version,foundVersion,MODELICAPATH_LEVELS6)) {
2236 memcpy(foundVersion,entries[i].version,sizeof(long)*MODELICAPATH_LEVELS6);
2237 foundIndex = i;
2238 }
2239 }
2240 }
2241 if (foundIndex >= 0) {
2242 *outDir = entries[foundIndex].dir;
2243 *outName = entries[foundIndex].file;
2244 *isDir = entries[foundIndex].fileIsDir;
2245 return 0;
2246 }
2247 }
2248 }
2249 if (*versionExtra) {
2250 /* fprintf(stderr, "Look for version %lx versionExtra: %s\n", version, versionExtra); */
2251 for (i=0; i<numEntries; i++) {
2252 /* fprintf(stderr, "entry %s/%s\n", entries[i].dir, entries[i].file);
2253 fprintf(stderr, "is %ld.%ld.%ld.%ld %s\n", entries[i].version[0], entries[i].version[1], entries[i].version[2], entries[i].version[3], entries[i].versionExtra); */
2254 if (modelicaPathEntryVersionEqual(entries[i].version,version,MODELICAPATH_LEVELS6) && 0==strncmp(entries[i].versionExtra,versionExtra,strlen(versionExtra))) {
2255 *outDir = entries[i].dir;
2256 *outName = entries[i].file;
2257 *isDir = entries[i].fileIsDir;
2258 return 0;
2259 }
2260 }
2261 }
2262 return 1;
2263}
2264
2265static int getLoadModelPathFromDefaultTarget(const char *name, modelicaPathEntry *entries, int numEntries, const char **outDir, char **outName, int *isDir)
2266{
2267 const char *foundExtra = 0;
2268 long foundVersion[MODELICAPATH_LEVELS6] = {-1,-1,-1,0};
2269 int i,foundIndex = -1;
2270
2271 /* Look for best release version */
2272 for (i=0; i<numEntries; i++) {
2273 if (modelicaPathEntryVersionGreater(entries[i].version,foundVersion,MODELICAPATH_LEVELS6) && entries[i].versionExtra[0] == '\0') {
2274 memcpy(foundVersion,entries[i].version,sizeof(long)*MODELICAPATH_LEVELS6);
2275 foundIndex = i;
2276 }
2277 }
2278 /* Look for best pre-release/named version */
2279 if (foundIndex == -1) {
2280 for (i=0; i<numEntries; i++) {
2281 if (modelicaPathEntryVersionGreater(entries[i].version,foundVersion,MODELICAPATH_LEVELS6) || (entries[i].version == foundVersion && strcmp(entries[i].versionExtra,foundExtra) > 0)) {
2282 memcpy(foundVersion,entries[i].version,sizeof(long)*MODELICAPATH_LEVELS6);
2283 foundExtra = entries[i].versionExtra;
2284 foundIndex = i;
2285 }
2286 }
2287 }
2288 if (foundIndex >= 0) {
2289 *outDir = entries[foundIndex].dir;
2290 *outName = entries[foundIndex].file;
2291 *isDir = entries[foundIndex].fileIsDir;
2292 return 0;
2293 }
2294 return 1;
2295}
2296
2297int System_getLoadModelPath(const char *name, void *prios, void *mps, int exactVersion, const char **outDir, char **outName, int *isDir)
2298{
2299 int numEntries,res=1;
2300 size_t nameLen = strlen(name);
2301 modelicaPathEntry *entries = getAllModelicaPaths(name, nameLen, mps, &numEntries);
2302 *outName = NULL((void*)0);
2303 while (MMC_NILHDR(((0) << 10) + (((0) & 255) << 2)) != MMC_GETHDR(prios)(*(mmc_uint_t*)((void*)((char*)(prios) - 3)))) {
2304 const char *prio = MMC_STRINGDATA(MMC_CAR(prios))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(prios) - 3))) + (1)))))) - 3)))->data
)
;
2305 if (0==strcmp("default",prio)) {
2306 if (!getLoadModelPathFromDefaultTarget(name,entries,numEntries,outDir,outName,isDir)) {
2307 res = 0;
2308 break;
2309 }
2310 } else {
2311 if (!getLoadModelPathFromSingleTarget(prio,entries,numEntries,exactVersion,outDir,outName,isDir)) {
2312 res = 0;
2313 break;
2314 }
2315 }
2316 prios = MMC_CDR(prios)(*(void**)(((void*)((void**)(((void*)((char*)(prios) - 3))) +
(2)))))
;
2317 }
2318 if (NULL((void*)0) == *outName) {
2319 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
2320 }
2321 /* fprintf(stderr, "result: %d %s %s %d", res, *outDir, *outName, *isDir); */
2322 return res;
2323}
2324
2325#define MAX_TMP_TICK50 50
2326
2327typedef struct systemMoData {
2328 int tmp_tick_no[MAX_TMP_TICK50];
2329 int tmp_tick_max_no[MAX_TMP_TICK50];
2330} systemMoData;
2331
2332pthread_once_t system_once_create_key = PTHREAD_ONCE_INIT0;
2333pthread_key_t systemMoKey;
2334
2335static void free_system_mo(void *data)
2336{
2337 systemMoData *members = (systemMoData*) data;
2338 if (data == NULL((void*)0)) return;
2339 free(members);
2340}
2341
2342static void make_key(void)
2343{
2344 pthread_key_create(&systemMoKey,free_system_mo);
2345}
2346
2347static systemMoData* getSystemMoData(threadData_t *threadData)
2348{
2349 systemMoData *res;
2350 if (threadData && threadData->localRoots[LOCAL_ROOT_SYSTEM_MO]) {
2351 return (systemMoData*) threadData->localRoots[LOCAL_ROOT_SYSTEM_MO];
2352 }
2353 pthread_once(&system_once_create_key,make_key);
2354 res = (systemMoData*) pthread_getspecific(systemMoKey);
2355 if (res != NULL((void*)0)) return res;
2356 /* We use malloc instead of new because when we do dynamic loading of functions, C++ objects in TLS might be free'd upon return to the main process. */
2357 res = (systemMoData*) calloc(1,sizeof(systemMoData));
2358 pthread_setspecific(systemMoKey,res);
2359 if (threadData) {
2360 /* Still use pthreads API to free the buffer on thread exit even though we pass this thing around
2361 * We could change this to storing the free function in MMC_CATCH_TOP, but this might be faster if we pool threads
2362 */
2363 threadData->localRoots[LOCAL_ROOT_SYSTEM_MO] = res;
2364 }
2365 return res;
2366}
2367
2368extern int SystemImpl_tmpTickIndex(threadData_t *threadData, int index)
2369{
2370 systemMoData *data = getSystemMoData(threadData);
2371 int res = data->tmp_tick_no[index];
2372 assert(index < MAX_TMP_TICK && index >= 0)((void) sizeof ((index < 50 && index >= 0) ? 1 :
0), __extension__ ({ if (index < 50 && index >=
0) ; else __assert_fail ("index < MAX_TMP_TICK && index >= 0"
, "./systemimpl.c", 2372, __extension__ __PRETTY_FUNCTION__);
}))
;
2373 data->tmp_tick_no[index] += 1;
2374 data->tmp_tick_max_no[index] = intMax(data->tmp_tick_no[index],data->tmp_tick_max_no[index]);
2375 return res;
2376}
2377
2378extern int SystemImpl_tmpTickIndexReserve(threadData_t *threadData, int index, int reserve)
2379{
2380 systemMoData *data = getSystemMoData(threadData);
2381 int res = data->tmp_tick_no[index];
2382 assert(index < MAX_TMP_TICK && index >= 0)((void) sizeof ((index < 50 && index >= 0) ? 1 :
0), __extension__ ({ if (index < 50 && index >=
0) ; else __assert_fail ("index < MAX_TMP_TICK && index >= 0"
, "./systemimpl.c", 2382, __extension__ __PRETTY_FUNCTION__);
}))
;
2383 data->tmp_tick_no[index] += reserve;
2384 data->tmp_tick_max_no[index] = intMax(data->tmp_tick_no[index],data->tmp_tick_max_no[index]);
2385 return res;
2386}
2387
2388extern void SystemImpl_tmpTickResetIndex(threadData_t *threadData, int start, int index)
2389{
2390 systemMoData *data = getSystemMoData(threadData);
2391 assert(index < MAX_TMP_TICK && index >= 0)((void) sizeof ((index < 50 && index >= 0) ? 1 :
0), __extension__ ({ if (index < 50 && index >=
0) ; else __assert_fail ("index < MAX_TMP_TICK && index >= 0"
, "./systemimpl.c", 2391, __extension__ __PRETTY_FUNCTION__);
}))
;
2392 /* fprintf(stderr, "tmpTickResetIndex %d => %d\n", index, start); */
2393 data->tmp_tick_no[index] = start;
2394 data->tmp_tick_max_no[index] = start;
2395}
2396
2397extern void SystemImpl_tmpTickSetIndex(threadData_t *threadData, int start, int index)
2398{
2399 systemMoData *data = getSystemMoData(threadData);
2400 assert(index < MAX_TMP_TICK && index >= 0)((void) sizeof ((index < 50 && index >= 0) ? 1 :
0), __extension__ ({ if (index < 50 && index >=
0) ; else __assert_fail ("index < MAX_TMP_TICK && index >= 0"
, "./systemimpl.c", 2400, __extension__ __PRETTY_FUNCTION__);
}))
;
2401 /* fprintf(stderr, "tmpTickResetIndex %d => %d\n", index, start); */
2402 data->tmp_tick_no[index] = start;
2403 data->tmp_tick_max_no[index] = intMax(start,data->tmp_tick_max_no[index]);
2404}
2405
2406/* If you use negative reserve or set, the maximum can be different from the tick */
2407extern int SystemImpl_tmpTickMaximum(threadData_t *threadData, int index)
2408{
2409 systemMoData *data = getSystemMoData(threadData);
2410 assert(index < MAX_TMP_TICK && index >= 0)((void) sizeof ((index < 50 && index >= 0) ? 1 :
0), __extension__ ({ if (index < 50 && index >=
0) ; else __assert_fail ("index < MAX_TMP_TICK && index >= 0"
, "./systemimpl.c", 2410, __extension__ __PRETTY_FUNCTION__);
}))
;
2411 return data->tmp_tick_max_no[index];
2412}
2413
2414#if defined(OPENMODELICA_BOOTSTRAPPING_STAGE_1)
2415extern int SystemImpl_tmpTick(threadData_t *threadData)
2416{
2417 int res = SystemImpl_tmpTickIndex(threadData,0);
2418 return res;
2419}
2420#endif
2421
2422extern void SystemImpl_tmpTickReset(threadData_t *threadData, int start)
2423{
2424 SystemImpl_tmpTickResetIndex(threadData,start,0);
2425}
2426
2427extern int SystemImpl__reopenStandardStream(int id,const char *filename)
2428{
2429 FILE *file;
2430 const char* mode;
2431 const char* streamName;
2432 switch (id) {
2433 case 0: file=stdinstdin;mode="r";streamName="stdin";break;
2434 case 1: file=stdoutstdout;mode="w";streamName="stdout";break;
2435 case 2: file=stderrstderr;mode="w";streamName="stderr";break;
2436 default: return 0;
2437 }
2438 file = freopen(filename,mode,file);
2439 if (file==NULL((void*)0)) {
2440 const char *tokens[4] = {strerror(errno(*__errno_location ())),streamName,mode,filename};
2441 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("freopen(%s,%s,%s) failed: %s")dcgettext (((void*)0), "freopen(%s,%s,%s) failed: %s", 5),tokens,4);
2442 return 0;
2443 }
2444 return 1;
2445}
2446
2447const char* SystemImpl__iconv__ascii(const char * str)
2448{
2449 char *buf = 0;
2450 size_t sz;
2451 int i;
2452 sz = strlen(str);
2453 buf = omc_alloc_interface.malloc_atomic(sz+1);
2454 *buf = 0;
2455 for (i=0; i<=sz; i++)
2456 buf[i] = str[i] & 0x80 ? '?' : str[i];
2457 return buf;
2458}
2459
2460static int isUtf8Encoding(const char *str)
2461{
2462 return strcasecmp(str, "UTF-8") || strcasecmp(str, "UTF8");
2463}
2464
2465extern const char* SystemImpl__iconv(const char * str, const char *from, const char *to, int printError)
2466{
2467 char *in_str,*res=NULL((void*)0);
2468 size_t sz,out_sz,buflen;
2469 iconv_t ic;
2470 int count;
2471 char *buf;
2472 sz = strlen(str);
2473 if (isUtf8Encoding(from) && isUtf8Encoding(to))
2474 {
2475 is_utf8((unsigned char*)str, sz, &res, &count);
2476 if (res==NULL((void*)0)) {
2477 /* Converting from UTF-8 to UTF-8 and the sequence is already UTF-8... */
2478 return str;
2479 }
2480 /* Converting from UTF-8, but is not valid UTF-8. Just quit early. */
2481 if (printError) {
2482 const char *ignore = SystemImpl__iconv__ascii(str);
2483 const char *tokens[4] = {res,from,to,ignore};
2484 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("iconv(\"%s\",from=\"%s\",to=\"%s\") failed: %s")dcgettext (((void*)0), "iconv(\"%s\",from=\"%s\",to=\"%s\") failed: %s"
, 5)
,tokens,4);
2485 omc_alloc_interface.free_uncollectable((char*)ignore);
2486 }
2487 return (const char*) "";
2488 }
2489 buflen = sz*4;
2490 /* fprintf(stderr,"iconv(%s,to=%s,%s) of size %d, buflen %d\n",str,to,from,sz,buflen); */
2491 ic = iconv_open(to, from);
2492 if (ic == (iconv_t) -1) {
2493 if (printError) {
2494 const char *ignore = SystemImpl__iconv__ascii(str);
2495 const char *tokens[4] = {strerror(errno(*__errno_location ())),from,to,ignore};
2496 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("iconv(\"%s\",to=\"%s\",from=\"%s\") failed: %s")dcgettext (((void*)0), "iconv(\"%s\",to=\"%s\",from=\"%s\") failed: %s"
, 5)
,tokens,4);
2497 omc_alloc_interface.free_uncollectable((char*)ignore);
2498 }
2499 return (const char*) "";
2500 }
2501 buf = (char*) omc_alloc_interface.malloc_atomic(buflen);
2502 if (0 == buf) {
2503 if (printError) {
2504 /* Make the error message small so we perhaps have a chance to recover */
2505 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("iconv() ran out of memory")dcgettext (((void*)0), "iconv() ran out of memory", 5),NULL((void*)0),0);
2506 }
2507 return (const char*) "";
2508 }
2509 *buf = 0;
2510 in_str = (char*) str;
2511 out_sz = buflen-1;
2512 res = buf;
2513 count = iconv(ic,&in_str,&sz,&res,&out_sz);
2514 iconv_close(ic);
2515 if (count == -1) {
2516 if (printError) {
2517 const char *ignore = SystemImpl__iconv__ascii(str);
2518 const char *tokens[4] = {strerror(errno(*__errno_location ())),from,to,ignore};
2519 c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("iconv(\"%s\",to=\"%s\",from=\"%s\") failed: %s")dcgettext (((void*)0), "iconv(\"%s\",to=\"%s\",from=\"%s\") failed: %s"
, 5)
,tokens,4);
2520 omc_alloc_interface.free_uncollectable((char*)ignore);
2521 }
2522 omc_alloc_interface.free_uncollectable(buf);
2523 return (const char*) "";
2524 }
2525 buf[(buflen-1)-out_sz] = 0;
2526 if (strlen(buf) != (buflen-1)-out_sz) {
2527 if (printError) c_add_message(NULL((void*)0),-1,ErrorType_scripting,ErrorLevel_error,gettext("iconv(to=%s) failed because the character set output null bytes in the middle of the string.")dcgettext (((void*)0), "iconv(to=%s) failed because the character set output null bytes in the middle of the string."
, 5)
,&to,1);
2528 omc_alloc_interface.free_uncollectable(buf);
2529 return (const char*) "";
2530 }
2531 if (!strcmp(from, to) && !strcmp(str, buf))
2532 {
2533 omc_alloc_interface.free_uncollectable(buf);
2534 return (const char*)str;
2535 }
2536 return buf;
2537}
2538
2539#include <tinymt64.h>
2540
2541static tinymt64_t system_random_seed = {{0,0},0,0,0};
2542
2543/* NOTES: Randomness provided by random() is guaranteed to be uniform
2544 * (high and low bits are the same).
2545 * rand() does not produce good results and should be avoided. */
2546static void seed(void)
2547{
2548 static int init = 0;
2549 if (!init) {
2550 /* Skip /dev/random stuff since we want this predictable */
2551 // set parameters
2552 system_random_seed.mat1 = 0x8f7011ee;
2553 system_random_seed.mat2 = 0xfc78ff1f;
2554 system_random_seed.tmat = 0x3793fdff;
2555 tinymt64_init(&system_random_seed,1);
2556 init = 1;
2557 }
2558}
2559
2560/* Returns a value (0,1] */
2561double SystemImpl__realRand(void)
2562{
2563 seed();
2564 return tinymt64_generate_double(&system_random_seed);
2565}
2566
2567/* Returns an integer [0,n) using the C function rand() */
2568int SystemImpl__intRandom(int n)
2569{
2570 return rand() % n;
2571}
2572
2573char* alloc_locale_str(const char *locale, int llen, const char *suffix, int slen)
2574{
2575 char *loc = (char*)omc_alloc_interface.malloc_atomic(sizeof(char) * (llen + slen + 1));
2576 assert(loc != NULL)((void) sizeof ((loc != ((void*)0)) ? 1 : 0), __extension__ (
{ if (loc != ((void*)0)) ; else __assert_fail ("loc != NULL",
"./systemimpl.c", 2576, __extension__ __PRETTY_FUNCTION__); }
))
;
2577 strncpy(loc, locale, llen);
2578 strncpy(loc + llen, suffix, slen + 1);
2579 return loc;
2580}
2581
2582void SystemImpl__gettextInit(const char *locale)
2583{
2584#if defined(_MSC_VER)
2585#else
2586 const char *omhome = SettingsImpl__getInstallationDirectoryPath();
2587 char *localedir,*clocale;
2588 int omlen;
2589#if defined(__MINGW32__)
2590 if (*locale) {
2591 char environment[strlen(locale)+9];
2592 strcpy(environment, "LANGUAGE=");
2593 putenv(strcat(environment, locale));
2594 } else {
2595 LCID userLocaleId = GetUserDefaultLCID();
2596 int localeBufferSize = GetLocaleInfo(userLocaleId, LOCALE_SISO639LANGNAME, NULL((void*)0), 0);
2597 char userLocaleStr[localeBufferSize];
2598 GetLocaleInfo(userLocaleId, LOCALE_SISO639LANGNAME, userLocaleStr, localeBufferSize);
2599 char environment[localeBufferSize+9];
2600 strcpy(environment, "LANGUAGE=");
2601 putenv(strcat(environment, userLocaleStr));
2602 }
2603#else
2604 /* We might get sent sv_SE when only sv_SE.utf8 exists, etc */
2605 int locale_len = strlen(locale);
2606 char *locale2 = alloc_locale_str(locale, locale_len, ".utf8", 5);
2607 char *locale3 = alloc_locale_str(locale, locale_len, ".UTF-8", 6);
2608 char *old_ctype_default = setlocale(LC_CTYPE0, "");
2609 if (!old_ctype_default)
2610 old_ctype_default = "UTF-8";
2611 char *old_ctype = omc_alloc_interface.malloc_strdup(old_ctype_default);
2612 int old_ctype_is_utf8 = strcmp(nl_langinfo(CODESETCODESET), "UTF-8") == 0;
2613
2614 int res =
2615 (*locale == 0 && setlocale(LC_MESSAGES5, "") && setlocale(LC_CTYPE0, "")) ||
2616 (*locale != 0 && setlocale(LC_MESSAGES5, locale3) && setlocale(LC_CTYPE0, locale3)) ||
2617 (*locale != 0 && setlocale(LC_MESSAGES5, locale2) && setlocale(LC_CTYPE0, locale2)) ||
2618 (*locale != 0 && setlocale(LC_MESSAGES5, locale) && setlocale(LC_CTYPE0, locale));
2619 if (!res && *locale) {
2620 fprintf(stderrstderr, gettext("Warning: Failed to set locale: '%s'\n")dcgettext (((void*)0), "Warning: Failed to set locale: '%s'\n"
, 5)
, locale);
2621 }
2622 if (!setlocale(LC_NUMERIC1, "C")) {
2623 fputs(gettext("Warning: Failed to set LC_NUMERIC to C locale\n")dcgettext (((void*)0), "Warning: Failed to set LC_NUMERIC to C locale\n"
, 5)
, stderrstderr);
2624 }
2625 clocale = setlocale(LC_CTYPE0, NULL((void*)0));
2626 int have_utf8 = strcmp(nl_langinfo(CODESETCODESET), "UTF-8") == 0;
2627 /* We succesfully forced a new non-system locale; let's clear some variables */
2628 if (*locale) {
2629 unsetenv("LANG");
2630 unsetenv("LANGUAGE");
2631 unsetenv("LC_ALL");
2632 }
2633 /* Try to make sure we force UTF-8; else gettext will fail */
2634 if (have_utf8)
2635 setlocale(LC_CTYPE0, clocale);
2636 else if (old_ctype_is_utf8)
2637 setlocale(LC_CTYPE0, old_ctype);
2638 else if (!(strstr(clocale, "UTF-8") || strstr(clocale, "UTF8") ||
2639 strstr(clocale, "utf-8") || strstr(clocale, "utf8")) &&
2640 !(setlocale(LC_CTYPE0, "C.UTF-8") ||
2641 setlocale(LC_CTYPE0, "en_US.UTF-8") ||
2642 setlocale(LC_CTYPE0, "en_GB.UTF-8") ||
2643 setlocale(LC_CTYPE0, "UTF-8"))) {
2644 fprintf(stderrstderr, gettext("Warning: Failed to set LC_CTYPE to UTF-8 using the chosen locale and C.UTF-8. OpenModelica assumes all input and output it makes is in UTF-8 so you might have some issues.\n")dcgettext (((void*)0), "Warning: Failed to set LC_CTYPE to UTF-8 using the chosen locale and C.UTF-8. OpenModelica assumes all input and output it makes is in UTF-8 so you might have some issues.\n"
, 5)
);
2645 }
2646#endif /* __MINGW32__ */
2647 if(omhome == NULL((void*)0))
2648 {
2649 fprintf(stderrstderr, "Warning: environment variable OPENMODELICAHOME is not set. Cannot load locale.\n");
2650 return;
2651 }
2652 omlen = strlen(omhome);
2653 localedir = (char*) omc_alloc_interface.malloc_atomic(omlen + 25);
2654 sprintf(localedir, "%s/share/locale", omhome);
2655 bindtextdomain ("openmodelica", localedir);
2656 textdomain ("openmodelica");
2657#endif /* _MSC_VER */
2658}
2659
2660const char* SystemImpl__gettext(const char *msgid)
2661{
2662#if defined(_MSC_VER)
2663 return msgid;
2664#else
2665 return gettext(msgid)dcgettext (((void*)0), msgid, 5);
2666#endif
2667}
2668
2669
2670int System_getTerminalWidth(void)
2671{
2672#if defined(__MINGW32__) || defined(_MSC_VER)
2673 return 80;
2674#else
2675 struct winsize w;
2676 ioctl(STDOUT_FILENO1, TIOCGWINSZ0x5413, &w);
2677 return w.ws_col ? w.ws_col : 80;
2678#endif
2679}
2680
2681#include "simulation_options.h"
2682
2683#define SB_SIZE8192*4 8192*4
2684#define SB_SIZE_MINUS_ONE(8192*4 -1) (SB_SIZE8192*4-1)
2685
2686/* snprintf check negative size */
2687static size_t check_nonnegative(long sz)
2688{
2689 if (sz < 0) {
2690 fprintf(stderrstderr, "%s:%d got negative size: %ld, which should not happen\n", __FILE__"./systemimpl.c", __LINE__2690, sz);
2691 exit(EXIT_FAILURE1);
2692 }
2693 return sz;
2694}
2695
2696#define CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)) check_nonnegative((long)SB_SIZE_MINUS_ONE(8192*4 -1)-(cur-buf))
2697
2698char* System_getSimulationHelpTextSphinx(int detailed, int sphinx)
2699{
2700 static char buf[SB_SIZE8192*4];
2701 int i,j;
2702 const char **desc = detailed ? FLAG_DETAILED_DESC : FLAG_DESC;
2703 char *cur = buf;
2704 *cur = 0;
2705 for(i=1; i<FLAG_MAX; ++i)
2706 {
2707 if (sphinx) {
2708 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), "\n.. _simflag-%s :\n\n", FLAG_NAME[i]);
2709 }
2710 if (FLAG_TYPE[i] == FLAG_TYPE_FLAG) {
2711 if (sphinx) {
2712 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), ":ref:`-%s <simflag-%s>`\n%s\n", FLAG_NAME[i], FLAG_NAME[i], desc[i]);
2713 } else {
2714 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), "<-%s>\n%s\n", FLAG_NAME[i], desc[i]);
2715 }
2716 } else if (FLAG_TYPE[i] == FLAG_TYPE_OPTION) {
2717 int numExtraFlags=0;
2718 int firstExtraFlag=1;
2719 const char **flagName;
2720 const char **flagDesc;
2721 if (sphinx) {
2722 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), ":ref:`-%s=value <simflag-%s>` *or* -%s value \n%s\n", FLAG_NAME[i], FLAG_NAME[i], FLAG_NAME[i], desc[i]);
2723 } else {
2724 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), "<-%s=value> or <-%s value>\n%s\n", FLAG_NAME[i], FLAG_NAME[i], desc[i]);
2725 }
2726
2727 switch(i) {
2728
2729 case FLAG_IDA_LS:
2730 numExtraFlags = IDA_LS_MAX;
2731 flagName = IDA_LS_METHOD;
2732 flagDesc = IDA_LS_METHOD_DESC;
2733 break;
2734
2735 case FLAG_IIM:
2736 numExtraFlags = IIM_MAX;
2737 flagName = INIT_METHOD_NAME;
2738 flagDesc = INIT_METHOD_DESC;
2739 break;
2740
2741 case FLAG_JACOBIAN:
2742 numExtraFlags = JAC_MAX;
2743 flagName = JACOBIAN_METHOD;
2744 flagDesc = JACOBIAN_METHOD_DESC;
2745 break;
2746
2747 case FLAG_LS:
2748 numExtraFlags = LS_MAX;
2749 flagName = LS_NAME;
2750 flagDesc = LS_DESC;
2751 break;
2752
2753 case FLAG_LSS:
2754 numExtraFlags = LSS_MAX;
2755 flagName = LSS_NAME;
2756 flagDesc = LSS_DESC;
2757 break;
2758
2759 case FLAG_LV:
2760 firstExtraFlag=firstOMCErrorStream;
2761 numExtraFlags = SIM_LOG_MAX;
2762 flagName = LOG_STREAM_NAME;
2763 flagDesc = LOG_STREAM_DESC;
2764 break;
2765
2766 case FLAG_NEWTON_STRATEGY:
2767 numExtraFlags = NEWTON_MAX;
2768 flagName = NEWTONSTRATEGY_NAME;
2769 flagDesc = NEWTONSTRATEGY_DESC;
2770 break;
2771
2772 case FLAG_NLS:
2773 numExtraFlags = NLS_MAX;
2774 flagName = NLS_NAME;
2775 flagDesc = NLS_DESC;
2776 break;
2777
2778 case FLAG_NLS_LS:
2779 numExtraFlags = NLS_LS_MAX;
2780 flagName = NLS_LS_METHOD;
2781 flagDesc = NLS_LS_METHOD_DESC;
2782 break;
2783
2784
2785 case FLAG_S:
2786 numExtraFlags = S_MAX;
2787 flagName = NULL((void*)0);
2788 flagDesc = SOLVER_METHOD_DESC;
2789 break;
2790 }
2791
2792 if (numExtraFlags) {
2793 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), "\n");
2794 if (flagName) {
2795 for (j=firstExtraFlag; j<numExtraFlags; j++) {
2796 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), " * %s (%s)\n", flagName[j], flagDesc[j]);
2797 }
2798 } else {
2799 for (j=firstExtraFlag; j<numExtraFlags; j++) {
2800 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), " * %s\n", flagDesc[j]);
2801 }
2802 }
2803 }
2804
2805 } else {
2806 cur += snprintf(cur, CHECK_NONNEGATIVE_BUFFER()check_nonnegative((long)(8192*4 -1)-(cur-buf)), "[unknown flag-type] <-%s>\n", FLAG_NAME[i]);
2807 }
2808 }
2809 *cur = 0;
2810 return buf;
2811}
2812
2813/* TODO: Remove me with new tarball */
2814char* System_getSimulationHelpText(int detailed)
2815{
2816 return System_getSimulationHelpTextSphinx(detailed, 0);
2817}
2818
2819int SystemImpl__fileIsNewerThan(const char *file1, const char *file2)
2820{
2821#if defined(_MSC_VER)
2822 WIN32_FIND_DATA FileData;
2823 HANDLE sh1,sh2;
2824 FILETIME ftWrite1, ftWrite2;
2825
2826 sh1 = FindFirstFile(file1, &FileData);
2827 if (sh1 == INVALID_HANDLE_VALUE) {
2828 return -1;
2829 }
2830 sh2 = FindFirstFile(file2, &FileData);
2831 if (sh2 == INVALID_HANDLE_VALUE) {
2832 FindClose(sh1);
2833 return -1;
2834 }
2835 if (!(GetFileTime(sh1, NULL((void*)0), NULL((void*)0), &ftWrite1) && GetFileTime(sh2, NULL((void*)0), NULL((void*)0), &ftWrite2))) {
2836 FindClose(sh1);
2837 FindClose(sh2);
2838 return -1;
2839 }
2840 FindClose(sh1);
2841 FindClose(sh2);
2842 return ((LARGE_INTEGER*)&ftWrite1)->QuadPart - ((LARGE_INTEGER*)&ftWrite2)->QuadPart > 0 ? 1 : 0;
2843#else
2844 struct stat buf1, buf2;
2845 if (stat(file1, &buf1)) {
2846 const char *c_tokens[2]={strerror(errno(*__errno_location ())),file1};
2847 c_add_message(NULL((void*)0),85,
2848 ErrorType_scripting,
2849 ErrorLevel_error,
2850 gettext("Could not access file %s: %s.")dcgettext (((void*)0), "Could not access file %s: %s.", 5),
2851 c_tokens,
2852 2);
2853 return -1;
2854 }
2855 if (stat(file2, &buf2)) {
2856 const char *c_tokens[2]={strerror(errno(*__errno_location ())),file2};
2857 c_add_message(NULL((void*)0),85,
2858 ErrorType_scripting,
2859 ErrorLevel_error,
2860 gettext("Could not access file %s: %s.")dcgettext (((void*)0), "Could not access file %s: %s.", 5),
2861 c_tokens,
2862 2);
2863 return -1;
2864 }
2865 return difftime(buf1.st_mtimest_mtim.tv_sec, buf2.st_mtimest_mtim.tv_sec) > 0 ? 1 : 0;
2866#endif
2867}
2868
2869void SystemImpl__initGarbageCollector(void)
2870{
2871 static int init=0;
2872 if (!init) {
2873 GC_init();
2874 GC_register_displacement(0);
2875#ifdef RML_STYLE_TAGPTR
2876 GC_register_displacement(3);
2877#endif
2878 GC_set_force_unmap_on_gcollect(1);
2879 init=1;
2880 }
2881}
2882
2883int SystemImpl__fileContentsEqual(const char *file1, const char *file2)
2884{
2885 char buf1[8192],buf2[8192];
2886 FILE *f1,*f2;
2887 int i1,i2,totalread=0,error=0;
2888#if !defined(_MSC_VER)
2889 struct stat stbuf1;
2890 struct stat stbuf2;
2891 if (stat(file1, &stbuf1)) return 0;
2892 if (stat(file2, &stbuf2)) return 0;
2893 if (stbuf1.st_size != stbuf2.st_size) return 0;
2894#endif
2895 f1 = fopen(file1,"rb");
2896 if (f1 == NULL((void*)0)) {
2897 return 0;
2898 }
2899 f2 = fopen(file2,"rb");
2900 if (f2 == NULL((void*)0)) {
2901 fclose(f1);
2902 return 0;
2903 }
2904 do {
2905 i1 = fread(buf1,1,8192,f1);
2906 i2 = fread(buf2,1,8192,f2);
2907 if (i1 != i2 || strncmp(buf1,buf2,i1)) {
2908 error = 1;
2909 }
2910 totalread += i1;
2911 } while(i1 != 0 && error == 0);
2912 fclose(f1);
2913 fclose(f2);
2914 return !error;
2915}
2916
2917int SystemImpl__rename(const char *source, const char *dest)
2918{
2919#if defined(__MINGW32__) || defined(_MSC_VER)
2920 return MoveFileEx(source, dest, MOVEFILE_REPLACE_EXISTING);
2921#endif
2922 return 0==rename(source,dest);
2923}
2924
2925char* SystemImpl__ctime(double time)
2926{
2927 char buf[64] = {0}; /* needs to be >=26 char */
2928 time_t t = (time_t) time;
2929 return omc_alloc_interface.malloc_strdup(ctime_r(&t,buf));
2930}
2931
2932#if defined(__MINGW32__)
2933/*
2934 * strtok_r implementation
2935 */
2936static char *omc_strtok_r(char *str, const char *delim, char **saveptr)
2937{
2938 char *token;
2939 if (!str && !(str = *saveptr))
2940 {
2941 return NULL((void*)0);
2942 }
2943 str += strspn(str, delim);
2944 if (!*str) {
2945 *saveptr = NULL((void*)0);
2946 return NULL((void*)0);
2947 }
2948 token = str++;
2949 str += strcspn(str, delim);
2950 if (*str) {
2951 *str = 0;
2952 *saveptr = str+1;
2953 } else {
2954 *saveptr = NULL((void*)0);
2955 }
2956
2957 return token;
2958}
2959
2960#define strtok_r omc_strtok_r
2961
2962#endif /* defined(__MINGW32__) */
2963
2964int SystemImpl__stat(const char *filename, double *size, double *mtime)
2965{
2966 struct stat stats;
2967 if (0 != stat(filename, &stats)) {
2968 *size = 0;
2969 *mtime = 0;
2970 return 0;
2971 }
2972 *size = stats.st_size;
2973 *mtime = stats.st_mtimest_mtim.tv_sec;
2974 return 1;
2975}
2976
2977#if defined(__MINGW32__) || defined(_MSC_VER)
2978
2979int SystemImpl__alarm(int seconds)
2980{
2981 return alarm(seconds);
2982}
2983
2984#else
2985
2986static int default_alarm_action_set = 0;
2987static struct sigaction default_alarm_action;
2988
2989static void alarm_handler(int signo, siginfo_t *si, void *ptr)
2990{
2991 assert(signo == SIGALRM)((void) sizeof ((signo == 14) ? 1 : 0), __extension__ ({ if (
signo == 14) ; else __assert_fail ("signo == SIGALRM", "./systemimpl.c"
, 2991, __extension__ __PRETTY_FUNCTION__); }))
;
2992 kill(-getpid(), SIGALRM14);
2993 sigaction(SIGALRM14, &default_alarm_action, 0);
2994}
2995
2996int SystemImpl__alarm(int seconds)
2997{
2998 if (default_alarm_action_set == 0) {
2999 struct sigaction sa = {
3000 .sa_sigaction__sigaction_handler.sa_sigaction = alarm_handler,
3001 .sa_flags = SA_SIGINFO4
3002 };
3003 sigaction(SIGALRM14, &sa, NULL((void*)0));
3004 default_alarm_action_set = 1;
3005 }
3006 return alarm(seconds);
3007}
3008
3009#endif
3010
3011int SystemImpl__covertTextFileToCLiteral(const char *textFile, const char *outFile, const char* target)
3012{
3013 FILE *fin;
3014 FILE *fout = NULL((void*)0);
3015 int result = 0, n, i, j, k, isMSVC = !strcmp(target, "msvc");
3016 char buffer[512];
3017 char obuffer[1024];
3018 fin = fopen(textFile, "r");
3019 if (!fin) {
3020 goto done;
3021 }
3022 errno(*__errno_location ()) = 0;
3023#if defined(__APPLE_CC__)||defined(__MINGW32__)||defined(__MINGW64__)
3024 unlink(outFile);
3025#endif
3026 fout = fopen(outFile, "w");
3027 if (!fout) {
3028 const char *c_token[1]={strerror(errno(*__errno_location ()))};
3029 c_add_message(NULL((void*)0),85,
3030 ErrorType_scripting,
3031 ErrorLevel_error,
3032 gettext("SystemImpl__covertTextFileToCLiteral failed: %s. Maybe the total file name is too long.")dcgettext (((void*)0), "SystemImpl__covertTextFileToCLiteral failed: %s. Maybe the total file name is too long."
, 5)
,
3033 c_token,
3034 1);
3035 goto done;
3036 }
3037
3038 if (isMSVC) /* handle joke compilers */
3039 {
3040 fputc('{', fout);
3041 fputc('\n', fout);
3042 do {
3043 n = fread(buffer,1,511,fin);
3044 j = 0;
Value stored to 'j' is never read
3045 /* adrpo: encode each char */
3046 for (i=0; i<n; i++) {
3047 fputc('\'', fout);
3048
3049 switch (buffer[i]) {
3050 case '\n':
3051 fputc('\\', fout);
3052 fputc('n', fout);
3053 break;
3054 case '\r':
3055 fputc('\\', fout);
3056 fputc('r', fout);
3057 break;
3058 case '\\':
3059 fputc('\\', fout);
3060 fputc('\\', fout);
3061 break;
3062 case '"':
3063 fputc('\\', fout);
3064 fputc('\"', fout);
3065 break;
3066 case '\'':
3067 fputc('\\', fout);
3068 fputc('\'', fout);
3069 break;
3070 default:
3071 fputc(buffer[i], fout);
3072 }
3073 fputc('\'', fout);
3074 fputc(',', fout);
3075 }
3076 fputc('\n', fout);
3077 } while (!feof(fin));
3078
3079 fputc('\'', fout); fputc('\\', fout); fputc('0', fout); fputc('\'', fout); fputc('\n', fout);
3080 fputc('}', fout);
3081 }
3082 else /* handle real compilers */
3083 {
3084 fputc('\"', fout);
3085 do {
3086 n = fread(buffer,1,511,fin);
3087 j = 0;
3088 for (i=0; i<n; i++) {
3089 switch (buffer[i]) {
3090 case '\n':
3091 obuffer[j++] = '\\';
3092 obuffer[j++] = 'n';
3093 break;
3094 case '\r':
3095 obuffer[j++] = '\\';
3096 obuffer[j++] = 'r';
3097 break;
3098 case '\\':
3099 obuffer[j++] = '\\';
3100 obuffer[j++] = '\\';
3101 break;
3102 case '"':
3103 obuffer[j++] = '\\';
3104 obuffer[j++] = '"';
3105 break;
3106 default:
3107 obuffer[j++] = buffer[i];
3108 }
3109 }
3110 if (j!=fwrite(obuffer,1,j,fout)) {
3111 fprintf(stderrstderr, "failed to write\n");
3112 return 1;
3113 }
3114 } while (!feof(fin));
3115 fputc('\"', fout);
3116 }
3117
3118 result = 1;
3119
3120done:
3121 if (fin) {
3122 fclose(fin);
3123 }
3124 if (fout) {
3125 fclose(fout);
3126 }
3127 return result;
3128}
3129
3130void SystemImpl__dladdr(void *symbol, const char **file, const char **name)
3131{
3132#if defined(_MSC_VER)
3133 *file = "dladdr failed";
3134 *name = "not available on Windows";
3135#else /* mingw & Linux */
3136 Dl_info info;
3137 void *ptr = (MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(symbol), 1))(*(void**)(((void*)((void**)(((void*)((char*)(symbol) - 3))) +
(1)))))
);
3138 if (0 == dladdr(ptr, &info)) {
3139 *file = "dladdr failed";
3140 *name = "";
3141 } else {
3142 *file = info.dli_fname ? omc_alloc_interface.malloc_strdup(info.dli_fname) : "(null)";
3143 *name = info.dli_sname ? omc_alloc_interface.malloc_strdup(info.dli_sname) : "(null)";
3144 }
3145#endif
3146}
3147
3148const char* SystemImpl__createTemporaryDirectory(const char *templatePrefix)
3149{
3150 char *template = (char*) omc_alloc_interface.malloc_atomic(strlen(templatePrefix) + 7);
3151 const char *c_tokens[2];
3152 sprintf(template, "%sXXXXXX", templatePrefix);
3153 if (template==mkdtemp(template)) {
3154 return template;
3155 }
3156 GC_free(template);
3157 c_tokens[0]=strerror(errno(*__errno_location ()));
3158 c_tokens[1]=templatePrefix;
3159 c_add_message(NULL((void*)0),85, /* ERROR_OPENING_FILE */
3160 ErrorType_scripting,
3161 ErrorLevel_error,
3162 gettext("Error creating temporary directory %s: %s.")dcgettext (((void*)0), "Error creating temporary directory %s: %s."
, 5)
,
3163 c_tokens,
3164 2);
3165 MMC_THROW(){longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key
))->mmc_jumper,1);}
;
3166}
3167
3168#if defined(OMC_GENERATE_RELOCATABLE_CODE)
3169static void addDLError(const char *msg, const char *fileName)
3170{
3171 const char *err[2] = {dlerror(),fileName};
3172 c_add_message(NULL((void*)0), 85,
3173 ErrorType_scripting,
3174 ErrorLevel_error,
3175 msg,
3176 err,
3177 2
3178 );
3179}
3180
3181int SystemImpl__relocateFunctions(const char *fileName, void *names)
3182{
3183 void *localHandle,*remoteHandle;
3184 remoteHandle = dlopen(fileName, RTLD_NOW0x00002 | RTLD_GLOBAL0x00100 | RTLD_NODELETE0x01000);
3185 if (!remoteHandle) {
3186 addDLError(gettext("Error opening library %s: %s.")dcgettext (((void*)0), "Error opening library %s: %s.", 5), fileName);
3187 return 0;
3188 }
3189 localHandle = dlopen(NULL((void*)0), RTLD_NOW0x00002);
3190 if (!localHandle) {
3191 addDLError(gettext("Error opening library %s: %s.")dcgettext (((void*)0), "Error opening library %s: %s.", 5), fileName);
3192 return 0;
3193 }
3194 int length = listLength(names);
3195 void **localSyms[length], *remoteSyms[length];
3196 for (int i=0; i<length; i++) {
3197 void *tpl = MMC_CAR(names)(*(void**)(((void*)((void**)(((void*)((char*)(names) - 3))) +
(1)))))
;
3198 const char *local = MMC_STRINGDATA(MMC_CAR(tpl))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(tpl) - 3))) + (1)))))) - 3)))->data)
;
3199 const char *remote = MMC_STRINGDATA(MMC_CDR(tpl))(((struct mmc_string*)((void*)((char*)((*(void**)(((void*)((void
**)(((void*)((char*)(tpl) - 3))) + (2)))))) - 3)))->data)
;
3200
3201 remoteSyms[i] = dlsym(remoteHandle, remote);
3202 if (remoteSyms[i]==0) {
3203 addDLError(gettext("Error opening library %s: %s.")dcgettext (((void*)0), "Error opening library %s: %s.", 5), fileName);
3204 }
3205 localSyms[i] = (void**) dlsym(localHandle, local);
3206 if (localSyms[i]==0) {
3207 addDLError(gettext("Error opening library %s: %s.")dcgettext (((void*)0), "Error opening library %s: %s.", 5), fileName);
3208 }
3209
3210 names = MMC_CDR(names)(*(void**)(((void*)((void**)(((void*)((char*)(names) - 3))) +
(2)))))
;
3211 }
3212 /* All loaded fine. Now relocate all the symbols. */
3213 for (int i=0; i<length; i++) {
3214 *localSyms[i] = remoteSyms[i];
3215 }
3216 return 1;
3217}
3218#else
3219int SystemImpl__relocateFunctions(const char *fileName, void *names)
3220{
3221 c_add_message(NULL((void*)0), 85,
3222 ErrorType_scripting,
3223 ErrorLevel_error,
3224 gettext("OMC not compiled with support for relocatable functions.")dcgettext (((void*)0), "OMC not compiled with support for relocatable functions."
, 5)
,
3225 NULL((void*)0),
3226 0
3227 );
3228 return 0;
3229}
3230#endif
3231
3232#ifdef __cplusplus
3233}
3234#endif