Thread: Any tool to find all include from a given c++ file?

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    127

    Any tool to find all include from a given c++ file?

    Does anyone know of any tools that will output all the included files from a given c++ file? A lot of times headers include other headers. So when you see #include x it may actually be including a, b, and c too.

  2. #2
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    'cl /showIncludes file.cpp' for Visual Studio, I'm sure GCC has something similar

  3. #3
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I remember writing this tool a while ago. It was pretty trivial. I can't find it anymore, though.

  4. #4
    C++ Junkie Mozza314's Avatar
    Join Date
    Jan 2011
    Location
    Australia
    Posts
    174
    Quick and dirty. Ignores files without a period so that standard headers are ignored. Also assumes all files are in the current directory (doesn't implement include path lookup stuff). If you actually want to use it I'll probably put a path lookup in there (or feel free to do it yourself :-P).

    Code:
    #include <cassert>
    #include <cstdlib>
    #include <fstream>
    #include <iostream>
    #include <list>
    #include <string>
    
    void ShowIncludes(const std::string& filename, std::list<std::string>& includes);
    
    int main(int argc, char** argv)
    {
        if (argc != 2)
        {
            std::cerr << "Usage: " << argv[0] << " filename" << std::endl;
            return 0;
        }
    
        std::list<std::string> includes;
        ShowIncludes(argv[1], includes);
    
        includes.sort();
    
        for (std::list<std::string>::iterator it = includes.begin(); it != includes.end(); ++it)
            std::cout << *it << std::endl;
    
        return 0;
    }
    
    void ShowIncludes(const std::string& filename, std::list<std::string>& includes)
    {
        std::ifstream ifs(filename.c_str());
    
        if (!ifs.good())
        {
            std::cerr << "Couldn't open " << filename << std::endl;
            exit(1);
        }
    
        std::string line;
        getline(ifs, line);
        while (!ifs.eof())
        {
            if (line.size() >= 12 && line[0] == '#')
            {
                int start = 1;
                while (start < line.size() && line[start] == ' ')
                    ++start;
    
                bool couldBeInclude = true;
                for (int i = 0; i != 7 && couldBeInclude; ++i)
                    couldBeInclude &= (line[start + i] == "include"[i]);
    
                if (couldBeInclude)
                {
                    int fileStart = start + 7;
                    while (fileStart < line.size() && line[fileStart] == ' ')
                        ++fileStart;
    
                    assert(fileStart < line.size());
                    assert(line[fileStart] == '"' || line[fileStart] == '<');
                    ++fileStart;
    
                    int fileEnd = fileStart;
                    bool dotFound = false;
                    while (fileEnd < line.size() && line[fileEnd] != '"' && line[fileEnd] != '>')
                    {
                        dotFound |= (line[fileEnd] == '.');
                        ++fileEnd;
                    }
    
                    assert(fileEnd < line.size());
                    assert(line[fileEnd] == '"' || line[fileEnd] == '>');
    
                    if (dotFound) // ignore standard headers that don't have a period in them
                    {
                        line[fileEnd] = '\0';
                        includes.push_back(&line[fileStart]);
                        ShowIncludes(includes.back(), includes);
                    }
                }
            }
    
            getline(ifs, line);
        }
    }
    I just realised you can take advantage of the preprocessor for this and if you're on linux you can also use grep and such to do this quite easily:

    Code:
    g++ -E $1 |\
        grep '^# [0-9]* "[^"]*"' |\
        grep -o '"[^"]*"' |\
        grep -o '[^"<>]*' |\
        grep -v '^/usr/' |\
        sort |\
        uniq
    Last edited by Mozza314; 04-01-2011 at 05:59 PM.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Use the -H option to compile your code in g++:
    Preprocessor Options - Using the GNU Compiler Collection (GCC)
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you help me about tolower() in file
    By nctar in forum C Programming
    Replies: 7
    Last Post: 05-12-2010, 10:04 AM
  2. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  3. C programing doubt
    By sivasankari in forum C Programming
    Replies: 2
    Last Post: 04-29-2008, 09:19 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM