1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
6 <title>The graph-includes toolkit</title>
9 <firstname>Yann</firstname>
10 <surname>Dirson</surname>
11 <email>ydirson@altern.org</email>
15 <simpara>This program is free software; you can redistribute it
16 and/or modify it under the terms of the GNU General Public
17 License, version 2, as published by the Free Software
20 <simpara>This program is distributed in the hope that it will be
21 useful, but WITHOUT ANY WARRANTY; without even the implied
22 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 See the GNU General Public License for more details.</simpara>
28 <holder>Yann Dirson</holder>
33 <title>In short</title>
35 <simpara>Graph-includes creates a graph of dependencies between
36 source-files and/or groups of source-files, with an emphasis on
37 getting readable and usable graphs even for large
40 <para>Usability of the dependency graphs are currently improved by:
42 <listitem><simpara>customizable grouping of several source files into
43 a single node</simpara></listitem>
45 <listitem><simpara>transitive reduction of the
46 graph</simpara></listitem>
51 <simpara>It currently supports graphing the C/C++ #include
52 relationship, using graphviz.</simpara>
57 <title>Important notice</title>
59 <simpara>This tool has evolved from a 50-line script written for a
60 particular project (<ulink url="http://wesnoth.org/">Battle for
61 Wesnoth</ulink>). Although it has been generalized much, there
62 are still somewhat ad-hoc heuristics harcoded here and there,
63 especially in the default project class (see class descriptions
66 <simpara>Although work is under way to make this tool as generic
67 as possible, work still has to be done at all levels. It is still
68 under development, and may not suit your needs (at least, not
74 <title>Installation instructions</title>
76 <simpara>Be sure you have a recent version of Perl installed. At
77 least List::Util is missing from versions earlier than 5.8. You
78 can also just fetch this additional package from CPAN if you
79 cannot upgrade. If you notice that another package is missing
80 from your installation, please report it, so it can be listed
83 <para>Install it like standard perl packages.</para>
85 <title>Sample install session</title>
86 <literallayout><prompt>$</prompt> perl Makefile.PL prefix=/usr/local
87 <prompt>$</prompt> make
89 <prompt>#</prompt> make install</literallayout>
92 <simpara>Be sure that the directory in which the library modules
93 got installed is in your perl library path. Eg, if
94 "graph-includes --version" does not give the expected result,
95 try setting the PERL5LIB environment variable to (in the above
96 example) /usr/local/share/perl/5.8.4/.</simpara>
98 <simpara>New versions can be found at
99 <uri>http://ydirson.free.fr/soft/graph-includes/</uri>.</simpara>
101 <simpara>A darcs repository is available at <uri
102 type="darcs">http://ydirson.free.fr/soft/graph-includes/darcs/</uri
105 <simpara>To be able to format the produced graphs, you will need
106 one of <ulink url="http://www.graphviz.org/">graphviz</ulink> and
107 <ulink url="http://www.tulip-software.org/"
108 >tulip</ulink></simpara>
113 <title>How to take advantage of this tool to improve your code</title>
115 <simpara>Graph-includes is only a supporting tool for a
116 refactoring effort. It can be useful in helping a developper to
117 see where he should put its efforts in order to get cleaner and
118 saner dependencies in a project.</simpara>
120 <simpara>In this respect, it is quite similar to a microscope: if
121 you don't look at the right place, you won't see anything
122 interesting. But if you start with a small magnifying factor, you
123 can locate regions of interest, and then zoom on those to get to
124 the interesting stuff.</simpara>
127 <title>On the spirit of dependency cleanup</title>
130 <title>First look at a dependency graph</title>
132 <simpara>When developping a project of medium size (we'll talk
133 mostly C/C++ here, but that will apply to most languages),
134 expecially with many people writing code, it is quite easy to
135 get to a point where each file (out of several tens of
136 hundreds of files) depends on too many other files.</simpara>
138 <simpara>The most obvious relation is the #include one. The
139 more #includes a file has, the more time it takes to build -
140 especially when those included files #include themselves a
141 bunch of other files. For a project of about 100 files, just
142 producing a graph of all those files, with arrows representing
143 the #include dependencies, will usually give an unreadable
144 graph, and will show very little about possible improvements.
145 This is why this tool has been written: to make it possible to
146 get to the useful information hidden in this unusable
147 dependency graph.</simpara>
151 <title>Looking further</title>
153 <simpara>A less obvious relation appears more clearly when you
154 consider not files by themselves, but the set of files made of
155 an interface and the matching implementation. Let's consider
156 two such sets, made of the files a.h, a.c, b.h, b.c. a.c
157 includes b.h, and b.c includes a.h, and each implementation,
158 following good practice, includes its own interface. A simple
159 dependency graph as described above would show such a
162 <literallayout class="monospaced"
168 b.c -> a.h</literallayout>
170 <para>If OTOH we represent those sets of files instead of
171 the files themselves, we now have something like:</para>
173 <literallayout class="monospaced"
174 >a <--> b</literallayout>
176 <para>This shows much more clearly that those two modules are
177 intrinsicately related. In many cases, this will express that
178 whenever you use the a.o file resulting from the build of a.c,
179 you'll need to link b.o as well, and vice versa. This will be
180 the case when each file uses the headers to get function
181 prototypes. Then hunting for abusive dependencies will allow,
182 for example, to select with finer grain which of those modules
183 of code will need to go into which executable, thus producing
184 lighter executables.</para>
186 <simpara>Note that such a reciprocal dependency may not be
187 pathological. Many projects tend to split a large module into
188 several files for clarity, even when those files are
189 inter-dependant. It is much often in cycles of unidirectional
190 dependencies that we find dependencies that should not be
193 <simpara>In other cases, headers would just have been used to
194 access a type definition from b.h, and the associated b.o
195 would not be needed. In such cases, you may want to consider
196 splitting such "low-level" declarations into their own
197 headers. Not only this would simplify the graph, allowing you
198 to get a better grasp on your source code, but it can also
199 lead to faster compilations, since each file will be able
200 include less unrelated definitions.</simpara>
206 <title>Tuning the "files" and "includes" parameters</title>
208 <simpara>Your first run will surely looks somewhat
211 <literallayout class="monospaced">graph-includes -o project.ps src/ lib/</literallayout>
213 <simpara>You will take care of specifying all directories or
214 individual source files that make up your project.</simpara>
216 <simpara>In addition to an initial graph in the project.ps file,
217 which is quite likely to be incomplete by far, you will find a
218 file named project.ps.graph-includes.report. It is a text file,
219 which will help us to finetune ou command-line. Its first
220 section will look something like:</simpara>
222 <literallayout class="monospaced"
226 412 files, 353 nodes (14% dropped)
227 245 dependencies, 137 edges (44% dropped)
230 280 dependencies not found
231 0 dependencies identified as system headers</literallayout>
233 <simpara>As you can see, many dependencies are declared as "not
234 found". What happens is quite similar to running a C compiler
235 without any -I flags: most header files are not
238 <simpara>We have in graph-includes two different flags to
239 specify paths where to look for the dependencies. -I (aka
240 -Include) specifies directories that are part of the project,
241 and will allow to find all of our include-style dependencies.
242 OTOH, -sysI (aka -sysInclude) specifies system directories;
243 included files found in such a directory will of course not
244 result in an intra-project dependency, and will add no edge to
245 our graph, but will stop being displayed as part of the
246 "dependencies not found" count. Thus, they will help us to see
247 how far we are from specifying all the -I flags.</simpara>
249 <simpara>Now you will most likely require several iterations of
250 adding -I/-sysI flags and checking the results. But that alone
251 may not be sufficient to reach the ultimate "0 dependencies not
256 <simpara>multi-platform source often have conditional
257 #include directives, and eg. win32 headers will probably not
258 be located on a Un*x box.</simpara>
261 <simpara>some generated files will require the source tree
262 to be configured in some way, or even to be partly or
263 completely built (eg. config.h generated by a "configure"
264 script, or Qt source generated by the meta-object
269 <simpara>When you are confident that those remaining missing
270 dependencies are system headers for other platforms, you can go
271 on and look at the graph.</simpara>
276 <title>Possible strategies to help locating abusive
279 <simpara>Keeping in mind that we are essentially looking for
280 dependency loops, we expect to obtain in then end a graph that
281 will be wihout cycles, that is, with all (or, at least, most of)
282 arrows pointing from left to right in our graph.</simpara>
284 <simpara>Then we will look for those arrows pointing backwards,
285 as a sure sign for a cycle. Remember that if the cycle is not a
286 long one, it may be legitimate; only if you judge that some of
287 the modules in this cycle are really unrelated, should your
288 consider it pathological. Those backward arrows are not
289 necessarily directly pointing to the abusive dependency, but
290 they can surely be used to locate the culprit: by finding the
291 various cycles of which our backward arrows are part of, and
292 checking one by one all the dependencies in those cycles, you
293 can bet at least one that, with some work, could be
296 <simpara>Then, the way to modifications to do are really
297 dependant on your code. Some possibilities include:</simpara>
301 <simpara>removing an #include which is not necessary,
302 perhaps remaining from a revious code
303 reorganization</simpara>
306 <simpara>splitting a file in two parts, when you can easily
307 split the components of the file into distinct sets. One
308 productive distinction to look for is to find a couple of
309 really high-level parts, that not all the parts depending on
310 this module would need. This will most probably be related
311 to the dependency that you found abusive when looking at the
312 cycle in the graph.</simpara>
319 <title>Tool architecture</title>
322 <title>Overview:</title>
324 <simpara>Graph-includes was initially developped with only a
325 handful of ideas, and then started to grow as I noticed where
326 useful things were missing. That initial phase was useful for
327 me to get a grasp on the domain of dependency graphing, and
328 provided the ground for a (hopefully) decent design, which still
329 has to be completely implemented.</simpara>
331 <simpara>Together with blocking issues marked
332 <emphasis>+</emphasis> in the TODO list, the implementation of
333 this design shall be the goal for a 1.0 release.</simpara>
335 <simpara>The planned design is architectured as successive
336 layers, all of which should be pluggable to allow a high degree
337 of customization.</simpara>
339 <literallayout class="monospaced"
346 graph transformations
355 rendering</literallayout>
357 <simpara>We will then be able to consider the graph-includes
358 project as being made of a number of parts:</simpara>
362 <simpara>core classes and glue, implementing the above
366 <simpara>standard classes, doing the real work </simpara>
369 <simpara>command-line and gui tools to allow easy use of the
374 <simpara>This will hopefully make it easy for anyone to plug
375 their own work at any place in the architecture.</simpara>
380 <title>State of things</title>
382 <simpara>Currently, only the extractor and the renderer are
383 properly customizable.</simpara>
385 <simpara>The source locator takes parameters from the
386 per-language extractors to find files.</simpara>
388 <simpara>Project classes allow some customisation of the
389 grouping transformation, and of styling, but this has to be
390 split and generalized, as the design plans imply.</simpara>
392 <simpara>Graph transformations are mostly limited to a set of
393 hardcoded operations (grouping, transitive reduction, edge
394 labelling), not all of which can be individually switched off;
395 only the "special edge" mechanism is customizable to some
398 <simpara>There is no distinction (yet ?) between the layout
399 engine and the renderer. In fact, it may not be easy to do
400 this, since most layout engines are tied to a particular
407 <title>Command-line usage</title>
409 <simpara>See "graph-includes --help".</simpara>
412 <title>output type</title>
414 <simpara>The default output is a .dot file on standard output,
415 suitable for formatting by dot (from the graphviz toolkit), or
416 interactive editing by dotty (also from graphviz).
417 Alternatively, a graph file for the Tulip graph visualizer can
418 be generated instead using "--renderer=tulip".</simpara>
420 <simpara>You can ask graph-includes to do the formatting for
421 you, eg. using "--output=<file>.<suffix>". It will
422 run "dot -T<suffix>", so that "--output=mydeps.ps" or
423 "--output=mydeps.jpg" will have the expected behaviour. If your
424 suffix is not known to dot, it will complain itself, so asking
425 for --output=foo.bar will cause a message like:</simpara>
427 <simpara>Warning: language bar not recognized, use one of: canon
428 cmap cmapx dia dot fig gd gd2 gif hpgl imap ismap jpeg jpg mif
429 mp pcl pic plain plain-ext png ps ps2 svg svgz vrml vtx wbmp
432 <simpara>If you intend to print the result on paper, the default
433 layout will likely be too large. You can use --paper=a4 to
434 select parameters that will produce a smaller graph and spilt it
435 into pages. This flag also changes the default output format to
436 postscript. Be warned that dot may not honor the page-splitting
437 parameter for all output formats.</simpara>
439 <simpara>Since the transitive reduction can take time, you may
440 like the --verbose switch, which will show a progress
446 <title>what to draw</title>
448 <simpara>The files to be analyzed are given as non-option
449 arguments, and can be explicitely specified, or found by
450 recursing in directories. Eg, to analyse foo.c in current
451 directory, as well as all C/C++ files in the src/ directory,
454 <literallayout class="monospaced">$ graph-includes foo.c src/</literallayout>
456 <simpara>When an directory argument is specified, it is searched
457 for files whose name matches a specific regexp pattern, whose
458 default value depends on the specified language (see --language
459 below). This pattern can be overriden using the --fileregexp
460 option. Eg, to match in addition to .c and .h files, those with
461 an additional .tmpl suffix, you could write:</simpara>
463 <literallayout class="monospaced">$ graph-includes -I src -fileregexp '\.[ch](\.tmpl)?$' src/</literallayout>
465 <simpara>How dependencies get extracted from the source files
466 depend on the language used in those files. You can specify it
467 with the --language flag. Default value is C (which should also
468 be used for other languages based on the C preprocessor, like
469 C++). There is also some partial support for perl - see
470 comments in lib/graphincludes/extractor/perl.pm for more
473 <simpara>In order to tell the #include resolver where to look
474 for included files, you can use the cpp-like -I (aka. --Include)
477 <literallayout class="monospaced">$ graph-includes -I src src/</literallayout>
479 <simpara>Dependencies not found in the project (ie. files
480 appearing in #include but not given on command-line) are listed
481 as "not found" in the graph-includes.report file for diagnostics
482 purposes, unless they are found in a system directory. System
483 directories are declared in a similar fashion, with the
484 --sysInclude option. Eg:</simpara>
486 <literallayout class="monospaced">$ graph-includes -I src -sysI /opt/foo/include src/</literallayout>
488 <simpara>Language extractor have some knowledge about default
489 system include dirs: the C extractor knows about /usr/include,
490 and the Perl extractor asks perl itself.</simpara>
492 <simpara>To avoid having useless information on the graph,
493 --prefixstrip=<prefix> can be used to avoid repeating a
494 given prefix in all node labels. Typically:</simpara>
496 <literallayout class="monospaced">$ graph-includes --prefixstrip=src/ src/</literallayout>
501 <title>how to draw</title>
503 <simpara>Files will be grouped in a hierarchy of groups, level 0
504 groups typically containing just one file. Groups are defined
505 by the selected project class, selected by the
506 --class=<class> option. See below for descriptions of the
507 project classes available by default, and for instructions to
508 write customized project classes.</simpara>
510 <simpara>The range of group levels to be drawn is selected with
511 --group=<min>-<max>, which defaults to 1-1. Eg, for
512 class "default", whose group levels are defined as:</simpara>
516 <glossterm>0</glossterm>
518 <simpara>one file per group</simpara>
522 <glossterm>1</glossterm>
524 <simpara><filename>what/ever.*</filename> go into a
525 <filename>what/ever</filename> group (usually interface +
526 implementation)</simpara>
530 <glossterm>2</glossterm>
532 <simpara><filename>what/*</filename> go into a
533 <filename>what</filename> group, supposing top-level
534 directories denote modules of some sort</simpara>
539 <simpara>Group levels below "min" or above "max" are not
540 displayed as nodes. Groups of level "min" are drawn as nodes of
541 the graph. If "max" is strictly greater than "min", then groups
542 of levels "min+1" through "max" are drawn as box clusters
543 containing lower-level groups.</simpara>
545 <simpara>Since such a way of grouping nodes will not improve the
546 readability in projects where the inter-groups dependencies have
547 not been cleaned up yet, higher-level groups can instead be
548 colored, using a class-defined color scheme, possibly modified
549 by <userinput>--color
550 <n>:<label>=<color>[,<label>=<color>…]</userinput>
551 options, where <n> is the group level in which the group
552 name <label> will receive a background of the specified
553 color, which can be defined either by a named X11 color (like
554 "blue" or "palegreen"), or by a RGB color using the standard X11
555 "#RRGGBB" syntax.</simpara>
557 <simpara>The number of grouping levels to be colored is limited
558 by the renderer to be used. As of 0.11, the dot renderer only
559 supports coloring 2 group levels. Groups of a lower level than
560 the minimal level requested to --group cannot be colored, for
561 obvious reasons.</simpara>
563 <simpara>For those wanting to see what edges the transitive
564 reduction dropped, the --showdropped will add them to the graph
565 in a different color. Be prepared for your computer room to get
566 a noticeable temperature increase for anything else than a small
567 set of files with only few dependencies.</simpara>
569 <simpara>OTOH, <option
570 >--focus=<replaceable>node-label</replaceable ></option> will do
571 the same, but only for the dependencies of a specified node.
572 That should prevent the nasty effects described above, and will
573 be useful for various purposes, including debugging the
574 transitive reducer. The node-label refers to a node in the
575 lowest group-level drawn, ie. the "min" argument to
578 <simpara>People still getting cold may also like to circumvent
579 the transitive-reduction engine completely, using --alldeps.
580 The author assumes no responsibility for losses of mental health
581 induced by trying to make any serious use of the resulting
588 <title>Existing project classes</title>
591 <title>class "default"</title>
593 <simpara>As implied by its name, it is the one which will be
594 used unless you use the --class option. Although it is the
595 default one, it may still be quite rough at the moment, still
596 using some ad-hoc heuristics, and will be improved in the near
597 future. Here are its main characteristics:</simpara>
601 <simpara>looks at C-style #include lines</simpara>
604 <simpara>creates level-1 groups for all files sharing the same
605 path and (disregarding the suffix) filename. Eg, files
606 "foo/bar.c" and "foo/bar.h" would be grouped in a "foo/bar"
607 level-1 group. In clear, it won't connect include files if
608 they are all located in an include/ directory.</simpara>
611 <simpara>creates by-directory level-2 groups. Eg. in the
612 above example, a group "foo" would exist at level-2.</simpara>
618 <title>class "uniqueincludes"</title>
620 <simpara>Built on top of the default class, it is meant for
621 projects where file names are kept unique across all directories.
622 If the ad-hoc #include processing of the default class does not
623 suit your project, it is the only out-of-the-box alternative
624 available today. Here are its main characteristics:</simpara>
628 <simpara>provides a single grouping level based on filenames,
629 disregarding all the directory hierarchy.</simpara>
633 <simpara>Note that it is not meant for general use, as:</simpara>
637 <simpara>it will group any files with the same name in the
638 same level-0 group, possibly causing confusion.</simpara>
641 <simpara>it does not make any directory name appear in the
650 <title>Examples of use</title>
653 <title>Pure command-line examples</title>
656 <title>Graphing graph-includes itself:</title>
658 <literallayout>$ ./graph-includes -lang perl -I lib -prefixstrip lib/ -o deps.ps graph-includes lib/</literallayout>
660 <simpara>graph-includes does not know in advance which classes
661 it will use</simpara>
665 <title>Rather clean ones:</title>
667 <simpara>a rather clean dependency graph</simpara>
669 <literallayout>Maelstrom-3.0.6$ graph-includes -v -sysI /usr/include/SDL -I . -I ./netlogic -I ./maclib -I ./screenlib --prefixstrip ./ -o deps.ps .</literallayout>
671 <simpara>more work has to be put in the wesnoth example class:</simpara>
673 <literallayout>wesnoth-0.9.1$ graph-includes -v --class wesnoth --group 1-1 -sysI /usr/include/c++/3.3 -sysI /usr/include/SDL --prefixstrip src/ -I src -o deps.ps src/</literallayout>
678 <title>Examples only here as a reminder to write proper project
679 classes for them</title>
681 <para>needs supporting features for multi-arch source trees:</para>
683 <literallayout>qemu-0.7.0$ graph-includes -v -sysI /usr/include/SDL $(find -name CVS -prune -o -type d -printf <emphasis>-I %p\n</emphasis>) -o deps.ps .</literallayout>
685 <para>needs proper file-grouping:</para>
687 <literallayout>mesag-6.2.1$ graph-includes -o -I ./include -I ./include/GL -I ./src/mesa -I ./src/mesa/main -I ./src/glu/sgi/include -I ./src/glu/sgi/libnurbs/internals -I ./src/mesa/glapi -o deps.ps .</literallayout>
693 <title>Customization examples</title>
695 <simpara>See graphincludes::project::wesnoth in the examples/
696 dir as an example of a custom project class.</simpara>
698 <simpara>Keep in mind that the API is not frozen yet, and will
699 probably be overhauled more than once before an official API
700 gets blessed.</simpara>
706 <title>Caveats</title>
710 <simpara>this script only handles explicitely-declared
711 dependencies, it won't detect it if eg. a prototype was
712 cut'n'pasted instead of using the correct #include, but you
713 shouldn't do that anyway :)</simpara>
719 <title>Related tools</title>
721 <simpara>I finally found a couple of tools out there, from which I
722 may borrow ideas some day. I'd be happy to hear about more of
727 <simpara>cinclude2dot, originally from Darxus
728 (http://www.chaosreigns.com/code/cinclude2dot/), then taken
729 over by F. Flourish (http://www.flourish.org/cinclude2dot/) is
730 a GPL C/C++-only tool, which apparently has support for
731 grouping, but not for transitive reduction. Should I have
732 searched better, and found it a couple of months ago, maybe
733 graph-includes would have never been developped :)
737 <simpara>http://www.tarind.com/depgraph.html has a dependency
738 grapher for python, without transitive reduction as well. It
739 does however allow customisation of project classes, somewhat
740 similar to graph-includes.</simpara>
743 <simpara>OptimalAdvisor
744 (http://javacentral.compuware.com/pasta/) is a refactoring
745 tool, which goes far beyond simple dependency analysis, but is
746 non-free/libre/open-source (also they have a
747 functionally-limited free/gratis edition) and seems to support
751 <simpara>codeproject.com has some VisualStudio(tm) plugins
752 targetting C++, which I cannot test, but appear to scale badly
754 (http://www.codeproject.com/csharp/DependencyGraph.asp).</simpara>
762 <title>general</title>
766 <simpara>continue merging the verbose/debug behaviour into
767 the global report file</simpara>
770 <simpara>change case of class names when the API gets
774 <simpara>finalize filename portability support, using
775 File::Spec volume information</simpara>
781 <title>core engine</title>
785 <simpara>allow to associate attributes to files (eg. an ARCH
786 attribute for multi-architecture trees, like kernels,
787 development tools and emulators)</simpara>
790 <simpara>modularization (finish the restructuring into a
791 cleaner and more modular design)</simpara>
793 <listitem override="+">
794 <simpara>rework the recording of
795 edges to make them apply to files, not to graph nodes, since
796 more advanced features will need more flexibility</simpara>
799 <simpara>allow passing options to modules (-O param=value
803 <simpara>separate styling from project classes</simpara>
806 <simpara>allow to define several views in a project-class,
807 several of which can be generated by default.</simpara>
810 <simpara>find out whether we can declare
811 protocols/pure-virtual-classes in some way, to cleanup the
812 class graph</simpara>
815 <simpara>generalize --prefix-strip
819 <simpara>give consistent access to all commonly-needed
820 features through command-line and class
821 customization</simpara>
827 <title>graph-includes tool</title>
831 <simpara>allow to run from a build directory</simpara>
834 <simpara>--class does not allow to find the project file
835 (need to set PERL5LIB)</simpara>
838 <simpara>caller must prepend path to source tree to
839 --prefixstrip and all relative -I flags</simpara>
841 <listitem override="+">
842 <simpara>find the accessory classes as easily as possible
843 (like bugzilla ?)</simpara>
846 <simpara>better robustness to incorrect arguments
847 (eg. --group 1:2)</simpara>
850 <simpara>automate --help production (see Pod::Usage
853 <listitem override="+">
854 <simpara>multi-sheet paper support may be broken</simpara>
857 <simpara>use an existing source of paper formats (libpaper,
858 LC_PAPER, whatever)</simpara>
861 <simpara>maybe use graphviz' tred(1) to check our transitive
862 reductions.</simpara>
865 <simpara>some autodetection of the language to use based on
866 filenames ?</simpara>
869 <simpara>provide an initial list of system directories to
870 avoid repeating them (ask compiler)</simpara>
876 <title>other tools</title>
879 <simpara>provide an interactive tool to help understanding a
880 project's structure. Maybe with graphviz' lefty, or as a
881 specialized tulip gui ?</simpara>
887 <title>extractors</title>
889 <listitem override="+">
890 <simpara>allow -I syntax for programs using eg. -I. from
891 source subdirectory</simpara>
893 <listitem override="+">
894 <simpara>behave as expected wrt leading "./", use
895 File::Spec for more portability</simpara>
898 <simpara>consider using Cwd::realpath or so, for correct
899 "../" handling</simpara>
902 <simpara>write other extractors (java, python,
907 <title>C-like extractor</title>
909 <simpara>some support for CPP symbol conditionals
910 (mostly #ifdef), perhaps coupling this with
915 <title>write an openc++-based dependency
918 <simpara>extract more fine-grained dependency
919 (depending on a header does not necessarily imply
920 depending on code)</simpara>
923 <simpara>handle (warn about) the case where the
924 declarations for a given implementation file are
925 scattered in more than one header</simpara>
932 <simpara>detect undeclared dependencies (eg. manually
933 inserted prototypes)</simpara>
936 <simpara>check necessity of declared includes</simpara>
940 <title>perl extractor</title>
942 <simpara>improve the perl extractor</simpara>
950 <title>project classes</title>
954 <simpara>proper way to define include paths in project
958 <simpara>make default project-class consider multiple levels
959 of directories as group levels, but only if they
960 (consistently ?) have multiple subgroups ?</simpara>
963 <simpara>write a linux-kernel class and others as examples
967 <simpara>provide a simple hash-based filelabel
968 implementation</simpara>
971 <simpara>provide tools for automatic grouping (eg. using
972 cycles, or selected external deps, or from leaves)</simpara>
978 <title>presentation</title>
982 <simpara>allow styling through font color, node shape
983 (dot/tulip), number of peripheries (dot)</simpara>
986 <simpara>generalize the special_edge() mechanism (use a hash
987 of edge attributes ?)</simpara>
990 <simpara>allow different node shapes when mixing high-level
991 nodes with lower-level ones through the default singleton
992 groups (special_node mechanism similar to the special_edge
996 <simpara override="+">optionally show labels (using
997 attributes ?) or count for files (subnodes) in a node and
998 color arcs according to them</simpara>
1001 <simpara>optionally show external deps (deps on files not on
1002 command-line)</simpara>
1005 <simpara>limit graph to one or more given group(s) of files
1006 (specified by <level>:<label>)</simpara>
1009 <simpara>draw cycles in a given color</simpara>
1012 <simpara>draw a specific path</simpara>
1015 <simpara>provide automatic coloring schemes</simpara>
1018 <simpara>color intra-group edges with the same color as
1019 nodes (post-processing ?)</simpara>
1022 <simpara>allow to request drawing of who in a high-level
1023 node points to another node (ie. violates some
1024 constraint)</simpara>
1027 <simpara>propagate excuses in some way when they are dropped
1028 by the transitive reducer</simpara>
1031 <simpara>investigate candidate tools for hyperbolic layout
1035 <simpara>allow to show the count of deps in a given edge
1036 using line width instead of labels</simpara>
1042 <title>documentation</title>
1045 <simpara>write more documentation</simpara>
1051 <title>testsuite</title>
1055 <simpara>write a testsuite.</simpara>
1058 <simpara>ensure that all provided non-abstract classes are
1059 self-contained</simpara>
1067 <title>Known bugs</title>
1071 <simpara>traversal counts on edges are unreasonably high on
1072 cycles (real graph traversal issue, but unlikely to get fixed
1073 before we get another visual way to spot cycles ;)</simpara>
1076 <simpara>--showdropped mode draws too many edges as dropped
1077 (ie. does not consider marked edges as dropped when deciding
1078 whether to consider subsequent edges as dropped)</simpara>
1081 <simpara>transitive reduction may not be complete, some more
1082 edges could possibly be dropped - wesnoth tree at 2005-03-25
1083 exhibits the problem with the "display -> builder ->
1084 animated -> image" path</simpara>