]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / doc / src / docutils / tools / doxygen_xml2qbk / doxygen_xml2qbk.cpp
CommitLineData
7c673cae
FG
1// doxml2qbk (developed in the context of Boost.Geometry documentation)
2//
3// Copyright (c) 2010-2013 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
5// Use, modification and distribution is subject to the Boost Software License,
6// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9//
10// Barend Gehrels, Aug 1, 2010
11// In continuation of the QuickBook documentation of Boost.Geometry
12//
13// Converts XML files created by Doxygen to Quickbook
14// Notes:
15// - basically generic, but implemented with Boost.Geometry in mind
16// - makes use of some specific XML elements, which can be created by Doxygen
17// using /xmlonly
18// currently this is the element <qbk.example> which will make a reference
19// to an example.
20// - currently still in draft
21
22#include <iostream>
23#include <fstream>
24#include <sstream>
25#include <vector>
26#include <map>
27
28#include <boost/foreach.hpp>
29#include <boost/algorithm/string.hpp>
30#include <boost/algorithm/string/split.hpp>
31
32
33#include <boost/program_options.hpp>
34
35#include <rapidxml.hpp>
36
37#include <configuration.hpp>
38#include <file_to_string.hpp>
39#include <doxygen_elements.hpp>
40#include <doxygen_xml_parser.hpp>
41#include <parameter_predicates.hpp>
42#include <quickbook_output.hpp>
43#include <rapidxml_util.hpp>
44
45static const std::string version = "1.1.1";
46
47inline std::string program_description(bool decorated)
48{
49 std::string result;
50 if (decorated)
51 {
52 result = "=== ";
53 }
54 result += "doxygen_xml2qbk ";
55 result += version;
56 if (decorated)
57 {
58 result += " ===";
59 }
60 return result;
61}
62
63
64int main(int argc, char** argv)
65{
66 std::string filename;
67 try
68 {
69 configuration config;
70 std::string copyright_filename;
71 std::string output_style;
72
73 // Read/get configuration
74 {
75 namespace po = boost::program_options;
76 po::options_description description;
77
78 std::string convenience_headers;
79
80 description.add_options()
81 ("help", "Help message")
82 ("version", "Version description")
83 ("xml", po::value<std::string>(&filename),
84 "Name of XML file written by Doxygen")
85 ("start_include", po::value<std::string>(&config.start_include),
86 "Start include")
87 ("convenience_header_path", po::value<std::string>(&config.convenience_header_path),
88 "Convenience header path")
89 ("convenience_headers", po::value<std::string>(&convenience_headers),
90 "Convenience header(s) (comma-separated)")
91 ("skip_namespace", po::value<std::string>(&config.skip_namespace),
92 "Namespace to skip (e.g. boost::mylib::)")
93 ("copyright", po::value<std::string>(&copyright_filename),
94 "Name of QBK file including (commented) copyright and license")
95
96 ("output_style", po::value<std::string>(&output_style),
97 "Docbook output style. Available values: 'alt'")
98 ("output_member_variables", po::value<bool>(&config.output_member_variables),
99 "Output member variables inside the class")
100 ;
101
102 po::variables_map varmap;
103
104 if (argc == 2 && ! boost::starts_with(argv[1], "--"))
105 {
106 // (especially for debugging) options might go into an INI file
107 std::ifstream config_file (argv[1], std::ifstream::in);
108 po::store(po::parse_config_file(config_file, description), varmap);
109 }
110 else
111 {
112 po::store(po::parse_command_line(argc, argv, description), varmap);
113 }
114
115 po::notify(varmap);
116
117 if (varmap.count("version"))
118 {
119 std::cout << version << std::endl;
120 return 0;
121 }
122 else if (varmap.count("help"))
123 {
124 std::cout
125 << program_description(true) << std::endl
126 << "Available options:" << std::endl
127 << description << std::endl;
128 return 0;
129 }
130 else if (filename.empty())
131 {
132 std::cout
133 << program_description(true) << std::endl
134 << "Allowed options:" << std::endl
135 << description << std::endl;
136 return 1;
137 }
138
139 // Split CSV with headerfile names into configuration
140 if (! convenience_headers.empty())
141 {
142 boost::split(config.convenience_headers, convenience_headers, boost::is_any_of(","));
143 }
144 }
145
146 // Set output style
147 if ("alt" == output_style)
148 {
149 config.output_style = configuration::alt;
150 }
151
152 // Read files into strings
153 std::string xml_string = file_to_string(filename);
154 std::string license = copyright_filename.empty()
155 ? ""
156 : file_to_string(copyright_filename);
157
158 // Parse the XML outputted by Doxygen
159 xml_doc xml(xml_string.c_str());
160
161 documentation doc;
162 parse(xml.first_node(), config, doc);
163
164 // Check for duplicate function names
165 for (std::size_t i = 0; i < doc.functions.size(); i++)
166 {
167 function& f1 = doc.functions[i];
168 for (std::size_t j = i + 1; j < doc.functions.size(); j++)
169 {
170 function& f2 = doc.functions[j];
171
172 if (f1.name == f2.name)
173 {
174 // It is not a unique function, so e.g. an overload,
175 // so a description must distinguish them.
176 // Difference is either the number of parameters, or a const / non-const version
177 // Use the "\qbk{distinguish,with strategy}" in the source code to distinguish
178 f1.unique = false;
179 f2.unique = false;
180 }
181 }
182 }
183
184
185 // Write copyright/license (keep inspect silent)
186 if (! license.empty())
187 {
188 std::cout << license << std::endl;
189 }
190
191 // Write warning comment
192 std::cout
193 << "[/ Generated by " << program_description(false) << ", don't change, will be overwritten automatically]" << std::endl
194 << "[/ Generated from " << filename << "]" << std::endl;
195
196 if ( configuration::def == config.output_style )
197 {
198 // Write the rest: functions, defines, classes or structs
199 BOOST_FOREACH(function const& f, doc.functions)
200 {
201 quickbook_output(f, config, std::cout);
202 }
203 BOOST_FOREACH(function const& f, doc.defines)
204 {
205 quickbook_output(f, config, std::cout);
206 }
207 BOOST_FOREACH(enumeration const& e, doc.enumerations)
208 {
209 quickbook_output(e, config, std::cout);
210 }
211
212 if (! doc.cos.name.empty())
213 {
214 std::sort(doc.cos.functions.begin(), doc.cos.functions.end(), sort_on_line<function>());
215 quickbook_output(doc.cos, config, std::cout);
216 }
217 }
218 else if ( configuration::alt == config.output_style )
219 {
220 if (! doc.cos.name.empty())
221 {
222 std::sort(doc.cos.functions.begin(), doc.cos.functions.end(), sort_on_line<function>());
223 quickbook_output_alt(doc.cos, config, std::cout);
224 }
225
226 if (! doc.group_id.empty())
227 {
228 quickbook_output_alt(doc, config, std::cout);
229 }
230 }
231 }
232 catch(std::exception const& e)
233 {
234 std::cerr << "Exception in doxygen_xml2qbk: " << std::endl
235 << " Message: " << e.what() << std::endl
236 << " File: " << filename << std::endl
237 << " Type: " << typeid(e).name() << std::endl
238 << std::endl;
239 return 1;
240 }
241 catch(...)
242 {
243 std::cerr << "Unknown exception in doxygen_xml2qbk"
244 << std::endl;
245 return 1;
246 }
247 return 0;
248}
249