root/branches/maintenance/2.2.2/Modelica/Utilities/Files.mo

Revision 573, 26.8 kB (checked in by otter, 15 months ago)

Fixed about 200 link errors in the generated html file. Reasons:
- "Hierarchical" classes in UsersGuides have been defined with "class"

and not with "package", but Dymola generates sub-hierarchies only
for "packages". Fixed this by renaming the corresponding classes to
"package".

- If a link is included in bold, e.g. <b><a href ....>...</a></b>,

Dymola does not translate the Modelica link in a html link.
Fixed this by removing the bold-type.

- There had been several errors in the link definition

(e.g. href=Modelica:Modelica..). Fixed them all.

- The link Modelica://Modelica.Blocks.Examples.BusUsage_Utilities.Interfaces.Internal

was not transformed because no documentation for "Internal" was generated.
It seems useful to not generate documentation for a class called "Internal".
On the other hand, for buses, it seems useful to have the documentation.
Fixed this by renaming "Internal" to "InternalConnectors".

There are the following remaining link errors:

Modelica://Modelica_Fluid.Interfaces
Modelica://Modelica_Fluid.Utilities.PipeFriction
Modelica://Magnetic.Interfaces
Modelica://HyLibLight.Interfaces
Modelica://PneuLibLight.Interfaces
Modelica://ModelicaReference.Operators.SemiLinear
Modelica://ModelicaReference.Operators.string

i.e., links to other libraries. Probably, one cannot do much and
it seems o.k. to have these errors.

