Class: Funit::Depend

Inherits:
Object
  • Object
show all
Defined in:
lib/funit/fortran_deps.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(searchPath = %w[ ../lib . ]) ⇒ Depend

Returns a new instance of Depend.



21
22
23
24
25
26
# File 'lib/funit/fortran_deps.rb', line 21

def initialize( searchPath = %w[ ../lib . ] )
  @parsed = Array.new
  @hash = build_hash_of_modules_in_files_within searchPath
  @file_dependencies = Hash.new
  @source_files = Array.new
end

Instance Attribute Details

#file_dependenciesObject (readonly)

Returns the value of attribute file_dependencies.



19
20
21
# File 'lib/funit/fortran_deps.rb', line 19

def file_dependencies
  @file_dependencies
end

#source_filesObject (readonly)

Returns the value of attribute source_files.



19
20
21
# File 'lib/funit/fortran_deps.rb', line 19

def source_files
  @source_files
end

Instance Method Details

#build_dictionary_of_modules_in(files) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/funit/fortran_deps.rb', line 40

def build_dictionary_of_modules_in( files )
  file_containing_module = Hash.new
  files.each do |file|
    modules_defined_in( file ).each{ |mod| file_containing_module[mod]=file }
  end
  file_containing_module
end

#build_hash_of_modules_in_files_within(searchPath = %w[../lib .]) ⇒ Object



55
56
57
# File 'lib/funit/fortran_deps.rb', line 55

def build_hash_of_modules_in_files_within( searchPath = %w[../lib .] )
  build_dictionary_of_modules_in( fortran_files_within( searchPath ) )
end

#dependencies(start) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/funit/fortran_deps.rb', line 83

def dependencies( start )
  modules = modules_used_in( start )
  @parsed = @parsed || [start]
  newSourceFiles = modules.collect{ |mod| @hash[mod] }.compact
  makefile_dependency_line(start) +
  newSourceFiles.collect do |file|
    next if @parsed.include?(file)
    @parsed.push file
    dependencies file
  end.to_s
end

#fortran_files_within(search_path = %w[ ../lib . ]) ⇒ Object



48
49
50
51
52
53
# File 'lib/funit/fortran_deps.rb', line 48

def fortran_files_within( search_path = %w[ ../lib . ] )
  source = search_path.map{ |path| Dir[path+"/*.[fF]90"] }
  source.flatten!.uniq!
  source.delete_if{ |file| File.lstat(file).symlink? }
  source.delete_if{ |file| file.match(/lmpi_module_template.F90/) }
end

#makefile_dependency_line(source) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/funit/fortran_deps.rb', line 59

def makefile_dependency_line( source )
  realSource = source.sub(/PHYSICS_DUMMY/,'PHYSICS_MODULES')# What's this?
  sourceNoPath = File.basename source
  @source_files.push sourceNoPath.gsub(%r|^.*/|,'')
  output = ''
  if (File.expand_path(source) != File.expand_path(sourceNoPath))
    output += sourceNoPath+ ": " + realSource + "\n"
    output += "\tln -sf "+realSource+" .\n"
  end
  output += source.gsub(/\.(f|F)90$/, ".o").gsub(%r|^.*/|,"" ) +
            ": " + source.gsub(%r|^.*/|,"" ) 
  modules_used_in( source ).each do |use|
    unless @hash[use]
      unless ( use=~/f90_unix/ || use=~/nas_system/ )
        $stderr.puts "Warning: unable to locate module #{use} used in #{source}." if $DEBUG
      end
      next
    end
    output = output + " \\\n " +
             @hash[use].gsub(/\.(f|F)90$/, ".o").gsub(%r|^.*/|,"" )
  end
  output+"\n"
end

#modules_defined_in(file) ⇒ Object



34
35
36
37
38
# File 'lib/funit/fortran_deps.rb', line 34

def modules_defined_in( file )
  modules = IO.readlines( file ).map do |line| 
    $1.downcase if line.match( /^\s*module\s+(\w+)/i )
  end.uniq.compact
end

#modules_used_in(file) ⇒ Object



28
29
30
31
32
# File 'lib/funit/fortran_deps.rb', line 28

def modules_used_in( file )
  modules = IO.readlines( file ).map do |line|
    $1.downcase if line.match( /^\s*use\s+(\w+)/i )
  end.uniq.compact
end

#required_source_files(head_f90) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/funit/fortran_deps.rb', line 106

def required_source_files( head_f90 )
  @parsed.clear
  source_file_dependencies( head_f90 )
  sources = Array.new
  while ! @file_dependencies.empty? do
    no_dependents_pair = @file_dependencies.detect{ |h,d| d == [] }
    no_dependents = no_dependents_pair.first
    sources.push no_dependents
    @file_dependencies.delete(no_dependents){ |el| "#{el} not found" }
    @file_dependencies.each_value{ |deps| deps.delete(no_dependents) }
  end
  sources
end

#source_file_dependencies(head_f90) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'lib/funit/fortran_deps.rb', line 95

def source_file_dependencies( head_f90 )
  modules_head_uses = modules_used_in( head_f90 )
  required_f90s = modules_head_uses.map{ |mod| @hash[mod] }.compact
  @file_dependencies[head_f90] = required_f90s
  required_f90s.each do |required_f90|
    next if @parsed.include?(required_f90)
    source_file_dependencies( required_f90 )
  end
  @parsed.push head_f90
end