graph.scm 4.2 KB

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