Includes – An application to show what was included and how, in you C/C++ source

This application grew out of my need to understand how various files were hung together
in a project that I inherited a few years ago. I’d been used to compilers that when they
find an error in a header file, tell you not only what header the error was in, but from
what file and line the inclusion came from. This is really useful when the response to an
error, is "where did that come from, and why am I using it?". Granted, if you
wrote the code that may not happen too often, but if someone else did then all bets are
off.

What I present here is a small GUI app that takes a specific source file, scans it, and
recursively scans all included file building a list of inclusions to then display in a
nice little tree.

Includes.exe at work

I hope that some of you may find it useful.

Download source and executable here, [size 143K].

Features:

  • Fast:
    On my PII 266, I can generally scan all of a fairly complex stdafx.h in under 4 seconds.
  • Full Drag and Drop server support:
    You can drag a file from the list in the tree window into another application, e.g.
    DevStudio.
  • Topmost window support:
    The pushpin on the title bar pins the window to the screen so that it is always the
    topmost window. This makes browsing in combination with DevStudio much more convenient.
  • INCLUDE path support:
    You can set two include paths, the first is for your system includes, i.e. what DevStudio
    has in its Options/Directories dialog. The second is for your project specific paths.
  • Find support:
    You can search through the list for a file or part of file name.
  • Source Code:
    You get the source; use it, abuse it, credit who wrote it. Seriously, I may have put this
    together but a huge amount of the code here has been culled from the work of others.

Usage:

This should be fairly obvious, but regardless, this is what to do.

  1. Set your INCLUDE path. The default is to simply pull in your INCLUDE environment value
    if you have one. The first time that you run Includes then you may want to check that this
    is accurate. You will only need to change the per-file INCLUDE value if you are adding
    /I… options to the compile line.
  2. The include depth defaults to 10, the intent here is more to simply fix any recursion
    loops than anything else, if you find that the number is too low, then simply increase it.
  3. Open a file. That’s it.

Bugs/Limitations:

  • Parsing the source files is a little simplistic. I simply find every #include… entry,
    get the filename and then open that file and recurse. There is no note taken of any
    conditional compilation options, this means that the tree can show you headers as being
    included that simply aren’t. As a rule I’ve not found this to be a problem, but do be
    aware of it.
  • I only show a file once. The first time that a file is encountered it is logged and
    ignored from that point on. If you are interested in changing this there is a run time
    flag in the code (CIncludesDoc::m_once) that if set to true will force a full tree to be
    built. This is much, much slower and is also subject to recursion loops since there are
    many circular dependencies in both the MFC and standard headers, this is where the
    inclusion depth limit comes in to bail from ludicrous recursion. I decided that this
    wasn’t of enough general use to even bother adding a GUI for this option, but it should be
    simple for anyone who’s interested.

On to the Code:

First you’ll see that there is a fair mix of styles in this code, sorry. I’ve been
looking at more of the new standard C++ library and fiddling around with using std::string
rather than CString, this does mean that both are used in this project, I can’t say that
I’m completely happy with this, but it’s very hard to avoid using CString if you use MFC
and I wanted to use std::string to see what it was like.

I’m very happy with the standard container classes, std::vector, std::set etc, you’ll
see that they crop up quite a bit.

The source has been built and tested on both VC 5 and 6.

The major files:

  • Includes.cpp & Includes.h
    Not too much, the main application object and about box.
  • Includes.dsp
    The ubiquitous project file.
  • IncludesDoc.cpp & IncludesDoc.h
    The main scanning and parsing routines, along with the checks to see if the file has been
    visited once already.
  • IncludeView.cpp & IncludeView.h
    All of the code for adding the elements to the ListView as well as the grunt work
    of the drag and drop and find support.
  • item.cpp & item.h
    Storage object for the include file that we’ve processed.
  • DropHelpers.cpp & DropHelpers.h
    Some very neat code written by Jeffrey Richter for his book "Windows 95: A
    Developer’s Guide", This deals with providing server support for WM_DROPFILES.
  • HyperLink.cpp & HyperLink.h
    Used in the about box to provide a hyperlink control.
  • PaintCap.cpp & PaintCap.h
    Paul DiLascia’s Code to support owner draw caption bar painting, mainly used here
    as a foundation for my CTopCaption Class.
  • Subclass.cpp & Subclass.h
    Again from Paul DiLascia, this class supports the arbitrary subclassing of an MFC
    CWnd object, very cool.
  • TopCaption.cpp & TopCaption.h
    Derived from CCaptionPainter, this class’ purpose is to provide a caption bar
    with a topmost pushpin.
  • MainFrm.cpp & MainFrm.h
    Responsible for persistent window positioning, and caption painting. If the OS
    supports drawing a gradient colour on the caption bar (Win98 and Win2K) then we use the
    system GradientFill routine to make the caption bar fall in with the rest of the OS, if we
    are in NT 4 or Win95 then we do our own gradient fill.
  • Regexp.cpp & Regexp.h
    My regular expression class, see http://www.codeguru.com/string/regexp.shtml
  • split_string.h
    Convert a string with a sequence of delimited segments into a collection of those
    segments.
  • SuperGridCtrl.cpp & SuperGridCtrl.h
    Taken from Allan Nielsen’s Multi column treelist, this
    version is slightly modified. I didn’t need any of the editing options so this version can
    be compiled to be read only.
  • TreeGridCtrl.cpp & TreeGridCtrl.h
    Subclassed from CSuperGridCtrl, this class reflects some of the drag ‘n’ drop
    related messages up to the parent as well as providing searching support. Note that the
    searching uses regular expressions.
  • block.h
    block<> is a simple class that provides std library iterator semantics to a block
    of memory. This can be handy for applying std library algorithms and functions to
    arbitrary lumps of memory.
  • clock.h
    Very simply routing to assist in function timings, search for _TIME_IT in the
    code to see an example.
  • DebugStream.cpp &DebugStream.h
    std::stream derived class to provide an interface to OutputDebugString.
  • RTFStream.cpp & RTFStream.h
    std::stream derived class to allow the insertion of formatted text into an RTF
    control.

Guy Gascoigne – Piggford

Last modified: Wed Jan 20 15:24:46 Pacific Standard Time 1999

More by Author

Must Read