]> git.lyx.org Git - lyx.git/blob - src/lyxlex.C
Minimal fix needed to give Qt a label dialog again.
[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         pimpl_->printError("Bad integer `$$Token'");
119         return -1;
120 }
121
122
123 float LyXLex::getFloat() const
124 {
125         // replace comma with dot in case the file was written with
126         // the wrong locale (should be rare, but is easy enough to
127         // avoid).
128         string str = subst(pimpl_->getString(), ",", ".");
129         if (isStrDbl(str))
130                 return strToDbl(str);
131         pimpl_->printError("Bad float `$$Token'");
132         return -1;
133 }
134
135
136 string const LyXLex::getString() const
137 {
138         return pimpl_->getString();
139 }
140
141
142 // I would prefer to give a tag number instead of an explicit token
143 // here, but it is not possible because Buffer::readLyXformat2 uses
144 // explicit tokens (JMarc)
145 string const LyXLex::getLongString(string const & endtoken)
146 {
147         string str, prefix;
148         bool firstline = true;
149
150         while (isOK()) {
151                 if (!eatLine())
152                         // blank line in the file being read
153                         continue;
154
155                 string const token = trim(getString(), " \t");
156
157                 lyxerr[Debug::PARSER] << "LongString: `"
158                                       << getString() << '\'' << endl;
159
160                 // We do a case independent comparison, like search_kw
161                 // does.
162                 if (compare_ascii_no_case(token, endtoken) == 0)
163                         break;
164
165                 string tmpstr = getString();
166                 if (firstline) {
167                         string::size_type i(tmpstr.find_first_not_of(' '));
168                         if (i != string::npos)
169                                 prefix = tmpstr.substr(0, i);
170                         firstline = false;
171                         lyxerr[Debug::PARSER]
172                                 << "Prefix = `" << prefix << "\'" << endl;
173                 }
174
175                 // further lines in long strings may have the same
176                 // whitespace prefix as the first line. Remove it.
177                 if (prefix.length() && prefixIs(tmpstr, prefix)) {
178                         tmpstr.erase(0, prefix.length() - 1);
179                 }
180
181                 str += ltrim(tmpstr, "\t") + '\n';
182         }
183
184         if (!isOK()) {
185                 printError("Long string not ended by `" + endtoken + '\'');
186         }
187
188         return str;
189 }
190
191
192 bool LyXLex::getBool() const
193 {
194         if (compare(pimpl_->buff, "true") == 0) {
195                 return true;
196         } else if (compare(pimpl_->buff, "false") != 0) {
197                 pimpl_->printError("Bad boolean `$$Token'. Use \"false\" or \"true\"");
198         }
199         return false;
200 }
201
202
203 bool LyXLex::eatLine()
204 {
205         return pimpl_->eatLine();
206 }
207
208
209 bool LyXLex::next(bool esc)
210 {
211         return pimpl_->next(esc);
212 }
213
214
215 bool LyXLex::nextToken()
216 {
217         return pimpl_->nextToken();
218 }
219
220
221 void LyXLex::pushToken(string const & pt)
222 {
223         pimpl_->pushToken(pt);
224 }
225
226
227 int LyXLex::findToken(char const * str[])
228 {
229         if (!next()) {
230                 pimpl_->printError("file ended while scanning string token");
231                 return -1;
232         }
233
234         int i = 0;
235
236         if (compare(pimpl_->buff, "default")) {
237                 while (str[i][0] && compare(str[i], pimpl_->buff)) {
238                         ++i;
239                 }
240                 if (!str[i][0]) {
241                         pimpl_->printError("Unknown argument `$$Token'");
242                         i = -1;
243                 }
244         }
245
246         return i;
247 }