Click here to Skip to main content
15,885,546 members
Articles / Desktop Programming / MFC

Include File Hierarchy Viewer

Rate me:
Please Sign up or sign in to vote.
4.84/5 (108 votes)
29 Jul 2003CPOL8 min read 380.6K   4.5K   151  
A tool to view the include file hierarchy of your source code.
<!--------------------------------------------------------------------------->  
<!--                        IGNORE THIS SECTION                            -->
<html>
<head>
<title>The Code Project</title>
<Style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
<link rel="stylesheet" type=text/css href="http://www.codeproject.com/styles/global.css">
</head>
<body bgcolor="#FFFFFF" color=#000000>
<!--------------------------------------------------------------------------->  

<ul class=download>
<li><a href="IncludeFinder/IncludeFinder_demo.zip">Download program - 67 Kb </a></li>
<li><a href="IncludeFinder/IncludeFinder_src.zip">Download source - 215 Kb</a></li>
</ul>

<p><img src="IncludeFinder/IncludeFinder.jpg" alt="The demo in action" width=597 height=594></p>


<!-------------------------------     STEP 3      --------------------------->
<!--  Add the article text. Please use simple formatting (<h2>, <p> etc)   --> 

<h2>Introduction</h2>

<p>I've seen many people ask about utilities to view the tree of <code>#include</code>d files in their source code.  I think I've seen one
of these before, either here at CodeProject or maybe at CodeGuru, but I can't seem to find it.  Since I really enjoy text processing, I took 
it upon myself to write my own. What I've come up with is a fast, multi-threaded <code>#include</code> tree generator.

<h2>Features</h2>

<ul>
<li><a href="#dirsearch">Search Multiple Directories</a>
<li><a href="#wssearch">Search Files Loaded From VC6/VC7 Projects or Workspaces</a>
<li><a href="#viewsearch">View and Search the Output in a Tree Control</a>
<li><a href="#loadsave">Save and Reload Search Results in XML Format</a>
</ul>

<h3><a name="dirsearch">Searching Multiple Directories</a></h3>

<p><img src="IncludeFinder/includefinder6.jpg" alt="Directory Search Page" width=597 height=306></p>

As you can see in the screenshot above, there are a few fields to fill in before you can generate the tree.  I think it's pretty
self-explanatory, but I will explain the fields here just in case some think it's not.

<ul>
<p><li><b>Search in:</b>  Type in a list of directories you want to search.  You can enter multiple directories at one time by separating them with semi-colons.
Or, optionally, use the browse button ("...") to pick a directory from the standard Shell Browser.  This combo box will store the recently searched directories,
so you can also select a directory from the drop-down list if you like.

<p><li><b>File mask:</b>  Type in a list of file masks you want to search for.  You can enter multiple file masks at one time by separating
them with semi-colons.  This combo box will store the recently used file masks, so you can also select a mask from the drop-down list if you like.

<p><li><b>Includes:</b>  Type in a list of directories where external header files reside.  You can enter multiple include directories at one
time by separating them with semicolons.  Also, it's possible to enter an environment variable in this field, which the software will expand
at runtime.  To do this, simply prefix the variable with a '%' character (i.e. %INCLUDE).

<p><li><b>Recurse subdirectories:</b>  Set this check box if you want the program to recurse through subdirectories of the directories you entered.
</ul>

<h3><a name=wssearch>Searching files loaded from VC6/VC7 Workspaces or Projects</a></h3>

<p><img src="IncludeFinder/includefinder7.jpg" alt="Workspace Search Page" width=597 height=306></p>


When searching a workspace or project, you don't have to input as much information as when searching a directory, but you still have to load
a project or workspace, specify a file mask, and select a configuration.  The software will read settings related to preprocessing, such as
additional include directories, and preprocessor definitions.  Also, the VC6 project reader will read the registry for the VC6
include directories, and the VC7 project reader will read the registry for the VC7 include directories, which means if you have VC6 or VC7
configured already, you don't have to configure this program as well.

