Code Monkey home page Code Monkey logo

Comments (1)

perrette avatar perrette commented on July 18, 2024

Here is a reasonable workaround for my use case: just create a dummy module with all imports and replace any "use ..." statements in f90wra_*.f90 files with "use dummy ...".

Here a python script to do this on the fly (e.g. to be called from a Makefile just after f90wrap):

"""module {dummy}
!
! Fix cross-dependency bug associated with --move-methods flag to f90wrap.
! 
! The approach taken here is to create a dummy module which contains all needed module
! imports, and replace all "use {prefix}... " statements with "use {dummy}"
! It parses generated f90wrap_*.f90 code to create {dummy} sequentially.
!
! This module needs to be manually compiled and passed to f2py[-f90wrap] as object.

{statements}

contains

end module {dummy}
"""
from __future__ import print_function, absolute_import
import os, logging
logging.basicConfig(level=logging.INFO)

def parse_line(line):
    "use mod , only : name1, name2"
    if not ':' in line:
        usemod, names = line, ""
    else:
        useonly, names = line.split(':')
        usemod, _ = useonly.split(',')
    _, mod = usemod.strip().split()
    assert _.strip() == 'use'
    return mod, [nm.strip() for nm in names.split(',')]

class DummyModule(object):
    def __init__(self, name, prefix):
        self.name = name
        self.prefix = prefix
        self.statements = []

    def parse_line(self, line):
        if line.strip().startswith('use {}'.format(self.prefix)):
            mod, names = parse_line(line)
            assert mod != self.name, 'already parsed + prefix == dummy'

            # append use statement in dummy module
            self.append(mod)

            # replace original line
            line = "    use {}, only: {}".format(self.name, ", ".join(names))

        elif line.strip().startswith('use {}'.format(self.name)):
            raise ValueError('already parsed')

        return line

    def append(self, mod):
        statement = "    use "+mod
        if statement not in self.statements:
            logging.info("generate_dummy:: append module: "+mod)
            self.statements.append(statement)


    def format(self):
        return __doc__.format(dummy=self.name, prefix=self.prefix, statements="\n".join(self.statements))


def main():
    import argparse
    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('files', nargs='*', default=[], help='f90wrap_*.f90 files')
    parser.add_argument('--dummy', required=True, 
                        help='name of dummy module to create, e.g. module_dummy_')
    parser.add_argument('--prefix', required=True, help='prefix of modules to replace, e.g. module_')
    parser.add_argument('--dry-run', action='store_true', help='only print dummy module, do not modify any file')
    parser.add_argument('--add-modules', nargs='*', default=[], help='add additional modules (typically the extension modules erroneously removed by f90wrap with --move-method option activated)')
    args = parser.parse_args()

    dummy = DummyModule(args.dummy, args.prefix)

    for fname in args.files:
        logging.info("generate_dummy:: visit file: "+fname)

        txt = open(fname).read()

        lines = txt.splitlines()
        for i, line in enumerate(lines):
            lines[i] = dummy.parse_line(line)

        newtxt = "\n".join(lines)

        # replace file if modified
        if txt != newtxt and not args.dry_run:
            logging.info("generate_dummy:: update file: "+fname)
            with open(fname, 'w') as f:
                f.write(newtxt)

    # append additional modules
    for mod in args.add_modules:
        dummy.append(mod)

    print(dummy.format())

if __name__ == "__main__":
    main()

from f90wrap.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.