Jim Weirich wrote:
> Brad Phelan wrote:
>> Still a native Ruby solution would be nicer.
> 
> If someone wanted to contribute a dependency scanner for their favorite 
> language to the Rake project, I would be willing to consider it for 
> inclusion.
> 
> A C/C++ scanner shouldn't be that hard to write.  Its just that I've not 
> working in a C/C++ project since starting Rake, so I've never had the 
> need to write one.
> 
> --
> -- Jim Weirich


With regards to the RANT project http://rubyforge.org/projects/make/
where I nicked the scanner this should do the job.

===========================================

module Rake
    module C
       module Include
          def Include.depends(file)
             File.open file do |f|
                txt = f.read
                parse_includes txt
             end
          end

          # Searches for all `#include' statements in the C/C++ source
          # from the string +src+.
          #
          # Returns two arguments:
          # 1. A list of all standard library includes (e.g. #include 
<stdio.h>).
          # 2. A list of all local includes (e.g. #include "stdio.h").
          def Include.parse_includes(src)
             if src.respond_to? :to_str
                src = src.to_str
             else
                raise ArgumentError, "src has to be a string"
             end
             s_includes = []
             l_includes = []
             in_block_comment = false
             prev_line = nil
             src.each { |line|
                line.chomp!
                if block_start_i = line.index("/*")
                   c_start_i = line.index("//")
                   if !c_start_i || block_start_i < c_start_i
                      if block_end_i = line.index("*/")
                         if block_end_i > block_start_i
                            line[block_start_i..block_end_i+1] = ""
                         end
                      end
                   end
                end
                if prev_line
                   line = prev_line << line
                   prev_line = nil
                end
                if line =~ /\\$/
                   prev_line = line.chomp[0...line.length-1]
                end
                if in_block_comment
                   in_block_comment = false if line =~ %r|\*/|
                   next
                end
                case line
                when /\s*#\s*include\s+"([^"]+)"/
                   l_includes << $1
                when /\s*#\s*include\s+<([^>]+)>/
                   s_includes << $1
                when %r|(?!//)[^/]*/\*|
                   in_block_comment = true
                end
             }
             [s_includes, l_includes]
          end
       end
    end
end


# RAKE Rule figures out the dependencies for the C file

rule( /\.o$/ =>

       proc do |task_name|
           a = []
           name = task_name.sub(/\.[^.]+$/, '.c')
           s_includes, l_includes = Rake::C::Include.depends(name)
           a << name
           a << l_includes
           a
       end

     ) do |t|
      sh "cc #{t.source} -c -o #{t.name}"
end


The scanner is not recursive yet but should be simple
to implement but I have to run ......

Regards

--
Brad Phelan
http://xtargets.com