Files
Fortran-docker-mvc/flibs-0.9/flibs/app/dependencies.tcl
Tommy Parnell a7037b9e92 init
2017-02-20 16:06:45 -05:00

142 lines
3.5 KiB
Tcl

# dependencies.tcl
# Examine the available Fortran sources and set up a
# list of dependencies for use in make for instance
#
# Limitations:
# - include files are not examined
# - no directory information about where to find the include file
# is taken into account (that is: no -I options!)
# - include files with a Fortran-type extensions are examined
# as if they were ordinary source files, thus leading to
# too many source files in the dependency list
#
# getDependencyItems --
# Analyse the file and return a list of items
# Arguments:
# filename Name of the file to examine
# Result:
# A list of lists:
# - Element 1 is a list of modules defined in the file
# - Element 2 is a list of external modules referred to in the file
# - Element 3 is a list of include files
#
proc getDependencyItems {filename} {
set infile [open $filename r]
set provided {}
set required {}
set include {}
while { [gets $infile line] >= 0 } {
switch -re -- [string tolower $line] {
{ *include +['"]} {
lappend include [GetInclude $line]
}
{ *use +[a-z]} {
lappend required [GetUse $line]
}
{ *module +[a-z]} {
lappend provided [GetModule $line]
}
}
}
return [list $provided $required $include]
}
# GetInclude, GetUse, GetModule --
# Extract the relevant information from the list
# Arguments:
# line Line of code
# Result:
# Name of a file or a module
#
proc GetInclude {line} {
return [lindex [split $line {'"}] 1]
}
proc GetUse {line} {
return [lindex $line 1]
}
proc GetModule {line} {
return [lindex $line 1]
}
# ObjectFile, ModuleFile --
# Transform the file name
# Arguments:
# name Source file/module name
# Result:
# Name of a file or a module
#
proc ObjectFile {name} {
return "[file root $name].o"
}
proc ModuleFile {name} {
return "[string toupper $name].mod"
}
# analyseAllFiles --
# Analyse all files in the current directory
# Arguments:
# filename Name of the file for dependencies
# type Type of output ("make" or "ordered")
# Result:
# None
#
proc analyseAllFiles {filename type} {
set outfile [open $filename w]
if { $::tcl_platform(platform) == "windows" } {
set mask "*.f *.for *.f90"
} else {
set mask "*.f *.for *.f90 *.F *.FOR *.F90"
}
set files {}
foreach f [eval glob -type f $mask] {
foreach {provided required include} [getDependencyItems $f] {break}
set deps($f) {}
foreach i $include {
lappend deps($f) $i
}
foreach m $provided {
set mod [ModuleFile $m]
lappend files $mod
set deps($mod) $f
}
foreach m $required {
set mod [ModuleFile $m]
set deps($f) $mod
}
lappend files $f
}
switch -- $type {
"make" {
foreach f $files {
if { [lsearch {.f .for .f90 .F .FOR .F90} [file extension $f]] >= 0 } {
puts $outfile [ObjectFile $f]\t:\t$f\n\t[join $deps($f) \\\n\t]
} else {
puts $outfile $f\t:\t[join $deps($f) \\\n\t]
}
}
}
"ordered" {
puts "TO BE DONE!"
}
}
close $outfile
}
# main --
# Get the thing going
#
analyseAllFiles test.mk make