]> git.lyx.org Git - lyx.git/blob - src/lyxlex.C
split LyXText::rowlist_ into individual Paragraph::rows_ chunks
[lyx.git] / src / lyxlex.C
1 /**
2  * \file lyxlex.C
3  * Copyright 1996-2002 the LyX Team
4  * Read the file COPYING
5  *
6  * Generalized simple lexical analyzer.
7  * It can be used for simple syntax parsers, like lyxrc,
8  * texclass and others to come.
9  *
10  * \author Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
11  */
12
13 #include <config.h>
14
15 #include "lyxlex.h"
16 #include "lyxlex_pimpl.h"
17 #include "debug.h"
18 #include "support/filetools.h"
19 #include "support/lstrings.h"
20
21 using namespace lyx::support;
22
23 using std::ostream;
24 using std::istream;
25 using std::endl;
26
27
28 LyXLex::LyXLex(keyword_item * tab, int num)
29         : pimpl_(new Pimpl(tab, num))
30 {}
31
32
33 LyXLex::~LyXLex()
34 {
35         delete pimpl_;
36 }
37
38
39 bool LyXLex::isOK() const
40 {
41         return pimpl_->is.good();
42 }
43
44
45 void LyXLex::setLineNo(int l)
46 {
47         pimpl_->lineno = l;
48 }
49
50
51 int LyXLex::getLineNo() const
52 {
53         return pimpl_->lineno;
54 }
55
56
57 istream & LyXLex::getStream()
58 {
59         return pimpl_->is;
60 }
61
62
63 void LyXLex::pushTable(keyword_item * tab, int num)
64 {
65         pimpl_->pushTable(tab, num);
66 }
67
68
69 void LyXLex::popTable()
70 {
71         pimpl_->popTable();
72 }
73
74
75 void LyXLex::printTable(ostream & os)
76 {
77         pimpl_->printTable(os);
78 }
79
80
81 void LyXLex::printError(string const & message) const
82 {
83         pimpl_->printError(message);
84 }
85
86
87 bool LyXLex::setFile(string const & filename)
88 {
89         return pimpl_->setFile(filename);
90 }
91
92
93 void LyXLex::setStream(istream & i)
94 {
95         pimpl_->setStream(i);
96 }
97
98
99 void LyXLex::setCommentChar(char c)
100 {
101         pimpl_->setCommentChar(c);
102 }
103
104 int LyXLex::lex()
105 {
106         return pimpl_->lex();
107 }
108
109
110 int LyXLex::getInteger() const
111 {
112         if (isStrInt(pimpl_->getString()))
113                 return strToInt(pimpl_->getString());
114         pimpl_->printError("Bad integer `$$Token'");
115         return -1;
116 }
117
118
119 float LyXLex::getFloat() const
120 {
121         // replace comma with dot in case the file was written with
122         // the wrong locale (should be rare, but is easy enough to
123         // avoid).
124         string str = subst(pimpl_->getString(), ",", ".");
125         if (isStrDbl(str))
126                 return strToDbl(str);
127         pimpl_->printError("Bad float `$$Token'");
128         return -1;
129 }
130
131
132 string const LyXLex::getString() const
133 {
134         return pimpl_->getString();
135 }
136
137
138 // I would prefer to give a tag number instead of an explicit token
139 // here, but it is not possible because Buffer::readBody uses
140 // explicit tokens (JMarc)
141 string const LyXLex::getLongString(string const & endtoken)
142 {
143         string str, prefix;
144         bool firstline = true;
145
146         while (isOK()) {
147                 if (!eatLine())
148                         // blank line in the file being read
149                         continue;
150
151                 string const token = trim(getString(), " \t");
152
153                 lyxerr[Debug::PARSER] << "LongString: `"
154                                       << getString() << '\'' << endl;
155
156                 // We do a case independent comparison, like search_kw
157                 // does.
158                 if (compare_ascii_no_case(token, endtoken) == 0)
159                         break;
160
161                 string tmpstr = getString();
162                 if (firstline) {
163                         string::size_type i(tmpstr.find_first_not_of(' '));
164                         if (i != string::npos)
165                                 prefix = tmpstr.substr(0, i);
166                         firstline = false;
167                         lyxerr[Debug::PARSER]
168                                 << "Prefix = `" << prefix << "\'" << endl;
169                 }
170
171                 // further lines in long strings may have the same
172                 // whitespace prefix as the first line. Remove it.
173                 if (prefix.length() && prefixIs(tmpstr, prefix)) {
174                         tmpstr.erase(0, prefix.length() - 1);
175                 }
176
177                 str += ltrim(tmpstr, "\t") + '\n';
178         }
179
180         if (!isOK()) {
181                 printError("Long string not ended by `" + endtoken + '\'');
182         }
183
184         return str;
185 }
186
187
188 bool LyXLex::getBool() const
189 {
190         if (pimpl_->getString() == "true") {
191                 return true;
192         } else if (pimpl_->getString() != "false") {
193                 pimpl_->printError("Bad boolean `$$Token'. Use \"false\" or \"true\"");
194         }
195         return false;
196 }
197
198
199 bool LyXLex::eatLine()
200 {
201         return pimpl_->eatLine();
202 }
203
204
205 bool LyXLex::next(bool esc)
206 {
207         return pimpl_->next(esc);
208 }
209
210
211 bool LyXLex::nextToken()
212 {
213         return pimpl_->nextToken();
214 }
215
216
217 void LyXLex::pushToken(string const & pt)
218 {
219         pimpl_->pushToken(pt);
220 }
221
222
223 int LyXLex::findToken(char const * str[])
224 {
225         if (!next()) {
226                 pimpl_->printError("file ended while scanning string token");
227                 return -1;
228         }
229
230         int i = 0;
231
232         string const search_token = pimpl_->getString();
233
234         if (search_token != "default") {
235                 while (str[i][0] && str[i] != search_token) {
236                         ++i;
237                 }
238                 if (!str[i][0]) {
239                         pimpl_->printError("Unknown argument `$$Token'");
240                         i = -1;
241                 }
242         }
243
244         return i;
245 }