Additionally, "versionBuild" (of subversion) was included as top level
annotations. Should be updated, for the release.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1within Modelica.Utilities;
2package Files "Functions to work with files and directories" 
3function list "List content of file or directory" 
4  extends Modelica.Icons.Function;
5  input String name
6      "If name is a directory, list directory content. If it is a file, list the file content";
7//..............................................................
8  protected 
9encapsulated package Local "Local utility functions" 
10      import Modelica.Utilities.*;
11      import Modelica.Utilities.Internal;
12     
13  function listFile "List content of file" 
14     input String name;
15      protected 
16     String file[Streams.countLines(name)] =  Streams.readFile(name);
17  algorithm 
18     for i in 1:min(size(file,1), 100) loop
19        Streams.print(file[i]);
20     end for;
21  end listFile;
22     
23  function sortDirectory
24        "Sort directory in directories and files with alphabetic order" 
25     input String directory
26          "Directory that was read (including a trailing '/')";
27     input String names[:] 
28          "File and directory names of a directory in any order";
29     output String orderedNames[size(names,1)] 
30          "Names of directories followed by names of files";
31     output Integer nDirectories
32          "The first nDirectories entries in orderedNames are directories";
33      protected 
34     Integer nEntries = size(names,1);
35     Integer nFiles;
36     Integer lenDirectory = Strings.length(directory);
37     String directory2;
38  algorithm 
39     // Construct directory with a trailing "/"
40     directory2 := if Strings.substring(directory,lenDirectory,lenDirectory) == "/" then 
41                      directory else directory + "/";
42       
43     // Distinguish directories and files
44     nDirectories := 0;
45     nFiles := 0;
46     for i in 1:nEntries loop
47        if Internal.stat(directory2 + names[i]) == Types.FileType.Directory then
48           nDirectories := nDirectories + 1;
49           orderedNames[nDirectories] := names[i];
50        else
51           nFiles := nFiles + 1;
52           orderedNames[nEntries - nFiles + 1] := names[i];
53        end if;
54     end for;
55       
56     // Sort files and directories alphabetically
57     if nDirectories > 0 then
58        orderedNames[1:nDirectories] := Strings.sort(orderedNames[1:nDirectories], caseSensitive=false);
59     end if;
60     if nFiles > 0 then
61        orderedNames[nDirectories+1:nEntries] :=
62                Strings.sort(orderedNames[nDirectories+1:nEntries], caseSensitive=false);
63     end if;
64  end sortDirectory;
65     
66  function listDirectory "List content of directory" 
67     input String directoryName;
68     input Integer nEntries;
69      protected 
70     String files[nEntries];
71     Integer nDirectories;
72  algorithm 
73     if nEntries > 0 then
74        Streams.print("\nDirectory \"" + directoryName + "\":");
75        files :=  Internal.readDirectory(directoryName, nEntries);
76        (files, nDirectories) := sortDirectory(directoryName, files);
77         
78        // List directories
79        if nDirectories > 0 then
80           Streams.print("  Subdirectories:");
81           for i in 1:nDirectories loop
82              Streams.print("    " + files[i]);
83           end for;
84           Streams.print(" ");
85        end if;
86         
87        // List files
88        if nDirectories < nEntries then
89           Streams.print("  Files:");
90           for i in nDirectories+1:nEntries loop
91              Streams.print("    " + files[i]);
92           end for;
93        end if;
94     else
95        Streams.print("... Directory\"" + directoryName + "\" is empty");
96     end if;
97  end listDirectory;
98end Local;
99   
100//..............................................................
101   
102  Types.FileType.Type fileType;
103algorithm 
104  fileType := Internal.stat(name);
105  if fileType == Types.FileType.RegularFile then
106     Local.listFile(name);
107  elseif fileType == Types.FileType.Directory then
108     Local.listDirectory(name, Internal.getNumberOfFiles(name));
109  elseif fileType == Types.FileType.SpecialFile then
110     Streams.error("Cannot list file \"" + name + "\"\n" +
111                   "since it is not a regular file (pipe, device, ...)");
112  else
113     Streams.error("Cannot list file or directory \"" + name + "\"\n" +
114                   "since it does not exist");
115  end if;
116  annotation (preferedView="info",Documentation(info="<html>
117<h4>Syntax</h4>
118<blockquote><pre>
119Files.<b>list</b>(name);
120</pre></blockquote>
121<h4>Description</h4>
122<p>
123If \"name\" is a regular file, the content of the
124file is printed.
125</p>
126<p>
127If \"name\" is a directory, the directory and file names
128in the \"name\" directory are printed in sorted order.
129</p>
130</html>"));
131end list;
132  extends Modelica.Icons.Library;
133    annotation (
134  version="0.8",
135  versionDate="2004-08-24",
136  preferedView="info",
137Documentation(info="<HTML>
138<p>
139This package contains functions to work with files and directories.
140As a general convention of this package, '/' is used as directory
141separator both for input and output arguments of all functions.
142For example:
143</p>
144<pre>
145   exist(\"Modelica/Mechanics/Rotational.mo\");
146</pre>
147<p>
148The functions provide the mapping to the directory separator of the
149underlying operating system. Note, that on Windows system the usage
150of '\\' as directory separator would be inconvenient, because this
151character is also the escape character in Modelica and C Strings.
152</p>
153<p>
154In the table below an example call to every function is given:
155</p>
156<table border=1 cellspacing=0 cellpadding=2>
157  <tr><th><b><i>Function/type</i></b></th><th><b><i>Description</i></b></th></tr>
158  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.list\">list</a>(name)</td>
159      <td valign=\"top\"> List content of file or of directory.</td>
160  </tr>
161  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.copy\">copy</a>(oldName, newName)<br>
162          <a href=\"Modelica://Modelica.Utilities.Files.copy\">copy</a>(oldName, newName, replace=false)</td>
163      <td valign=\"top\"> Generate a copy of a file or of a directory.</td>
164  </tr>
165  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.move\">move</a>(oldName, newName)<br>
166          <a href=\"Modelica://Modelica.Utilities.Files.move\">move</a>(oldName, newName, replace=false)</td>
167      <td valign=\"top\"> Move a file or a directory to another place.</td>
168  </tr>
169  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.remove\">remove</a>(name)</td>
170      <td valign=\"top\"> Remove file or directory (ignore call, if it does not exist).</td>
171  </tr>
172  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.removeFile\">removeFile</a>(name)</td>
173      <td valign=\"top\"> Remove file (ignore call, if it does not exist)</td>
174  </tr>
175  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.createDirectory\">createDirectory</a>(name)</td>
176      <td valign=\"top\"> Create directory (if directory already exists, ignore call).</td>
177  </tr>
178  <tr><td valign=\"top\">result = <a href=\"Modelica://Modelica.Utilities.Files.exist\">exist</a>(name)</td>
179      <td valign=\"top\"> Inquire whether file or directory exists.</td>
180  </tr>
181  <tr><td valign=\"top\"><a href=\"Modelica://Modelica.Utilities.Files.assertNew\">assertNew</a>(name,message)</td>
182      <td valign=\"top\"> Trigger an assert, if a file or directory exists.</td>
183  </tr>
184  <tr><td valign=\"top\">fullName = <a href=\"Modelica://Modelica.Utilities.Files.fullPathName\">fullPathName</a>(name)</td>
185      <td valign=\"top\"> Get full path name of file or directory name.</td>
186  </tr>
187  <tr><td valign=\"top\">(directory, name, extension) = <a href=\"Modelica://Modelica.Utilities.Files.splitPathName\">splitPathName</a>(name)</td>
188      <td valign=\"top\"> Split path name in directory, file name kernel, file name extension.</td>
189  </tr>
190  <tr><td valign=\"top\">fileName = <a href=\"Modelica://Modelica.Utilities.Files.temporaryFileName\">temporaryFileName</a>()</td>
191      <td valign=\"top\"> Return arbitrary name of a file that does not exist<br>
192           and is in a directory where access rights allow to <br>
193           write to this file (useful for temporary output of files).</td>
194  </tr>
195</table>
196</HTML>"),
197      Coordsys(
198        extent=[0, 0; 417, 614],
199        grid=[1, 1],
200        component=[20, 20]),
201      Window(
202        x=0.03,
203        y=0.02,
204        width=0.42,
205        height=0.86,
206        library=1,
207        autolayout=1));
208 
209function copy "Generate a copy of a file or of a directory" 
210  extends Modelica.Icons.Function;
211  input String oldName "Name of file or directory to be copied";
212  input String newName "Name of copy of the file or of the directory";
213  input Boolean replace=false 
214      "= true, if an existing file may be replaced by the required copy";
215//..............................................................
216  protected 
217  encapsulated function copyDirectory "Copy a directory" 
218      import Modelica.Utilities.*;
219      import Modelica.Utilities.Internal;
220     input String oldName
221        "Old directory name without trailing '/'; existance is guaranteed";
222     input String newName
223        "New diretory name without trailing '/'; directory was already created";
224     input Boolean replace "= true, if an existing newName may be replaced";
225    protected 
226     Integer nNames = Internal.getNumberOfFiles(oldName);
227     String oldNames[nNames];
228     String oldName_i;
229     String newName_i;
230  algorithm 
231     oldNames :=Internal.readDirectory(oldName, nNames);
232     for i in 1:nNames loop
233        oldName_i := oldName + "/" + oldNames[i];
234        newName_i := newName + "/" + oldNames[i];
235        Files.copy(oldName_i, newName_i, replace);
236     end for;
237  end copyDirectory;
238//..............................................................
239   
240  Integer lenOldName = Strings.length(oldName);
241  Integer lenNewName = Strings.length(newName);
242  String oldName2 = if Strings.substring(oldName,lenOldName,lenOldName) == "/" then 
243                       Strings.substring(oldName,1,lenOldName-1) else oldName;
244  String newName2 = if Strings.substring(newName,lenNewName,lenNewName) == "/" then 
245                       Strings.substring(newName,1,lenNewName-1) else newName;
246  Types.FileType.Type oldFileType = Internal.stat(oldName2);
247  Types.FileType.Type newFileType;
248algorithm 
249  if oldFileType == Types.FileType.NoFile then
250     Streams.error("It is not possible to copy the file or directory\n" +
251                   "\"" + oldName2 + "\" because it does not exist.");
252  elseif oldFileType == Types.FileType.Directory then
253     newFileType :=Internal.stat(newName2);
254     if newFileType == Types.FileType.NoFile then
255        createDirectory(newName2);
256     elseif newFileType == Types.FileType.RegularFile or 
257            newFileType == Types.FileType.SpecialFile then
258        if replace then
259           Files.removeFile(newName2);
260           Files.createDirectory(newName2);
261        else
262           Streams.error("Directory \"" + oldName2 + "\" should be copied to\n" +
263                         "\"" + newName2 + "\" which is an existing file.\n" +
264                         "Since argument replace=false, this is not allowed");
265        end if;
266     end if;
267     copyDirectory(oldName2, newName2, replace);
268  else // regular or special file
269     if replace then
270        Files.removeFile(newName2);
271     else
272        Files.assertNew(newName2, "File \"" + oldName2 + "\" should be copied or moved to\n" +
273                                  "\"" + newName2 + "\" which is an existing file or directory.\n" +
274                                  "Since argument replace=false, this is not allowed");
275     end if;
276     Internal.copyFile(oldName2, newName2);
277  end if;
278  annotation (preferedView="info",Documentation(info="<HTML>
279<h4>Syntax</h4>
280<blockquote><pre>
281Files.<b>copy</b>(oldName, newName);
282Files.<b>copy</b>(oldName, newName, replace = true);
283</pre></blockquote>
284<h4>Description</h4>
285<p>
286Function <b>copy</b>(..) copies a file or a directory
287to a new location. Via the optional argument <b>replace</b>
288it can be defined whether an already existing file may
289be replaced by the required copy.
290</p>
291<p>
292If oldName/newName are directories, then the newName
293directory may exist. In such a case the content of oldName
294is copied into directory newName. If replace = <b>false</b>
295it is required that the existing files
296in newName are different from the existing files in
297oldName.
298</p>
299<h4>Example</h4>
300<blockquote><pre>
301  copy(\"C:/test1/directory1\", \"C:/test2/directory2\");
302     -> the content of directory1 is copied into directory2
303        if \"C:/test2/directory2\" does not exist, it is newly
304        created. If \"replace=true\", files in directory2
305        may be overwritten by their copy
306  copy(\"test1.txt\", \"test2.txt\")
307     -> make a copy of file \"test1.txt\" with the name \"test2.txt\"
308        in the current directory
309</pre></blockquote>
310</HTML>"));
311end copy;
312 
313function move "Move a file or a directory to another place" 
314  extends Modelica.Icons.Function;
315  input String oldName "Name of file or directory to be moved";
316  input String newName "New name of the moved file or directory";
317  input Boolean replace=false 
318      "= true, if an existing file or directory may be replaced";
319algorithm 
320  // if both oldName and newName are in the current directory
321  // use Internal.renameFile
322  if Strings.find(oldName,"/") == 0 and Strings.find(newName,"/") == 0 then
323     Internal.rename(oldName, newName);
324  else
325     Files.copy(oldName, newName, replace);
326     Files.remove(oldName);
327  end if;
328  annotation (preferedView="info",Documentation(info="<HTML>
329<h4>Syntax</h4>
330<blockquote><pre>
331Files.<b>move</b>(oldName, newName);
332Files.<b>move</b>(oldName, newName, replace = true);
333</pre></blockquote>
334<h4>Description</h4>
335<p>
336Function <b>move</b>(..) moves a file or a directory
337to a new location. Via the optional argument <b>replace</b>
338it can be defined whether an already existing file may
339be replaced.
340</p>
341<p>
342If oldName/newName are directories, then the newName
343directory may exist. In such a case the content of oldName
344is moved into directory newName. If replace = <b>false</b>
345it is required that the existing files
346in newName are different from the existing files in
347oldName.
348</p>
349<h4>Example</h4>
350<blockquote><pre>
351  move(\"C:/test1/directory1\", \"C:/test2/directory2\");
352     -> the content of directory1 is moved into directory2.
353        Afterwards directory1 is deleted.
354        if \"C:/test2/directory2\" does not exist, it is newly
355        created. If \"replace=true\", files in directory2
356        may be overwritten
357   move(\"test1.txt\", \"test2.txt\")
358     -> rename file \"test1.txt\" into \"test2.txt\"
359        within the current directory
360</pre></blockquote>
361</HTML>"));
362end move;
363 
364function remove "Remove file or directory (ignore call, if it does not exist)" 
365  extends Modelica.Icons.Function;
366  input String name "Name of file or directory to be removed";
367//..............................................................
368  protected 
369  encapsulated function removeDirectory
370      "Remove a directory, even if it is not empty" 
371      import Modelica.Utilities.*;
372      import Modelica.Utilities.Internal;
373     input String name;
374    protected 
375     Integer nNames = Internal.getNumberOfFiles(name);
376     Integer lenName = Strings.length(name);
377     String fileNames[nNames];
378     // remove an optional trailing "/"
379     String name2 = if Strings.substring(name,lenName,lenName) == "/" then 
380                       Strings.substring(name,lenName-1,lenName-1) else name;
381  algorithm 
382     fileNames :=Internal.readDirectory(name2, nNames);
383     for i in 1:nNames loop
384        Files.remove(name2 + "/" + fileNames[i]);
385     end for;
386     Internal.rmdir(name2);
387  end removeDirectory;
388//..............................................................
389  String fullName = Files.fullPathName(name);
390  Types.FileType.Type fileType=Internal.stat(fullName);
391algorithm 
392  if fileType == Types.FileType.RegularFile or 
393     fileType == Types.FileType.SpecialFile then
394     Internal.removeFile(fullName);
395  elseif fileType == Types.FileType.Directory then
396     removeDirectory(fullName);
397  end if;
398  annotation (preferedView="info",Documentation(info="<html>
399<h4>Syntax</h4>
400<blockquote><pre>
401Files.<b>remove</b>(name);
402</pre></blockquote>
403<h4>Description</h4>
404<p>
405Removes the file or directory \"name\". If \"name\" does not exist,
406the function call is ignored. If \"name\" is a directory, first
407the content of the directory is removed and afterwards
408the directory itself.
409</p>
410<p>
411This function is silent, i.e., it does not print a message.
412</p>
413</html>"));
414end remove;
415 
416function removeFile "Remove file (ignore call, if it does not exist)" 
417  extends Modelica.Icons.Function;
418  input String fileName "Name of file that should be removed";
419  protected 
420  Types.FileType.Type fileType = Internal.stat(fileName);
421algorithm 
422  if fileType == Types.FileType.RegularFile then
423     Internal.removeFile(fileName);
424  elseif fileType == Types.FileType.Directory then
425     Streams.error("File \"" + fileName + "\" should be removed.\n" +
426                   "This is not possible, because it is a directory");
427  elseif fileType == Types.FileType.SpecialFile then
428     Streams.error("File \"" + fileName + "\" should be removed.\n" +
429                   "This is not possible, because it is a special file (pipe, device, etc.)");
430  end if;
431  annotation (preferedView="info",Documentation(info="<html>
432<h4>Syntax</h4>
433<blockquote><pre>
434Files.<b>removeFile</b>(fileName);
435</pre></blockquote>
436<h4>Description</h4>
437<p>
438Removes the file \"fileName\". If \"fileName\" does not exist,
439the function call is ignored. If \"fileName\" exists but is
440no regular file (e.g., directory, pipe, device, etc.) an
441error is triggered.
442</p>
443<p>
444This function is silent, i.e., it does not print a message.
445</p>
446</html>"));
447end removeFile;
448 
449function createDirectory
450    "Create directory (if directory already exists, ignore call)" 
451  extends Modelica.Icons.Function;
452  input String directoryName
453      "Name of directory to be created (if present, ignore call)";
454//..............................................................
455  protected 
456encapsulated package Local "Local utility functions" 
457      import Modelica.Utilities.*;
458      import Modelica.Utilities.Internal;
459     
460  function existDirectory
461        "Inquire whether directory exists; if present and not a directory, trigger an error" 
462     input String directoryName;
463     output Boolean exists "true if directory exists";
464      protected 
465     Types.FileType.Type fileType = Internal.stat(directoryName);
466  algorithm 
467     if fileType == Types.FileType.RegularFile or 
468        fileType == Types.FileType.SpecialFile then
469        Streams.error("Directory \"" + directoryName + "\" cannot be created\n" +
470                      "because this is an existing file.");
471     elseif fileType == Types.FileType.Directory then
472        exists :=true;
473     else
474        exists :=false;
475     end if;
476  end existDirectory;
477     
478  function assertCorrectIndex
479        "Print error, if index to last essential character in directory is wrong" 
480     input Integer index "Index must be > 0";
481     input String directoryName "Directory name for error message";
482  algorithm 
483     if index < 1 then
484        Streams.error("It is not possible to create the directory\n" +
485                      "\"" + directoryName + "\"\n" +
486                      "because this directory name is not valid");
487     end if;
488  end assertCorrectIndex;
489end Local;
490//..............................................................
491  String fullName;
492  Integer index;
493  Integer oldIndex;
494  Integer lastIndex;
495  Boolean found;
496  Boolean finished;
497  Integer nDirectories = 0 "Number of directories that need to be generated";
498algorithm 
499  // Ignore call, if directory exists
500  if not Local.existDirectory(directoryName) then
501     fullName := Files.fullPathName(directoryName);
502     
503     // Remove a trailing "/"
504        index :=Strings.length(fullName);
505        if Strings.substring(fullName,index,index) == "/" then
506           index :=index - 1;
507           Local.assertCorrectIndex(index,fullName);
508        end if;
509        lastIndex := index;
510        fullName := Strings.substring(fullName,1,index);
511     
512     // Search upper directories until a directory is found that exists
513     // ??? check the following while loop later, if also cases such as
514     //  "c:/", "c:", "//name" are handled correctly ???
515        found := false;
516        while not found loop
517           oldIndex := index;
518           index := Strings.findLast(fullName,"/",startIndex=index);
519           if index == 0 then
520              index := oldIndex;
521              found := true;
522           else
523              index := index - 1;
524              Local.assertCorrectIndex(index, fullName);
525              found := Local.existDirectory(Strings.substring(fullName,1,index));
526           end if;
527        end while;
528        index := oldIndex;
529     
530     // Create directories
531        finished := false;
532        while not finished loop
533           Internal.mkdir(Strings.substring(fullName,1,index));
534           if index >= lastIndex then
535              finished := true;
536           elseif index < lastIndex then
537              index := Strings.find(fullName, "/", startIndex=index+2);
538              if index == 0 then
539                 index :=lastIndex;
540              end if;
541           end if;
542        end while;
543  end if;
544  annotation (preferedView="info",Documentation(info="<html>
545<h4>Syntax</h4>
546<blockquote><pre>
547Files.<b>createDirectory</b>(directoryName);
548</pre></blockquote>
549<h4>Description</h4>
550<p>
551Creates directory \"directorName\". If this directory already exists,
552the function call is ignored. If several directories in \"directoryName\"
553do not exist, all of them are created. For example, assume
554that directory \"E:/test1\" exists and that directory
555\"E:/test1/test2/test3\" shall be created. In this case
556the directories \"test2\" in \"test1\" and \"test3\" in \"test2\"
557are created.
558</p>
559<p>
560This function is silent, i.e., it does not print a message.
561In case of error (e.g., \"directoryName\" is an existing regular
562file), an assert is triggered.
563</p>
564</html>"));
565end createDirectory;
566 
567function exist "Inquire whether file or directory exists" 
568  extends Modelica.Icons.Function;
569  input String name "Name of file or directory";
570  output Boolean result "= true, if file or directory exists";
571algorithm 
572  result := Internal.stat(name) > Types.FileType.NoFile;
573  annotation (preferedView="info",Documentation(info="<html>
574<h4>Syntax</h4>
575<blockquote><pre>
576result = Files.<b>exist</b>(name);
577</pre></blockquote>
578<h4>Description</h4>
579<p>
580Returns true, if \"name\" is an existing file or directory.
581If this is not the case, the function returns false.
582</p>
583</html>"));
584end exist;
585 
586function assertNew "Trigger an assert, if a file or directory exists" 
587  extends Modelica.Icons.Function;
588  input String name "Name of file or directory";
589  input String message="This is not allowed." 
590      "Message that should be printed after the default message in a new line";
591  protected 
592  Types.FileType.Type fileType = Internal.stat(name);
593algorithm 
594  if fileType == Types.FileType.RegularFile then
595     Streams.error("File \"" + name + "\" already exists.\n" + message);
596  elseif fileType == Types.FileType.Directory then
597     Streams.error("Directory \"" + name + "\" already exists.\n" + message);
598  elseif fileType == Types.FileType.SpecialFile then
599     Streams.error("A special file (pipe, device, etc.) \"" + name + "\" already exists.\n" + message);
600  end if;
601  annotation (preferedView="info",Documentation(info="<html>
602<h4>Syntax</h4>
603<blockquote><pre>
604Files.<b>assertNew</b>(name);
605Files.<b>assertNew</b>(name, message=\"This is not allowed\");
606</pre></blockquote>
607<h4>Description</h4>
608<p>
609Triggers an assert, if \"name\" is an existing file or
610directory. The error message has the following structure:
611</p>
612<pre>
613  File \"&lt;name&gt;\" already exists.
614  &lt;message&gt;
615</pre>
616</p>
617</html>"));
618end assertNew;
619 
620function fullPathName "Get full path name of file or directory name" 
621  extends Modelica.Icons.Function;
622  input String name "Absolute or relative file or directory name";
623  output String fullName "Full path of 'name'";
624external "C" fullName = ModelicaInternal_fullPathName(name);
625  annotation (preferedView="info",Documentation(info="<html>
626<h4>Syntax</h4>
627<blockquote><pre>
628fullName = Files.<b>fullPathName</b>(name);
629</pre></blockquote>
630<h4>Description</h4>
631<p>
632Returns the full path name of a file or directory \"name\".
633</p>
634</html>"));
635end fullPathName;
636 
637function splitPathName
638    "Split path name in directory, file name kernel, file name extension" 
639  extends Modelica.Icons.Function;
640  input String pathName "Absolute or relative file or directory name";
641  output String directory "Name of the directory including a trailing '/'";
642  output String name "Name of the file without the extension";
643  output String extension "Extension of the file name. Starts with '.'";
644  annotation (preferedView="info",Documentation(info="<HTML>
645<h4>Syntax</h4>
646<blockquote><pre>
647(directory, name, extension) = Files.<b>splitPathName</b>(pathName);
648</pre></blockquote>
649<h4>Description</h4>
650<p>
651Function <b>splitPathName</b>(..) splits a path name into its parts.
652</p>
653<h4>Example</h4>
654<pre>
655  (directory, name, extension) = Files.splitPathName(\"C:/user/test/input.txt\")
656 
657  -> directory = \"C:/user/test/\"
658     name      = \"input\"
659     extension = \".txt\"
660</pre>
661</HTML>"));
662  protected 
663  Integer lenPath = Strings.length(pathName);
664  Integer i = lenPath;
665  Integer indexDot = 0;
666  Integer indexSlash = 0;
667  String c;
668algorithm 
669  while i >= 1 loop
670    c :=Strings.substring(pathName, i, i);
671    if c == "." then
672       indexDot := i;
673       i := 0;
674    elseif c == "/" then
675       indexSlash := i;
676       i := 0;
677    else
678       i := i - 1;
679    end if;
680  end while;
681   
682  if indexSlash == lenPath then
683     directory := pathName;
684     name      := "";
685     extension := "";
686  elseif indexDot > 0 then
687     indexSlash :=Strings.findLast(pathName, "/", startIndex=indexDot - 1);
688     if indexSlash == 0 then
689        directory :="";
690        name :=Strings.substring(pathName, 1, indexDot - 1);
691     else
692        directory :=Strings.substring(pathName, 1, indexSlash);
693        name :=Strings.substring(pathName, indexSlash + 1, indexDot - 1);
694     end if;
695     extension :=Strings.substring(pathName, indexDot, lenPath);
696   else
697     extension :="";
698     if indexSlash > 0 then
699       directory :=Strings.substring(pathName, 1, indexSlash);
700       name :=Strings.substring(pathName, indexSlash + 1, lenPath);
701     else
702       directory :="";
703       name :=pathName;
704     end if;
705   end if;
706end splitPathName;
707 
708function temporaryFileName
709    "Return arbitrary name of a file that does not exist and is in a directory where access rights allow to write to this file (useful for temporary output of files)" 
710