![]() |
Web Development »
Applications & Tools »
Tools with source code
Intermediate
Include File Hierarchy ViewerBy Chris RichardsonA tool to view the include file hierarchy of your source code. |
VC6Win2K, WinXP, MFC, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||

I've seen many people ask about utilities to view the tree of #included 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 #include tree generator.

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.
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.
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.
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).
Set this check box if you want the program to recurse through subdirectories of the directories you entered.

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.
Note: 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.
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.
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 Start, the Include Finder will use the first configuration found in each project.
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.
Select a project configuration. The configuration you select will determine which preprocessor include directories are used, and also which preprocessor definitions are used.
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.
Once you've entered some valid data, click Start 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 "Stop" once you click Start. To stop the search, simply click Stop and the thread will quit, turning the Stop button back into the Start button.
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 #included 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:
This icon is used to denote a regular file.
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).
This icon is used to denote that the file could not be found along the specified include paths.
This icon is used to denote that the file has been recursively included.
To search the tree for a particular file, select the Find... menu item, or click F3 to search for the next occurrence of a string.
If you click on the Save toolbar icon, or select the Save Results... 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.

Once you have saved an XML file, you can click the Open toolbar icon, or select the Open... menu item to select a file to reload. The XML tree will be reloaded into the Include Finder.
Note: 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.
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.
I'd like to thank the following people:
CMMFStream class, which improved parsing performance greatly. CMMFStream would incorrectly handle files with zero length.
CParser::FindFullPath had a bug which made it find the incorrect file in certain cases.
CLexer incorrectly handled certain characters that could be found in binary files.
CLexer incorrectly handled files which had a strange combination of \r\n, which caused a crash. FindFullPath would incorrectly handle two files with the same name but in different paths. - Thanks to Oliver Wahl.
SHGetSpecialFolderPath and replaced it with SHGetSpecialFolderLocation/SHGetPathFromIDList. - Thanks to brownfox and Hemal Shah. 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.
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.
Thanks for taking the time to read my article. I hope you enjoyed it, and I hope you find the Include Finder useful.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 29 Jul 2003 Editor: Rinish Biju |
Copyright 2003 by Chris Richardson Everything else Copyright © CodeProject, 1999-2009 Web12 | Advertise on the Code Project |