1// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2// (C) Copyright 2005-2007 Jonathan Turkanis
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6// See http://www.boost.org/libs/iostreams for documentation.
7
8// Adapted from an example of James Kanze, with suggestions from Peter Dimov.
9// See https://web.archive.org/web/20041222094942/http://www.gabi-soft.fr/codebase-en.html.
10
11#ifndef BOOST_IOSTREAMS_SHELL_COMMENTS_FILTER_HPP_INCLUDED
12#define BOOST_IOSTREAMS_SHELL_COMMENTS_FILTER_HPP_INCLUDED
13
14#include <cassert>
15#include <cstdio> // EOF.
16#include <iostream> // cin, cout.
17#include <boost/iostreams/concepts.hpp>
18#include <boost/iostreams/detail/ios.hpp> // BOOST_IOS.
19#include <boost/iostreams/filter/stdio.hpp>
20#include <boost/iostreams/operations.hpp>
21
22namespace boost { namespace iostreams { namespace example {
23
24class shell_comments_stdio_filter : public stdio_filter {
25public:
26 explicit shell_comments_stdio_filter(char comment_char = '#')
27 : comment_char_(comment_char)
28 { }
29private:
30 void do_filter()
31 {
32 bool skip = false;
33 int c;
34 while ((c = std::cin.get()) != EOF) {
35 skip = c == comment_char_ ?
36 true :
37 c == '\n' ?
38 false :
39 skip;
40 if (!skip)
41 std::cout.put(c: c);
42 }
43 }
44 char comment_char_;
45};
46
47class shell_comments_input_filter : public input_filter {
48public:
49 explicit shell_comments_input_filter(char comment_char = '#')
50 : comment_char_(comment_char), skip_(false)
51 { }
52
53 template<typename Source>
54 int get(Source& src)
55 {
56 int c;
57 while (true) {
58 if ((c = boost::iostreams::get(src)) == EOF || c == WOULD_BLOCK)
59 break;
60 skip_ = c == comment_char_ ?
61 true :
62 c == '\n' ?
63 false :
64 skip_;
65 if (!skip_)
66 break;
67 }
68 return c;
69 }
70
71 template<typename Source>
72 void close(Source&) { skip_ = false; }
73private:
74 char comment_char_;
75 bool skip_;
76};
77
78class shell_comments_output_filter : public output_filter {
79public:
80 explicit shell_comments_output_filter(char comment_char = '#')
81 : comment_char_(comment_char), skip_(false)
82 { }
83
84 template<typename Sink>
85 bool put(Sink& dest, int c)
86 {
87 skip_ = c == comment_char_ ?
88 true :
89 c == '\n' ?
90 false :
91 skip_;
92
93 if (skip_)
94 return true;
95
96 return iostreams::put(dest, c);
97 }
98
99 template<typename Source>
100 void close(Source&) { skip_ = false; }
101private:
102 char comment_char_;
103 bool skip_;
104};
105
106class shell_comments_dual_use_filter : public dual_use_filter {
107public:
108 explicit shell_comments_dual_use_filter(char comment_char = '#')
109 : comment_char_(comment_char), skip_(false)
110 { }
111
112 template<typename Source>
113 int get(Source& src)
114 {
115 int c;
116 while (true) {
117 if ((c = boost::iostreams::get(src)) == EOF || c == WOULD_BLOCK)
118 break;
119 skip_ = c == comment_char_ ?
120 true :
121 c == '\n' ?
122 false :
123 skip_;
124 if (!skip_)
125 break;
126 }
127 return c;
128 }
129
130 template<typename Sink>
131 bool put(Sink& dest, int c)
132 {
133 skip_ = c == comment_char_ ?
134 true :
135 c == '\n' ?
136 false :
137 skip_;
138
139 if (skip_)
140 return true;
141
142 return iostreams::put(dest, c);
143 }
144
145 template<typename Device>
146 void close(Device&, BOOST_IOS::openmode) { skip_ = false; }
147private:
148 char comment_char_;
149 bool skip_;
150};
151
152class shell_comments_multichar_input_filter : public multichar_input_filter {
153public:
154 explicit shell_comments_multichar_input_filter(char comment_char = '#')
155 : comment_char_(comment_char), skip_(false)
156 { }
157
158 template<typename Source>
159 std::streamsize read(Source& src, char* s, std::streamsize n)
160 {
161 for (std::streamsize z = 0; z < n; ++z) {
162 int c;
163 while (true) {
164 if ((c = boost::iostreams::get(src)) == EOF)
165 return z != 0 ? z : -1;
166 else if (c == WOULD_BLOCK)
167 return z;
168 skip_ = c == comment_char_ ?
169 true :
170 c == '\n' ?
171 false :
172 skip_;
173 if (!skip_)
174 break;
175 }
176 s[z] = c;
177 }
178 return n;
179 }
180
181 template<typename Source>
182 void close(Source&) { skip_ = false; }
183private:
184 char comment_char_;
185 bool skip_;
186};
187
188class shell_comments_multichar_output_filter : public multichar_output_filter {
189public:
190 explicit shell_comments_multichar_output_filter(char comment_char = '#')
191 : comment_char_(comment_char), skip_(false)
192 { }
193
194 template<typename Sink>
195 std::streamsize write(Sink& dest, const char* s, std::streamsize n)
196 {
197 std::streamsize z;
198 for (z = 0; z < n; ++z) {
199 int c = s[z];
200 skip_ = c == comment_char_ ?
201 true :
202 c == '\n' ?
203 false :
204 skip_;
205 if (skip_)
206 continue;
207 if (!iostreams::put(dest, c))
208 break;
209 }
210 return z;
211 }
212
213 template<typename Source>
214 void close(Source&) { skip_ = false; }
215private:
216 char comment_char_;
217 bool skip_;
218};
219
220} } } // End namespaces example, iostreams, boost.
221
222#endif // #ifndef BOOST_IOSTREAMS_SHELL_COMMENTS_FILTER_HPP_INCLUDED
223

source code of boost/libs/iostreams/example/shell_comments_filter.hpp