[comment {-*- flibs -*- doctools manpage}]
[manpage_begin flibs/m_vfile n 1.0]
[copyright {2008 Michael Baudin michael.baudin@gmail.com}]
[copyright {2008 Arjen Markus arjenmarkus@sourceforge.net}]
[moddesc flibs]
[titledesc {Processing files}]

[description]

The module [strong m_vfile] provides OO services to process files and directories.
This component is based on a dynamic strings so that the
file or directory name may be defined with no limit in the
number of characters.

[section OVERVIEW]

   This component allows to manage the file system, by providing 
   services to create, move and destroy files and directories, and 
   to get informations about files and directories.
   The services provided are based either on standard fortran,
   or on fortran extensions.

[subsection Portability]

   One of the main interest of this component is to separate
   the client-side application from platform-specific file 
   management or from compiler-specific fortran extensions. 

[para]

   This separation is possible because m_vfile
   deals for the platform directly, by using the m_platform
   module. This allows to design a client source code which 
   portable on several operating systems (for example windows,
   linux) without any change. For example, the several file 
   separators used on the various operating systems are taken
   into account internally : "/" on linux systems, "\" on 
   windows systems and ":" on Mac OS.

[para]

   The portability is also ensured with respect to the 
   fortran compiler used to create the executable.
   All fortran compilers provide commands to rename the files
   or get the working directory. But not all fortran compilers
   define these commands the same way : some provide subroutines,
   some provide functions, etc... The current component can 
   be configured at compile-time with pre-processing commands.
   This allows to configure the component with compiler 
   specific settings, to make so that the component know
   what features your particular compiler knows about.

[para]

     <your application> > m_vfile (operating system , fortran compiler) > m_platform (operating system , fortran compiler)

 [subsection "How to use it"]

   Before using the services provided by m_vfile, the client
   code must call vfile_startup which initializes platform-specific 
   commands. After using these services, the client code should call
   vfile_shutdown.

[para]

   The commands vfile_delete, vfile_copy, vfile_rename
   allow to delete, copy and rename files or directories.
   To inquire about a file or directory, one can use 
   vfile_exists or vfile_isdirectory.
  
[para]

   In the following example, one creates a new file with vfile_touch,
   rename that file and finally delete it.

[example {
     call vfile_startup ()
     call vstring_new ( file , "foo.txt" )
     call vfile_touch ( file )
     call vfile_rename ( file , "toto.txt" )
     call vfile_delete ( file )
     call vstring_free ( file )
     call vfile_shutdown ()
}]

[para]

   The component makes no differences between file names 
   and directory names, except for methods which are specific 
   for file or for directory.

[para]

   The vfile_separator method returns the platform-specific character 
   used on the current operating system.

[para]

   The commands vfile_nativename , vfile_normalize , vfile_pathtype
   provide ways to manage file names and paths.
   The vfile_nativename function returns the platform-specific name of the file. 
   The vfile_pathtype command returns one of VFILE_PATHTYPE_ABSOLUTE, 
   VFILE_PATHTYPE_RELATIVE, VFILE_PATHTYPE_VOLUMERELATIVE which correspond to 
   the current file. The VFILE_PATHTYPE_VOLUMERELATIVE only exist on 
   windows. The vfile_normalize command returns a unique normalized 
   path representation for the file-system object (file, directory, link, 
   etc), whose string value can be used as a unique identifier for it.

[para]

   The vfile_split and vfile_join services allows to separate
   or concatenate the components of a file. This can be useful
   when dealing with relative file or directories.
   The vfile_split command splits a file into pieces each time 
   the platform-specific separator is found.
   The vfile_join command concatenate a list of strings with 
   the platform-specific separator and returns the concatenated
   file name.

[para]

   In the following example, extracted from the unit tests included in flibs,
   the file "declaration.txt" is first normalized, so that the normalized 
   dynamic string may have the value
   "/home/bill/flibs/tests/filedir/declaration.txt" under Windows 
   or "C:/workbench/flibs/tests/filedir/declaration.txt" under Linux.
   Then the file name is split into a list of strings, for example "home",
   "bill", "flibs", "tests", "filedir", "declaration.txt".
   The number of strings in the list is then computed with the method 
   vstrlist_length.

