Last active
August 29, 2015 14:13
Revisions
-
Karsten Meier revised this gist
Jan 18, 2015 . 1 changed file with 5 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,10 @@ #!/usr/bin/env ruby -w # # construct dependency graph for C/C++ projects. # input is directory with c and h files. # output as plain text or as dot file for processing with graphviz # # Copyright (c) 2004-2015 by Karsten Meier, http://meier-online.com # This program is free software. # You can distribute/modify this program under the terms of # the GNU General Public License version as published by @@ -100,7 +102,7 @@ def dotname(filename) exit } opts.on("-d", "--dotoutput=FILE", String, "Create dot output file"){ |filename| @dotoutputfile = filename } opts.parse! end -
handylearn created this gist
Jan 18, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,125 @@ #!/usr/bin/env ruby -w # # construct dependency graph for C/C++ projects # # Copyright (c) 2004 by Karsten Meier, http://meier-online.com # This program is free software. # You can distribute/modify this program under the terms of # the GNU General Public License version as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # require 'find' require 'optparse' # $/ = "\r" # uncomment for macintosh linebreaks # get all source files under a directory. # a source file is either a .c file or a .h file def get_source_files(startpath) sources = [] Find.find(startpath) do |filename| if /\.c[p]*$/.match(filename) sources.push filename end if /\.h$/.match(filename) sources.push filename end end sources end class IncludeAnalyser def initialize @dependend = Hash.new{Array.new} end def extract_dependency(filename) File.open(filename).each { |line| if /^\#include\s*\"([\w\.]+)\"/.match(line) add_dependency(filename, $1) end if /^\#include\s*\<([\w\.]+)\>/.match(line) add_dependency(filename, $1) end } end def add_dependency(sourcepath, included) base = File.basename(sourcepath) if @dependend[base].empty? @dependend[base] = [included] else @dependend[base].push(included) end end def print_all @dependend.each{|source, includes| print_childs(source, 0) # puts "Source #{source}" # puts "Includes #{includes.join(' ')}" } end def print_childs(source, level) puts(" " * level + source) for child in @dependend[source] print_childs(child, level + 1) end end def print_dot(stream) stream.puts "digraph G {" stream.puts " rankdir=LR;" stream.puts " node [shape=rect];" @dependend.each{|source, includes| for include in includes stream.puts " #{dotname(source)} -> #{dotname(include)};" end } stream.puts "}" end def dotname(filename) filename.sub(/\./,'_') end end # ----- analysing of command line arguments ARGV.options do |opts| opts.banner = "Usage: ruby #{$0} [-d DOTOUTPUTFILE] INPUTDIRECTORY" opts.on("-h", "--help", "show this message"){ puts opts exit } opts.on("-d", "--dotoutput=FILE", String, "Create dot output file"){ |@dotoutputfile| } opts.parse! end # ----- main program files = [] for path in ARGV files = files + get_source_files(path) end analyser = IncludeAnalyser.new for file in files analyser.extract_dependency(file) end if defined? @dotoutputfile File.open(@dotoutputfile, "w"){ |stream| analyser.print_dot(stream) } else analyser.print_all end