<p><b>Note: </b>The workspace and project loading isn't perfect yet, but I have tested it in a variety of scenarios,
and it works well for me.  The biggest problem is accurately interpreting the project settings, which there are still issues with.

<ul>
<p><li><b>Workspace:</b>  Type in the path to the workspace or project you want to load.  Or, optionally, use the browse button ("...") to pick a
workspace from the standard File Open dialog box.  This combo box will store the recently searched workspaces, so you can also select a recent entry
from the drop-down list if you like.

<p><li><b>Load Workspace:</b>  Click this button to load the selected workspace or project, so you can select a configuration.  If you don't
load the workspace before you click <b>Start</b>, the Include Finder will use the first configuration found in each project.

<p><li><b>File mask:</b>  Type in a list of file masks you want to search for.  You can enter multiple file masks at one time by separating
them with semi-colons.  This combo box will store the recently used file masks, so you can also select a mask from the drop-down list if you like.

<p><li><b>Configuration:</b>  Select a project configuration.  The configuration you select will determine which preprocessor include directories
are used, and also which preprocessor definitions are used.
</ul>

<h3>Other Options</h3>

<ul>
<p><li><b>Parse preprocessor macros</b>.  There is now the capability to parse the preprocessor macros, and this flag is used to turn that 
feature on and off.  Since the parsing may not be 100% accurate (with respect to the compiler), I leave this as a choice to you.
</ul>

<p>Once you've entered some valid data, click <b>Start</b> and the program will start the search.  The searching is done in a separate thread,
so you will see the button's text turn to "<b>Stop</b>" once you click <b>Start</b>.  To stop the search, simply click <b>Stop</b> and the thread will quit,
turning the <b>Stop</b> button back into the <b>Start</b> button.

<h3><a name=viewsearch>Viewing and Searching the Output</a></h3>

The output is shown in a standard Win32 tree control, using MFC's CTreeCtrl.  As each source file is completed, the program populates
the tree with the source file and all the files <code>#include</code>d by it.  You will notice that there are a few icons used in the tree
that denote properties of the item.  Here's an explanation of them:

<p><img src="IncludeFinder/includefinder1.jpg" alt="Regular" width=16 height=16>  This icon is used to denote a regular file.</p>

<p><img src="IncludeFinder/includefinder2.jpg" alt="Multiply Included" width=16 height=16>  This icon is used to denote that the instance of the file is not the
first time it was included by the current source file (either directly or indirectly).</p>

<p><img src="IncludeFinder/includefinder3.jpg" alt="Not Found" width=16 height=16>  This icon is used to denote that the file could not be found along the specified include paths.</p>

<p><img src="IncludeFinder/includefinder4.jpg" alt="Recursive" width=16 height=16>  This icon is used to denote that the file has been recursively included.</p>

<p>To search the tree for a particular file, select the <b>Find...</b> menu item, or click <b>F3</b> to search for the next occurrence of a string.

<h3><a name="loadsave">Saving and Restoring the Data</a></h3>

If you click on the <b>Save</b> toolbar icon, or select the <b>Save Results...</b> menu item, you will be prompted to enter a file name to save to.
The results are saved in XML format like the sample shown below.

<p><i>Sample XML Output (viewed with IE):</i>
<p><img src="IncludeFinder/includefinder5.jpg" alt="Sample XML" width=593 height=157></p>

<p>Once you have saved an XML file, you can click the <b>Open</b> toolbar icon, or select the <b>Open...</b> menu item to select a file to reload.
The XML tree will be reloaded into the Include Finder.

<h2>About the Code</h2>

<p><b>Note:</b> At my work we have a coding standard which is a form of Hungarian Notation.  I've also used this standard in this project.
It's what I've been using for the past few years, and I like it, but that's not the point of the article or the code, so please don't flame me for it.