[example {
     use m_vstring
     use m_vstringlist
     use m_vfile
     type ( t_vstring ) :: normalized
     type ( t_vstringlist ) :: listOfFiles
     integer :: numberOfStrings
     normalized = vfile_normalize ( "declaration.txt" )
     listOfFiles = vfile_split ( normalized )
     numberOfStrings = vstrlist_length ( listOfFiles )
}]

[para]

   One particularly useful command when dealing with files is 
   vfile_findbypattern. The command takes a string as an input
   file pattern. It then computes the list of all files which
   match that pattern. The string matching system is based on 
   the vstring_match method of the m_vstring module.

[para]

   In the following example, extracted again from the unit tests
   of flibs, one computes the list of files in the directory "testfindbypattern"
   matching the pattern "*dec*.txt".

[example {
     type ( t_vstringlist ) :: listOfFiles
     listOfFiles = vfile_findbypattern ( "testfindbypattern" , pattern = "*dec*.txt" )
}]

 [subsection "Error management"]

   The file management may raise errors, for example when the 
   user want to rename a file which does not exist.
   Many of the provided commands have an optional integer output 
   argument "status" which is zero when no error occurred 
   and non-zero in case of error.
   If the status argument is not provided and an error is generated,
   then the program stops and a message is displayed on standard 
   output.
   These are the public error flags that the current component may generate :

[example {
     VFILE_ERROR_OK
     VFILE_ERROR_UNABLE_TO_OPEN_SOURCE
     VFILE_ERROR_UNABLE_TO_OPEN_TARGET
     VFILE_ERROR_UNABLE_TO_WRITE_TARGET
     VFILE_ERROR_SOURCE_FILE_DOES_NOT_EXIST
}]

[subsection "Intel Fortran portability"]

Several methods of this component are based on Fortran extensions,
which requires compiler-specific settings.
For Intel Fortran compiler, the current implementation was based on
IFPORT.F90 file in the Intel release for details on the interfaces provided.
If the client code use these routines, it must define the pre-processing
macro _VFILE_INTEL_FORTRAN_PORTABILITY_ROUTINES

[subsection "RENAME and GETCWD fortran extension"]

Depending on the compiler, the "RENAME" fortran extension is
provided as a subroutine or a function.
For example, this is a short list of compilers and their particular
RENAME provided :
[list_begin bullet]
[bullet] function : Intel Fortran, g95
[bullet] subroutine : gfortran
[list_end]
To inform the m_vfile module of the particular RENAME extension, 
one of the following pre-processing macro must be defined :
[list_begin bullet]
[bullet] _VFILE_RENAME_FUNCTION
[bullet] _VFILE_RENAME_SUBROUTINE
[list_end]

[para]
The same situation happens with the GETCWD fortran extension. 
To inform the m_vfile module of the particular GETCWD extension, 
one of the following pre-processing macro must be defined :
[list_begin bullet]
[bullet] _VFILE_GETCWD_FUNCTION
[bullet] _VFILE_GETCWD_SUBROUTINE
[list_end]

[subsection "Dynamic or static buffer"]

The internal algorithms provided by m_vstrings are based on
basic fortran character strings. In several situations, the
dynamic vstring has to be converted into a basic fortran character
buffer string, which size has to be given explicitly in the source
code, with "character ( len = <something>)" statement.
Two solutions are provided, and the user can define the pre-processing macro
_VFILE_STATIC_BUFFER to configure that :
[list_begin bullet]
[bullet] the first solution is to set the size of the buffer statically,
to a constant integer value VSTRING_BUFFER_SIZE.
[bullet] the second solution is to compute the size
of the buffer dynamically, with the fortran 90 len = vstring_length(this)
statement.
[list_end]

If the _VFILE_STATIC_BUFFER is defined, then character strings of
constant size are used as buffers.
If the _VFILE_STATIC_BUFFER is not defined (which is the default),
then character strings of dynamic size are used as buffers.
The second solution is more efficient, because the strings are not
oversized or undersized, depending on the real number of characters
in the dynamic string. But the feature may not be provided
by the compiler at hand. For example, problems with the dynamic
length character string have been experienced with Intel Fortran 8.

