root/branches/maintenance/2.2.2/Modelica/C-Sources/ModelicaInternal.c

Revision 324, 24.6 kB (checked in by Christian, 3 years ago)

Updated copyright to 2006

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* External utility functions for Modelica packages
2   Modelica_Utilities.Internal
3
4   The functions are mostly non-portable. The following #define's are used
5   to define the system calls of the operating system
6 
7    _WIN32        : System calls of Windows'95, Windows'NT
8                    (Note, that these system calls allow both '/' and '\'
9                    as directory separator for input arguments. As return
10                    argument '\' is used).
11                    All system calls are from the library libc.a.
12    _POSIX_       : System calls of POSIX
13    _MSC_VER      : Microsoft Visual C++
14    __GNUC__      : GNU C compiler
15    NO_FILE_SYSTEM: A file system is not present (e.g. on dSpace or xPC).
16   
17     
18    Release Notes:
19      Sept. 26, 2004: by Martin Otter, DLR.
20        Added missing implementations, merged code from previous ModelicaFiles
21        and clean-up of code.
22
23      Sep.  9, 2004: by Dag Bruck, Dynasim AB.
24        Further implementation and clean-up of code.
25
26      Aug. 24, 2004: by Martin Otter, DLR.
27        Adapted to Dymola 5.3 with minor improvements.
28       
29      Jan.  7, 2002: by Martin Otter, DLR.
30        First version implemented.
31        Only tested for _WIN32, but implemented all
32        functions also for _POSIX_, with the exception of
33        ModelicaInternal_getFullPath
34         
35           
36    Copyright (C) 2002-2006, Modelica Association and DLR.
37             
38    The content of this file is free software; it can be redistributed
39    and/or modified under the terms of the Modelica license, see the
40    license conditions and the accompanying disclaimer in file
41    _ModelicaLicense.txt or in Modelica.UsersGuide.ModelicaLicense.
42
43*/
44
45#if defined(linux)
46#define _POSIX_ 1
47#endif
48
49#include <string.h>
50#include "ModelicaUtilities.h"
51
52static void ModelicaNotExistError(const char* name) {
53   /* Print error message if a function is not implemented */
54   ModelicaFormatError("C-Function \"%s\" is called\n" 
55                       "but is not implemented for the actual environment\n"
56                       "(e.g., because there is no file system available on the machine\n"
57                       "as for dSpace or xPC systems)", name); 
58}
59
60#if NO_FILE_SYSTEM
61  static void ModelicaInternal_mkdir(const char* directoryName) {
62              ModelicaNotExistError("ModelicaInternal_mkdir"); }
63  static void ModelicaInternal_rmdir(const char* directoryName) {
64              ModelicaNotExistError("ModelicaInternal_rmdir"); }
65  static int  ModelicaInternal_stat(const char* name) {
66              ModelicaNotExistError("ModelicaInternal_stat"); return 0; }
67  static void ModelicaInternal_rename(const char* oldName, const char* newName)  {
68              ModelicaNotExistError("ModelicaInternal_rename"); }
69  static void ModelicaInternal_removeFile(const char* file) {
70              ModelicaNotExistError("ModelicaInternal_removeFile"); }
71  static void ModelicaInternal_copyFile(const char* oldFile, const char* newFile) {
72              ModelicaNotExistError("ModelicaInternal_copyFile"); }
73  static void ModelicaInternal_readDirectory(const char* directory, int nFiles, const char* files[]) {
74              ModelicaNotExistError("ModelicaInternal_readDirectory"); }
75  static int  ModelicaInternal_getNumberOfFiles(const char* directory) {
76              ModelicaNotExistError("ModelicaInternal_getNumberOfFiles"); return 0; }
77  static const char* ModelicaInternal_fullPathName(const char* name) {
78              ModelicaNotExistError("ModelicaInternal_fullPathName"); return 0; }
79  static const char* ModelicaInternal_temporaryFileName() {
80              ModelicaNotExistError("ModelicaInternal_temporaryFileName"); return 0; }
81  static void ModelicaInternal_print(const char* string, const char* fileName) {
82              ModelicaNotExistError("ModelicaInternal_print"); }
83  static int  ModelicaInternal_countLines(const char* fileName) {
84              ModelicaNotExistError("ModelicaInternal_countLines"); return 0; }
85  static void ModelicaInternal_readFile(const char* fileName, const char* string[], size_t nLines) {
86              ModelicaNotExistError("ModelicaInternal_readFile"); }
87  static const char* ModelicaInternal_readLine(const char* fileName, int lineNumber, int* endOfFile) {
88              ModelicaNotExistError("ModelicaInternal_readLine"); return 0; }
89  static void ModelicaInternal_chdir(const char* directoryName) {
90              ModelicaNotExistError("ModelicaInternal_chdir"); }
91  static const char* ModelicaInternal_getcwd(int dummy) {
92              ModelicaNotExistError("ModelicaInternal_getcwd"); return 0; }
93  static const char* ModelicaInternal_getenv(const char* name, int convertToSlash, int* exist) {
94              ModelicaNotExistError("ModelicaInternal_getenv"); return 0; }
95  static void ModelicaInternal_setenv(const char* name, const char* value, int convertFromSlash) {
96              ModelicaNotExistError("ModelicaInternal_setenv"); }
97#else
98
99#  include <stdio.h>
100#  include <stdlib.h>
101#  include <errno.h>
102
103#  if defined(__WATCOMC__)
104#     include <direct.h>
105#     include <sys/types.h>
106#     include <sys/stat.h>
107#  elif defined(_WIN32)
108#     include <direct.h>
109#     include <sys/types.h>
110#     include <sys/stat.h>
111
112      /* include the opendir/readdir/closedir implementation for _WIN32 */
113#     include "win32_dirent.c"
114#  elif defined(_POSIX_)
115#     include <dirent.h>
116#     include <unistd.h>
117#     include <sys/types.h>
118#     include <sys/stat.h>
119#     include <dirent.h>
120#  endif
121
122#define BUFFER_LENGTH 1000
123static char buffer[BUFFER_LENGTH];  /* Buffer for temporary storage */
124
125typedef enum {
126   FileType_NoFile = 1,
127   FileType_RegularFile,
128   FileType_Directory,
129   FileType_SpecialFile   /* pipe, FIFO, device, etc. */
130} ModelicaFileType;
131
132
133
134/* Convert to Unix directory separators: */
135#if defined(_WIN32)
136   static void ModelicaConvertToUnixDirectorySeparator(char* string) {
137      /* convert to Unix directory separators */
138      char* c = string;
139      while ( *c ) {
140         if ( *c == '\\' )  {*c = '/';}
141         c++;
142      }
143   };
144
145   static void ModelicaConvertFromUnixDirectorySeparator(char* string) {
146      /* convert from Unix directory separators */
147      char* c = string;
148      while ( *c ) {
149         if ( *c == '/' )  {*c = '\\';}
150         c++;
151      }
152   };
153#else
154#  define ModelicaConvertToUnixDirectorySeparator(string) ;
155#  define ModelicaConvertFromUnixDirectorySeparator(string) ;
156#endif
157
158
159/* --------------------- Modelica_Utilities.Internal --------------------------------- */
160
161static void ModelicaInternal_mkdir(const char* directoryName)
162{
163    /* Create directory */
164       
165#if defined(_WIN32)
166    int result = _mkdir(directoryName);
167#elif defined(_POSIX_)
168    int result = mkdir(directoryName, S_IRUSR | S_IWUSR | S_IXUSR);
169#else
170    int result = -1;
171    ModelicaNotExistError("ModelicaInternal_mkdir");
172#endif
173   
174    if (result != 0) {
175        ModelicaFormatError("Not possible to create new directory\n"
176            "\"%s\":\n%s", directoryName, strerror(errno));
177    }
178}
179
180
181static void ModelicaInternal_rmdir(const char* directoryName)
182{
183#if defined(__WATCOMC__)
184    int result = rmdir(directoryName);
185#elif defined(_WIN32) && !defined(SimStruct)
186    int result = _rmdir(directoryName);
187#elif defined(_POSIX_)
188    int result = rmdir(directoryName);
189#else
190    int result = -1;
191    ModelicaNotExistError("ModelicaInternal_rmdir");
192#endif
193   
194    if (result != 0) {
195        ModelicaFormatError("Not possible to remove directory\n"
196            "\"%s\":\n%s", directoryName, strerror(errno));
197    }
198}
199
200
201static int ModelicaInternal_stat(const char* name)
202{
203    /* Inquire type of file */
204    ModelicaFileType type = FileType_NoFile;
205   
206#if defined(_WIN32) && defined(_MSC_VER)
207    struct _stat fileInfo;
208    if ( _stat(name, &fileInfo) != 0 ) {
209        type = FileType_NoFile;
210    } else if ( fileInfo.st_mode & S_IFREG ) {
211        type = FileType_RegularFile;
212    } else if ( fileInfo.st_mode & S_IFDIR ) {
213        type = FileType_Directory;
214    } else {
215        type = FileType_SpecialFile;
216    }
217#elif defined(_POSIX_) || defined(__GNUC__)
218    struct stat fileInfo;
219    if ( stat(name, &fileInfo) != 0 ) {
220        type = FileType_NoFile;
221    } else if ( S_ISREG(fileInfo.st_mode) ) {
222        type = FileType_RegularFile;
223    } else if ( S_ISDIR(fileInfo.st_mode) ) {
224        type = FileType_Directory;
225    } else {
226        type = FileType_SpecialFile;
227    }
228#else
229    ModelicaNotExistError("ModelicaInternal_stat");
230#endif
231    return type;
232}
233
234
235
236static void ModelicaInternal_rename(const char* oldName, const char* newName) {
237   /* Changes the name of a file or of a directory */
238
239   if ( rename(oldName, newName) != 0 ) {
240      ModelicaFormatError("renaming \"%s\" to \"%s\" failed:\n%s",
241                    oldName, newName, strerror(errno));
242   }
243}
244
245
246static void ModelicaInternal_removeFile(const char* file) {
247  /* Remove file. */
248  if ( remove(file) != 0 ) {
249     ModelicaFormatError("Not possible to remove file \"%s\":\n%s",
250                   file, strerror(errno));
251  }
252}
253
254
255
256static void ModelicaInternal_copyFile(const char* oldFile, const char* newFile) {
257  /* Copy file */
258     #ifdef _WIN32
259        const char* modeOld = "rb";
260        const char* modeNew = "wb";
261     #else
262        const char* modeOld = "r";
263        const char* modeNew = "w";
264     #endif
265     FILE* fpOld;
266     FILE* fpNew;
267     ModelicaFileType type;
268     int c;
269
270  /* Check file existence */
271     type = (ModelicaFileType) ModelicaInternal_stat(oldFile);
272     if ( type == FileType_NoFile ) {
273        ModelicaFormatError("\"%s\" cannot be copied\nbecause it does not exist", oldFile);
274        return;
275     } else if ( type == FileType_Directory ) {
276        ModelicaFormatError("\"%s\" cannot be copied\nbecause it is a directory", oldFile);
277        return;
278     } else if ( type == FileType_SpecialFile ) {
279        ModelicaFormatError("\"%s\" cannot be copied\n"
280                      "because it is not a regular file", oldFile);
281        return;
282     }
283     type = (ModelicaFileType) ModelicaInternal_stat(newFile);
284     if ( type != FileType_NoFile ) {
285        ModelicaFormatError("\"%s\" cannot be copied\nbecause the target "
286                      "\"%s\" exists", oldFile, newFile);
287        return;
288     }
289
290  /* Copy file */
291     fpOld = fopen(oldFile, modeOld);
292     if ( fpOld == NULL ) {
293        ModelicaFormatError("\"%s\" cannot be copied:\n%s", oldFile, strerror(errno));
294        return;
295     }
296     fpNew = fopen(newFile, modeNew);
297     if ( fpNew == NULL ) {
298        fclose(fpOld);
299        ModelicaFormatError("\"%s\" cannot be copied to \"%s\":\n%s",
300                      oldFile, newFile, strerror(errno));
301        return;
302     }
303     while ( (c = getc(fpOld)) != EOF ) putc(c, fpNew);
304     fclose(fpOld);
305     fclose(fpNew);
306}
307
308
309static void ModelicaInternal_readDirectory(const char* directory, int nFiles, 
310                                           const char** files) {
311  /* Get all file and directory names in a directory in any order
312     (must be very careful, to call closedir if an error occurs)
313  */
314  #if defined(_WIN32) || defined(_POSIX_)
315     int errnoTemp;
316     int iFiles  = 0;
317     char *pName;
318     struct dirent *pinfo;
319     DIR* pdir;
320
321     /* Open directory information inquiry */
322        pdir = opendir(directory);
323        if ( pdir == NULL ) {
324           ModelicaFormatError("1: Not possible to get file names of \"%s\":\n%s",
325                         directory, strerror(errno));
326        }
327
328     /* Read file and directory names and store them in vector "files" */
329     errno = 0;
330     while ( (pinfo = readdir(pdir)) != NULL ) {
331        if ( (strcmp(pinfo->d_name, "." ) != 0) &&
332             (strcmp(pinfo->d_name, "..") != 0) ) {
333           /* Check if enough space in "files" vector */
334              if ( iFiles >= nFiles ) {
335                closedir(pdir);
336                ModelicaFormatError("Not possible to get file names of \"%s\":\n"
337                              "More files in this directory as reported by nFiles (= %i)",
338                              directory, nFiles);
339              }
340
341           /* Allocate Modelica memory for file/directory name and copy name */
342              pName = ModelicaAllocateStringWithErrorReturn(strlen(pinfo->d_name));
343              if ( pName == NULL ) {
344                errnoTemp = errno;
345                closedir(pdir);
346                if ( errnoTemp == 0 ) {
347                   ModelicaFormatError("Not possible to get file names of \"%s\":\n"
348                                 "Not enough storage", directory);
349                } else {
350                   ModelicaFormatError("Not possible to get file names of \"%s\":\n%s",
351                                 directory, strerror(errnoTemp));
352                }
353              }
354              strcpy(pName, pinfo->d_name);
355
356           /* Save pointer to file */
357              files[iFiles] = pName;
358              iFiles++;
359        };
360     };
361
362     if ( errno != 0 ) {
363        errnoTemp = errno;
364        closedir(pdir);
365        ModelicaFormatError("Not possible to get file names of \"%s\":\n%s",
366                      directory, strerror(errnoTemp));
367     }
368
369
370     /* Check, whether the whole "files" vector is filled and close inquiry */
371        if ( iFiles != nFiles) {
372           closedir(pdir);
373           ModelicaFormatError("Not possible to get file names of \"%s\":\n"
374                         "Less files (= %d) found as defined by argument nNames (= %d)",
375                         directory, iFiles, nFiles);
376        }
377
378        if ( closedir(pdir) != 0 ) {
379           ModelicaFormatError("Not possible to get file names of \"%s\":\n",
380                         directory, strerror(errno));
381        }
382
383  #else
384     ModelicaNotExistError("ModelicaInternal_readDirectory");
385  #endif
386};
387
388
389
390static int ModelicaInternal_getNumberOfFiles(const char* directory) {
391    /* Get number of files and directories in a directory */
392   
393#if defined(_WIN32) || defined(_POSIX_)
394    int nFiles = 0;
395    int errnoTemp;
396    struct dirent *pinfo;
397    DIR* pdir;
398       
399    pdir = opendir(directory);
400    if ( pdir == NULL ) goto ERROR;
401    errno = 0;
402    while ( (pinfo = readdir(pdir)) != NULL ) {
403        if ( (strcmp(pinfo->d_name, "." ) != 0) &&
404            (strcmp(pinfo->d_name, "..") != 0) ) {
405            nFiles++;
406        };
407    };
408    errnoTemp = errno;
409    closedir(pdir);
410    if ( errnoTemp != 0 ) {errno = errnoTemp; goto ERROR;}
411
412    return nFiles;
413   
414ERROR: ModelicaFormatError("Not possible to get number of files in \"%s\":\n%s",
415                           directory, strerror(errno));
416       return 0;
417#else
418       ModelicaNotExistError("ModelicaInternal_getNumberOfFiles");
419       return 0;
420#endif
421};
422
423
424/* --------------------- Modelica_Utilities.Files ------------------------------------- */
425
426static const char* ModelicaInternal_fullPathName(const char* name)
427{
428    /* Get full path name of file or directory */
429   
430    char* fullName;
431
432#if defined(_WIN32)
433    char* tempName = _fullpath(buffer, name, sizeof(buffer));
434    if (tempName == NULL) {
435        ModelicaFormatError("Not possible to construct full path name of \"%s\"\n%s",
436            name, strerror(errno));
437        return "";
438    }
439    fullName = ModelicaAllocateString(strlen(tempName));
440    strcpy(fullName, tempName);
441    ModelicaConvertToUnixDirectorySeparator(fullName);
442#else
443    /* No such system call in _POSIX_ available */
444    char* cwd = getcwd(buffer, sizeof(buffer));
445    if (cwd == NULL) {
446        ModelicaFormatError("Not possible to get current working directory:\n%s",
447            strerror(errno));
448    }
449    fullName = ModelicaAllocateString(strlen(cwd) + strlen(name) + 1);
450    strcpy(fullName, cwd);
451    strcat(fullName, "/");
452    strcat(fullName, name);
453#endif
454   
455    return fullName;
456}
457
458static const char* ModelicaInternal_temporaryFileName()
459{
460    /* Get full path name of a temporary */
461   
462    char* fullName;
463
464    char* tempName = tmpnam(NULL);
465    if (tempName == NULL) {
466        ModelicaFormatError("Not possible to get temporary filename\n%s", strerror(errno));
467        return "";
468    }
469    fullName = ModelicaAllocateString(strlen(tempName));
470    strcpy(fullName, tempName);
471    ModelicaConvertToUnixDirectorySeparator(fullName);
472   
473    return fullName;
474}
475
476
477
478/* --------------------- Abstract data type for stream handles --------------------- */
479
480/* Needs to be improved for cashing of the open files */
481
482static FILE* ModelicaStreams_openFileForReading(const char* fileName) {
483   /* Open text file for reading */
484      FILE* fp;
485
486   /* Open file */
487      fp = fopen(fileName, "r");
488      if ( fp == NULL ) {
489         ModelicaFormatError("Not possible to open file \"%s\" for reading:\n"
490                             "%s\n", fileName, strerror(errno));
491      }
492      return fp;
493}
494
495
496static FILE* ModelicaStreams_openFileForWriting(const char* fileName) {
497   /* Open text file for writing (with append) */
498      FILE* fp;
499   
500   /* Check fileName */
501      if ( strlen(fileName) == 0 ) {
502         ModelicaError("fileName is an empty string.\n"
503                       "Opening of file is aborted\n");
504      }
505
506   /* Open file */
507      fp = fopen(fileName, "a");
508      if ( fp == NULL ) {
509         ModelicaFormatError("Not possible to open file \"%s\" for writing:\n"
510                             "%s\n", fileName, strerror(errno));
511      }
512      return fp;
513}
514
515static void ModelicaStreams_closeFile(const char* fileName) {
516   /* close file */
517}
518
519
520/* --------------------- Modelica_Utilities.Streams ----------------------------------- */
521
522static void ModelicaInternal_print(const char* string, const char* fileName) {
523  /* Write string to terminal or to file */
524
525     if ( fileName[0] == '\0' ) {
526        /* Write string to terminal */
527           ModelicaMessage(string);
528     } else {
529        /* Write string to file */
530           FILE* fp = ModelicaStreams_openFileForWriting(fileName);
531           if ( fputs(string,fp) < 0 ) goto ERROR;
532           if ( fputs("\n",fp)   < 0 ) goto ERROR;
533           fclose(fp);
534           return;
535
536           ERROR: fclose(fp);
537                  ModelicaFormatError("Error when writing string to file \"%s\":\n"
538                                      "%s\n", fileName, strerror(errno));
539     }
540}
541
542
543static int ModelicaInternal_countLines(const char* fileName)
544/* Get number of lines of a file */
545{
546    int c;
547    int nLines = 0;
548    int start_of_line = 1;
549    /* If true, next character starts a new line. */
550   
551    FILE* fp = ModelicaStreams_openFileForReading(fileName); 
552   
553    /* Count number of lines */
554    while ((c = fgetc(fp)) != EOF) {
555        if (start_of_line) {
556            nLines++;
557            start_of_line = 0;
558        }
559        if (c == '\n') start_of_line = 1;
560    }
561    fclose(fp);
562    return nLines;
563}
564
565static void ModelicaInternal_readFile(const char* fileName, const char* string[], size_t nLines) {
566  /* Read file into string vector string[nLines] */
567     FILE* fp = ModelicaStreams_openFileForReading(fileName);
568     char*  line;
569     int    c;
570     size_t lineLen;
571     size_t iLines;
572     long   offset;
573     size_t nc;
574
575  /* Read data from file */
576     iLines = 1;
577     while ( iLines <= nLines ) {
578        /* Determine length of next line */
579           offset  = ftell(fp);
580           lineLen = 0;
581           c = fgetc(fp);
582           while ( c != '\n' && c != EOF ) {
583              lineLen++;
584              c = fgetc(fp);
585           }
586           
587        /* Allocate storage for next line */
588           line = ModelicaAllocateStringWithErrorReturn(lineLen);
589           if ( line == NULL ) {
590              fclose(fp);
591              ModelicaFormatError("Not enough memory to allocate string for reading line %i from file\n"
592                                  "\"%s\".\n"
593                                  "(this file contains %i lines)\n", iLines, fileName, nLines);
594           }
595
596        /* Read next line */
597           if ( fseek(fp, offset, SEEK_SET != 0) ) {
598              fclose(fp);
599              ModelicaFormatError("Error when reading line %i from file\n\"%s\":\n"
600                                  "%s\n", iLines, fileName, strerror(errno));
601           };
602           nc = ( iLines < nLines ? lineLen+1 : lineLen);
603           if ( fread(line, sizeof(char), nc, fp) != nc ) {
604              fclose(fp);
605              ModelicaFormatError("Error when reading line %i from file\n\"%s\"\n",
606                                  iLines, fileName);
607           };
608           line[lineLen] = '\0';
609           string[iLines-1] = line;
610           iLines++;
611     }
612     fclose(fp);
613}
614
615
616static const char* ModelicaInternal_readLine(const char* fileName, int lineNumber, int* endOfFile) {
617  /* Read line lineNumber from file fileName */
618     FILE* fp = ModelicaStreams_openFileForReading(fileName);
619     char*  line;
620     int    c;
621     size_t lineLen;
622     size_t iLines;
623     long   offset;
624
625  /* Read upto line lineNumber-1 */
626     iLines = 0;
627     c = 1;
628     while ( iLines != (size_t) lineNumber-1 && c != EOF ) {
629        c = fgetc(fp);
630        while ( c != '\n' && c != EOF ) {
631           c = fgetc(fp);
632        }
633        iLines++;
634     }
635     if ( iLines != (size_t) lineNumber-1 ) goto END_OF_FILE;
636
637  /* Determine length of line lineNumber */
638     offset  = ftell(fp);
639     lineLen = 0;
640     c = fgetc(fp);
641     while ( c != '\n' && c != EOF ) {
642        lineLen++;
643        c = fgetc(fp);
644     }
645     if ( lineLen == 0 && c == EOF ) goto END_OF_FILE;
646
647  /* Read line lineNumber */
648     line = ModelicaAllocateStringWithErrorReturn(lineLen);
649     if ( line == NULL ) goto ERROR;
650     if ( fseek(fp, offset, SEEK_SET != 0) ) goto ERROR;
651     if ( fread(line, sizeof(char), lineLen, fp) != lineLen ) goto ERROR;
652     fclose(fp);
653     line[lineLen] = '\0';
654     *endOfFile = 0;
655     return line;
656
657  /* End-of-File or error */
658     END_OF_FILE: fclose(fp);
659                  *endOfFile = 1;
660                  line = ModelicaAllocateString(0);
661                  return line;
662
663     ERROR      : fclose(fp);
664                  ModelicaFormatError("Error when reading line %i from file\n\"%s\":\n%s",
665                                      lineNumber, fileName, strerror(errno));
666                  return "";
667}
668
669
670/* --------------------- Modelica_Utilities.System ------------------------------------ */
671
672static void ModelicaInternal_chdir(const char* directoryName)
673{
674/* Change current working directory. */
675#if defined(__WATCOMC__)
676    int result = chdir(directoryName);
677#elif defined(_WIN32) && !defined(SimStruct)
678    int result = _chdir(directoryName);
679#elif defined(_POSIX_)
680    int result = chdir(directoryName);
681#else
682    int result = -1;
683    ModelicaNotExistError("ModelicaInternal_chdir");
684#endif
685
686    if (result != 0) {
687        ModelicaFormatError("Not possible to change current working directory to\n"
688            "\"%s\":\n%s", directoryName, strerror(errno));
689    }
690}
691
692
693static const char* ModelicaInternal_getcwd(int dummy)
694{
695    const char* cwd;
696    char* directory;
697   
698#if defined(_WIN32)
699    cwd = _getcwd(buffer, sizeof(buffer));
700#elif defined(_POSIX_)
701    cwd = getcwd(buffer, sizeof(buffer));
702#else
703    ModelicaNotExistError("ModelicaInternal_getcwd");
704    cwd = "";
705#endif
706   
707    if (cwd == NULL) {
708        ModelicaFormatError("Not possible to get current working directory:\n%s",
709            strerror(errno));
710        cwd = "";
711    }
712   
713    directory = ModelicaAllocateString(strlen(cwd));
714    strcpy(directory, cwd);
715    ModelicaConvertToUnixDirectorySeparator(directory);
716    return directory;
717}
718
719
720static const char* ModelicaInternal_getenv