// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) // (C) Copyright 2005-2007 Jonathan Turkanis // Distributed under 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.) // See http://www.boost.org/libs/iostreams for documentation. // Adapted from an example of James Kanze, with suggestions from Peter Dimov. // See https://web.archive.org/web/20041222094942/http://www.gabi-soft.fr/codebase-en.html. #ifndef BOOST_IOSTREAMS_SHELL_COMMENTS_FILTER_HPP_INCLUDED #define BOOST_IOSTREAMS_SHELL_COMMENTS_FILTER_HPP_INCLUDED #include #include // EOF. #include // cin, cout. #include #include // BOOST_IOS. #include #include namespace boost { namespace iostreams { namespace example { class shell_comments_stdio_filter : public stdio_filter { public: explicit shell_comments_stdio_filter(char comment_char = '#') : comment_char_(comment_char) { } private: void do_filter() { bool skip = false; int c; while ((c = std::cin.get()) != EOF) { skip = c == comment_char_ ? true : c == '\n' ? false : skip; if (!skip) std::cout.put(c); } } char comment_char_; }; class shell_comments_input_filter : public input_filter { public: explicit shell_comments_input_filter(char comment_char = '#') : comment_char_(comment_char), skip_(false) { } template int get(Source& src) { int c; while (true) { if ((c = boost::iostreams::get(src)) == EOF || c == WOULD_BLOCK) break; skip_ = c == comment_char_ ? true : c == '\n' ? false : skip_; if (!skip_) break; } return c; } template void close(Source&) { skip_ = false; } private: char comment_char_; bool skip_; }; class shell_comments_output_filter : public output_filter { public: explicit shell_comments_output_filter(char comment_char = '#') : comment_char_(comment_char), skip_(false) { } template bool put(Sink& dest, int c) { skip_ = c == comment_char_ ? true : c == '\n' ? false : skip_; if (skip_) return true; return iostreams::put(dest, c); } template void close(Source&) { skip_ = false; } private: char comment_char_; bool skip_; }; class shell_comments_dual_use_filter : public dual_use_filter { public: explicit shell_comments_dual_use_filter(char comment_char = '#') : comment_char_(comment_char), skip_(false) { } template int get(Source& src) { int c; while (true) { if ((c = boost::iostreams::get(src)) == EOF || c == WOULD_BLOCK) break; skip_ = c == comment_char_ ? true : c == '\n' ? false : skip_; if (!skip_) break; } return c; } template bool put(Sink& dest, int c) { skip_ = c == comment_char_ ? true : c == '\n' ? false : skip_; if (skip_) return true; return iostreams::put(dest, c); } template void close(Device&, BOOST_IOS::openmode) { skip_ = false; } private: char comment_char_; bool skip_; }; class shell_comments_multichar_input_filter : public multichar_input_filter { public: explicit shell_comments_multichar_input_filter(char comment_char = '#') : comment_char_(comment_char), skip_(false) { } template std::streamsize read(Source& src, char* s, std::streamsize n) { for (std::streamsize z = 0; z < n; ++z) { int c; while (true) { if ((c = boost::iostreams::get(src)) == EOF) return z != 0 ? z : -1; else if (c == WOULD_BLOCK) return z; skip_ = c == comment_char_ ? true : c == '\n' ? false : skip_; if (!skip_) break; } s[z] = c; } return n; } template void close(Source&) { skip_ = false; } private: char comment_char_; bool skip_; }; class shell_comments_multichar_output_filter : public multichar_output_filter { public: explicit shell_comments_multichar_output_filter(char comment_char = '#') : comment_char_(comment_char), skip_(false) { } template std::streamsize write(Sink& dest, const char* s, std::streamsize n) { std::streamsize z; for (z = 0; z < n; ++z) { int c = s[z]; skip_ = c == comment_char_ ? true : c == '\n' ? false : skip_; if (skip_) continue; if (!iostreams::put(dest, c)) break; } return z; } template void close(Source&) { skip_ = false; } private: char comment_char_; bool skip_; }; } } } // End namespaces example, iostreams, boost. #endif // #ifndef BOOST_IOSTREAMS_SHELL_COMMENTS_FILTER_HPP_INCLUDED