[subsection "Preprocessing"]
The following preprocessing macro must be considered :
[list_begin bullet]
[bullet] _VFILE_STATIC_BUFFER : see  the section "Dynamic or static buffer"
[bullet] _VFILE_RENAME_FUNCTION or _VFILE_RENAME_SUBROUTINE : see the section "RENAME and GETCWD fortran extension"
[bullet] _VFILE_GETCWD_FUNCTION or _VFILE_GETCWD_SUBROUTINE : see the section "RENAME and GETCWD fortran extension"
[list_end]

[subsection "Example of compiler settings"]

This is an abstract of all macros for several compilers.

[para]

Compiler : [emph "Intel Fortran V8.0"]
[list_begin bullet]
[bullet] _VFILE_INTEL_FORTRAN_PORTABILITY_ROUTINES
[bullet] _VFILE_RENAME_FUNCTION
[bullet] _VFILE_STATIC_BUFFER
[bullet] _VFILE_GETCWD_FUNCTION
[list_end]

[para]
Compiler : [emph "g95"]
[list_begin bullet]
[bullet] _VFILE_RENAME_FUNCTION
[bullet] _VFILE_GETCWD_FUNCTION
[list_end]

[para]
Compiler : [emph "gfortran"]
[list_begin bullet]
[bullet] _VFILE_RENAME_SUBROUTINE
[bullet] _VFILE_GETCWD_SUBROUTINE
[list_end]

[section METHODS]


[list_begin definitions]


[call [method "vfile_rootname"] ( [arg filename]) result ( rootname )]
[list_begin arg]
[arg_def [type "type ( t_vstring ) , intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] rootname]
[list_end]
Returns the name without the extension (if any), that is, 
The part of the name _before_ the last "." in [arg filename] or the whole name
if no "." is present in [arg filename]. 
Example : if filename is "declaration.txt", the file root name is "declaration".

[call [method "vfile_rootname"] ( [arg filename]) result ( rootname )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] rootname]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_extension"] ( [arg filename]) result ( extension )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] extension]
[list_end]
Returns the extension (if any), that is the part of the name 
[emph after] and including the last "." or empty if none
present. Example : if filename is "declaration.txt", the file extension is ".txt".

[call [method "vfile_extension"] ( [arg filename]) result ( extension )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] extension]
[list_end]
Same as previous but with [arg filename] as a character string.

[call [method "vfile_tail"] ( [arg filename]) result ( filetail )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] filetail]
[list_end]
Returns all of the characters in name after the last directory separator.
If [arg filename] contains no separators then returns [arg filename].
Example : if filename is "dir1/declaration.txt", the file tail is "declaration.txt".


[call [method "vfile_tail"] ( [arg filename]) result ( filetail )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] filetail]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_dirname"] ( [arg filename]) result ( dirname )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] dirname]
[list_end]
Return the directory, that is, the part of the name [emph before] 
the last directory separator.
Example : if filename is "dir1/declaration.txt", the directory name 
is "dir1".


[call [method "vfile_dirname"] ( [arg filename]) result ( dirname )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] dirname]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_first_separator_index"] ( [arg filename]) result ( sepindex )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer ::"] sepindex]
[list_end]
Returns the index of the first separator in the given filename
or 0 if there is no separator in the given file name.


[call [method "vfile_first_separator_index"] ( [arg filename]) result ( sepindex )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer ::"] sepindex]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_last_separator_index"] ( [arg filename]) result ( sepindex )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer ::"] sepindex]
[list_end]
Returns the index of the last separator in the given filename
or 0 if there is no separator in the given file name.


[call [method "vfile_last_separator_index"] ( [arg filename]) result ( sepindex )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer ::"] sepindex]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_join"] ( [arg dirname] [arg filename]) result ( fullname )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] dirname]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] fullname]
[list_end]
Join the current file with the given file name,
using the platform-specific separator as the joining character.
The result is always canonical for the current platform: / for
Unix and Windows, and : for Macintosh.
If a particular name is relative, then it will be joined to the previous
file name argument. Otherwise, any earlier arguments will be discarded,
and joining will proceed from the current argument. 


[call [method "vfile_join"] ( [arg dirname] [arg ", filename"]) result ( fullname )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] dirname]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] fullname]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_add_extension"] ( [arg filename] [arg ", extension"] ) result ( newname )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ), intent(in) ::"] extension]
[arg_def [type "type ( t_vstring ) ::"] newname]
[list_end]
Return a new file name with the given extension concatenated.
If the given file name ends with a dot and the given extension begins
with a dot, only one dot is kept.
Note that the extension of one file begins with a dot : ".txt" is a file
extension while "txt" is not.


