diff --git a/mkhelper/depgen.py b/mkhelper/depgen.py index 75d52c1..715def3 100755 --- a/mkhelper/depgen.py +++ b/mkhelper/depgen.py @@ -534,7 +534,7 @@ def format_debug_line(line, msg): parser.include_callback = include_callback parser.module_start_callback = lambda module: provided_modules.add( module - ) or (args.fc_root_smod and provided_submodules.add((module, None))) + ) parser.submodule_start_callback = ( lambda submodule, parent, module: provided_submodules.add( (module, submodule) @@ -547,6 +547,11 @@ def format_debug_line(line, msg): ) parser.module_use_callback = lambda module: required_modules.add(module) + if args.fc_root_smod: + parser.extendable_module_callback = ( + lambda module: provided_submodules.add((module, None)) + ) + if args.debug: parser.debug_callback = lambda line, msg: ftn_debug_info.append( format_debug_line(line, msg) diff --git a/mkhelper/depgen/fortran.py b/mkhelper/depgen/fortran.py index 92ac1bd..757303e 100644 --- a/mkhelper/depgen/fortran.py +++ b/mkhelper/depgen/fortran.py @@ -53,6 +53,12 @@ class Parser: r"^\s*use(?:\s+|(?:\s*,\s*((?:non_)?intrinsic))?\s*::\s*)(\w+)", re.I ) _re_module_end = re.compile(r"^\s*end\s+module(?:\s+(\w+))?\s*$", re.I) + _re_module_prefixed_procedure = re.compile( + r"^\s*(?:\w+(?:\(.*\))?\s+)*" + r"module\s+" + r"(?:\w+(?:\(.*\))?\s+)*(?:function|subroutine)", + re.I, + ) def __init__( self, @@ -84,6 +90,7 @@ def __init__( self.module_start_callback = None self.submodule_start_callback = None self.module_use_callback = None + self.extendable_module_callback = None self.debug_callback = None self._include_finder = IncludeFinder(include_order, include_dirs) @@ -95,6 +102,7 @@ def parse(self, stream, stream_name): include_stack.push(stream, stream_name) current_module = None + current_module_is_extendable = False for line in Parser.streamline_input(include_stack): # module definition start @@ -213,7 +221,39 @@ def parse(self, stream, stream_name): self.debug_callback(line, "ignored (file not found)") continue - if self.debug_callback is None: + if not (self.extendable_module_callback or self.debug_callback): + continue + + # procedure with the module prefix + match = Parser._re_module_prefixed_procedure.match(line) + if match: + if current_module: + if current_module_is_extendable: + if self.debug_callback: + self.debug_callback( + line, + "ignored module subroutine/function " + "(module '{0}' is already known " + "to be extendable)".format(current_module), + ) + else: + current_module_is_extendable = True + if self.extendable_module_callback: + self.extendable_module_callback(current_module) + if self.debug_callback: + self.debug_callback( + line, + "module subroutine/function " + "(module '{0}' is extendable)".format( + current_module + ), + ) + elif self.debug_callback: + self.debug_callback( + line, + "ignored module subroutine/function " + "(not in the module scope)".format(current_module), + ) continue # module definition end @@ -245,6 +285,7 @@ def parse(self, stream, stream_name): ), ) current_module = None + current_module_is_extendable = False continue include_stack.clear()