/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. // Aug 14/15: added classes, defines, various enhancements.
  21. #include <iostream>
  22. #include <fstream>
  23. #include <sstream>
  24. #include <vector>
  25. #include <map>
  26. #include <boost/foreach.hpp>
  27. #include <boost/algorithm/string.hpp>
  28. #include <boost/algorithm/string/split.hpp>
  29. #include <boost/program_options.hpp>
  30. #include <rapidxml.hpp>
  31. #include <configuration.hpp>
  32. #include <file_to_string.hpp>
  33. #include <doxygen_elements.hpp>
  34. #include <doxygen_xml_parser.hpp>
  35. #include <parameter_predicates.hpp>
  36. #include <quickbook_output.hpp>
  37. #include <rapidxml_util.hpp>
  38. int main(int argc, char** argv)
  39. {
  40. std::string filename;
  41. try
  42. {
  43. configuration config;
  44. std::string copyright_filename;
  45. // Read/get configuration
  46. {
  47. namespace po = boost::program_options;
  48. po::options_description description("=== doxml2qbk ===\nAllowed options");
  49. std::string convenience_headers;
  50. description.add_options()
  51. ("help", "Help message")
  52. ("xml", po::value<std::string>(&filename),
  53. "Name of XML file written by Doxygen")
  54. ("start_include", po::value<std::string>(&config.start_include),
  55. "Start include")
  56. ("convenience_header_path", po::value<std::string>(&config.convenience_header_path),
  57. "Convenience header path")
  58. ("convenience_headers", po::value<std::string>(&convenience_headers),
  59. "Convenience header(s) (comma-separated)")
  60. ("skip_namespace", po::value<std::string>(&config.skip_namespace),
  61. "Namespace to skip (e.g. boost::mylib::")
  62. ("copyright", po::value<std::string>(&copyright_filename),
  63. "Name of QBK file including (commented) copyright and license")
  64. ;
  65. po::variables_map varmap;
  66. if (argc == 2 && ! boost::starts_with(argv[1], "--"))
  67. {
  68. // (especially for debugging) options might go into an INI file
  69. std::ifstream config_file (argv[1], std::ifstream::in);
  70. po::store(po::parse_config_file(config_file, description), varmap);
  71. }
  72. else
  73. {
  74. po::store(po::parse_command_line(argc, argv, description), varmap);
  75. }
  76. po::notify(varmap);
  77. if (varmap.count("help") || filename.empty())
  78. {
  79. std::cout << description << std::endl;
  80. return 1;
  81. }
  82. // Split CSV with headerfile names into configuration
  83. if (! convenience_headers.empty())
  84. {
  85. boost::split(config.convenience_headers, convenience_headers, boost::is_any_of(","));
  86. }
  87. }
  88. // Read files into strings
  89. std::string xml_string = file_to_string(filename);
  90. std::string license = copyright_filename.empty()
  91. ? ""
  92. : file_to_string(copyright_filename);
  93. // Parse the XML outputted by Doxygen
  94. xml_doc xml(xml_string.c_str());
  95. documentation doc;
  96. parse(xml.first_node(), config, doc);
  97. // Check for duplicate function names
  98. for (std::size_t i = 0; i < doc.functions.size(); i++)
  99. {
  100. function& f1 = doc.functions[i];
  101. for (std::size_t j = i + 1; j < doc.functions.size(); j++)
  102. {
  103. function& f2 = doc.functions[j];
  104. if (f1.name == f2.name)
  105. {
  106. // It is not a unique function, so e.g. an overload,
  107. // so a description must distinguish them.
  108. // Difference is either the number of parameters, or a const / non-const version
  109. // Use the "\qbk{distinguish,with strategy}" in the source code to distinguish
  110. f1.unique = false;
  111. f2.unique = false;
  112. }
  113. }
  114. }
  115. // Write copyright/license (keep inspect silent)
  116. if (! license.empty())
  117. {
  118. std::cout << license << std::endl;
  119. }
  120. // Write warning comment
  121. std::cout
  122. << "[/ Generated by doxygen_xml2qbk, don't change, will be overwritten automatically]" << std::endl
  123. << "[/ Generated from " << filename << "]" << std::endl;
  124. // Write the rest: functions, defines, classes or structs
  125. BOOST_FOREACH(function const& f, doc.functions)
  126. {
  127. quickbook_output(f, config, std::cout);
  128. }
  129. BOOST_FOREACH(function const& f, doc.defines)
  130. {
  131. quickbook_output(f, config, std::cout);
  132. }
  133. BOOST_FOREACH(enumeration const& e, doc.enumerations)
  134. {
  135. quickbook_output(e, config, std::cout);
  136. }
  137. if (! doc.cos.name.empty())
  138. {
  139. std::sort(doc.cos.functions.begin(), doc.cos.functions.end(), sort_on_line<function>());
  140. quickbook_output(doc.cos, config, std::cout);
  141. }
  142. }
  143. catch(std::exception const& e)
  144. {
  145. std::cerr << "Exception in doxygen_xml2qbk: " << std::endl
  146. << " Message: " << e.what() << std::endl
  147. << " File: " << filename << std::endl
  148. << " Type: " << typeid(e).name() << std::endl
  149. << std::endl;
  150. return 1;
  151. }
  152. catch(...)
  153. {
  154. std::cerr << "Unknown exception in doxygen_xml2qbk"
  155. << std::endl;
  156. return 1;
  157. }
  158. return 0;
  159. }