tree2dotx.sh 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/bin/bash
  2. # tree2dot.sh --- transfer a "tree"(such as the result of tree,calltree)
  3. # to a p_w_picpath discribed by DOT language(provided by Graphviz)
  4. # author: falcon<zhangjinw@gmail.com>
  5. # update: 2007-11-14
  6. # usage:
  7. # tree -L 2 -d /path/to/a/directory | bash tree2dot.sh > tree.dot
  8. # cd /path/to/a/c/project/; calltree -gb -np -m *.c | bash tree2dot.sh > tree.dot
  9. # indicate the symbols you not concern with space as decollator here
  10. filterstr="";
  11. # transfer the tree result to a file described in DOT language
  12. grep -v ^$ | grep -v "^[0-9]* director" \
  13. | awk '{if(NR==1) system("basename "$0); else printf("%s\n", $0);}' |\
  14. awk -v fstr="$filterstr" '# function for filter the symbols you not concern
  15. function need_filter(node) {
  16. for( i in farr ) {
  17. if(match(node,farr[i]" ") == 1 || match(node,"^"farr[i]"$") == 1) {
  18. return 1;
  19. }
  20. }
  21. return 0;
  22. }
  23. BEGIN{ # filternode array are used to record the symbols who have been filtered.
  24. oldnodedepth=-1; oldnode=""; nodep[-1]=""; filternode[nodep[-1]]=0;
  25. # store the symbols to an array farr
  26. split(fstr,farr," ");
  27. # print some setting info
  28. printf("digraph G{\n");
  29. printf("\trankdir=LR;\n");
  30. printf("\tsize=\"800,600\";\n");
  31. printf("\tnode [fontsize=10,fontcolor=red,style=filled,fillcolor=lightblue];\n");
  32. }{
  33. # get the node, and its depth(nodedepth)
  34. nodedepth=match($0, "[^| `]");
  35. node=substr($0,nodedepth);
  36. nodedepth=int(nodedepth/4)
  37. # if whose depth is 1 less than him, who is his parent
  38. if(nodedepth-oldnodedepth == 1) {
  39. nodep[nodedepth-1]=oldnode;
  40. }
  41. # for debugging
  42. #printf("%d %s\n", nodedepth, node);
  43. #printf("\t\"%s\";\n",node);
  44. # print the vectors
  45. if (oldnodedepth != -1) {
  46. # if need filter or whose parent have been filter, not print it, and set the flat of filter to 1
  47. if(need_filter(node) || filternode[nodep[nodedepth-1]]==1) {
  48. filter[node]=1;
  49. } else if (nodep[nodedepth-1] != "") {
  50. printf("\t\"%s\" -> \"%s\";\n", nodep[nodedepth-1], node, nodep[nodedepth-1], node);
  51. # printf("\t\"%s\" -> \"%s\"[label=\"%s>%s\"];\n", nodep[nodedepth-1], node, nodep[nodedepth-1], node);
  52. }
  53. }
  54. # save the old depth and the old node
  55. oldnodedepth=nodedepth;
  56. oldnode=node;
  57. }END{
  58. printf("}");
  59. }'