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