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