142 lines
3.5 KiB
Tcl
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
|