PageRenderTime 26ms CodeModel.GetById 13ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.cpp

http://hadesmem.googlecode.com/
C++ | 190 lines | 126 code | 31 blank | 33 comment | 12 complexity | 8d02f9a4f4d8a49d8d3d1089e1538a2d MD5 | raw file
  1// doxml2qbk (developed in the context of Boost.Geometry documentation)
  2//
  3// Copyright (c) 2010 Barend Gehrels, Amsterdam, the Netherlands.
  4// Use, modification and distribution is subject to the Boost Software License,
  5// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6// http://www.boost.org/LICENSE_1_0.txt)
  7//
  8//
  9// Barend Gehrels, Aug 1, 2010
 10// In continuation of the QuickBook documentation of Boost.Geometry
 11//
 12// Converts XML files created by Doxygen to Quickbook
 13// Notes:
 14// - basically generic, but implemented with Boost.Geometry in mind
 15// - makes use of some specific XML elements, which can be created by Doxygen
 16//       using /xmlonly
 17//     currently this is the element <qbk.example> which will make a reference
 18//     to an example.
 19// - currently still in draft
 20
 21// Aug 14/15: added classes, defines, various enhancements.
 22
 23#include <iostream>
 24#include <fstream>
 25#include <sstream>
 26#include <vector>
 27#include <map>
 28
 29#include <boost/foreach.hpp>
 30#include <boost/algorithm/string.hpp>
 31#include <boost/algorithm/string/split.hpp>
 32
 33
 34#include <boost/program_options.hpp>
 35
 36#include <rapidxml.hpp>
 37
 38#include <configuration.hpp>
 39#include <file_to_string.hpp>
 40#include <doxygen_elements.hpp>
 41#include <doxygen_xml_parser.hpp>
 42#include <parameter_predicates.hpp>
 43#include <quickbook_output.hpp>
 44#include <rapidxml_util.hpp>
 45
 46
 47
 48int main(int argc, char** argv)
 49{
 50    std::string filename;
 51    try
 52    {
 53        configuration config;
 54        std::string copyright_filename;
 55
 56        // Read/get configuration
 57        {
 58            namespace po = boost::program_options;
 59            po::options_description description("=== doxml2qbk ===\nAllowed options");
 60
 61
 62            std::string convenience_headers;
 63
 64            description.add_options()
 65                ("help", "Help message")
 66                ("xml", po::value<std::string>(&filename), 
 67                            "Name of XML file written by Doxygen")
 68                ("start_include", po::value<std::string>(&config.start_include), 
 69                            "Start include")
 70                ("convenience_header_path", po::value<std::string>(&config.convenience_header_path), 
 71                            "Convenience header path")
 72                ("convenience_headers", po::value<std::string>(&convenience_headers), 
 73                            "Convenience header(s) (comma-separated)")
 74                ("skip_namespace", po::value<std::string>(&config.skip_namespace), 
 75                            "Namespace to skip (e.g. boost::mylib::")
 76                ("copyright", po::value<std::string>(&copyright_filename), 
 77                            "Name of QBK file including (commented) copyright and license")
 78            ;
 79
 80            po::variables_map varmap;
 81
 82            if (argc == 2 && ! boost::starts_with(argv[1], "--"))
 83            {
 84                // (especially for debugging) options might go into an INI file
 85                std::ifstream config_file (argv[1], std::ifstream::in);
 86                po::store(po::parse_config_file(config_file, description), varmap);
 87            }
 88            else
 89            {
 90                po::store(po::parse_command_line(argc, argv, description), varmap);
 91            }
 92
 93            po::notify(varmap);
 94
 95            if (varmap.count("help") || filename.empty())
 96            {
 97                std::cout << description << std::endl;
 98                return 1;
 99            }
100
101            // Split CSV with headerfile names into configuration
102            if (! convenience_headers.empty())
103            {
104                boost::split(config.convenience_headers, convenience_headers, boost::is_any_of(","));
105            }
106        }
107
108        // Read files into strings
109        std::string xml_string = file_to_string(filename);
110        std::string license = copyright_filename.empty() 
111            ? "" 
112            : file_to_string(copyright_filename);
113
114        // Parse the XML outputted by Doxygen
115        xml_doc xml(xml_string.c_str());
116
117        documentation doc;
118        parse(xml.first_node(), config, doc);
119
120        // Check for duplicate function names
121        for (std::size_t i = 0; i < doc.functions.size(); i++)
122        {
123            function& f1 = doc.functions[i];
124            for (std::size_t j = i + 1; j < doc.functions.size(); j++)
125            {
126                function& f2 = doc.functions[j];
127
128                if (f1.name == f2.name)
129                {
130                    // It is not a unique function, so e.g. an overload,
131                    // so a description must distinguish them.
132                    // Difference is either the number of parameters, or a const / non-const version
133                    // Use the "\qbk{distinguish,with strategy}" in the source code to distinguish
134                    f1.unique = false;
135                    f2.unique = false;
136                }
137            }
138        }
139
140
141        // Write copyright/license (keep inspect silent)
142        if (! license.empty())
143        {
144            std::cout << license << std::endl;
145        }
146
147        // Write warning comment
148        std::cout
149            << "[/ Generated by doxygen_xml2qbk, don't change, will be overwritten automatically]" << std::endl
150            << "[/ Generated from " << filename << "]" << std::endl;
151
152        // Write the rest: functions, defines, classes or structs
153        BOOST_FOREACH(function const& f, doc.functions)
154        {
155            quickbook_output(f, config, std::cout);
156        }
157        BOOST_FOREACH(function const& f, doc.defines)
158        {
159            quickbook_output(f, config, std::cout);
160        }
161        BOOST_FOREACH(enumeration const& e, doc.enumerations)
162        {
163            quickbook_output(e, config, std::cout);
164        }
165
166        if (! doc.cos.name.empty())
167        {
168            std::sort(doc.cos.functions.begin(), doc.cos.functions.end(), sort_on_line<function>());
169            quickbook_output(doc.cos, config, std::cout);
170        }
171
172    }
173    catch(std::exception const& e)
174    {
175        std::cerr << "Exception in doxygen_xml2qbk: " << std::endl
176            << "   Message: " << e.what() << std::endl
177            << "   File: " << filename << std::endl
178            << "   Type: " << typeid(e).name() << std::endl
179            << std::endl;
180        return 1;
181    }
182    catch(...)
183    {
184        std::cerr << "Unknown exception in doxygen_xml2qbk" 
185            << std::endl;
186        return 1;
187    }
188    return 0;
189}
190