Commit 8782985c authored by sparonuz's avatar sparonuz
Browse files

[run_@r14986]: Fix for Issue #155

parent d5933db7
......@@ -162,7 +162,7 @@ def insert_variable_precision_specification_to_allocatable(variable, counter_obj
break
else:
# Check that we did not match a member with the same name: a_i will also match %a_i
if re.search(RegexPattern.allocation_member_name % variable.name, line.replace(" ",""), re.I):
if re.search(RegexPattern.allocation_member_name % variable.name, line.replace(" ", ""), re.I):
continue
member_name = None
variable.id = counter_object.count
......@@ -462,6 +462,35 @@ def find_call_in_original_file(subprogram, argument, argument_index, _file, targ
return False
def find_subprogram_lines(subprogram, module):
indices = []
# if module is None:
# module = subprogram.module
begin_pattern = RegexPattern.subprogram_name_declaration % subprogram.name
end_pattern = RegexPattern.subprogram_name_end_declaration % subprogram.name
# First find the subprogram body inside the module
for index, line in enumerate(module.lines):
# If it's the start or end of the subprogram
line = BasicFunctions.remove_comments(line)
if re.search(begin_pattern, line, re.I):
indices.append(index)
# End of the program was hit
if re.search(end_pattern, line, re.I):
break
if not len(indices):
raise Error.ProcedureNotFound
# In case more than one start/end index was found:
#
# #if defined key_agrif
# RECURSIVE SUBROUTINE stp_MLF( )
# INTEGER :: kstp ! ocean time-step index
# #else
# SUBROUTINE stp_MLF( kstp )
# INTEGER, INTENT(in) :: kstp ! ocean time-step index
# #endif
#
# return the broader range
return indices[0], indices[-1]
## PRIVATE
......@@ -473,77 +502,59 @@ class Counter:
def up(self, how_much=1):
self.count += how_much
def find_first_use(variable):
procedure = variable.procedure
module = procedure.module
subprogram = variable.procedure
module = subprogram.module
# pattern = '(^|\W+)%s(\W+|$)' % variable.name
pattern = r'\W*%s\W*' % variable.name
searching = False
loop_level = 0
loop_start = None
in_where_statement = False
where_level = 0
where_statement_start = None
# Scroll all the lines
for line_index, line in enumerate(module.lines):
line = line.strip().lower()
# Until it finds the subroutine to which the variables belongs (routine.name)
if not searching:
match = re.search(r"(subroutine|function)\s+\b%s\b" % procedure.name, line, re.IGNORECASE)
if match:
searching = True
# In the subroutine
else:
# Scroll all the lines searching for the first use
if re.search(pattern, line, re.IGNORECASE):
# skip declarations: bad workaround, but avoids false positive that will block compilation.
if line.count("::") or line.lower().count("implicit none"):
continue
# Skip the first line
elif line.count("subroutine"):
# Reach the end: the variable has not been used
if line.count("end subroutine"):
break
continue
# Skip import statements
elif line.find("use ") == 0:
continue
# Other statement
elif line.find("data ") == 0:
continue
# Find start and end of subprogram declaration
indices = find_subprogram_lines(subprogram, module)
# Search for first use, avoiding subprogram declaration and end lines
for line_index, line in enumerate(module.lines[indices[0] + 1:indices[1]]):
# Skip all declarations to avoids false positive that will block compilation.
if line.count("::") or line.lower().count("implicit none") or line.find("use ") == 0:
continue
# Scroll subprogram's lines searching for the first use
if re.search(RegexPattern.variable_name_occurrence % variable.name, line, re.IGNORECASE):
# Check the variable is not mentioned in a ".NOT.PRESENT" statement
if _check_if_condition(line, variable.name):
continue
# The variable is found
if where_level > 0:
# Inside a where statement
return module, indices[0] + where_statement_start
else:
# In a (nested) loop
if loop_level > 0:
return module, indices[0] + loop_start
# On a normal line
else:
# Check the variable is not mentioned in a ".NOT.PRESENT" statement
if _check_if_condition(line, variable.name):
continue
# The variable is found
if in_where_statement:
# Inside a where statement
return module, where_statement_start
else:
# In a (nested) loop
if loop_level > 0:
return module, loop_start
# On a normal line
else:
return module, line_index
elif line.count("end subroutine"):
break
# Whenever a 'do loop' starts increment nesting index
elif re.search(r"^ *do *[\w]* *=", line, re.IGNORECASE):
if loop_level == 0:
loop_start = line_index
loop_level += 1
# Whenever a 'do loop' ends decrement nesting index
# This way match bot the expression 'end do' and 'enddo' but excludes matches like 'enddo loop_name'
elif re.search(r"^ *end\s*do", line, re.IGNORECASE):
loop_level -= 1
# Do the same for where statement
elif line.find("where") == 0:
in_where_statement = True
return module, indices[0] + line_index
# Whenever a 'do loop' starts increment nesting index
elif re.search(r"^ *do *[\w]* *=", line, re.IGNORECASE):
if loop_level == 0:
loop_start = line_index
loop_level += 1
# Whenever a 'do loop' ends decrement nesting index
# This way match bot the expression 'end do' and 'enddo' but excludes matches like 'enddo loop_name'
elif re.search(r"^ *end\s*do", line, re.IGNORECASE):
loop_level -= 1
# Do the same for where statement
elif line.lower().strip().find("where") == 0:
if where_level == 0:
where_statement_start = line_index
elif line.find("end where") == 0:
in_where_statement = False
where_level += 1
elif line.lower().strip().find("end where") == 0:
where_level -= 1
# The variable was not found in the subroutine
return None, None
......
......@@ -226,41 +226,10 @@ def find_structure_declarations_index(structure, module):
return [start, end]
def find_subprogram_lines(subprogram, module):
indices = []
# if module is None:
# module = subprogram.module
begin_pattern = RegexPattern.subprogram_name_declaration % subprogram.name
end_pattern = RegexPattern.subprogram_name_end_declaration % subprogram.name
# First find the subprogram body inside the module
for index, line in enumerate(module.lines):
# If it's the start or end of the subprogram
line = BasicFunctions.remove_comments(line)
if re.search(begin_pattern, line, re.I):
indices.append(index)
# End of the program was hit
if re.search(end_pattern, line, re.I):
break
if not len(indices):
raise Error.ProcedureNotFound
# In case more than one start/end index was found:
#
# #if defined key_agrif
# RECURSIVE SUBROUTINE stp_MLF( )
# INTEGER :: kstp ! ocean time-step index
# #else
# SUBROUTINE stp_MLF( kstp )
# INTEGER, INTENT(in) :: kstp ! ocean time-step index
# #endif
#
# return the broather range
return indices[0], indices[-1]
def find_subprogram_declarations_index(subprogram, module):
"""Find start and end indexes of variables declaration in subprogram code """
# Find start and end of subprogram declaration
indices = find_subprogram_lines(subprogram, module)
indices = Inserter.find_subprogram_lines(subprogram, module)
start = -1
end = 0
......@@ -452,7 +421,7 @@ def arguments_to_cast(subprogram_call):
if dummy_a.intent == "in":
# If is wp, maintain wp
# If is sp for sure there is a dp version of this, otherwise the code would not work in dp
if dummy_a.type in [VariablePrecision.real_id['sp'], VariablePrecision.real_id['wp']]:
if dummy_a.type in [VariablePrecision.real_id['sp'], VariablePrecision.real_id['wp']]:
cast_precision = "wp"
else:
# There is no sp/dp interface (otherwise we would be in the other branch of the if/else)
......
......@@ -8,6 +8,7 @@ number_exp_DPE_notation = r'\s*\d+\.?\d*[e|d][+|-]*\d+[\w]*'
#### VARIABLE
variable = r"^\w+$"
variable_name_occurrence = r'\W*%s\W*'
#### ARRAY
# Matches simple array, and sliced array
array = r"\w+\s*\(\s*[\w,:\d\s+\-\*=]+\s*\)"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment