Skip to content

Commit

Permalink
Update check_structures.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison committed Jan 28, 2025
1 parent d0f6a5e commit 07e2608
Showing 1 changed file with 102 additions and 40 deletions.
142 changes: 102 additions & 40 deletions .github/julia/check_structures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@ using Test

global n = 0

# Definition of a Fortran structure with an alias
lazy_definitions = Dict(
"bllsb_control_type" => "clls_control_type",
"bllsb_inform_type" => "clls_inform_type",
"bllsb_time_type" => "clls_time_type",
"bqpb_control_type" => "cqp_control_type",
"bqpb_inform_type" => "cqp_inform_type",
"bqpb_time_type" => "cqp_time_type",
"gls_ainfo_type" => "gls_ainfo",
"gls_control_type" => "gls_control",
"gls_finfo_type" => "gls_finfo",
"gls_sinfo_type" => "gls_sinfo",
"lms_control_type" => "lmt_control_type",
"lms_inform_type" => "lmt_control_type",
"lms_time_type" => "lmt_time_type",
"sils_ainfo_type" => "sils_ainfo",
"sils_control_type" => "sils_control",
"sils_finfo_type" => "sils_finfo",
"sils_sinfo_type" => "sils_sinfo",
"spral_ssids_inform" => "ssids_inform",
"spral_ssids_options" => "ssids_options",
)

mapping_types_c2f = Dict(
"[100]" => "[history_max]",
"ipc_" => "ip_",
"spc_" => "sp_",
"rpc_" => "rp_",
"int64_t" => "long_",
"bool" => "logical",
"char[2]" => "char[1]",
"char[4]" => "char[3]",
"char[13]" => "char[12]",
"char[21]" => "char[20]",
"char[31]" => "char[30]",
"char[81]" => "char[80]",
"char[401]" => "char[400]",
"char[501]" => "char[500]",
) lazy_definitions

function F_structures()
f_types = Dict{String,Vector{String}}()
f_structures = Dict{String,Vector{String}}()
Expand All @@ -15,15 +55,16 @@ function F_structures()
folders = split(root, '/')
(folders[end-1] != "src") && continue
package = folders[end]
(package == "bnls") && continue
if file == "$package.F90"
if (file == "$package.F90") || (package == "ssids" && file == "inform.F90") || (package == "ssids" && file == "datatypes.F90")
code = read(path, String)
lines = split(code, '\n')
f_contains = false
for (i, line) in enumerate(lines)
startswith(line |> strip, "!") && continue
startswith(line, "#") && continue
isempty(line) && continue
startswith(line |> strip, "PRIVATE") && continue
startswith(line |> strip, "contains") && continue
if f_struct == ""
if contains(line |> uppercase, "TYPE, PUBLIC")
f_struct = split(line, "::")[2] |> strip
Expand All @@ -38,10 +79,18 @@ function F_structures()
f_extend[f_struct] = lowercase(extension) |> strip
end
end
if contains(line |> uppercase, "TYPE SSIDS_INFORM") || contains(line |> uppercase, "TYPE SSIDS_OPTIONS")
f_struct = split(line, "type")[2] |> strip
f_types[f_struct] = String[]
f_structures[f_struct] = String[]
end
else
if contains(line |> uppercase, "END TYPE")
if startswith(line |> strip, "contains")
f_contains = true
elseif contains(line |> uppercase, "END TYPE")
f_struct = ""
else
f_contains && continue
endswith(line, "&") && continue
newline = line
j = 1
Expand All @@ -63,6 +112,7 @@ function F_structures()
type = type * "]"
end
end
type = replace(type, "len_solver" => "20")
for len in ("LEN", "len")
if contains(type, len)
type = replace(type, len => "[")
Expand All @@ -72,10 +122,11 @@ function F_structures()
field = lowercase(field)
type = lowercase(type)
type = replace(type, " " => "")
println(type)

push!(f_types[f_struct], type)
push!(f_structures[f_struct], field)
if !(field f_structures[f_struct])
push!(f_types[f_struct], type)
push!(f_structures[f_struct], field)
end
end
end
end
Expand Down Expand Up @@ -144,6 +195,7 @@ function C_structures()
type = type * "]"
end
end
field = lowercase(field)
type = lowercase(type)
type = replace(type, " " => "")

Expand Down Expand Up @@ -210,6 +262,9 @@ function H_structures()
field = split(field, "[")[1]
end
type = replace(type, "real_sp_" => "spc_")
field = lowercase(field)
type = lowercase(type)

