Listing 2

#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/exception.hpp>
#include <boost/graph/graphviz.hpp>

namespace bfs = boost::filesystem;
typedef boost::GraphvizDigraph Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor VertexDescriptor;
bool TraversePath(bfs::path topDir, VertexDescriptor topDirVertex,
                  unsigned int depth, Graph& treeGraph);
VertexDescriptor CreateVertex(std::string dirName, Graph& treeGraph);
int main(int argc, char* argv[])
{
    // Parse command line arguments
    if (argc != 3)  {
        std::cerr << "Usage: dirtree <topDir> <depth>" << std::endl;
        return -1;
    }
    bfs::path topDir(argv[1]);
    if (!is_directory(topDir))  {
        std::cerr << "Usage: dirtree <topDir> <depth>" << std::endl;
        return -1;
    }
    unsigned int depth;
    try  {
        depth = boost::lexical_cast<unsigned int>(argv[2]);
    }
    catch (boost::bad_lexical_cast&)  {
        std::cerr << "Usage: dirtree <topDir> <depth>" << std::endl;
        return -1;
    }
    // Construct the graph
    Graph treeGraph;

    VertexDescriptor topDirVertex = 
                 CreateVertex(topDir.native_directory_string(), treeGraph);
    TraversePath(topDir, topDirVertex, depth, treeGraph);
    // Set properties of the graph
    boost::graph_property<Graph, boost::graph_graph_attribute_t>::
         type& graphAttr = boost::get_property(treeGraph, 
            boost::graph_graph_attribute);
    graphAttr["name"] = "treeDir";
    graphAttr["rankdir"] = "LR";
    // Set properties that apply to all the nodes of the graph
    boost::graph_property<Graph, boost::graph_vertex_attribute_t>::
         type& graphVertAttr = boost::get_property(treeGraph, 
            boost::graph_vertex_attribute);
    graphVertAttr["shape"] = "box";
    graphVertAttr["height"] = "0.1";
    // Output the graph
    boost::write_graphviz("1.dot", treeGraph);
    std::cout << num_vertices(treeGraph) << std::endl;
}
bool TraversePath(bfs::path topPath, VertexDescriptor topDirVertex,
                  unsigned int depth, Graph& treeGraph)
{
    // Safety checks
    if (!bfs::exists(topPath))  {
        return false;
    }
    bfs::directory_iterator dirIter, endIter;
    try  {
        dirIter = bfs::directory_iterator(topPath);
    }
    catch (bfs::filesystem_error& err)  {
        // We cannot traverse this directory, mark it with a dashed line
        std::cerr << "Error: " << err.what() << std::endl;
        const boost::property_map<Graph, boost::vertex_attribute_t>::
           type& vertAttr = boost::get(boost::vertex_attribute, 					       treeGraph);
        vertAttr[topDirVertex]["style"] = "dashed";
        return false;
    }
    try  {
        for ( ; dirIter != endIter; ++dirIter)  {
            // Process only directories under topPath (discard files)
            if (is_directory(*dirIter))  {
                VertexDescriptor newVertex = 
                            CreateVertex(dirIter->leaf(), treeGraph);
                add_edge(topDirVertex, newVertex, treeGraph);

                if (depth > 1)  {
                   // Recursion through the subdirectory
                    TraversePath(*dirIter, newVertex, depth-1, treeGraph);
                }
            }
        }
    }
    catch (bfs::filesystem_error& err)  {
        std::cerr << "Error: " << err.what() << std::endl;
        return false;
    }
    return true;
}
VertexDescriptor CreateVertex(std::string dirName, Graph& treeGraph)
{
    // Add the vertex
    VertexDescriptor vertex = add_vertex(treeGraph);
    // Add its property
    const boost::property_map<Graph, boost::vertex_attribute_t>::
        type& vertAttrMap = boost::get(boost::vertex_attribute, treeGraph);
    vertAttrMap[vertex]["label"] = dirName;

    return vertex;
}