[call [method "vfile_separator"] ( ) result ( separator )]
[list_begin arg]
[arg_def [type "type ( t_vstring ) ::"] separator]
[list_end]
Return the native separator for the current platform
The separator depends on the platform :
[list_begin bullet]
[bullet] "/" on Unix, Linux systems,
[bullet] "\" on Windows systems,
[bullet] ":" on Macintosh.
[list_end]


[call [method "vfile_pwd"] ( [arg pwd] [opt ", status"] )]
[list_begin arg]
[arg_def [type "type ( t_vstring ) ::"] pwd]
[arg_def [type "integer , intent(out) , optional ::"] status]
[list_end]
Returns the name of the current directory by using the fortran
extension GETCWD.
The separator used here is the platform-independent "/".


[call [method "vfile_exists"] ( [arg filename] ) result ( exists )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "logical ::"] exists]
[list_end]
Returns .true. if file name exists, .false. otherwise.


[call [method "vfile_exists"] ( [arg filename] ) result ( exists )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "logical ::"] exists]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_rename"] ( [arg filename] [arg ", newfn"] [opt ", status"] )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ), intent(in) ::"] newfn]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Renames the file ofdln to newfn by using the RENAME fortran extension.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.



[call [method "vfile_rename"] ( [arg filename] [arg ", newfn"] [opt ", status"] )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "character(len=*), intent(in) ::"] newfn]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Same as previous but with [arg newfn] as a character string.



[call [method "vfile_copy"] ( [arg filename] [arg ", targetfn"] [opt ", status"] [opt ", mode"] [opt ", force"] [opt ", trimline"] )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ), intent(in) ::"] targetfn]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "character(len=*), intent(in), optional ::"] mode]
[arg_def [type "logical, intent(in) , optional ::"] force]
[arg_def [type "logical, intent(in) , optional ::"] trimline]
[list_end]
Copy the ascii file ofdln to targetfn.
If the source file does not exists, generates an error.
If the target file allready exists and force option is undefined
or defined to false, generates an error.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return
[list_begin bullet]
[bullet] status = 1 when one was unable to open the source file
[bullet] status = 2 when one was unable to open the target file
[bullet] status = 3 when there was a problem while writing the target file
[bullet] status = 4 when the source file does not exist
[list_end]
If [arg mode] is not supplied or supplied and equals to "system", then 
the copy is made using an operating system command.
If [arg mode] is supplied and equals to "ascii", then the copy is made using standard
fortran.
The [arg force] option is available only in "ascii" mode. 
If [arg force] is supplied and true, if the target file allready exists, delete it before
making the copy. 
The [arg trimline] option is available only in "ascii" mode. 
If [arg trimline] is supplied and true, or not supplied, the lines of 
the file copy are trimmed.
If [arg trimline] is supplied and false, the number of columns in the file copy are all
of maximum possible length.
[para]
The "ascii" mode may not behave as expected :
[list_begin bullet]
[bullet] The maximum number of columns in the source filename is 1000.
[bullet] After execution, the target file is not an exact copy of the source file.
Because of the fortran format used, all the lines of the target file are of length 1000 :
blank spaces are appended at the end of the string.
[list_end]



[call [method "vfile_copy"] ( [arg filename] [arg ", targetfn"] [opt ", status"] [opt ", mode"] [opt ", force"] [opt ", trimline"] )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "character(len=*), intent(in) ::"] targetfn]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "character(len=*), intent(in), optional ::"] mode]
[arg_def [type "logical, intent(in) , optional ::"] force]
[arg_def [type "logical, intent(in) , optional ::"] trimline]
[list_end]
Same as previous but with [arg targetfn] as a character string.



[call [method "vfile_delete"] ( [arg filename] [opt ", force"] [opt ", status"] )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "logical, intent(in) , optional ::"] force]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Removes the file or directory [arg filename]. 
Non-empty directories will be removed only if the [arg force] option is specified.
If [arg force] is supplied and true, forces to delete the directory, even if it is empty.
If [arg force] is not supplied or supplied and false, the directory is not deleted if it is empty.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.



