From: Brad Phelan Date: 2007-08-16T18:54:58+09:00 Subject: Re: Rake and Rant 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 ). # 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