inter-package dependence graph generation (in dot format)
authorMorgan Deters <mdeters@gmail.com>
Wed, 27 Oct 2010 05:02:29 +0000 (05:02 +0000)
committerMorgan Deters <mdeters@gmail.com>
Wed, 27 Oct 2010 05:02:29 +0000 (05:02 +0000)
contrib/depgraph [new file with mode: 0644]

diff --git a/contrib/depgraph b/contrib/depgraph
new file mode 100644 (file)
index 0000000..c03c220
--- /dev/null
@@ -0,0 +1,113 @@
+#!/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
+
+if [ $# -gt 0 ]; then
+  if [ $# -eq 1 -a "$1" = "-a" ]; then
+    postproc=cat
+    mode=headers
+  else
+    echo "usage: $progname [-a]"
+    echo "  -a ("all") produces _all_ headers in the source, with clusters for packages."
+    echo "  the default behavior produces just package dependence information."
+    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 "$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,'`
+    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/,,"`
+      if [ "$mode" = packages ]; then
+        incdir=`echo "$incpath" | sed 's,^\([^/]*\).*,\1,'`
+        incpackage=`echo "$incpath" | sed 's,^\(.*\)/.*,\1,'`
+        incfile=`echo "$incpath" | sed 's,^.*/,,'`
+        [ "$package" != "$incpackage" ] && echo "  \"$package\" -> \"$incpackage\";"
+      else
+        echo "  \"$package/$file\" -> \"$incpath\";"
+      fi
+    done
+  done | $postproc
+
+echo "}"