[call [method "vfile_delete"] ( [arg filename] [opt ", force"] [opt ", status"] )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "logical, intent(in) , optional ::"] force]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_isdirectory"] ( [arg filename]) result ( isdirectory )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "logical ::"] isdirectory]
[list_end]
Returns .true. if file name is a directory, .false. otherwise.

[call [method "vfile_isdirectory"] ( [arg filename]) result ( isdirectory )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "logical ::"] isdirectory]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_isfile"] ( [arg filename]) result ( isfile )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "logical ::"] isfile]
[list_end]
Returns .true. if file name is a file, .false. otherwise.

[call [method "vfile_isfile"] ( [arg filename]) result ( isfile )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "logical ::"] isfile]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_size"] ( [arg filename] [opt ", status"]) result ( vfile_size )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "integer ::"] vfile_size]
[list_end]
Returns .true. if file name is a file, .false. otherwise.
Returns an integer giving the size of file name in bytes. 
If the file doesn't exist or its size cannot be queried then an error is generated.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.

[call [method "vfile_size"] ( [arg filename] [opt ", status"]) result ( vfile_size )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "integer ::"] vfile_size]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_atime"] ( [arg filename] [opt ", status"]) result ( vfile_atime )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "integer ::"] vfile_atime]
[list_end]
Returns an integer representing the time at which file name was last accessed.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.


[call [method "vfile_atime"] ( [arg filename] [opt ", status"]) result ( vfile_atime )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "integer ::"] vfile_atime]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_mtime"] ( [arg filename] [opt ", status"]) result ( vfile_mtime )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "integer ::"] vfile_mtime]
[list_end]
Returns an integer representing the time at which file name was last modified.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.


[call [method "vfile_mtime"] ( [arg filename] [opt ", status"]) result ( vfile_mtime )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[arg_def [type "integer ::"] vfile_mtime]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_normalize"] ( [arg filename] ) result ( vfile_normalize )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] vfile_normalize]
[list_end]
Returns a unique normalized path representation for the
file-system object (file, directory, link, etc), whose string
value can be used as a unique identifier for it. A normalized path
is an absolute path which has all '../', './' removed. Also it is one which
is in the ``standard'' format for the native platform.
On Windows or Mac, any platform-specific separator in the path
is replaced by the platform-independent separator "/".
On Windows it also means we want the long form with that form's
case-dependence (which gives us a unique, case-dependent path).

[call [method "vfile_normalize"] ( [arg filename] ) result ( vfile_normalize )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstring ) ::"] vfile_normalize]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_find"] ( [opt basedir] ) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in), optional ::"] basedir]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
An implementation of the unix command find.
Returns a list of files or directories which are located in the
given basedir directory, and, recursively, in all sub-directories.
Each file in the resulting list has a path relative to the given
basedir directory.
If [arg basedir] is provided, this is the name of the base directory into which the search is done.
If [arg basedir] is not provided, the current directory is used by default.

[call [method "vfile_find"] ( [arg basedir] ) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] basedir]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
Same as previous but with [arg basedir] as a character string.


[call [method "vfile_find"] ( [opt basedir] [arg ", filtercmd"] ) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in), optional ::"] basedir]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
[example {
    interface
       function filtercmd ( filename ) result ( keepfile )
         use m_vstring, only : t_vstring
         type ( t_vstring ), intent(in) :: filename
         logical :: keepfile
       end function filtercmd
    end interface}]
An implementation of the unix command find.
Returns a list of files or directories which are located in the
given basedir directory, and, recursively, in all sub-directories.
Each file in the resulting list has a path relative to the given
basedir directory.
If [arg basedir] is provided, this is the name of the base directory into which the search is done.
If [arg basedir] is not provided, the current directory is used by default.
The [arg filtercmd] command, if provided, is interpreted as a command prefix and 
one argument is passed to it, the name of the file or directory find is currently
looking at. Note that this name is not fully qualified. It has to be joined it with
the result of pwd to get an absolute filename. The result of filtercmd is a boolean value
that indicates if the current file should be included in the list of interesting files.


[call [method "vfile_find"] ( [arg basedir] [arg ", filtercmd"] ) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] basedir]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
[example {
    interface
       function filtercmd ( filename ) result ( keepfile )
         use m_vstring, only : t_vstring
         type ( t_vstring ), intent(in) :: filename
         logical :: keepfile
       end function filtercmd
    end interface}]
