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