a Code for the Combination of Indirect and Direct Constraints on High Energy Physics Models Logo
CommentedTextParser.hpp
Go to the documentation of this file.
1/*
2 * CommentedTextParser.hpp
3 *
4 * Created on: Jan 22, 2012
5 * Author: Ben O'Leary (benjamin.oleary@gmail.com)
6 *
7 * This file is part of BOLlib, released under the
8 * GNU General Public License. Please see the accompanying
9 * README.BOLlib.txt file for a full list of files, brief documentation
10 * on how to use these classes, and further details on the license.
11 */
12
13#ifndef COMMENTEDTEXTPARSER_HPP_
14#define COMMENTEDTEXTPARSER_HPP_
15
16#include <fstream>
17#include "StringParser.hpp"
18#include "VectorlikeArray.hpp"
19
20namespace BOL
21{
22 /* this class breaks up lines of text into pairs of "line before comment
23 * marking character" with "rest of line (including comment marker)". it can
24 * take in a block of text as a string (including newline characters) or it
25 * can open a file to read in text.
26 */
28 {
29 public:
30 CommentedTextParser( std::string const& commentMarker,
31 bool const isVerbose );
34 bool const isVerbose );
35 virtual
37
39 parseString( std::string const& textToParse );
40 /* this breaks up textToParse into lines based on '\n' & '\r', then breaks
41 * up each line based on commentMarker, stores everything in parsedText &
42 * returns a reference to parsedText. N.B. entirely empty lines are skipped
43 * over (i.e. any uninterrupted sequence of '\n' chars is treated as a
44 * single newline)!
45 */
46 bool
47 openFile( std::string const& fileName );
48 /* this opens a file based on the given name. if this CommentedTextParser
49 * instance was already reading a file, the old file is closed. this
50 * returns true if the file was opened successfully.
51 */
52 bool
54 // this returns true if all the lines of the file have been read, either by
55 // parseNextLineOfFile() or readNextNonEmptyLineOfFileWithoutComment(...).
57 closeFile();
58 bool
59 parseNextLineOfFile( std::string& stringForData,
60 std::string& stringForComment );
61 /* this reads the next line of the file (i.e. up to the next newline char),
62 * splits it into a bit before the comment marker & the rest (including the
63 * comment marker characters), & puts the 2 parts into the given strings
64 * (the comment in the 2nd part), & returns true if the line was
65 * successfully parsed.
66 */
67 bool
68 readNextNonEmptyLineOfFileWithoutComment( std::string& stringToFill );
69 /* this reads in lines into stringToFill until, after the following
70 * manipulations, stringToFill is not empty, or the end of inputFile is
71 * reached. the manipulations are that any comment it has is removed, &
72 * then any leading & trailing whitespace characters are removed. if the
73 * end of the file is reached before stringToFill is not empty after the
74 * manipulations, stringToFill is left empty & false is returned.
75 */
76 bool
77 readJustNextValidLine( std::string& stringToFill )
78 { return readNextNonEmptyLineOfFileWithoutComment( stringToFill ); }
79 // this is just to shorten the name without breaking backwards
80 // compatibility.
81
82
83 protected:
84 static std::string const trimmingChars;
85
86 bool const isVerbose;
89 std::pair< std::string, std::string > parsedLine;
91 std::string lineBeingRead;
93 // this is used as a safer bool than inputFile.eof() because inputFile is
94 // not necessarily open or otherwise.
95 std::ifstream inputFile;
96 // this is the file being read in.
97
98 bool
100 /* this reads in the next line of inputFile into lineBeingRead, unless
101 * inputFile has been read to its end, & if reading in this line brings
102 * inputFile to its EOF, this function sets parsedLine & linesOfFileRemain
103 * appropriately, as well as closing inputFile. it returns true if a line
104 * was successfully read in.
105 */
106 void
108 // this reports on whether this instance will no longer read in any more
109 // lines because the end of the file was reached or because of some error.
110 };
111
112
113
115 CommentedTextParser::parseString( std::string const& textToParse )
116 /* this breaks up textToParse into lines based on '\n' & '\r', then breaks
117 * up each line based on commentMarker, stores everything in parsedText &
118 * returns a reference to parsedText. N.B. entirely empty lines are skipped
119 * over (i.e. any uninterrupted sequence of '\n' chars is treated as a single
120 * newline)!
121 */
122 {
126 // now textAsLines is textToParse broken up into strings corresponding to
127 // each line of textToParse. parsedText has to fit all of textAsLines:
128 parsedText.setSize( textAsLines.getSize() );
129 for( int lineIndex( textAsLines.getLastIndex() );
130 0 <= lineIndex;
131 --lineIndex )
132 {
133 parsedText[ lineIndex ].first.assign(
136 &(parsedText[ lineIndex ].second) ) );
137 /* this puts all of textAsLines[ lineIndex ] before the comment marker
138 * into parsedText[ lineIndex ].first & the remainder into
139 * parsedText[ lineIndex ].second (including the comment characters).
140 */
141 }
142 return parsedText;
143 }
144
145 inline bool
146 CommentedTextParser::openFile( std::string const& fileName )
147 /* this opens a file based on the given name. if this CommentedTextParser
148 * instance was already reading a file, the old file is closed. this returns
149 * true if the file was opened successfully.
150 */
151 {
152 closeFile();
153 // this sets notYetAtEndOfFile to false & also closes inputFile if it was
154 // open.
155 inputFile.open( fileName.c_str() );
156 if( inputFile.is_open()
157 &&
158 !(inputFile.eof()) )
159 {
160 linesOfFileRemain = true;
161 }
162 else
163 {
164 std::cout
165 << std::endl
166 << "BOL::error! CommentedTextParser tried to open "
167 << fileName << " but could not (or " << fileName << " is empty)!";
168 std::cout << std::endl;
169 linesOfFileRemain = false;
170 }
171 return linesOfFileRemain;
172 }
173
174 inline bool
176 // this returns true if all the lines of the file have been read, either by
177 // parseNextLineOfFile() or readNextNonEmptyLineOfFileWithoutComment(...).
178 {
179 return !linesOfFileRemain;
180 }
181
182 inline CommentedTextParser&
184 {
185 linesOfFileRemain = false;
186 if( inputFile.is_open() )
187 {
188 inputFile.close();
189 }
190 return *this;
191 }
192
193 inline bool
194 CommentedTextParser::parseNextLineOfFile( std::string& stringForData,
195 std::string& stringForComment )
196 /* this reads the next line of the file (i.e. up to the next newline char),
197 * splits it into a bit before the comment marker & the rest (including the
198 * comment marker characters), & puts the 2 parts into the given strings
199 * (the comment in the 2nd part), & returns true if the line was
200 * successfully parsed.
201 */
202 {
203 if( readInNextLine() )
204 {
205 stringForData.assign( BOL::StringParser::substringToFirst(
209 &stringForComment ) );
210 /* this puts all of the line just read before the comment marker into
211 * stringForData & the remainder into stringForComment (including the
212 * comment characters).
213 */
214 BOL::StringParser::trimFromBack( stringForData,
216 return true;
217 }
218 else
219 {
220 return false;
221 }
222 }
223
224 inline bool
226 std::string& stringToFill )
227 /* this reads in lines into stringToFill until, after the following
228 * manipulations, stringToFill is not empty, or the end of inputFile is
229 * reached. the manipulations are that any comment it has is removed, &
230 * then any leading & trailing whitespace characters are removed. if the
231 * end of the file is reached before stringToFill is not empty after the
232 * manipulations, stringToFill is left empty & false is returned.
233 */
234 {
235 stringToFill.clear();
236 while( stringToFill.empty()
237 &&
239 // the order of these conditionals is important: it has to check if it
240 // needs to read in the next line before it tries to read it in!
241 {
244 /* this puts all of the line just read before the comment marker into
245 * stringToFill & throws away the remainder. now all trimmingChars chars
246 * are trimmed from the front & back of stringToFill:
247 */
248 stringToFill.assign( BOL::StringParser::trimFromFrontAndBack(
249 stringToFill,
250 trimmingChars ) );
251 }
252 // now either stringToFill is not empty, or inputFile ran out of lines.
253 return !(stringToFill.empty());
254 }
255
256 inline bool
258 /* this reads in the next line of inputFile into lineBeingRead, unless
259 * inputFile has been read to its end, & if reading in this line brings
260 * inputFile to its EOF, this function sets parsedLine & linesOfFileRemain
261 * appropriately, as well as closing inputFile. it returns true if a line
262 * was successfully read in.
263 */
264 {
266 {
267 std::getline( inputFile,
271 &&
272 isVerbose )
273 {
275 }
276 return true;
277 }
278 else
279 {
280 return false;
281 }
282 }
283
284 inline void
286 // this reports on whether this instance will no longer read in any more
287 // lines because the end of the file was reached or because of some error.
288 {
289 if( inputFile.eof() )
290 // if reading in this line brought inputFile to its end, note that.
291 {
292 std::cout
293 << std::endl
294 << "BOL::CommentedTextParser reached the end of the file.";
295 std::cout << std::endl;
296 }
297 else
298 {
299 std::cout
300 << std::endl
301 << "BOL::CommentedTextParser cannot read in any more of the file after"
302 << " a bad reading operation.";
303 std::cout << std::endl;
304 }
305 }
306
307}
308
309#endif /* COMMENTEDTEXTPARSER_HPP_ */
VectorlikeArray< std::string > commentMarkerSet
VectorlikeArray< std::string > textAsLines
CommentedTextParser(std::string const &commentMarker, bool const isVerbose)
bool readJustNextValidLine(std::string &stringToFill)
bool openFile(std::string const &fileName)
bool parseNextLineOfFile(std::string &stringForData, std::string &stringForComment)
std::pair< std::string, std::string > parsedLine
VectorlikeArray< std::pair< std::string, std::string > > const & parseString(std::string const &textToParse)
VectorlikeArray< std::pair< std::string, std::string > > parsedText
CommentedTextParser & closeFile()
bool readNextNonEmptyLineOfFileWithoutComment(std::string &stringToFill)
static std::string const trimmingChars
static std::string trimFromBack(std::string const &stringToTrim, std::string const &charsToTrim)
static std::string const newlineChars
static std::string trimFromFrontAndBack(std::string const &stringToTrim, std::string const &charsToTrim=whitespaceAndNewlineChars)
static std::string substringToFirst(std::string const &stringToParse, VectorlikeArray< std::string > const &delimitersOfSubstring, std::string *const remainderString=NULL)
static void parseByChar(std::string const &stringToParse, VectorlikeArray< std::string > &destinationArray, std::string const &divisionCharSet=whitespaceChars)