Same as previous but with [arg basedir] as a character string.



[call [method "vfile_findbypattern"] ( [opt basedir] [arg ", pattern"] ) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in), optional ::"] basedir]
[arg_def [type "type ( t_vstring ), intent(in) ::"] pattern]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
Returns a list of files which match the given pattern.
Internally, this command is based on vfile_find, with a particular filter command applied.
If [arg basedir] is provided, this is the name of the base directory into which the search is done.
If [arg basedir] is not provided, the current directory is used by default.
The [arg pattern] is the pattern for the file names (like: *.f90) against which 
each file name is compared. The method used for string matching 
is vstring_match, so that all features available is vstring_match are 
available in vfile_findbypattern.


[call [method "vfile_findbypattern"] ( [opt basedir] [arg ", pattern"] ) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in), optional ::"] basedir]
[arg_def [type "character(len=*), intent(in) ::"] pattern]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
Same as previous but with [arg basedir] and [arg pattern] as a character string.




[call [method "vfile_listfiles"] ( [opt directory] [opt ", filetypes"] [opt ", pattern"]  [opt ", tails"]) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in), optional ::"] basedir]
[arg_def [type "type ( t_vstringlist ), intent(in), optional ::"] pattern]
[arg_def [type "type ( t_vstring ), intent(in), optional ::"] pattern]
[arg_def [type "logical, intent(in), optional ::"] tails]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
Returns a list of files in one directory.
Only the file tails are in the list.
If [arg directory] is provided, the directory into which the list is to be computed.
If [arg directory] is not provided, the current directory is used and only the file names are file tails.
If [arg directory] is provided, the computed files names are relative and begin with the given 
directory (following the template directory/filetail).
If [arg filetypes] is provided, only list files or directories which match filetypes,
with d (directory), f (plain file).
If [arg filetypes] is not provided, the filetypes "d" , "f" list is used.
If [arg pattern] is provided, only list files which match the given pattern.
If [arg pattern] is not provided, the "*" pattern is used.
The vstring_match command is used to compare the file against the pattern so that
all the pattern types available in vstring_match are available in vfile_listfiles.
If [arg tails] is provided and true, only return the part of each file found 
which follows the last directory named in directory.
Thus the statement
[example {
listoffiles = vfile_listfile ( tails = .true. , directory = directory , pattern = "*" )
}]
is equivalent to
[example {
call vfile_pwd ( cwd )
call vstrplatform_cd ( directory )
listoffiles = vfile_listfile ( tails = .true. , pattern = "*" )
call vstrplatform_cd ( cwd )
}]
If [arg tails] is provided and false, or not provided, the files are left as specified by the
directory argument.

[call [method "vfile_listfiles"] ( [arg directory] [opt ", filetypes"] [opt ", pattern"]  [opt ", tails"]) result ( listOfFiles )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] basedir]
[arg_def [type "type ( t_vstringlist ), intent(in), optional ::"] pattern]
[arg_def [type "character(len=*), intent(in), optional ::"] pattern]
[arg_def [type "logical, intent(in), optional ::"] tails]
[arg_def [type "type ( t_vstringlist ) ::"] listOfFiles]
[list_end]
Same as previous but with [arg directory] and [arg pattern] as a character string.



[call [method "vfile_type"] ( [arg filename] [opt ", status"]) result ( filetype )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer , intent(out), optional ::"] status]
[arg_def [type "type ( t_vstring ) ::"] filetype]
[list_end]
Returns a string giving the type of file name, which will be one of "file" or "directory".
If [arg status] is provided and the file type could be computed,
the status is set to 0.
If [arg status] is provided and the file type could not be computed,
the status is set to VFILE_ERROR_UNKNOWN_FILE_TYPE.
If [arg status] is not provided and the file type could not be computed,
an error is generated.



[call [method "vfile_type"] ( [arg filename] [opt ", status"]) result ( filetype )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer , intent(out), optional ::"] status]
[arg_def [type "type ( t_vstring ) ::"] filetype]
[list_end]
Same as previous but with [arg filename] as a character string.




[call [method "vfile_split"] ( [arg filename]) result ( listOfComponents )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "type ( t_vstringlist ) ::"] listOfComponents]
[list_end]
Returns a list of strings where elements are the path components in name.


[call [method "vfile_split"] ( [arg filename]) result ( listOfComponents )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "type ( t_vstringlist ) ::"] listOfComponents]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_touch"] ( [arg filename] [opt ", status"])]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Implementation of touch. Alter the atime and mtime of the specified files. 
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.
If [arg status] is not provided and the process could not be done,
an error is generated.


