libcruft-util/cpp.hpp

128 lines
4.1 KiB
C++
Raw Normal View History

2018-04-01 14:49:10 +10:00
/*
2018-08-04 15:14:06 +10:00
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
2018-04-01 14:49:10 +10:00
*
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
*/
#ifndef CRUFT_UTIL_CPP_HPP
#define CRUFT_UTIL_CPP_HPP
#include "string.hpp"
#include "view.hpp"
#include <experimental/filesystem>
#include <string>
#include <map>
#include <stdexcept>
#include <stack>
namespace cruft::cpp {
2018-04-01 14:49:10 +10:00
///////////////////////////////////////////////////////////////////////////
struct context {
std::stack<std::experimental::filesystem::path> source;
std::map<std::string,std::string> defines;
};
///////////////////////////////////////////////////////////////////////////
2018-05-07 13:28:31 +10:00
/// an abstract base that performs processing for a directive
2018-04-01 14:49:10 +10:00
class directive {
public:
virtual ~directive () = default;
2018-05-07 13:28:31 +10:00
/// handles a preprocessor directive by:
/// * perform some processing on any number of input lines,
/// * optionally writes to the supplied stream,
/// * and returns the line that should be consumed next
///
/// \param lines is a tokenised view over all the lines of the input
/// \return the next line that processing should continue from
virtual cruft::tokeniser<const char*>::iterator
2018-04-01 14:49:10 +10:00
process (std::ostream&,
context&,
cruft::view<cruft::tokeniser<const char*>::iterator> lines) const = 0;
2018-04-01 14:49:10 +10:00
};
///////////////////////////////////////////////////////////////////////////
class processor {
public:
processor ();
void add (std::string token, std::unique_ptr<directive>);
void process (std::ostream&, const std::experimental::filesystem::path&) const;
std::experimental::filesystem::path
resolve (const std::experimental::filesystem::path&) const;
cruft::tokeniser<const char*>::iterator
2018-04-01 14:49:10 +10:00
process (std::ostream&,
context&,
cruft::view<cruft::tokeniser<const char*>::iterator>) const;
2018-04-01 14:49:10 +10:00
private:
std::map<std::string, std::unique_ptr<directive>> m_directives;
};
///////////////////////////////////////////////////////////////////////////
2018-05-07 13:28:31 +10:00
/// thrown when a processor encounters a directive it has not been
/// configured to handle
2018-04-01 14:49:10 +10:00
class unknown_directive : public std::runtime_error {
using runtime_error::runtime_error;
};
///////////////////////////////////////////////////////////////////////////
2018-05-07 13:28:31 +10:00
/// silently ignores configured directive by advancing the input cursor
/// past the provided line without writing to the output stream.
class ignore : public directive {
cruft::tokeniser<const char*>::iterator
2018-04-01 14:49:10 +10:00
process (std::ostream&,
context&,
cruft::view<cruft::tokeniser<const char*>::iterator> lines) const override
2018-04-01 14:49:10 +10:00
{ return lines.begin ()++; }
};
2018-05-07 13:28:31 +10:00
///------------------------------------------------------------------------
/// copies the supplied directive to the output stream without any
/// modification
class passthrough : public directive {
2018-04-01 14:49:10 +10:00
public:
passthrough (const std::string &name);
virtual cruft::tokeniser<const char*>::iterator
2018-04-01 14:49:10 +10:00
process (std::ostream&,
context&,
cruft::view<cruft::tokeniser<const char*>::iterator>) const override;
2018-04-01 14:49:10 +10:00
private:
const std::string m_name;
};
2018-05-07 13:28:31 +10:00
///------------------------------------------------------------------------
/// handles include directives by copying the contents of the referenced
/// path into the input stream
2018-04-01 14:49:10 +10:00
class include : public directive {
public:
include (processor &_parent);
void add (const std::experimental::filesystem::path&);
virtual cruft::tokeniser<const char*>::iterator
2018-04-01 14:49:10 +10:00
process (std::ostream&,
context&,
cruft::view<cruft::tokeniser<const char*>::iterator>) const override;
2018-04-01 14:49:10 +10:00
private:
processor &m_parent;
std::vector<std::experimental::filesystem::path> m_paths;
};
};
#endif