Beispiel #1
0
def check_pointers(parser, codedir=None, mfilter=None, recursive=False):
    """Checks the modules in the specified code parser to see if they
    have common, but subtle, pointer bugs in:

    1. subroutines with a parameter of intent(out) and user-derived type
      must* set *all* members of that parameter or they will have an
      *undefined* status.
    2. pointer-type arrays that are not nullified are set to a valid target
      will return 'T' when passed to `associated`. Best practice is to nullify
      pointer arrays in user-derived types as the default value on those types.
    
    :arg parser: [fortpy.code.CodeParser] with the modules to search *already loaded*.
    :arg codedir: specify the full path to the library whose modules should be searched,
      just another way to filter which modules are generating the warnings.
    :arg mfilter: filter to apply to module names; can use the wildcard standard
      from bash.
    """
    from fnmatch import fnmatch
    from fortpy.msg import std, set_verbosity, info

    set_verbosity(0)
    W1 = "   {} '{}' does not set the value of members '{}' in parameter '{}'."
    W2 = "   Type '{}' does not nullify members '{}' on creation."

    offenders = {}
    for (modname, module) in parser.modules.items():
        if not recursive and codedir is not None and not codedir.lower() in module.filepath.lower():
            continue
        if mfilter is not None and not fnmatch(module.name.lower(), mfilter.lower()):
            continue

        #Test the first condition above for all subroutines in the module; also handle
        #the recursively defined subroutines.
        hprinted = False
        for xname, xvalue in module.executables.items():
            oparams, pmembers = _exec_check_pointers(xvalue)
            if len(oparams) > 0:
                if not hprinted:
                    info("Best practice suggestions: {}".format(module.filepath))
                    hprinted = True
                    
                for oparam in oparams:
                    plist = ', '.join([p.name for p in pmembers[oparam]])                
                    std(W1.format(type(xvalue).__name__, xname, plist, oparam), 0)
                offenders[xvalue.full_name] = (oparams, pmembers)

        for tname, tvalue in module.types.items():
            result = _type_check_pointers(tvalue)
            if len(result) > 0:
                if not hprinted:
                    info("Best practice suggestions: {}".format(module.filepath))
                    hprinted = True

                plist = ', '.join([p.name for p in result])
                std(W2.format(tname, plist), 0)            
                offenders[xvalue.full_name] = result

    return offenders
Beispiel #2
0
def check_pointers(parser, codedir=None, mfilter=None, recursive=False):
    """Checks the modules in the specified code parser to see if they
    have common, but subtle, pointer bugs in:

    1. subroutines with a parameter of intent(out) and user-derived type
      must* set *all* members of that parameter or they will have an
      *undefined* status.
    2. pointer-type arrays that are not nullified are set to a valid target
      will return 'T' when passed to `associated`. Best practice is to nullify
      pointer arrays in user-derived types as the default value on those types.
    
    :arg parser: [fortpy.code.CodeParser] with the modules to search *already loaded*.
    :arg codedir: specify the full path to the library whose modules should be searched,
      just another way to filter which modules are generating the warnings.
    :arg mfilter: filter to apply to module names; can use the wildcard standard
      from bash.
    """
    from fnmatch import fnmatch
    from fortpy.msg import std, set_verbosity, info

    set_verbosity(0)
    W1 = "   {} '{}' does not set the value of members '{}' in parameter '{}'."
    W2 = "   Type '{}' does not nullify members '{}' on creation."

    offenders = {}
    for (modname, module) in parser.modules.items():
        if not recursive and codedir is not None and not codedir.lower() in module.filepath.lower():
            continue
        if mfilter is not None and not fnmatch(module.name.lower(), mfilter.lower()):
            continue

        #Test the first condition above for all subroutines in the module; also handle
        #the recursively defined subroutines.
        hprinted = False
        for xname, xvalue in module.executables.items():
            oparams, pmembers = _exec_check_pointers(xvalue)
            if len(oparams) > 0:
                if not hprinted:
                    info("Best practice suggestions: {}".format(module.filepath))
                    hprinted = True
                    
                for oparam in oparams:
                    plist = ', '.join([p.name for p in pmembers[oparam]])                
                    std(W1.format(type(xvalue).__name__, xname, plist, oparam), 0)
                offenders[xvalue.full_name] = (oparams, pmembers)

        for tname, tvalue in module.types.items():
            result = _type_check_pointers(tvalue)
            if len(result) > 0:
                if not hprinted:
                    info("Best practice suggestions: {}".format(module.filepath))
                    hprinted = True

                plist = ', '.join([p.name for p in result])
                std(W2.format(tname, plist), 0)            
                offenders[xvalue.full_name] = result

    return offenders