[call [method "vfile_touch"] ( [arg filename] [opt ", status"])]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_pathtype"] ( [arg filename]) result ( pathtype )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer ::"] pathtype]
[list_end]
Returns one of VFILE_PATHTYPE_ABSOLUTE, VFILE_PATHTYPE_RELATIVE, VFILE_PATHTYPE_VOLUMERELATIVE. 
If [arg filename] refers to a specific file on a specific volume, the path
type will be absolute. If [arg filename] refers to a file relative to the current
working directory, then the path type will be relative. If name refers to
a file relative to the current working directory on a specified volume, or to
a specific file on the current working volume, then the path type is volumerelative.
[para]
Examples :
[list_begin bullet]
[bullet] "." is relative on all platforms
[bullet] ".." is relative on all platforms
[bullet] "/" is absolute on Linux/Unix
[bullet] "C:/" is absolute on Windows (if the C:/ exists)
[bullet] "/" is volumerelative on windows and refers to the current volume (for example C:/)
[bullet] "toto.txt" is relative on all platforms
[bullet] "./toto.txt" is relative on all platforms
[list_end]


[call [method "vfile_pathtype"] ( [arg filename]) result ( pathtype )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer ::"] pathtype]
[list_end]
Same as previous but with [arg filename] as a character string.



[call [method "vfile_nativename"] ( [arg filename]) result ( nativename )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "( t_vstring ) ::"] nativename]
[list_end]
Returns the platform-specific name of the file. 
filename is useful if the filename is needed to pass to a platform-specific
call, such as the execution of a system command under Windows or
AppleScript on the Macintosh.


[call [method "vfile_nativename"] ( [arg filename]) result ( nativename )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "( t_vstring ) ::"] nativename]
[list_end]
Same as previous but with [arg filename] as a character string.


[call [method "vfile_mkdir"] ( [arg filename] [opt ", status"])]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Create a directory.
If [arg status] is supplied, it contains 0 on success or nonzero error code
upon return.
If [arg status] is not provided and the process could not be done,
an error is generated.


[call [method "vfile_mkdir"] ( [arg filename] [opt ", status"])]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] status]
[list_end]
Same as previous but with [arg filename] as a character string.




