blob: 0a2e5309c55e5b7a60b54fc80d99977ab118904f [file] [log] [blame]
/*=============================================================================
Copyright (c) 2002 2004 2006 Joel de Guzman
Copyright (c) 2004 Eric Niebler
Copyright (c) 2011 Daniel James
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_QUICKBOOK_FILES_HPP)
#define BOOST_QUICKBOOK_FILES_HPP
#include <string>
#include <boost/filesystem/path.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/utility/string_ref.hpp>
#include <stdexcept>
#include <cassert>
#include <iosfwd>
namespace quickbook {
namespace fs = boost::filesystem;
struct file;
typedef boost::intrusive_ptr<file> file_ptr;
struct file_position
{
file_position() : line(1), column(1) {}
file_position(int l, int c) : line(l), column(c) {}
int line;
int column;
bool operator==(file_position const& other) const
{
return line == other.line && column == other.column;
}
friend std::ostream& operator<<(std::ostream&, file_position const&);
};
struct file
{
private:
// Non copyable
file& operator=(file const&);
file(file const&);
public:
fs::path const path;
std::string source_;
bool is_code_snippets;
private:
unsigned qbk_version;
unsigned ref_count;
public:
boost::string_ref source() const { return source_; }
file(fs::path const& path, boost::string_ref source,
unsigned qbk_version) :
path(path), source_(source.begin(), source.end()), is_code_snippets(false),
qbk_version(qbk_version), ref_count(0)
{}
file(file const& f, boost::string_ref source) :
path(f.path), source_(source.begin(), source.end()),
is_code_snippets(f.is_code_snippets),
qbk_version(f.qbk_version), ref_count(0)
{}
virtual ~file() {
assert(!ref_count);
}
unsigned version() const {
assert(qbk_version);
return qbk_version;
}
void version(unsigned v) {
// Check that either version hasn't been set, or it was
// previously set to the same version (because the same
// file has been loaded twice).
assert(!qbk_version || qbk_version == v);
qbk_version = v;
}
virtual file_position position_of(boost::string_ref::const_iterator) const;
friend void intrusive_ptr_add_ref(file* ptr) { ++ptr->ref_count; }
friend void intrusive_ptr_release(file* ptr)
{ if(--ptr->ref_count == 0) delete ptr; }
};
// If version isn't supplied then it must be set later.
file_ptr load(fs::path const& filename,
unsigned qbk_version = 0);
struct load_error : std::runtime_error
{
explicit load_error(std::string const& arg)
: std::runtime_error(arg) {}
};
// Interface for creating fake files which are mapped to
// real files, so that the position can be found later.
struct mapped_file_builder_data;
struct mapped_file_builder
{
typedef boost::string_ref::const_iterator iterator;
typedef boost::string_ref::size_type pos;
mapped_file_builder();
~mapped_file_builder();
void start(file_ptr);
file_ptr release();
void clear();
bool empty() const;
pos get_pos() const;
void add_at_pos(boost::string_ref, iterator);
void add(boost::string_ref);
void add(mapped_file_builder const&);
void add(mapped_file_builder const&, pos, pos);
void unindent_and_add(boost::string_ref);
private:
mapped_file_builder_data* data;
mapped_file_builder(mapped_file_builder const&);
mapped_file_builder& operator=(mapped_file_builder const&);
};
}
#endif // BOOST_QUICKBOOK_FILES_HPP