3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alejandro Aguilar Sierra
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
11 * Full author contact details are available in file CREDITS.
19 #include "lyxlex_pimpl.h"
21 #include "support/convert.h"
22 #include "support/lstrings.h"
29 using support::compare_ascii_no_case;
30 using support::isStrDbl;
31 using support::isStrInt;
33 using support::prefixIs;
43 LyXLex::LyXLex(keyword_item * tab, int num)
44 : pimpl_(new Pimpl(tab, num))
54 bool LyXLex::isOK() const
56 return pimpl_->inputAvailable();
60 void LyXLex::setLineNo(int l)
66 int LyXLex::getLineNo() const
68 return pimpl_->lineno;
72 istream & LyXLex::getStream()
78 void LyXLex::pushTable(keyword_item * tab, int num)
80 pimpl_->pushTable(tab, num);
84 void LyXLex::popTable()
90 void LyXLex::printTable(ostream & os)
92 pimpl_->printTable(os);
96 void LyXLex::printError(string const & message) const
98 pimpl_->printError(message);
102 bool LyXLex::setFile(support::FileName const & filename)
104 return pimpl_->setFile(filename);
108 void LyXLex::setStream(istream & i)
110 pimpl_->setStream(i);
114 void LyXLex::setCommentChar(char c)
116 pimpl_->setCommentChar(c);
121 return pimpl_->lex();
125 int LyXLex::getInteger() const
127 lastReadOk_ = pimpl_->status == LEX_DATA || pimpl_->status == LEX_TOKEN;
129 pimpl_->printError("integer token missing");
133 if (isStrInt(pimpl_->getString()))
134 return convert<int>(pimpl_->getString());
137 pimpl_->printError("Bad integer `$$Token'");
142 double LyXLex::getFloat() const
144 // replace comma with dot in case the file was written with
145 // the wrong locale (should be rare, but is easy enough to
147 lastReadOk_ = pimpl_->status == LEX_DATA || pimpl_->status == LEX_TOKEN;
149 pimpl_->printError("float token missing");
153 string const str = subst(pimpl_->getString(), ",", ".");
155 return convert<double>(str);
158 pimpl_->printError("Bad float `$$Token'");
163 string const LyXLex::getString() const
165 lastReadOk_ = pimpl_->status == LEX_DATA || pimpl_->status == LEX_TOKEN;
168 return pimpl_->getString();
174 docstring const LyXLex::getDocString() const
176 lastReadOk_ = pimpl_->status == LEX_DATA || pimpl_->status == LEX_TOKEN;
179 return pimpl_->getDocString();
185 // I would prefer to give a tag number instead of an explicit token
186 // here, but it is not possible because Buffer::readDocument uses
187 // explicit tokens (JMarc)
188 string const LyXLex::getLongString(string const & endtoken)
191 bool firstline = true;
193 while (pimpl_->is) { //< eatLine only reads from is, not from pushTok
195 // blank line in the file being read
198 string const token = trim(getString(), " \t");
200 lyxerr[Debug::PARSER] << "LongString: `"
201 << getString() << '\'' << endl;
203 // We do a case independent comparison, like search_kw does.
204 if (compare_ascii_no_case(token, endtoken) == 0)
207 string tmpstr = getString();
209 string::size_type i(tmpstr.find_first_not_of(' '));
210 if (i != string::npos)
211 prefix = tmpstr.substr(0, i);
213 lyxerr[Debug::PARSER]
214 << "Prefix = `" << prefix << "\'" << endl;
217 // further lines in long strings may have the same
218 // whitespace prefix as the first line. Remove it.
219 if (prefix.length() && prefixIs(tmpstr, prefix)) {
220 tmpstr.erase(0, prefix.length() - 1);
223 str += ltrim(tmpstr, "\t") + '\n';
227 printError("Long string not ended by `" + endtoken + '\'');
234 bool LyXLex::getBool() const
236 if (pimpl_->getString() == "true") {
239 } else if (pimpl_->getString() != "false") {
240 pimpl_->printError("Bad boolean `$$Token'. "
241 "Use \"false\" or \"true\"");
249 bool LyXLex::eatLine()
251 return pimpl_->eatLine();
255 bool LyXLex::next(bool esc)
257 return pimpl_->next(esc);
261 bool LyXLex::nextToken()
263 return pimpl_->nextToken();
267 void LyXLex::pushToken(string const & pt)
269 pimpl_->pushToken(pt);
272 LyXLex::operator void const *() const
274 // This behaviour is NOT the same as the std::streams which would
275 // use fail() here. However, our implementation of getString() et al.
276 // can cause the eof() and fail() bits to be set, even though we
277 // haven't tried to read 'em.
278 return lastReadOk_? this: 0;
282 bool LyXLex::operator!() const
288 LyXLex & LyXLex::operator>>(std::string & s)
300 LyXLex & LyXLex::operator>>(docstring & s)
312 LyXLex & LyXLex::operator>>(double & s)
324 LyXLex & LyXLex::operator>>(int & s)
336 LyXLex & LyXLex::operator>>(unsigned int & s)
348 LyXLex & LyXLex::operator>>(bool & s)
360 /// quotes a string, e.g. for use in preferences files or as an argument of the "log" dialog
361 string const LyXLex::quoteString(string const & arg)
363 std::ostringstream os;
364 os << '"' << subst(subst(arg, "\\", "\\\\"), "\"", "\\\"") << '"';