push!(h_types[h_struct], type)
push!(h_structures[h_struct], field)
end
Expand All @@ -226,24 +281,17 @@ function diff_structures(char1::Char, structure1::Vector{String}, char2::Char, s
common_fields = intersect(structure1, structure2)
for field in unique(structure1)
if !(field in common_fields)
println("• [$char1] -- The field $field is missing.")
end
ncount = mapreduce(x -> x == field, +, structure1, init=0)
if ncount > 1
println("• [$char1] -- The field $field appears $ncount times in the structure.")
println("• The field `$field` is in the `$char1` structure but not the `$char2` structure.")
end
end
for field in structure2
if !(field in common_fields)
if (field != "f_indexing") || !(char1 == 'F' && char2 == 'C')
println("• [$char2] -- The field $field is missing.")
end
ncount = mapreduce(x -> x == field, +, structure2, init=0)
if ncount > 1
println("• [$char2] -- The field $field appears $ncount times in the structure.")
println("• The field `$field` is in the `$char2` structure but not the `$char1` structure.")
end
end
end
println()
end

f_types, f_structures = F_structures()
Expand Down Expand Up @@ -271,6 +319,9 @@ println("-------------------------------------------------------------")
println("The following structures are only defined in the C interfaces")
println("-------------------------------------------------------------")
for val in c_list
if val in keys(lazy_definitions)
val = lazy_definitions[val]
end
if !(val in f_list)
println(val)
global n += 1
Expand All @@ -282,27 +333,28 @@ println("--------------Check errors in H / C structures---------------")
println("-------------------------------------------------------------")
for structure in c_list
if !(structure in h_list)
println("The structure $structure can't be find in a header file.")
println("The structure `$structure` can't be find in a header file.")
global n += 1
else
package = split(structure, '_')[1] |> uppercase
c_nfields = length(c_structures[structure])
h_nfields = length(h_structures[structure])
if c_nfields != h_nfields
println("The structure $structure has missing attributes (H:$h_nfields / C:$c_nfields).")
println("[$package] -- The structure `$structure` has missing attributes (H:$h_nfields / C:$c_nfields).")
diff_structures('H', h_structures[structure], 'C', c_structures[structure])
global n += 1
else
for i = 1:h_nfields
h_field = h_structures[structure][i]
c_field = c_structures[structure][i]
if h_field != c_field
println("The field $i of the structure $structure is not consistent (H:$h_field / C:$c_field).")
println("[$package] -- The field $i of the structure `$structure` is not consistent (H:$h_field / C:$c_field).")
global n += 1
else
h_type = h_types[structure][i]
c_type = c_types[structure][i]
if h_type != c_type
println("The type of field $(h_field) of the structure $structure is not consistent (H:$h_type / C:$c_type).")
println("[$package] -- The type of field `$(h_field)` of the structure `$structure` is not consistent (H:$h_type / C:$c_type).")
global n += 1
end
end
Expand All @@ -315,31 +367,41 @@ println("-------------------------------------------------------------")
println("--------------Check errors in F / C structures---------------")
println("-------------------------------------------------------------")
for structure in c_list
if structure in f_list
f_nfields = length(f_structures[structure])
haskey(lazy_definitions, structure)
structure2 = haskey(lazy_definitions, structure) ? lazy_definitions[structure] : structure
if !(structure2 in f_list)
println("The structure `$(structure2)` can't be find in a Fortran file.")
global n += 1
else
package = split(structure, '_')[1] |> uppercase
f_nfields = length(f_structures[structure2])
c_nfields = length(c_structures[structure])
c_nfields = ("f_indexing" in c_structures[structure]) ? c_nfields-1 : c_nfields

if f_nfields != c_nfields
println("The structure $structure has missing attributes (F:$f_nfields / C:$c_nfields).")
diff_structures('F', f_structures[structure], 'C', c_structures[structure])
println("[$package] -- The structure `$structure` has missing attributes (F:$f_nfields / C:$c_nfields).")
diff_structures('F', f_structures[structure2], 'C', c_structures[structure])
global n += 1
# else
# for i = 1:f_nfields
# f_field = f_structures[structure][i]
# c_field = c_structures[structure][i]
# if f_field != c_field
# println("The field $i of the structure $structure is not consistent (F:$f_field / C:$c_field).")
# global n += 1
# else
# f_type = f_types[structure][i]
# c_type = c_types[structure][i]
# if f_type != c_type
# println("The type of field $(h_field) of the structure $structure is not consistent (F:$f_type / C:$c_type).")
# global n += 1
# end
# end
# end
else
for (i, c_field) in enumerate(c_structures[structure])
(c_field == "f_indexing") && continue
if !(c_field in f_structures[structure2])
println("[$package] -- The field `$(c_field)` of the C structure `$structure` can't be found in the Fortran structure `$structure2`.")
global n += 1
else
j = findfirst(str -> str == c_field, f_structures[structure2])
c_type = c_types[structure][i]
f_type = f_types[structure2][j]
c_type2 = c_type
for (key, val) in mapping_types_c2f
c_type2 = replace(c_type2, key => val)
end
if (c_type != f_type) && (c_type2 != f_type)
println("[$package] -- The type of field `$(c_field)` of the structures `$structure2` (Fortran) and `$structure` (C) is not consistent (F:$f_type / C:$c_type).")
global n += 1
end
end
end
end
end
end
Expand Down

0 comments on commit 07e2608

Please sign in to comment.