<p>I've tried to keep the core code of the program as separated from the interface as possible, so that it will be easy for someone
to reuse the interesting portions.  Since the code has grown substantially in size since the first version, I decided to omit descriptions
of the classes.  If you are interested in using the code, you can find a description of what's in each file in the headers at the top of them.

<h2>Acknowledgements</h2>

<p>I'd like to thank the following people:

<ul>
<li><a href="http://www.codeproject.com/script/profile/whos_who.asp?6533">Neville Franks</a> for sending me his .dsp/.dsw reading code, which helped make the parsing of them more robust.
<li><a href="http://www.codeproject.com/script/profile/whos_who.asp?42845">.S.Rod.</a> for his <a href="http://www.codeproject.com/tools/prjconverter.asp">VC7->VC6 Project Converter</a> code, which I used as a starting point for parsing the .sln and .vcproj formats.
<li><a href="http://www.codeproject.com/script/profile/whos_who.asp?66056">Kristen Wegner</a> for her <a href="http://www.codeproject.com/useritems/pugxml.asp">PugXml</a> parser.
</ul>

<h2>To Do</h2>

<ul>
<li>It would be neat to make a static library out of the core, thereby making it possible to use the core in a Developer Studio add-in,
as well as the external tool that it currently is.
<li>The preprocessor macro handling could be better.
<li>Interpreting the project settings could also be better.
<li>I've tried to write the code cleanly, but I'm sure it could still use some clean-up.
<li>Documentation for those who would like to use the code?
</ul>

<h2>History</h2>

<ol>
<li>January 7, 2003 - Initial Release
<li>January 27, 2003
<ul>
<li>Added the capability to read .dsp/.dsw/.vcproj/.sln files.
<li>Added an option to parse preprocessor macros.
<li>Added the capability to search multiple directories at once.
<li>Added an option to show only files which couldn't be found.
<li>Added support for entering environment variables in the <b>Includes</b> field.
<li>Added the capability to load a saved XML file from disk.
<li>Added the capability to select a custom program for viewing source files.
<li>Added the capability to double-click a leaf node in the tree to open the file.
<li>Added the capability to search the tree for specified strings.
<li>Added CMMFStream class, which improved parsing performance greatly.
</ul>
<li>February 24, 2003 (bug fixes) - Thanks to Medved, Oliver Wahl, and Andreas Saurwin for alerting me to, and/or showing patches for these bugs.
<ul>
<li>CMMFStream would incorrectly handle files with zero length.
<li>CParser::FindFullPath had a bug which made it find the incorrect file in certain cases.
<li>CLexer incorrectly handled certain characters that could be found in binary files.
<li>CLexer incorrectly handled files which had a strange combination of \r\n, which caused a crash.
</ul>
</ul>
<li>July 30, 2003 (bug fixes and some changes to run on NT 4 without IE shell update)
<ul>
<li>Fixed a bug where FindFullPath would incorrectly handle two files with the same name but in different paths. - Thanks to Oliver Wahl.
<li>Fixed a bug where bracketed include directories from project settings weren't read. - Thanks to EvanKeats
<li>Removed use of SHGetSpecialFolderPath and replaced it with SHGetSpecialFolderLocation/SHGetPathFromIDList. - Thanks to brownfox and Hemal Shah
</ul>
</ul>
</ol>


<h2>Disclaimer and Copyright</h2>
Although great care has gone into developing this software,
it is provided without any guarantee of reliability, accuracy
of information, or correctness of operation.  I am not responsible
for any damages that may occur as a result of using this software.
Use this software entirely at your own risk.
Copyright 2003, Chris Richardson.

<h2>Final Notes</h2>

<p>Any feedback or bug reports will be greatly appreciated.  If you do or do not like the article, the code, or the program I've provided,
please tell me why.

<p>Thanks for taking the time to read my article.  I hope you enjoyed it, and I hope you find the Include Finder useful.

</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I like to program, I like to sail.

Comments and Discussions