#!/bin/sh # Cdeps.cgi 1.0, see http://dirk.rave.org/cdeps.html # This is a cool but not particularly useful demo of cdeps. When dropped # among 10 to 20 interdependent source and header files it generates # a nice website with a clickable cdeps -z map. # For extra coolness value, the maps are always generated on demand, # without any caching. # Best use ordinary cdeps first to check if everything works fine, and to # generate a cdeps.db if this is desired. (Files only known from the # cdeps.db database will not be clickable in the map.) # Cdeps itself is well-documented, the comments are not repeated here. TEMPFILES=`mktemp -d ./run.XXXXXX` CTAGS=ctags if which ectags >/dev/null 2>&1; then CTAGS=ectags; fi if test -e cdeps.db; then ln -f cdeps.db $TEMPFILES/cdeps.db else $CTAGS -x --c-kinds=pd --file-scope=no *.c *.h | awk '{ print $1 " " $4 }' | sort | uniq > $TEMPFILES/cdeps.db fi echo 'digraph test { node [fontname = "Vera"] edge [fontname = "Vera"]' \ 'graph [ranksep = 1]' > $TEMPFILES/cdeps.dot extractprog='/^\t@/ { do { getline if ($0 ~ /^\t`/) print substr($1,2) } while ($0 !~ /^\t@/) exit }' for f in *.c *.h; do cscope -b -c -k -f $TEMPFILES/cdeps.cscope $f awk "$extractprog" $TEMPFILES/cdeps.cscope | sort | uniq -c | awk "{ print \$2 \" \" \"$f\" \" \" \$1 }" done | sort | join $TEMPFILES/cdeps.db - | sort | awk 'function printout() { if (functionname) print callers " " header " " functionname " " amounts } { if ($1==functionname && $2==header) { callers = callers "," $3; amounts = amounts "," $4 } else { printout(); functionname=$1; header=$2; callers=$3; amounts=$4 } } END { printout() }' | sort | awk 'function printout() { if (callers) { arrlen = split(callers, arr, ","); dashed = "invis"; for (count=1; count<=arrlen; count++) { solid = "invis"; if (!ENVIRON["QUERY_STRING"]||ENVIRON["QUERY_STRING"]==arr[count]) { dashed = "dashed"; solid = "solid" } print "\"" arr[count] "\" -> \"" functions \ "\" [ label = \"" amounts[count] "\", style = " solid " ]"; } print "\"" functions "\" -> \"" header \ "\" [ label = \"" arrlen "\", style = " dashed " ]" } } { if ($1==callers && $2==header) { functions = functions "\\n" $3; amountslen = split($4, addamounts, ","); for (count=1; count<=amountslen; count++) amounts[count] = amounts[count] "," addamounts[count] } else { printout(); callers=$1; header=$2; functions=$3; split($4, amounts, ",") } } END { printout() }' >> $TEMPFILES/cdeps.dot for f in *.c *.h; do echo "\"$f\" [ URL = \"$SCRIPT_NAME?$f\" ]" done >> $TEMPFILES/cdeps.dot echo "}" >> $TEMPFILES/cdeps.dot dot -Tjpg $TEMPFILES/cdeps.dot -o $TEMPFILES/cdeps.jpg chmod a+x $TEMPFILES echo "Content-type: text/html" echo "" echo "" echo "" dot -Tcmap $TEMPFILES/cdeps.dot echo "" echo "Complete view" rm -R $TEMPFILES/cdeps.[cd]* `find . -name "run.??????" -cmin +5`