Automatic Class Diagram Generation

Some time ago, I needed a widget toolkit that would be able to draw widgets in an existing OpenGL window. However, I also needed it to be independent of the underlying graphics library, or event system, so I could use it in conjunction to both OpenGL, and another nameless 3D graphics API, that I was forced to use at the time for reasons I won’t go into right now. Anyhow, to cut the long story short, I started writing one such toolkit from scratch.

I opted for a fully object-oriented design, such as I rarely do lately, because OOP really makes sense for widget toolkits, and used C++ for the implementation.

Before long, I wanted to show what I was doing, to the rest of the team working on the project, for which I was writing the toolkit. And decided I should visualize the class hierarchy, as a quick overview of the widgets and their relations.

I didn’t want to have to learn how to use vector drawing programs just for this little thing, so my first thoughts went towards ditta. An excellent little hack, by Stathis Sideris, that turns ASCII diagrams of boxes and arrows into beautiful antialiased raster images.

However, it would be too tiresome, to manually create all those ASCII boxes representing my classes. I needed something more “automatic”. Finally I remembered “dot”, of the “graphviz” project. Another excelent program, that
takes simple text files describing graphs, and again, turns them into images. Here’s what a dot input file for my class diagram would look like:

digraph class_diagram {
    rankdir=BT;
    Label -> Widget;
    Button -> Widget;
    ... and so on ...
}

Now, people who know me, know that I’m a lazy person. I’d hate to have to maintain a separate file describing my classes, and I knew that it would go out of sync soon. Then it hit me, why don’t I generate the dot input file from my source files? So, I added the following rule to my makefile:

diag_file = diag.ps

.PHONY: $(diag_file)
$(diag_file):
    echo 'digraph class_diagram {' >/tmp/cdiag.dot
    echo '    rankdir=BT;' >>/tmp/cdiag.dot
    for i in src/*.h; do grep class $$i | grep ':' | sed 's/class /    /' \
        | sed 's/: public/->/' | sed 's/ {/;/' >>/tmp/cdiag.dot; done
    echo '}' >>/tmp/cdiag.dot
    dot -Tps /tmp/cdiag.dot >$(diag_file)

This is far from perfect, as it depends on my coding style to work correctly, still fine for my purposes. Here’s the output it produces:

About these ads
Posted in hacks. 3 Comments »

3 Responses to “Automatic Class Diagram Generation”

  1. keramida Says:

    That’s probably a silly question to make, since I’m sure you know of Doxygen already, but the temptation to ask is great…

    Isn’t it much easier to run Doxygen instead of manually parsing the source code with sed/awk? The makefile snippet shown above will keep working as long as you keep a consistent style in writing stuff like this:

    class XXX : public YYY

    But it won’t be able to parse stuff like:

    class
    XXX :
    public
    YYY

    which is fugly like hell, but still valid C++.

  2. Nuclear Says:

    Good point. I don’t know if and how easily I can extract the class diagram of doxygen from its output. I’ve never really used it for more than a short test-run a few years ago, and I’m hardly familliar with it. Is it possible to instruct doxygen to just produce a class diagram image instead of a full html documentation?

    As for the script, indeed I mentioned that it only works correctly for my coding style. But that was sufficient for what I needed :)

  3. machining of castings Says:

    Hey I know this is off topic but I was wondering if you knew
    of any widgets I could add to my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time
    and was hoping maybe you would have some experience with something like this.
    Please let me know if you run into anything. I truly enjoy reading your blog and I
    look forward to your new updates.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: