#!/bin/sh # # depgraph # Morgan Deters, 27 October 2010 # # Builds a graphviz graph of dependences between source and header files in CVC4. # progname=`basename "$0"` postproc='sort -u' mode=packages target= if [ $# -gt 0 ]; then if [ "$1" = "-a" ]; then postproc=cat mode=headers shift fi if [ $# -gt 0 -a "$1" != "-h" ]; then target="$1" shift fi if [ $# -gt 0 ]; then echo "usage: $progname [-a] [target]" echo " -a ("all") produces _all_ headers in the source, with clusters for packages." echo " the default behavior produces just package dependence information." echo " with target, focus on dependences of that particular package (e.g. \"expr\")" exit 1 fi fi cd "`dirname \"$0\"`/.." if ! [ -d src -a -d test/unit ]; then echo "$progname: source directory malformed; is this CVC4 ?!" >&2 exit 1 fi echo "digraph G {" paths=`find src -name '*.c' \ -o -name '*.cc' \ -o -name '*.cpp' \ -o -name '*.C' \ -o -name '*.h' \ -o -name '*.hh' \ -o -name '*.hpp' \ -o -name '*.H' \ -o -name '*.y' \ -o -name '*.yy' \ -o -name '*.ypp' \ -o -name '*.Y' \ -o -name '*.l' \ -o -name '*.ll' \ -o -name '*.lpp' \ -o -name '*.L' \ -o -name '*.g'` if [ "$mode" = headers ]; then oldpackage= for path in $paths; do dir=`echo "$path" | sed 's,^\([^/]*\).*,\1,'` file=`echo "$path" | sed 's,^[^/]*/,,'` package=`echo "$file" | sed 's,^\(.*\)/.*,\1,'` file=`echo "$file" | sed 's,^.*/,,'` if [ -n "$target" -a "$target" != "$package" ]; then continue; fi if [ -n "$oldpackage" -a "$package" != "$oldpackage" ]; then echo ' }' fi if [ "$package" != "$oldpackage" ]; then echo " subgraph \"cluster$package\" {" echo " label=\"$package\";" oldpackage="$package" fi echo " \"$package/$file\"[label=\"$file\"];" done if [ -n "$oldpackage" ]; then echo ' }' fi fi for path in $paths; do dir=`echo "$path" | sed 's,^\([^/]*\).*,\1,'` file=`echo "$path" | sed 's,^[^/]*/,,'` package=`echo "$file" | sed 's,^\(.*\)/.*,\1,'` file=`echo "$file" | sed 's,^.*/,,'` incs=`grep '^# *include *".*"' "$path" | sed 's,^# *include *"\(.*\)".*,\1,'` if [ -n "$target" -a "$target" != "$package" ]; then continue; fi for inc in $incs; do case "$inc" in expr/expr.h) inc=expr/expr_template.h ;; expr/expr_manager.h) inc=expr/expr_manager_template.h ;; expr/kind.h) inc=expr/kind_template.h ;; expr/metakind.h) inc=expr/metakind_template.h ;; theory/theoryof_table.h) inc=theory/theoryof_table_template.h ;; util/integer.h) inc=util/integer.h.in ;; util/rational.h) inc=util/rational.h.in ;; util/tls.h) inc=util/tls.h.in ;; cvc4autoconfig.h) inc=cvc4autoconfig.h.in ;; esac incpath= dirpackageparent="$dir/`dirname "$package"`" for incdir in "$dir" "$dir/include" "$dir/$package" . "$dirpackageparent"; do if [ -e "$incdir/$inc" ]; then incpath="$incdir/$inc"; break; fi done if [ -z "$incpath" ]; then echo "$progname: error: can't find include file '$inc' from source '$path'" >&2 exit 1 fi incpath=`echo "$incpath" | sed 's,^\./,,'` incpath=`echo "$incpath" | sed "s,^$dir/,,"` incdir=`echo "$incpath" | sed 's,^\([^/]*\).*,\1,'` incpackage=`echo "$incpath" | sed 's,^\(.*\)/.*,\1,'` incfile=`echo "$incpath" | sed 's,^.*/,,'` if [ "$mode" = packages ]; then if [ "$package" != "$incpackage" ]; then if [ -n "$target" ]; then echo " \"$package\" -> \"$incpackage\"[label=\"$incfile\"];" else echo " \"$package\" -> \"$incpackage\";" fi fi else if [ -n "$target" ]; then [ "$package" != "$incpackage" ] && echo " \"$package/$file\" -> \"$incpackage\"[label=\"$incfile\"];" else echo " \"$package/$file\" -> \"$incpath\";" fi fi done done | $postproc echo "}"