Source code for AutoRPE.UtilsRPE.SourceManager

from __future__ import print_function
from os.path import dirname, abspath, isfile
import numpy as np


# Get all files contained in a source path (recursive)
[docs] def expand_sources(source_path: str): """ Recursively gets all source files with a Fortran extension (.f, .F, .f90, .F90) from the specified directory. Parameters: source_path (str): The directory to search for source files. Returns: list: A sorted list of file paths matching the Fortran source file pattern. Raises: OSError: If there is an issue accessing the directory. """ from os import walk from os.path import join import re pattern = r".*\.[fFh90]" files = [join(dp, f) for dp, dn, fn in walk(source_path) for f in fn] files = [f for f in files if re.search(pattern, f)] # Sorting the list to solve the random-like behaviour of walk files = list(sorted(files)) return files
# Gets the file path of the corresponding module
[docs] def match_module_and_filename(module: str, filenames: list[str]): """ Returns a list of filenames matching the module name with a Fortran extension. Parameters: module (str): The module name to search for. filenames (list[str]): A list of filenames to search through. Returns: list: A list of filenames that match the module name and Fortran extension. """ import re pattern = r".*/%s\.[fFh90]" % module matches = [fn for fn in filenames if re.match(pattern, fn)] return matches
[docs] def load_intrinsics(): """ Loads the list of Fortran intrinsics from a hardcoded file. Returns: dict: A dictionary mapping the lowercase name of each intrinsic to its corresponding name. """ package_directory = dirname(abspath(__file__)) # Hardcoded path to file. with open(package_directory + "/../AdditionalFiles/fortran_intrinsics") as f: intrinsics = dict((intrinsic.split(',')[0].lower(), intrinsic.split(',')[1]) for intrinsic in f) return intrinsics
[docs] def load_variable_list(filename: str, vault: 'Vault', is_used: bool=False, precision: bool=False): """ Loads and processes a list of banned variables from a file, with options to separate by usage or apply precision settings. Parameters: filename (str): The path to the file containing variable data. vault (object): The vault containing variable data to be matched. is_used (bool): If True, separates variables by whether they are used or not. precision (bool): If True, applies precision settings to variables. Returns: list: A list of variables (or two lists if `is_used` is True). """ from numpy import genfromtxt if filename is None: return [] # Firs column will be ids of variables, second a separator. Third column: variable name var_name = genfromtxt(filename, dtype='str', usecols=2) # Fourth column the variable subprogram var_procedure = genfromtxt(filename, dtype='str', usecols=3) # Fifth column: variable module var_module = genfromtxt(filename, dtype='str', usecols=4) # If there is just one banned variable in the file, we need to convert these to 1d arrays: if var_name.ndim == 0: var_name = np.atleast_1d(var_name) var_procedure = np.atleast_1d(var_procedure) var_module = np.atleast_1d(var_module) list_of_variables = [] for v_name, v_procedure, v_module in zip(var_name, var_procedure, var_module): variable = vault.get_variable_by_info(v_name, v_procedure, v_module) list_of_variables.append(variable) if is_used: # On the last column there can be if the variables was used or not usage = genfromtxt(filename, dtype='str', usecols=5) # Separate the list between used or not return [[v for index, v in enumerate(list_of_variables) if usage[index] == 'T'], [v for index, v in enumerate(list_of_variables) if usage[index] == 'F']] elif precision: precision = genfromtxt(filename, dtype='int', usecols=5) # set the final precision for var, prec in zip(list_of_variables, precision): if prec == 10: var.type = 'hp' elif prec == 23: var.type = 'wp' else: var.type = 'dp' return list_of_variables else: # Simply return the list return list_of_variables
# Hardcoded list, this should be solved list_of_intrinsics_2fix = ["max", "maxloc", "maxval", "min", "minloc", "minval", "epsilon", "isnan", "count", "abs", "mod", "reshape", "atanh", "sqrt", "log", "sum", "erfc", "merge", "dsqrt", "cmplx", "transfer", "matmul", "dot_product"] Fortran_builtins = ["dimension", "intent", "type", "if", "elseif", "elsewhere", "while", "allocate", "deallocate", "write", "read", "open", "inquire", "close", "where", "case", "character", "format", "flush", "rewind"] list_of_key = ["dim", "mask", "kind", "back"] comparison_operators = [">=", "<=", "==", "/=", ">", "<", ".not.", ".or.", ".and.", ".false.", ".true."] allowed_externals = ['histwrite', 'NF90_GET_VAR', 'histbeg', 'xios_recv_field', 'NF90_PUT_VAR', 'wheneq' ] # List of all the intrinsic list_of_intrinsics = load_intrinsics()
[docs] def load_list_of_files_to_keep_unmodified(filename: str=None): """ Loads a list of files to keep unmodified from a specified file (defaults to a hardcoded path). Returns a list of file paths, excluding comments. Parameters: filename (str, optional): The path to the file containing the list of files. Defaults to a hardcoded path. Returns: list: A list of file paths to keep unmodified. """ if filename is None: package_directory = dirname(abspath(__file__)) filename = package_directory + "/../AdditionalFiles/list_of_files_to_keep_unmodified.txt" # Hardcoded path to file. if isfile(filename): print("Loading list of exceptions from %s\n\n" % filename) with open(filename) as f: return [l.strip() for l in f if l.strip() and l.strip()[0] != "#"] else: return None