Beispiel #3
0
def initialize():
    from fortpy.msg import set_verbosity
    set_verbosity(args["verbose"])
    
    comparer = FileComparer(template_folder=args["templates"])
    result = comparer.compare(args["source"], args["target"], args["xmltemplate"], args["mode"])

    if args["save"]:
        from os import path
        fullpath = path.abspath(path.expanduser(args["save"]))
        with open(fullpath, "w") as f:
            f.write(print_compare_result(result, args["verbose"]))
    else:
        print((print_compare_result(result, args["verbose"])))

    return result
Beispiel #4
0
    return c

#Create a parser so that the script can receive arguments
parser = argparse.ArgumentParser(description="Fortpy File Parsing Unit Testing Tool")

#Add arguments to decide which of the systems and penalties to process.
parser.add_argument("source", help="Specify the path to the source file to parse.")
parser.add_argument("-verbose", help="Sets whether the comparison output is verbose.", type=int, default=0)
parser.add_argument("-reparse", help="Overwrite the cached version of the module.", action="store_true")
parser.add_argument("-pypath", help="Specify a path to add to sys.path before running the tests.")

#Parse the args from the commandline that ran the script, call initialize
args = vars(parser.parse_args())

#We added this argument for debugging installations. That way we can make changes
#without doing a pip install each time; just put the path to the repo root in 'pypath'
if args["pypath"]:
    import sys
    sys.path.append(args["pypath"])
    
import fortpy
from fortpy.code import CodeParser
from fortpy import settings
from fortpy import msg

if args["verbose"]:
    msg.set_verbosity(args["verbose"])
    
cparser = parse()
Beispiel #5
0
                    help="Specify the path to the source file to parse.")
parser.add_argument("-verbose",
                    help="Sets whether the comparison output is verbose.",
                    type=int,
                    default=0)
parser.add_argument("-reparse",
                    help="Overwrite the cached version of the module.",
                    action="store_true")
parser.add_argument(
    "-pypath",
    help="Specify a path to add to sys.path before running the tests.")

#Parse the args from the commandline that ran the script, call initialize
args = vars(parser.parse_args())

#We added this argument for debugging installations. That way we can make changes
#without doing a pip install each time; just put the path to the repo root in 'pypath'
if args["pypath"]:
    import sys
    sys.path.append(args["pypath"])

import fortpy
from fortpy.code import CodeParser
from fortpy import settings
from fortpy import msg

if args["verbose"]:
    msg.set_verbosity(args["verbose"])

cparser = parse()
Beispiel #6
0
                msg.okay("No uncaught exceptions on record.")
        elif usable == "clear":
            self.lasterr = None
            msg.okay("Cleared the last uncaught exception.")            
    def complete_error(self, text, line, istart, iend):
        possible = ["clear"]
        return [p for p in possible if p.startswith(text)]
    def help_error(self):
        lines = [("Prints the last uncaught exception generated in the shell. If 'clear' is "
                  "passed as a single argument, the last exception is cleared from the shell.")]
        self._fixed_width_info(lines)
        
parser = argparse.ArgumentParser(description="Fortpy Automated Test Result Analyzer")
parser.add_argument("-pypath", help="Specify a path to add to sys.path before running the tests.")
parser.add_argument("source", help="Specify the code library (and/or file) to auto-test.")
#Parse the args from the commandline that ran the script, call initialize
args = vars(parser.parse_args())

#We added this argument for debugging installations. That way we can make changes
#without doing a pip install each time; just put the path to the repo root in 'pypath'
if args["pypath"]:
    import sys
    sys.path.append(args["pypath"])
from fortpy import msg
from fortpy.testing.automation import Wizard

if __name__ == '__main__':
    msg.set_verbosity(0)
    shell = WizardShell(args["source"])
    shell.cmdloop()