graph.scm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Code to print out module dependencies in a format readable by the
  3. ; graph layout program AT&T DOT Release 1.0. (for information on DOT call
  4. ; the AT&T Software Technology Center Common Support Hotline (908) 582-7009)
  5. ; Follow link script up to the actual linking
  6. ;(load-configuration "scheme/interfaces.scm")
  7. ;(load-configuration "scheme/packages.scm")
  8. ;(flatload initial-structures)
  9. ;(load "build/initial.scm")
  10. ;
  11. ; Load this and run it
  12. ;(load "scheme/debug/graph.scm")
  13. ;(dependency-graph (initial-packages)
  14. ; (map structure-package (list scheme-level-1 scheme-level-0))
  15. ; "graph.dot")
  16. ;
  17. ; Run the graph layout program
  18. ; setenv SDE_LICENSE_FILE /pls/local/lib/DOT/LICENSE.dot
  19. ; /pls/local/lib/DOT/dot -Tps graph.dot -o graph.ps
  20. ; Returns a list of the packages in the initial system.
  21. (define (initial-packages)
  22. (map (lambda (p)
  23. (structure-package (cdr p)))
  24. (append (struct-list scheme
  25. environments
  26. module-system
  27. ensures-loaded
  28. packages
  29. packages-internal)
  30. (desirable-structures))))
  31. ; Write the dependency graph found by rooting from PACKAGES to FILENAME.
  32. ; Packages in the list IGNORE are ignored.
  33. ;
  34. ; Each configuration file's packages are done as a separate subgraph.
  35. (define (dependency-graph packages ignore filename)
  36. (call-with-output-file filename
  37. (lambda (out)
  38. (display prelude out)
  39. (newline out)
  40. (let ((subgraphs (do-next-package packages ignore '() ignore out)))
  41. (for-each (lambda (sub)
  42. (note-subgraph sub out))
  43. subgraphs)
  44. (display "}" out)
  45. (newline out)))))
  46. ; Do the first not-yet-done package, returning the subgraphs if there are
  47. ; no packages left. TO-DO, DONE, and IGNORE are lists of packages.
  48. ; SUBGRAPHS is an a-list indexed by source-file-name.
  49. (define (do-next-package to-do done subgraphs ignore out)
  50. (let loop ((to-do to-do))
  51. (if (null? to-do)
  52. subgraphs
  53. (let ((package (car to-do)))
  54. (if (memq package done)
  55. (loop (cdr to-do))
  56. (do-package package (cdr to-do) (cons package done)
  57. subgraphs ignore out))))))
  58. ; Find the correct subgraph, add PACKAGE to it, note any edges, and continue
  59. ; with the rest of the graph.
  60. (define (do-package package to-do done subgraphs ignore out)
  61. (let* ((source-file (package-file-name package))
  62. (opens (map structure-package
  63. ((package-opens-thunk package))))
  64. (old-subgraph (assq source-file subgraphs))
  65. (subgraph (or old-subgraph
  66. (list source-file))))
  67. (set-cdr! subgraph (cons package (cdr subgraph)))
  68. (do-edges package opens source-file ignore out)
  69. (do-next-package (append opens to-do)
  70. done
  71. (if old-subgraph
  72. subgraphs
  73. (cons subgraph subgraphs))
  74. ignore
  75. out)))
  76. ; Add an edge from each package in OPENS to PACKAGE, provided that the
  77. ; two were defined in the same file.
  78. (define (do-edges package opens source-file ignore out)
  79. (let loop ((opens opens) (done ignore))
  80. (if (not (null? opens))
  81. (loop (cdr opens)
  82. (let ((p (car opens)))
  83. (if (or (memq p done)
  84. (not (string=? source-file (package-file-name p))))
  85. done
  86. (begin
  87. (note-edge p package out)
  88. (cons p done))))))))
  89. ; Writing out the package name as a string (actually, its the name of
  90. ; the first of the package's clients).
  91. (define (package-name package out)
  92. (let ((clients (population->list (package-clients package))))
  93. (write-char #\" out)
  94. (display (structure-name (car clients)) out)
  95. (write-char #\" out)))
  96. ; Header for DOT files
  97. (define prelude
  98. "digraph G {
  99. orientation=landscape;
  100. size =\"10,7.5\";
  101. page =\"8.5,11\";
  102. ratio =fill;")
  103. ; Writing out edges and subgraphs
  104. (define (note-edge from to out)
  105. (display " " out)
  106. (package-name from out)
  107. (display " -> " out)
  108. (package-name to out)
  109. (write-char #\; out)
  110. (newline out))
  111. (define (note-subgraph subgraph out)
  112. (display " subgraph \"cluster_" out)
  113. (display (car subgraph) out)
  114. (display "\" { label=\"" out)
  115. (display (car subgraph) out)
  116. (display "\"; " out)
  117. (for-each (lambda (p)
  118. (package-name p out)
  119. (display "; " out))
  120. (cdr subgraph))
  121. (display "}" out)
  122. (newline out))