4This module contains the main PYFT class 
    5PYFT is the file level class (read/write...) 
   10from multiprocessing 
import Lock, RLock
 
   14from pyfortool.util import (debugDecor, tostring, tofortran, fortran2xml,
 
   15                            setVerbosity, printInfos, PYFTError)
 
   19def conservativePYFT(filename, parserOptions, wrapH,
 
   20                     tree=None, verbosity=None, clsPYFT=None):
 
   22    Return a conservative PYFT object usable for tree manipulation 
   23    :param filename: name of the file to open 
   24    :param parserOptions, wrapH: see the PYFT class 
   25    :param tree: Tree instance or None 
   26    :param verbosity: if not None, sets the verbosity level 
   27    :param clsPYFT: PYFT class to use 
   30    options = PYFT.DEFAULT_FXTRAN_OPTIONS 
if parserOptions 
is None else parserOptions
 
   31    options = options.copy()
 
   32    if len(set(options).intersection((
'-no-include', 
'-noinclude'))) == 0:
 
   34        options.append(
'-no-include')
 
   37    pft = clsPYFT(filename, parserOptions=options, wrapH=wrapH,
 
   38                  tree=tree, verbosity=verbosity)
 
 
   44    Generates an empty PYFT scope 
   45    :param filename: file name corresponding to this new PYFT scope 
   46    :param fortran: fortran text to include 
   47    :param **kwargs: other arguments for the PYFT class 
   49    with open(filename, 
'w', encoding=
'utf-8') 
as fo:
 
   50        fo.write(
'SUBROUTINE FOO\nEND' if fortran 
is None else fortran)
 
   51    pft = 
PYFT(filename, **kwargs)
 
   53        pft.remove(pft.find(
'.//{*}program-unit'))
 
 
   59    This class extends the PYFTscope one by adding file support (read/write) 
   61    DEFAULT_FXTRAN_OPTIONS = [
'-construct-tag', 
'-no-include', 
'-no-cpp', 
'-line-length', 
'9999']
 
   62    MANDATORY_FXTRAN_OPTIONS = [
'-construct-tag']
 
   64    NO_PARALLEL_LOCK = 
None   
   65    PARALLEL_FILE_LOCKS = 
None   
   68    def __init__(self, filename, output=None, parserOptions=None, verbosity=None,
 
   69                 wrapH=False, tree=None, enableCache=False):
 
   71        :param filename: Input file name containing FORTRAN code 
   72        :param output: Output file name, None to replace input file 
   73        :param parserOptions: dictionnary holding the parser options 
   74        :param verbosity: if not None, sets the verbosity level 
   75        :param wrapH: if True, content of .h file is put in a .F90 file (to force 
   76                      fxtran to recognize it as free form) inside a module (to 
   77                      enable the reading of files containing only a code part) 
   78        :param tree: an optional Tree instance 
   79        :param enableCache: True to cache node parents 
   82        if not sys.version_info >= (3, 8):
 
   85            raise PYFTError(
"PyForTool needs at least version 3.8 of python")
 
   88        assert os.path.exists(filename), 
'Input filename must exist' 
   90        tree = 
Tree() 
if tree 
is None else tree
 
   92            assert tree 
is not None, 
'tree must be None if setParallel has been called' 
   94        if parserOptions 
is None:
 
   98        for tDir 
in tree.getDirs():
 
  104        super().
__init__(xml, enableCache=enableCache, tree=tree)
 
  106            self.
tree.signal(self)
 
  107        if verbosity 
is not None:
 
  108            setVerbosity(verbosity)
 
 
  113        Prepare the class to be used to instanciate parallel objects 
  114        :param tree: Tree object shared among processes 
  115        :param clsLock: class to use for Lock (defaults to multiprocessing.Lock) 
  116        :param clsRLock: class to use for RLock (defaults to multiprocessing.RLock) 
  125                                   for file 
in tree.getFiles()}
 
 
  130        Acquire lock for filename 
  131        :param filename: name of the file whose lock must be acquired 
  133        filename = os.path.normpath(filename)
 
 
  142        Release lock for filename 
  143        :param filename: name of the file whose lock must be acquired 
  144        :param silence: do not raise exception if file is already unlocked 
  146        filename = os.path.normpath(filename)
 
 
  170        Closes the FORTRAN file 
 
  178        Returns the xml as a string 
  180        return tostring(self)
 
 
  185        Returns the FORTRAN as a string 
  187        return tofortran(self)
 
 
  191        The output file will have an upper case extension 
 
  197        The output file will have a lower case extension 
 
  203        The output file will have a modified extension. 
  204        :param mod: function to apply to the file extension 
  206        def _transExt(path, mod):
 
  207            filename, ext = os.path.splitext(path)
 
  208            return filename + mod(ext)
 
 
  216        Writes the output FORTRAN file 
  219                  encoding=
'utf-8') 
as fo:
 
  222            os.fsync(fo.fileno())  
 
 
  231        Writes the output XML file 
  232        :param filename: XML output file name 
  234        with open(filename, 
'w', encoding=
'utf-8') 
as fo: