Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/quickbook/detail/quickbook.cpp @ 32

Last change on this file since 32 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 9.0 KB
Line 
1/*=============================================================================
2    Copyright (c) 2002 2004 Joel de Guzman
3    Copyright (c) 2004 Eric Niebler
4    http://spirit.sourceforge.net/
5
6    Use, modification and distribution is subject to the Boost Software
7    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8    http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10#include "../block.hpp"
11#include "../doc_info.hpp"
12#include "./post_process.hpp"
13#include "utils.hpp"
14#include "actions.hpp"
15#include <boost/spirit/iterator/position_iterator.hpp>
16#include <boost/program_options.hpp>
17#include <boost/filesystem/path.hpp>
18#include <boost/filesystem/operations.hpp>
19#include <boost/ref.hpp>
20
21#include <stdexcept>
22#include <fstream>
23#include <iostream>
24#include <sstream>
25
26#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
27#pragma warning(disable:4355)
28#endif
29
30#define QUICKBOOK_VERSION "Quickbook Version 1.3"
31
32namespace quickbook
33{
34    using namespace boost::spirit;
35    namespace fs = boost::filesystem;
36    tm* current_time; // the current time
37    tm* current_gm_time; // the current UTC time
38    bool debug_mode; // for quickbook developers only
39    unsigned qbk_major_version = 0;
40    unsigned qbk_minor_version = 0;
41    unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version
42    bool ms_errors = false; // output errors/warnings as if for VS
43
44    ///////////////////////////////////////////////////////////////////////////
45    //
46    //  Load a file
47    //
48    ///////////////////////////////////////////////////////////////////////////
49    static int
50    load(char const* filename, file_storage& storage)
51    {
52        using std::cerr;
53        using std::endl;
54        using std::ios;
55        using std::ifstream;
56        using std::istream_iterator;
57
58        ifstream in(filename, std::ios_base::in);
59
60        if (!in)
61        {
62            detail::outerr(filename,1)
63                << "Could not open input file." << endl;
64            return 1;
65        }
66
67        // Turn off white space skipping on the stream
68        in.unsetf(ios::skipws);
69
70        std::copy(
71            istream_iterator<char>(in),
72            istream_iterator<char>(),
73            std::back_inserter(storage));
74
75        //  ensure that we have enough trailing newlines to eliminate
76        //  the need to check for end of file in the grammar.
77        storage.push_back('\n');
78        storage.push_back('\n');
79        return 0;
80    }
81
82    ///////////////////////////////////////////////////////////////////////////
83    //
84    //  Parse a file
85    //
86    ///////////////////////////////////////////////////////////////////////////
87    int
88    parse(char const* filein_, actions& actor, bool ignore_docinfo)
89    {
90        using std::cerr;
91        using std::vector;
92        using std::string;
93
94        file_storage storage;
95        int err = quickbook::load(filein_, storage);
96        if (err != 0)
97            return err;
98
99        typedef position_iterator<file_storage::const_iterator> iterator_type;
100        iterator_type first(storage.begin(), storage.end(), filein_);
101        iterator_type last(storage.end(), storage.end());
102
103        doc_info_grammar<actions> l(actor);
104        parse_info<iterator_type> info = parse(first, last, l);
105
106        if (info.hit || ignore_docinfo)
107        {
108            pre(actor.out, actor, ignore_docinfo);
109
110            block_grammar<actions> g(actor);
111            info = parse(info.hit ? info.stop : first, last, g);
112            if (info.full)
113            {
114                post(actor.out, actor, ignore_docinfo);
115            }
116        }
117
118        if (!info.full)
119        {
120            file_position const pos = info.stop.get_position();
121            detail::outerr(pos.file,pos.line)
122                << "Syntax Error near column " << pos.column << ".\n";
123            return 1;
124        }
125
126        return 0;
127    }
128
129    static int
130        parse(char const* filein_, fs::path const& outdir, std::ostream& out, bool ignore_docinfo = false)
131    {
132        actions actor(filein_, outdir, out);
133        bool r = parse(filein_, actor);
134        if (actor.level != 0)
135            detail::outwarn(filein_,1)
136                << "Warning missing [endsect] detected at end of file."
137                << std::endl;
138        return r;
139    }
140
141    static int
142    parse(
143        char const* filein_
144      , char const* fileout_
145      , int indent
146      , int linewidth
147      , bool pretty_print)
148    {
149        int result = 0;
150        std::ofstream fileout(fileout_);
151        fs::path outdir = fs::path(fileout_, fs::native).branch_path();
152        if (outdir.empty())
153            outdir = ".";
154        if (pretty_print)
155        {
156            std::stringstream buffer;
157            result = parse(filein_, outdir, buffer);
158            if (result == 0)
159            {
160                post_process(buffer.str(), fileout, indent, linewidth);
161            }
162        }
163        else
164        {
165            result = parse(filein_, outdir, fileout);
166        }
167        return result;
168    }
169}
170
171///////////////////////////////////////////////////////////////////////////
172//
173//  Main program
174//
175///////////////////////////////////////////////////////////////////////////
176int
177main(int argc, char* argv[])
178{
179    try 
180    {
181        using boost::program_options::options_description;
182        using boost::program_options::variables_map;
183        using boost::program_options::store;
184        using boost::program_options::parse_command_line;
185        using boost::program_options::command_line_parser;
186        using boost::program_options::notify;
187        using boost::program_options::value;
188        using boost::program_options::positional_options_description;
189
190        // First thing, the filesystem should record the current working directory.
191        boost::filesystem::initial_path();
192
193        options_description desc("Allowed options");
194        desc.add_options()
195            ("help", "produce help message")
196            ("version", "print version string")
197            ("no-pretty-print", "disable XML pretty printing")
198            ("indent", value<int>(), "indent spaces")
199            ("linewidth", value<int>(), "line width")
200            ("input-file", value<std::string>(), "input file")
201            ("output-file", value<std::string>(), "output file")
202            ("debug", "debug mode (for developers)")
203            ("ms-errors", "use Microsoft Visual Studio style error & warn message format")
204        ;
205       
206        positional_options_description p;
207        p.add("input-file", -1);
208   
209        variables_map vm;
210        int indent = -1;
211        int linewidth = -1;
212        bool pretty_print = true;
213        store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
214        notify(vm);   
215   
216        if (vm.count("help")) 
217        {
218            std::cout << desc << "\n";
219            return 0;
220        }
221
222        if (vm.count("version"))
223        {
224            std::cout << QUICKBOOK_VERSION << std::endl;
225            return 0;
226        }
227   
228        if (vm.count("ms-errors"))
229            quickbook::ms_errors = true;
230
231        if (vm.count("no-pretty-print"))
232            pretty_print = false;
233
234        if (vm.count("indent"))
235            indent = vm["indent"].as<int>();
236
237        if (vm.count("linewidth"))
238            linewidth = vm["linewidth"].as<int>();
239       
240        if (vm.count("debug"))
241        {
242            static tm timeinfo;
243            timeinfo.tm_year = 2000 - 1900;
244            timeinfo.tm_mon = 12 - 1;
245            timeinfo.tm_mday = 20;
246            timeinfo.tm_hour = 12;
247            timeinfo.tm_min = 0;
248            timeinfo.tm_sec = 0;
249            timeinfo.tm_isdst = -1;
250            mktime(&timeinfo);
251            quickbook::current_time = &timeinfo;
252            quickbook::current_gm_time = &timeinfo;
253            quickbook::debug_mode = true;
254        }
255        else
256        {
257            time_t t = std::time(0);
258            static tm lt = *localtime(&t);
259            static tm gmt = *gmtime(&t);
260            quickbook::current_time = &lt;
261            quickbook::current_gm_time = &gmt;
262            quickbook::debug_mode = false;
263        }
264
265        if (vm.count("input-file"))
266        {
267            std::string filein = vm["input-file"].as<std::string>();
268            std::string fileout;
269
270            if (vm.count("output-file"))
271            {
272                fileout = vm["output-file"].as<std::string>();
273            }
274            else
275            {
276                fileout = quickbook::detail::remove_extension(filein.c_str());
277                fileout += ".xml";
278            }
279
280            std::cout << "Generating Output File: "
281                << fileout
282                << std::endl;
283   
284            return quickbook::parse(filein.c_str(), fileout.c_str(), indent, linewidth, pretty_print);
285        }
286        else
287        {
288            quickbook::detail::outerr("",0) << "Error: No filename given" << std::endl;
289        }
290    }
291   
292    catch(std::exception& e) 
293    {
294        quickbook::detail::outerr("",0) << "Error: " << e.what() << "\n";
295        return 1;
296    }
297
298    catch(...) 
299    {
300        quickbook::detail::outerr("",0) << "Error: Exception of unknown type caught\n";
301    }
302
303    return 0;
304}
Note: See TracBrowser for help on using the repository browser.