@@ -648,6 +648,12 @@ def parse_fortran_function(file_path: Path, suppress_warnings=False):
648648 char_vars = set()
649649 logical_vars = set()
650650 array_vars = set()
651+
652+ do_real = False
653+ do_int = False
654+ do_char = False
655+ do_cplx = False
656+ do_logical = False
651657
652658 # Find the argument declaration section
653659 lines = content.split('\n')
@@ -666,99 +672,58 @@ def parse_fortran_function(file_path: Path, suppress_warnings=False):
666672 continue
667673
668674 # Also look for the actual declaration lines (not in comments)
669- if line_stripped and not line_stripped.startswith('*') and not line_stripped.startswith('C ') and in_args_section:
670- # Look for ARRAY variables
671- is_array = ('(' in line_stripped) and (')' in line_stripped) # Probably better: re.search(r'(\s*\*\s*)', line_stripped) != None
675+ if in_args_section and line_stripped and not line_stripped.startswith('*') and not line_stripped.startswith('C '):
672676
673677 # Parse variable declarations
674678 if looking_for_var_decl.startswith('REAL') or looking_for_var_decl.startswith('DOUBLE PRECISION') or looking_for_var_decl.startswith('FLOAT'):
675- # Extract variable names from REAL, DOUBLE PRECISION, or FLOAT declaration
676- real_decl = re.search(r'(?:REAL|DOUBLE PRECISION|FLOAT)\*?\d*(?:\(\w+\))?\s+(.+)', line_stripped, re.IGNORECASE)
677- if real_decl:
678- vars_str = real_decl.group(1)
679- # Before anything, remove F90 style '::' declaration
680- vars_str = vars_str.split("::")[-1]
681- # First remove array dimensions, then split by comma
682- vars_str_clean = re.sub(r'\([^)]*\)', '', vars_str)
683- # Split by comma and clean up
684- for var in vars_str_clean.split(','):
685- var = var.strip()
686- # Remove any remaining modifiers
687- var = re.sub(r'\*.*$', '', var)
688- if var and re.match(r'^[A-Za-z][A-Za-z0-9_]*$', var):
689- real_vars.add(var)
690- if is_array:
691- array_vars.add(var)
692-
693- elif looking_for_var_decl.startswith('INTEGER'):
694- int_decl = re.search(r'INTEGER\s+(.+)', line_stripped, re.IGNORECASE)
695- if int_decl:
696- vars_str = int_decl.group(1)
697- # Before anything, remove F90 style '::' declaration
698- vars_str = vars_str.split("::")[-1]
699- # First remove array dimensions, then split by comma
700- vars_str_clean = re.sub(r'\([^)]*\)', '', vars_str)
701- for var in vars_str_clean.split(','):
702- var = var.strip()
703- var = re.sub(r'\*.*$', '', var)
704- if var and re.match(r'^[A-Za-z][A-Za-z0-9_]*$', var):
705- integer_vars.add(var)
706- if is_array:
707- array_vars.add(var)
708-
679+ do_real = True
680+ do_int = False
681+ do_char = False
682+ do_cplx = False
683+ do_logical = False
684+ elif looking_for_var_decl.startswith('INTEGER'):
685+ do_real = False
686+ do_int = True
687+ do_char = False
688+ do_cplx = False
689+ do_logical = False
709690 elif looking_for_var_decl.startswith('CHARACTER'):
710- char_decl = re.search(r'CHARACTER\s+(.+)', line_stripped, re.IGNORECASE)
711- if char_decl:
712- vars_str = char_decl.group(1)
713- # Before anything, remove F90 style '::' declaration
714- vars_str = vars_str.split("::")[-1]
715- # First remove array dimensions, then split by comma
716- vars_str_clean = re.sub(r'\([^)]*\)', '', vars_str)
717- for var in vars_str_clean.split(','):
718- var = var.strip()
719- var = re.sub(r'\*.*$', '', var)
720- if var and re.match(r'^[A-Za-z][A-Za-z0-9_]*$', var):
721- char_vars.add(var)
722- if is_array:
723- array_vars.add(var)
724-
725- elif looking_for_var_decl.startswith('COMPLEX'):
726- # Extract variable names from COMPLEX declaration
727- complex_decl = re.search(r'COMPLEX\*?\d*(?:\(\w+\))?\s+(.+)', line_stripped, re.IGNORECASE)
728- if complex_decl:
729- vars_str = complex_decl.group(1)
730- # Before anything, remove F90 style '::' declaration
731- vars_str = vars_str.split("::")[-1]
732- # First remove array dimensions, then split by comma
733- vars_str_clean = re.sub(r'\([^)]*\)', '', vars_str)
734- # Split by comma and clean up
735- for var in vars_str_clean.split(','):
736- var = var.strip()
737- # Remove any remaining modifiers
738- var = re.sub(r'\*.*$', '', var)
739- if var and re.match(r'^[A-Za-z][A-Za-z0-9_]*$', var):
740- complex_vars.add(var) # Add complex variables to complex_vars
741- if is_array:
742- array_vars.add(var)
743-
691+ do_real = False
692+ do_int = False
693+ do_char = True
694+ do_cplx = False
695+ do_logical = False
696+ elif looking_for_var_decl.startswith('COMPLEX'):
697+ do_real = False
698+ do_int = False
699+ do_char = False
700+ do_cplx = True
701+ do_logical = False
744702 elif looking_for_var_decl.startswith('LOGICAL'):
745- if not keep_going:
746- # Extract variable names from COMPLEX declaration
747- bool_decl = re.search(r'LOGICAL\*?\d*(?:\(\w+\))?\s+(.+)', line_stripped, re.IGNORECASE)
748- if bool_decl:
749- vars_str = bool_decl.group(1)
750- # First remove array dimensions, then split by comma
751- vars_str_clean = re.sub(r'\([^)]*\)', '', vars_str)
752- if vars_str_clean:
753- # Split by comma and clean up
754- for var in vars_str_clean.split(','):
755- var = var.strip()
756- # Remove any remaining modifiers
757- var = re.sub(r'\*.*$', '', var)
758- if var and re.match(r'^[A-Za-z][A-Za-z0-9_]*$', var):
759- logical_vars.add(var) # Add complex variables to complex_vars
760- if is_array:
761- array_vars.add(var)
703+ do_real = False
704+ do_int = False
705+ do_char = False
706+ do_cplx = False
707+ do_logical = True
708+ # vars_decl = re.search(r'(?:REAL|DOUBLE PRECISION|FLOAT|INTEGER|LOGICAL|COMPLEX|CHARACTER){0,1}(?:\((?:kind=){0,1}\w+\)){0,1}(?:,\s*INTENT\(\s*(?:IN|OUT|INOUT)\s*\)){0,1}\s*(?:\:\:){0,1}\s*(.*)', s, re.IGNORECASE).group(1)
709+ vars_decl = re.search(r'(?:REAL|DOUBLE PRECISION|FLOAT|INTEGER|LOGICAL|COMPLEX|CHARACTER)?(?:\((?:kind=){0,1}\w+\))?(?:,\s*INTENT\(\s*(?:IN|OUT|INOUT)\s*\)){0,1}\s*(?:\:\:)?\s*(.*)', line_stripped, re.IGNORECASE).group(1)
710+ for var in re.findall(r'\w+(?:\([^)]*\))?', vars_decl):
711+ var = var.strip()
712+ # Look for ARRAY variables
713+ is_array = ('(' in var) and (')' in var)
714+ if is_array:
715+ var = re.sub(r'\([^)]*\)', '', var)
716+ array_vars.add(var)
717+ if do_real:
718+ real_vars.add(var)
719+ elif do_int:
720+ integer_vars.add(var)
721+ elif do_char:
722+ char_vars.add(var)
723+ elif do_cplx:
724+ complex_vars.add(var)
725+ elif do_logical:
726+ logical_vars.add(var)
762727
763728 # For FUNCTIONs with explicit return types, add function name to appropriate variable set
764729 if func_type == 'FUNCTION':
0 commit comments