[call [method "vfile_open"] ( [arg filename] [opt ", fileunit"] [opt ", iostat"] [opt ", status"] [opt ", access"] [opt ", form"] [opt ", recl"] [opt ", blank"] [opt ", position"] [opt ", action"] [opt ", delim"] [opt ", pad"]) result ( fileunit_real )]
[list_begin arg]
[arg_def [type "type ( t_vstring ), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] fileunit]
[arg_def [type "character(len=*) , intent(in) , optional ::"] action]
[arg_def [type "character(len=*) , intent(in) , optional ::"] status]
[arg_def [type "character(len=*) , intent(in) , optional ::"] access]
[arg_def [type "character(len=*) , intent(in) , optional ::"] form]
[arg_def [type "character(len=*) , intent(in) , optional ::"] blank]
[arg_def [type "character(len=*) , intent(in) , optional ::"] position]
[arg_def [type "character(len=*) , intent(in) , optional ::"] delim]
[arg_def [type "character(len=*) , intent(in) , optional ::"] pad]
[arg_def [type "integer , intent(in) , optional ::"] recl]
[arg_def [type "integer , intent(out) , optional ::"] iostat]
[arg_def [type "integer ::"] fileunit_real]
[list_end]
Open a file and returns the unit associated with the opened file.
The command is based on fortran intrinsic "open".
If the optional argument fileunit is provided, it is used to
open the file.
If not provided, a file unit is automatically computed
on the base of currently free logical units.
[para]
Note: 
[para]
All the options of the intrinsic "open" are provided
with the same behaviour and default values, with some exceptions.
[list_begin bullet]
[bullet] The file name is mandatory in vfile_open,
even if the "file=" specifier is not mandatory in fortran "open".
This behaviour allows the fortran to manage a status="scratch"
specifier, which provides a way to manage for temporary
files internally. Instead, the m_vfile component provides the
vfile_tempfile service.
[bullet] The "err=" option with an error label as argument is not
provided. The client code may use the iostat option instead.
[list_end]




[call [method "vfile_open"] ( [arg filename] [opt ", fileunit"] [opt ", iostat"] [opt ", status"] [opt ", access"] [opt ", form"] [opt ", recl"] [opt ", blank"] [opt ", position"] [opt ", action"] [opt ", delim"] [opt ", pad"]) result ( fileunit_real )]
[list_begin arg]
[arg_def [type "character(len=*), intent(in) ::"] filename]
[arg_def [type "integer, intent(out) , optional ::"] fileunit]
[arg_def [type "character(len=*) , intent(in) , optional ::"] action]
[arg_def [type "character(len=*) , intent(in) , optional ::"] status]
[arg_def [type "character(len=*) , intent(in) , optional ::"] access]
[arg_def [type "character(len=*) , intent(in) , optional ::"] form]
[arg_def [type "character(len=*) , intent(in) , optional ::"] blank]
[arg_def [type "character(len=*) , intent(in) , optional ::"] position]
[arg_def [type "character(len=*) , intent(in) , optional ::"] delim]
[arg_def [type "character(len=*) , intent(in) , optional ::"] pad]
[arg_def [type "integer , intent(in) , optional ::"] recl]
[arg_def [type "integer , intent(out) , optional ::"] iostat]
[arg_def [type "integer ::"] fileunit_real]
[list_end]
Same as previous but with [arg filename] as a character string.

[list_end]

[section "STATIC METHODS"]

[list_begin definitions]


[call [method "vfile_startup"] ()]
Initialize module internal state.
This routine must be called once before calling any method of the module.

[call [method "vfile_shutdown"] ()]
Shutdown module internal state.


[call [method "vfile_set_stoponerror"] ( [arg stoponerror] )]
[list_begin arg]
[arg_def [type "logical , intent(in) ::"] stoponerror]
[list_end]
Configure the behaviour of the component whenever an
error is met.
If [arg stoponerror] is true, then the execution stops if an error is encountered.
If [arg stoponerror] is false, then the execution continues if an error is encountered.
In both cases, a message is displayed on standard output.

[call [method "vfile_tempdir"] () result ( tempdir )]
[list_begin arg]
[arg_def [type "type ( t_vstring ) ::"] tempdir]
[list_end]
Returns the temporary directory for the current platform.
The command returns the path of a directory where the caller can
place temporary files, such as "/tmp" on Unix systems.
The algorithm we use to find the correct directory is as follows:
[list_begin enumerated]
[enum] The directory named in the TMPDIR environment variable.
[enum] The directory named in the TEMP environment variable.
[enum] The directory named in the TMP environment variable.
[enum] A platform specific location:
    [list_begin bullet]
    [bullet] Windows
    "C:\TEMP", "C:\TMP", "\TEMP", and "\TMP" are tried in that order.
    (classic) Macintosh
    The TRASH_FOLDER environment variable is used. filename is most likely not correct.
    [bullet] Unix
    The directories "/tmp", "/var/tmp", and "/usr/tmp" are tried in that order.
    [list_end]
[list_end]



[call [method "vfile_tempfile"]  result ( tempfile )]
[list_begin arg]
[arg_def [type "type ( t_vstring ) ::"] tempfile]
[list_end]
Returns the name of a temporary file name suitable for writing to. 
The [arg tempfile] name is unique, and the file will be writable and
contained in the appropriate system specific temp directory.


[call [method "vfile_volumes"]  result ( listofvolumes )]
[list_begin arg]
[arg_def [type "type ( t_vstringlist ) ::"] listofvolumes]
[list_end]
Returns the absolute paths to the volumes mounted on the 
system, as a proper string list.
On UNIX, the command will always return "/", since all filesystems are
locally mounted.
On Windows, it will return a list of the available
local drives (e.g. {a:/ c:/}).
[para]
Note:
[para]
With Intel Fortran, the portability routines provide the "GETDRIVESQQ" function,
which returns the list of current drive as a 26 letters string.


[list_end]


[manpage_end]
