summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/keyz-cfg/zkb.cpp716
-rw-r--r--noncore/apps/opie-gutenbrowser/gutenbrowser.cpp15
-rw-r--r--noncore/apps/opie-reader/BuffDoc.h116
-rw-r--r--noncore/apps/opie-reader/CEncoding.h16
-rw-r--r--noncore/apps/opie-reader/CExpander.h140
-rw-r--r--noncore/apps/opie-reader/Filedata.h56
-rw-r--r--noncore/apps/opie-reader/FontControl.h178
-rw-r--r--noncore/apps/opie-reader/Palm2QImage.cpp125
-rw-r--r--noncore/apps/opie-reader/QTReader.h124
-rw-r--r--noncore/apps/opie-reader/QTReaderApp.h112
-rw-r--r--noncore/apps/tinykate/libkate/document/katedocument.h14
-rw-r--r--noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp2282
12 files changed, 1957 insertions, 1937 deletions
diff --git a/noncore/apps/keyz-cfg/zkb.cpp b/noncore/apps/keyz-cfg/zkb.cpp
index 58bde2a..c9e1dc5 100644
--- a/noncore/apps/keyz-cfg/zkb.cpp
+++ b/noncore/apps/keyz-cfg/zkb.cpp
@@ -1,589 +1,589 @@
1#include "zkb.h" 1#include "zkb.h"
2
3/* OPIE */
4#include <opie2/odebug.h>
5
2#include <stdio.h> 6#include <stdio.h>
3 7
4// Implementation of Action class 8// Implementation of Action class
5Action::Action():state(0), keycode(0), unicode(0), flags(0) { 9Action::Action():state(0), keycode(0), unicode(0), flags(0) {
6} 10}
7 11
8Action::Action(State* s, ushort kc, ushort uni, int f): 12Action::Action(State* s, ushort kc, ushort uni, int f):
9 state(s), keycode(kc), unicode(uni), flags(f) { 13 state(s), keycode(kc), unicode(uni), flags(f) {
10} 14}
11 15
12Action::~Action() { 16Action::~Action() {
13} 17}
14 18
15State* Action::getState() const { 19State* Action::getState() const {
16 return state; 20 return state;
17} 21}
18 22
19void Action::setState(State* s) { 23void Action::setState(State* s) {
20 state = s; 24 state = s;
21 setDefined(true); 25 setDefined(true);
22} 26}
23 27
24bool Action::hasEvent() const { 28bool Action::hasEvent() const {
25 return flags & Event; 29 return flags & Event;
26} 30}
27 31
28void Action::setEvent(bool e) { 32void Action::setEvent(bool e) {
29 flags = (flags & ~Event) | ((e) ? Event : 0); 33 flags = (flags & ~Event) | ((e) ? Event : 0);
30 34
31 if (e) { 35 if (e) {
32 setDefined(true); 36 setDefined(true);
33 } else { 37 } else {
34 if (state == 0) { 38 if (state == 0) {
35 setDefined(false); 39 setDefined(false);
36 } 40 }
37 } 41 }
38} 42}
39 43
40bool Action::isDefined() const { 44bool Action::isDefined() const {
41 return flags & Defined; 45 return flags & Defined;
42} 46}
43 47
44void Action::setDefined(bool d) { 48void Action::setDefined(bool d) {
45 flags = (flags & ~Defined) | ((d) ? Defined : 0); 49 flags = (flags & ~Defined) | ((d) ? Defined : 0);
46} 50}
47 51
48int Action::getKeycode() const { 52int Action::getKeycode() const {
49 return keycode; 53 return keycode;
50} 54}
51 55
52void Action::setKeycode(int c) { 56void Action::setKeycode(int c) {
53 keycode = (ushort) c; 57 keycode = (ushort) c;
54 setEvent(true); 58 setEvent(true);
55} 59}
56 60
57int Action::getUnicode() const { 61int Action::getUnicode() const {
58 return unicode; 62 return unicode;
59} 63}
60 64
61void Action::setUnicode(int u) { 65void Action::setUnicode(int u) {
62 unicode = (ushort) u; 66 unicode = (ushort) u;
63 setEvent(true); 67 setEvent(true);
64} 68}
65 69
66int Action::getModifiers() const { 70int Action::getModifiers() const {
67 int ret = 0; 71 int ret = 0;
68 if (flags & Shift_Mod) { 72 if (flags & Shift_Mod) {
69 ret |= Qt::ShiftButton; 73 ret |= Qt::ShiftButton;
70 } 74 }
71 75
72 if (flags & Ctrl_Mod) { 76 if (flags & Ctrl_Mod) {
73 ret |= Qt::ControlButton; 77 ret |= Qt::ControlButton;
74 } 78 }
75 79
76 if (flags & Alt_Mod) { 80 if (flags & Alt_Mod) {
77 ret |= Qt::AltButton; 81 ret |= Qt::AltButton;
78 } 82 }
79 83
80 if (flags & Keypad_Mod) { 84 if (flags & Keypad_Mod) {
81 ret |= Qt::Keypad; 85 ret |= Qt::Keypad;
82 } 86 }
83 87
84 return ret; 88 return ret;
85} 89}
86 90
87void Action::setModifiers(int m) { 91void Action::setModifiers(int m) {
88 int n = 0; 92 int n = 0;
89 93
90 if (m & Qt::ShiftButton) { 94 if (m & Qt::ShiftButton) {
91 n |= Shift_Mod; 95 n |= Shift_Mod;
92 } 96 }
93 97
94 if (m & Qt::ControlButton) { 98 if (m & Qt::ControlButton) {
95 n |= Ctrl_Mod; 99 n |= Ctrl_Mod;
96 } 100 }
97 101
98 if (m & Qt::AltButton) { 102 if (m & Qt::AltButton) {
99 n |= Alt_Mod; 103 n |= Alt_Mod;
100 } 104 }
101 105
102 if (m & Qt::Keypad) { 106 if (m & Qt::Keypad) {
103 n |= Keypad_Mod; 107 n |= Keypad_Mod;
104 } 108 }
105 109
106 flags = flags & ~Mod_Bits | n; 110 flags = flags & ~Mod_Bits | n;
107 setEvent(true); 111 setEvent(true);
108} 112}
109 113
110bool Action::isPressed() const { 114bool Action::isPressed() const {
111 return (flags & Press) != 0; 115 return (flags & Press) != 0;
112} 116}
113 117
114void Action::setPressed(bool p) { 118void Action::setPressed(bool p) {
115 flags = (flags & ~Press) | ((p) ? Press : 0); 119 flags = (flags & ~Press) | ((p) ? Press : 0);
116 setEvent(true); 120 setEvent(true);
117} 121}
118 122
119bool Action::isAutorepeat() const { 123bool Action::isAutorepeat() const {
120 return (flags & Autorepeat) != 0; 124 return (flags & Autorepeat) != 0;
121} 125}
122 126
123void Action::setAutorepeat(bool p) { 127void Action::setAutorepeat(bool p) {
124 flags = (flags & ~Autorepeat) | ((p) ? Autorepeat : 0); 128 flags = (flags & ~Autorepeat) | ((p) ? Autorepeat : 0);
125 setEvent(true); 129 setEvent(true);
126} 130}
127 131
128// Implementation of State class 132// Implementation of State class
129const short State::x1[] = { /* from 0x20 to 0x5f */ 133const short State::x1[] = { /* from 0x20 to 0x5f */
130 31, 0, 28, 3, 5, 6, 9, 28, /* 0x20 - 0x27 */ 134 31, 0, 28, 3, 5, 6, 9, 28, /* 0x20 - 0x27 */
131 11, 26, 10, 13, 26, 1, 29, 27, /* 0x28 - 0x2f */ 135 11, 26, 10, 13, 26, 1, 29, 27, /* 0x28 - 0x2f */
132 15, 16, 22, 4, 17, 19, 24, 20, /* 0x30 - 0x37 */ 136 15, 16, 22, 4, 17, 19, 24, 20, /* 0x30 - 0x37 */
133 8, 14, 29, 26, 29, 12, 32, 27, /* 0x38 - 0x3f */ 137 8, 14, 29, 26, 29, 12, 32, 27, /* 0x38 - 0x3f */
134 18, 0, 1, 2, 3, 4, 5, 6, /* 0x40 - 0x47 */ 138 18, 0, 1, 2, 3, 4, 5, 6, /* 0x40 - 0x47 */
135 7, 8, 9, 10, 11, 12, 13, 14, /* 0x48 - 0x4f */ 139 7, 8, 9, 10, 11, 12, 13, 14, /* 0x48 - 0x4f */
136 15, 16, 17, 18, 19, 20, 21, 22, /* 0x50 - 0x57 */ 140 15, 16, 17, 18, 19, 20, 21, 22, /* 0x50 - 0x57 */
137 23, 24, 25, 30, -1, 26, 28, 7, /* 0x58 - 0x5f */ 141 23, 24, 25, 30, -1, 26, 28, 7, /* 0x58 - 0x5f */
138 31, -1, -1, -1, -1, -1, -1, -1, /* 0x60 - 0x67 */ 142 31, -1, -1, -1, -1, -1, -1, -1, /* 0x60 - 0x67 */
139 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x68 - 0x6f */ 143 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x68 - 0x6f */
140 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x70 - 0x77 */ 144 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x70 - 0x77 */
141 -1, -1, -1, 29, 31, 32, 32, 28, /* 0x78 - 0x7f */ 145 -1, -1, -1, 29, 31, 32, 32, 28, /* 0x78 - 0x7f */
142}; 146};
143 147
144const short State::x2[] = { /* from 0x1000 to 0x1057*/ 148const short State::x2[] = { /* from 0x1000 to 0x1057*/
145 42, 36, -1, 30, 32, -1, -1, -1, /* 0x1000 - 0x1007 */ 149 42, 36, -1, 30, 32, -1, -1, -1, /* 0x1000 - 0x1007 */
146 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1008 - 0x100f */ 150 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1008 - 0x100f */
147 -1, -1, 44, 45, 46, 47, -1, -1, /* 0x1010 - 0x1017 */ 151 -1, -1, 44, 45, 46, 47, -1, -1, /* 0x1010 - 0x1017 */
148 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1018 - 0x101f */ 152 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1018 - 0x101f */
149 33, 35, 34, -1, 36, 27, -1, -1, /* 0x1020 - 0x1027 */ 153 33, 35, 34, -1, 36, 27, -1, -1, /* 0x1020 - 0x1027 */
150 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1028 - 0x102f */ 154 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1028 - 0x102f */
151 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1030 - 0x1037 */ 155 -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1030 - 0x1037 */
152 37, 38, 40, 39, 41, -1, -1, -1, /* 0x1038 - 0x103f */ 156 37, 38, 40, 39, 41, -1, -1, -1, /* 0x1038 - 0x103f */
153 -1, -1, -1, -1, -1, 35, -1, -1, /* 0x1040 - 0x1047 */ 157 -1, -1, -1, -1, -1, 35, -1, -1, /* 0x1040 - 0x1047 */
154 -1, -1, -1, -1, -1, 48, -1, -1, /* 0x1048 - 0x104f */ 158 -1, -1, -1, -1, -1, 48, -1, -1, /* 0x1048 - 0x104f */
155 43, 49, 50, -1, -1, -1, -1, -1, /* 0x1050 - 0x1057 */ 159 43, 49, 50, -1, -1, -1, -1, -1, /* 0x1050 - 0x1057 */
156}; 160};
157 161
158State::State(State* p):parent(p), keys(0) { 162State::State(State* p):parent(p), keys(0) {
159 keys = new Action[Key_Max * 2 + 1]; 163 keys = new Action[Key_Max * 2 + 1];
160} 164}
161 165
162State::State(const State& s) { 166State::State(const State& s) {
163 parent = s.parent; 167 parent = s.parent;
164 keys = new Action[Key_Max * 2 + 1]; 168 keys = new Action[Key_Max * 2 + 1];
165 memcpy(keys, s.keys, sizeof(Action) * (Key_Max * 2 + 1)); 169 memcpy(keys, s.keys, sizeof(Action) * (Key_Max * 2 + 1));
166} 170}
167 171
168State::~State() { 172State::~State() {
169 if (keys!=0) { 173 if (keys!=0) {
170 delete [] keys; 174 delete [] keys;
171 } 175 }
172} 176}
173 177
174Action* State::get(int keycode, bool pressed, bool follow) const { 178Action* State::get(int keycode, bool pressed, bool follow) const {
175 Action* ret = 0; 179 Action* ret = 0;
176 int n = translateKeycode(keycode); 180 int n = translateKeycode(keycode);
177 181
178 if (n != -1 && keys != 0) { 182 if (n != -1 && keys != 0) {
179 if (pressed) { 183 if (pressed) {
180 n += Key_Max; 184 n += Key_Max;
181 } 185 }
182 ret = &keys[n]; 186 ret = &keys[n];
183 } 187 }
184 188
185 if (ret==0 || !ret->isDefined()) { 189 if (ret==0 || !ret->isDefined()) {
186 if (follow && parent!=0) { 190 if (follow && parent!=0) {
187 ret = parent->get(keycode, pressed, follow); 191 ret = parent->get(keycode, pressed, follow);
188 } 192 }
189 } 193 }
190 194
191 return ret; 195 return ret;
192} 196}
193 197
194bool State::set(int keycode, bool pressed, Action& action) { 198bool State::set(int keycode, bool pressed, Action& action) {
195 int n = translateKeycode(keycode); 199 int n = translateKeycode(keycode);
196 200
197 if (n==-1 || keys==0) { 201 if (n==-1 || keys==0) {
198 return false; 202 return false;
199 } 203 }
200 204
201 if (pressed) { 205 if (pressed) {
202 n += Key_Max + 1; 206 n += Key_Max + 1;
203 } 207 }
204 208
205 keys[n] = action; 209 keys[n] = action;
206 return true; 210 return true;
207} 211}
208 212
209State* State::getParent() const { 213State* State::getParent() const {
210 return parent; 214 return parent;
211} 215}
212 216
213void State::setParent(State* s) { 217void State::setParent(State* s) {
214 parent = s; 218 parent = s;
215} 219}
216 220
217int State::translateKeycode(int keycode) const { 221int State::translateKeycode(int keycode) const {
218 if (keycode < 0x20) { 222 if (keycode < 0x20) {
219 return -1; 223 return -1;
220 } 224 }
221 225
222 if (keycode < 0x80) { 226 if (keycode < 0x80) {
223 return x1[keycode - 0x20]; 227 return x1[keycode - 0x20];
224 } 228 }
225 229
226 if (keycode < 0x1000) { 230 if (keycode < 0x1000) {
227 return -1; 231 return -1;
228 } 232 }
229 233
230 if (keycode < 0x1057) { 234 if (keycode < 0x1057) {
231 return x2[keycode - 0x1000]; 235 return x2[keycode - 0x1000];
232 } 236 }
233 237
234 return -1; 238 return -1;
235} 239}
236 240
237// Implementation of Keymap class 241// Implementation of Keymap class
238Keymap::Keymap():enabled(true), currentState(0), autoRepeatAction(0), repeater(this) { 242Keymap::Keymap():enabled(true), currentState(0), autoRepeatAction(0), repeater(this) {
239 repeatDelay=400; 243 repeatDelay=400;
240 repeatPeriod=80; 244 repeatPeriod=80;
241 connect(&repeater, SIGNAL(timeout()), this, SLOT(autoRepeat())); 245 connect(&repeater, SIGNAL(timeout()), this, SLOT(autoRepeat()));
242} 246}
243 247
244Keymap::~Keymap() { 248Keymap::~Keymap() {
245 QMap<QString, State*>::Iterator it; 249 QMap<QString, State*>::Iterator it;
246 for(it = states.begin(); it != states.end(); ++it) { 250 for(it = states.begin(); it != states.end(); ++it) {
247 delete it.data(); 251 delete it.data();
248 } 252 }
249 states.clear(); 253 states.clear();
250} 254}
251 255
252bool Keymap::filter(int unicode, int keycode, int modifiers, 256bool Keymap::filter(int unicode, int keycode, int modifiers,
253 bool isPress, bool autoRepeat) { 257 bool isPress, bool autoRepeat) {
254 258
255 qDebug("filter: >>> unicode=%x, keycode=%x, modifiers=%x, " 259 odebug << "filter: >>> unicode=" << unicode << ", keycode=" << keycode
256 "ispressed=%x\n", unicode, keycode, modifiers, isPress); 260 << ", modifiers=" << modifiers << ", ispressed=" << isPress << oendl;
257 261
258 if (!enabled) { 262 if (!enabled) {
259 return false; 263 return false;
260 } 264 }
261 265
262 // the second check is workaround to make suspend work if 266 // the second check is workaround to make suspend work if
263 // the user pressed it right after he did resume. for some 267 // the user pressed it right after he did resume. for some
264 // reason the event sent by qt has autoRepeat true in this 268 // reason the event sent by qt has autoRepeat true in this
265 // case 269 // case
266 if (autoRepeat && keycode != 4177) { 270 if (autoRepeat && keycode != 4177) {
267 return true; 271 return true;
268 } 272 }
269 273
270 (void) unicode; (void) modifiers; 274 (void) unicode; (void) modifiers;
271 275
272 Action* action = currentState->get(keycode, isPress, true); 276 Action* action = currentState->get(keycode, isPress, true);
273 if (action==0 || !action->isDefined()) { 277 if (action==0 || !action->isDefined()) {
274 return true; 278 return true;
275 } 279 }
276 280
277 if (action->hasEvent()) { 281 if (action->hasEvent()) {
278 qDebug("filter:<<< unicode=%x, keycode=%x, modifiers=%x, " 282 odebug << "filter:<<< unicode=" << action->getUnicode() << ", keycode=" << action->getKeycode()
279 "ispressed=%x\n", action->getUnicode(), 283 << ", modifiers=" << action->getModifiers() << ", ispressed=" << action->isPressed() << oendl;
280 action->getKeycode(), action->getModifiers(),
281 action->isPressed());
282 284
283 QWSServer::sendKeyEvent(action->getUnicode(), 285 QWSServer::sendKeyEvent(action->getUnicode(),
284 action->getKeycode(), action->getModifiers(), 286 action->getKeycode(), action->getModifiers(),
285 action->isPressed(), false); 287 action->isPressed(), false);
286 } 288 }
287 289
288 if (action->isAutorepeat()) { 290 if (action->isAutorepeat()) {
289 autoRepeatAction = action; 291 autoRepeatAction = action;
290 repeater.start(repeatDelay, TRUE); 292 repeater.start(repeatDelay, TRUE);
291 } else { 293 } else {
292 autoRepeatAction = 0; 294 autoRepeatAction = 0;
293 } 295 }
294 296
295 State* nstate = action->getState(); 297 State* nstate = action->getState();
296 if (nstate != 0) { 298 if (nstate != 0) {
297 setCurrentState(nstate); 299 setCurrentState(nstate);
298 QString lbl = getCurrentLabel(); 300 QString lbl = getCurrentLabel();
299 if (!lbl.isEmpty()) { 301 if (!lbl.isEmpty()) {
300 emit stateChanged(lbl); 302 emit stateChanged(lbl);
301 } 303 }
302 } 304 }
303 305
304 306
305 return true; 307 return true;
306} 308}
307 309
308void Keymap::enable() { 310void Keymap::enable() {
309 enabled = true; 311 enabled = true;
310} 312}
311 313
312void Keymap::disable() { 314void Keymap::disable() {
313 enabled = false; 315 enabled = false;
314} 316}
315 317
316QStringList Keymap::listStates() { 318QStringList Keymap::listStates() {
317 QStringList ret; 319 QStringList ret;
318 320
319 QMap<QString, State*>::Iterator it; 321 QMap<QString, State*>::Iterator it;
320 for(it = states.begin(); it != states.end(); ++it) { 322 for(it = states.begin(); it != states.end(); ++it) {
321 ret.append(it.key()); 323 ret.append(it.key());
322 } 324 }
323 325
324 return ret; 326 return ret;
325} 327}
326 328
327State* Keymap::getStateByName(const QString& name) { 329State* Keymap::getStateByName(const QString& name) {
328 QMap<QString, State*>::Iterator it = states.find(name); 330 QMap<QString, State*>::Iterator it = states.find(name);
329 331
330 if (it == states.end()) { 332 if (it == states.end()) {
331 return 0; 333 return 0;
332 } 334 }
333 335
334 return it.data(); 336 return it.data();
335} 337}
336 338
337QStringList Keymap::listLabels() { 339QStringList Keymap::listLabels() {
338 QStringList ret; 340 QStringList ret;
339 341
340 for(uint i = 0; i < labelList.count(); i++) { 342 for(uint i = 0; i < labelList.count(); i++) {
341 ret.append(*labelList.at(i)); 343 ret.append(*labelList.at(i));
342 } 344 }
343 345
344 return ret; 346 return ret;
345} 347}
346 348
347State* Keymap::getStateByLabel(const QString& label) { 349State* Keymap::getStateByLabel(const QString& label) {
348 QMap<QString, QString>::Iterator lit = labels.find(label); 350 QMap<QString, QString>::Iterator lit = labels.find(label);
349 State* state = 0; 351 State* state = 0;
350 352
351 if (lit == labels.end()) { 353 if (lit == labels.end()) {
352 return 0; 354 return 0;
353 } 355 }
354 356
355 QString name = lit.data(); 357 QString name = lit.data();
356 358
357 int n = name.find(":*"); 359 int n = name.find(":*");
358 if (n>=0 && n==(int)(name.length()-2)) { 360 if (n>=0 && n==(int)(name.length()-2)) {
359 name=name.left(name.length() - 1); 361 name=name.left(name.length() - 1);
360 362
361 n = currentStateName.findRev(":"); 363 n = currentStateName.findRev(":");
362 if (n >= 0) { 364 if (n >= 0) {
363 name += currentStateName.mid(n+1); 365 name += currentStateName.mid(n+1);
364 } 366 }
365 } 367 }
366 368
367 //odebug << "look for: " << name.utf8() << "\n" << oendl; 369// odebug << "look for: " << name.utf8() << "\n" << oendl;
368 QMap<QString, State*>::Iterator sit = states.find(name); 370 QMap<QString, State*>::Iterator sit = states.find(name);
369 if (sit != states.end()) { 371 if (sit != states.end()) {
370 state = sit.data(); 372 state = sit.data();
371 } 373 }
372 374
373 return state; 375 return state;
374} 376}
375 377
376bool Keymap::addState(const QString& name, State* state) { 378bool Keymap::addState(const QString& name, State* state) {
377 if (states.find(name) != states.end()) { 379 if (states.find(name) != states.end()) {
378 return false; 380 return false;
379 } 381 }
380 382
381 states.insert(name, state); 383 states.insert(name, state);
382 lsmapInSync = false; 384 lsmapInSync = false;
383 385
384 if (currentState == 0) { 386 if (currentState == 0) {
385 setCurrentState(state); 387 setCurrentState(state);
386 } 388 }
387 389
388 return true; 390 return true;
389} 391}
390 392
391State* Keymap::getCurrentState() const { 393State* Keymap::getCurrentState() const {
392 return currentState; 394 return currentState;
393} 395}
394 396
395QString Keymap::getCurrentLabel() { 397QString Keymap::getCurrentLabel() {
396 return currentLabel; 398 return currentLabel;
397} 399}
398 400
399bool Keymap::setCurrentState(State* state) { 401bool Keymap::setCurrentState(State* state) {
400 QMap<QString, State*>::Iterator it; 402 QMap<QString, State*>::Iterator it;
401 for(it = states.begin(); it != states.end(); ++it) { 403 for(it = states.begin(); it != states.end(); ++it) {
402 State* s = it.data(); 404 State* s = it.data();
403 if (s == state) { 405 if (s == state) {
404 currentState = s; 406 currentState = s;
405 currentStateName = it.key(); 407 currentStateName = it.key();
406 408
407 qDebug("state changed: %s\n", (const char*) 409 odebug << "state changed: " << (const char*)currentStateName.utf8() << oendl;
408 currentStateName.utf8());
409 410
410 if (!lsmapInSync) { 411 if (!lsmapInSync) {
411 generateLabelStateMaps(); 412 generateLabelStateMaps();
412 } 413 }
413 414
414 QMap<State*, QString>::Iterator tit; 415 QMap<State*, QString>::Iterator tit;
415 tit = stateLabelMap.find(state); 416 tit = stateLabelMap.find(state);
416 if (tit != stateLabelMap.end()) { 417 if (tit != stateLabelMap.end()) {
417 currentLabel = tit.data(); 418 currentLabel = tit.data();
418 } else { 419 } else {
419 // odebug << "no label for: " + currentStateName + "\n" << oendl; 420// odebug << "no label for: " + currentStateName + "\n" << oendl;
420 currentLabel = ""; 421 currentLabel = "";
421 } 422 }
422 423
423 return true; 424 return true;
424 } 425 }
425 } 426 }
426 427
427 return false; 428 return false;
428} 429}
429 430
430bool Keymap::removeState(const QString& name, bool force) { 431bool Keymap::removeState(const QString& name, bool force) {
431 QMap<QString, State*>::Iterator it = states.find(name); 432 QMap<QString, State*>::Iterator it = states.find(name);
432 433
433 if (it == states.end()) { 434 if (it == states.end()) {
434 return false; 435 return false;
435 } 436 }
436 437
437 State* state = it.data(); 438 State* state = it.data();
438 QList<Action> acts = findStateUsage(state); 439 QList<Action> acts = findStateUsage(state);
439 440
440 if (!acts.isEmpty()) { 441 if (!acts.isEmpty()) {
441 if (!force) { 442 if (!force) {
442 return false; 443 return false;
443 } else { 444 } else {
444 for(Action* a = acts.first(); a != 0; a = acts.next()) { 445 for(Action* a = acts.first(); a != 0; a = acts.next()) {
445 a->setState(0); 446 a->setState(0);
446 } 447 }
447 } 448 }
448 } 449 }
449 450
450 if (state == currentState) { 451 if (state == currentState) {
451 if (states.begin() != states.end()) { 452 if (states.begin() != states.end()) {
452 setCurrentState(states.begin().data()); 453 setCurrentState(states.begin().data());
453 } 454 }
454 } 455 }
455 456
456 states.remove(it); 457 states.remove(it);
457 delete state; 458 delete state;
458 459
459 lsmapInSync = false; 460 lsmapInSync = false;
460 461
461 return true; 462 return true;
462} 463}
463 464
464void Keymap::autoRepeat() { 465void Keymap::autoRepeat() {
465 if (autoRepeatAction != 0) { 466 if (autoRepeatAction != 0) {
466 qDebug("filter:<<< unicode=%x, keycode=%x, modifiers=%x, " 467 odebug << "filter:<<< unicode=" << autoRepeatAction->getUnicode()
467 "ispressed=%x\n", autoRepeatAction->getUnicode(), 468 << ", keycode=" << autoRepeatAction->getKeycode()
468 autoRepeatAction->getKeycode(), 469 << ", modifiers=" << autoRepeatAction->getModifiers()
469 autoRepeatAction->getModifiers(), 470 << "ispressed=" << autoRepeatAction->isPressed() << oendl;
470 autoRepeatAction->isPressed());
471 471
472 QWSServer::sendKeyEvent(autoRepeatAction->getUnicode(), 472 QWSServer::sendKeyEvent(autoRepeatAction->getUnicode(),
473 autoRepeatAction->getKeycode(), 473 autoRepeatAction->getKeycode(),
474 autoRepeatAction->getModifiers(), 474 autoRepeatAction->getModifiers(),
475 autoRepeatAction->isPressed(), true); 475 autoRepeatAction->isPressed(), true);
476 } 476 }
477 477
478 repeater.start(repeatPeriod, TRUE); 478 repeater.start(repeatPeriod, TRUE);
479} 479}
480 480
481bool Keymap::addLabel(const QString& label, const QString& state, int index) { 481bool Keymap::addLabel(const QString& label, const QString& state, int index) {
482 if (labels.find(label) != labels.end()) { 482 if (labels.find(label) != labels.end()) {
483 return false; 483 return false;
484 } 484 }
485 485
486 labels.insert(label, state); 486 labels.insert(label, state);
487 const QString& l = labels.find(label).key(); 487 const QString& l = labels.find(label).key();
488 if (index == -1) { 488 if (index == -1) {
489 labelList.append(l); 489 labelList.append(l);
490 } else { 490 } else {
491 labelList.insert(labelList.at(index), l); 491 labelList.insert(labelList.at(index), l);
492 } 492 }
493 493
494 lsmapInSync = false; 494 lsmapInSync = false;
495 495
496 return true; 496 return true;
497} 497}
498 498
499bool Keymap::removeLabel(const QString& label) { 499bool Keymap::removeLabel(const QString& label) {
500 500
501 if (labels.find(label) == labels.end()) { 501 if (labels.find(label) == labels.end()) {
502 return false; 502 return false;
503 } 503 }
504 504
505 labels.remove(label); 505 labels.remove(label);
506 labelList.remove(label); 506 labelList.remove(label);
507 lsmapInSync = false; 507 lsmapInSync = false;
508 508
509 if (label == currentLabel) { 509 if (label == currentLabel) {
510 currentLabel = ""; 510 currentLabel = "";
511 } 511 }
512 512
513 return true; 513 return true;
514} 514}
515 515
516int Keymap::getAutorepeatDelay() const { 516int Keymap::getAutorepeatDelay() const {
517 return repeatDelay; 517 return repeatDelay;
518} 518}
519 519
520void Keymap::setAutorepeatDelay(int n) { 520void Keymap::setAutorepeatDelay(int n) {
521 repeatDelay = n; 521 repeatDelay = n;
522} 522}
523 523
524int Keymap::getAutorepeatPeriod() const { 524int Keymap::getAutorepeatPeriod() const {
525 return repeatPeriod; 525 return repeatPeriod;
526} 526}
527 527
528void Keymap::setAutorepeatPeriod(int n) { 528void Keymap::setAutorepeatPeriod(int n) {
529 repeatPeriod = n; 529 repeatPeriod = n;
530} 530}
531 531
532QList<Action> Keymap::findStateUsage(State* s) { 532QList<Action> Keymap::findStateUsage(State* s) {
533 QList<Action> ret; 533 QList<Action> ret;
534 534
535 QMap<QString, State*>::Iterator it; 535 QMap<QString, State*>::Iterator it;
536 for(it = states.begin(); it != states.end(); ++it) { 536 for(it = states.begin(); it != states.end(); ++it) {
537 State* state = it.data(); 537 State* state = it.data();
538 538
539 for(int i = 0; i < 0x1100; i++) { 539 for(int i = 0; i < 0x1100; i++) {
540 Action* action = state->get(i, false); 540 Action* action = state->get(i, false);
541 if (action!=0 && action->getState()==s) { 541 if (action!=0 && action->getState()==s) {
542 ret.append(action); 542 ret.append(action);
543 } 543 }
544 544
545 action = state->get(i, true); 545 action = state->get(i, true);
546 if (action!=0 && action->getState()==s) { 546 if (action!=0 && action->getState()==s) {
547 ret.append(action); 547 ret.append(action);
548 } 548 }
549 } 549 }
550 } 550 }
551 551
552 return ret; 552 return ret;
553} 553}
554 554
555void Keymap::generateLabelStateMaps() { 555void Keymap::generateLabelStateMaps() {
556 stateLabelMap.clear(); 556 stateLabelMap.clear();
557 557
558 QMap<QString, QString>::Iterator lit; 558 QMap<QString, QString>::Iterator lit;
559 for(lit = labels.begin(); lit != labels.end(); ++lit) { 559 for(lit = labels.begin(); lit != labels.end(); ++lit) {
560 QString label = lit.key(); 560 QString label = lit.key();
561 QString name = lit.data(); 561 QString name = lit.data();
562 562
563 bool wc = false; 563 bool wc = false;
564 int n = name.find("*"); 564 int n = name.find("*");
565 if (n>=0 && n==(int)(name.length()-1)) { 565 if (n>=0 && n==(int)(name.length()-1)) {
566 name=name.left(name.length() - 1); 566 name=name.left(name.length() - 1);
567 wc = true; 567 wc = true;
568 } 568 }
569 569
570 QMap<QString, State*>::Iterator sit; 570 QMap<QString, State*>::Iterator sit;
571 for(sit = states.begin(); sit != states.end(); ++sit) { 571 for(sit = states.begin(); sit != states.end(); ++sit) {
572 QString sname = sit.key(); 572 QString sname = sit.key();
573 State* state = sit.data(); 573 State* state = sit.data();
574 574
575 if (sname.length() < name.length()) { 575 if (sname.length() < name.length()) {
576 continue; 576 continue;
577 } 577 }
578 578
579 if (sname.left(name.length()) == name) { 579 if (sname.left(name.length()) == name) {
580 if (wc || sname.length()==name.length()) { 580 if (wc || sname.length()==name.length()) {
581 stateLabelMap.insert(state, label); 581 stateLabelMap.insert(state, label);
582 } 582 }
583 583
584 } 584 }
585 } 585 }
586 } 586 }
587 587
588 lsmapInSync = true; 588 lsmapInSync = true;
589} 589}
diff --git a/noncore/apps/opie-gutenbrowser/gutenbrowser.cpp b/noncore/apps/opie-gutenbrowser/gutenbrowser.cpp
index be2b897..f14080f 100644
--- a/noncore/apps/opie-gutenbrowser/gutenbrowser.cpp
+++ b/noncore/apps/opie-gutenbrowser/gutenbrowser.cpp
@@ -328,228 +328,230 @@ void Gutenbrowser::DownloadIndex() {
328 "or select an ftp site?\n")), 328 "or select an ftp site?\n")),
329 (tr("&Library Index")), (tr("&Ftp Site")), (tr("&Cancel")), 2, 2 ) ) 329 (tr("&Library Index")), (tr("&Ftp Site")), (tr("&Cancel")), 2, 2 ) )
330 { 330 {
331 case 0: // index clicked, 331 case 0: // index clicked,
332 downloadLibIndex(); 332 downloadLibIndex();
333 break; 333 break;
334 334
335 case 1: // ftp selected 335 case 1: // ftp selected
336 downloadFtpList(); 336 downloadFtpList();
337 break; 337 break;
338 338
339 case 2: // Cancel 339 case 2: // Cancel
340 break; 340 break;
341 }; 341 };
342 } 342 }
343#endif 343#endif
344} // end DownloadIndex 344} // end DownloadIndex
345 345
346 346
347void Gutenbrowser::downloadFtpList() { 347void Gutenbrowser::downloadFtpList() {
348 // QString cmd="wget http://www.promo.net/pg/list.html"); 348 // QString cmd="wget http://www.promo.net/pg/list.html");
349 //system(cmd); 349 //system(cmd);
350 qApp->processEvents(); 350 qApp->processEvents();
351 optionsDialog* optDlg; 351 optionsDialog* optDlg;
352 optDlg = new optionsDialog( this,"Options_Dlg", true); 352 optDlg = new optionsDialog( this,"Options_Dlg", true);
353 optDlg->getSite(); 353 optDlg->getSite();
354 if(optDlg) 354 if(optDlg)
355 delete optDlg; 355 delete optDlg;
356} 356}
357 357
358 358
359void Gutenbrowser::downloadLibIndex() { 359void Gutenbrowser::downloadLibIndex() {
360 // QString dwmloader = local_library + "pgwhole.zip"; 360 // QString dwmloader = local_library + "pgwhole.zip";
361 // QString cmd = "lynx -source http://www.gutenberg.net/pgwhole.zip | cat >> " + dwmloader; 361 // QString cmd = "lynx -source http://www.gutenberg.net/pgwhole.zip | cat >> " + dwmloader;
362 // system(cmd); 362 // system(cmd);
363 363
364 // QString outputFile= local_library+ "GUTINDEX.ALL"; 364 // QString outputFile= local_library+ "GUTINDEX.ALL";
365 // config.setGroup( "FTPsite" ); // ftp server config 365 // config.setGroup( "FTPsite" ); // ftp server config
366 // ftp_host=config.readEntry("SiteName", ""); 366 // ftp_host=config.readEntry("SiteName", "");
367 // ftp_base_dir= config.readEntry("base", ""); 367 // ftp_base_dir= config.readEntry("base", "");
368 // QString networkUrl= "ftp://"+ftp_host+ftp_base_dir+"/GUTINDEX.ALL"; 368 // QString networkUrl= "ftp://"+ftp_host+ftp_base_dir+"/GUTINDEX.ALL";
369 QDir dir( local_library); 369 QDir dir( local_library);
370 dir.cd("", TRUE); 370 dir.cd("", TRUE);
371 goGetit( "http://sailor.gutenberg.org/GUTINDEX.ALL", false); // until ghttp works on binaries -qt3 371 goGetit( "http://sailor.gutenberg.org/GUTINDEX.ALL", false); // until ghttp works on binaries -qt3
372 // goGetit( "http://www.gutenberg.net/pgwhole.zip", true); // until ghttp works on binaries -qt3 372 // goGetit( "http://www.gutenberg.net/pgwhole.zip", true); // until ghttp works on binaries -qt3
373 // NetworkDialog *NetworkDlg; 373 // NetworkDialog *NetworkDlg;
374 // NetworkDlg = new NetworkDialog( this,"Network Protocol Dialog", TRUE, 0, networkUrl, outputFile ); 374 // NetworkDlg = new NetworkDialog( this,"Network Protocol Dialog", TRUE, 0, networkUrl, outputFile );
375 // if( NetworkDlg->exec() != 0 ) 375 // if( NetworkDlg->exec() != 0 )
376 // { // use new, improved, *INSTANT* network-dialog-file-getterer 376 // { // use new, improved, *INSTANT* network-dialog-file-getterer
377 //// QMessageBox::message("Note",""); 377 //// QMessageBox::message("Note","");
378 // } 378 // }
379 // if(NetworkDlg) 379 // if(NetworkDlg)
380 // delete NetworkDlg; 380 // delete NetworkDlg;
381} 381}
382 382
383 383
384void Gutenbrowser::PrintBtn() { 384void Gutenbrowser::PrintBtn() {
385} 385}
386 386
387void Gutenbrowser::SearchBtn() { 387void Gutenbrowser::SearchBtn() {
388 if( loadCheck) { 388 if( loadCheck) {
389 odebug << "loadCheck: we have a loaded doc" << oendl; 389 odebug << "loadCheck: we have a loaded doc" << oendl;
390 Search(); 390 Search();
391 } 391 }
392 // else 392 // else
393 // QMessageBox::message("Note","Sorry, can't search. No etext is loaded"); 393 // QMessageBox::message("Note","Sorry, can't search. No etext is loaded");
394} 394}
395 395
396 396
397void Gutenbrowser::ForwardBtn() { 397void Gutenbrowser::ForwardBtn() {
398 398
399 if( !ForwardButton->autoRepeat() && !ForwardButton->isDown()) { 399 if( !ForwardButton->autoRepeat() && !ForwardButton->isDown()) {
400 400
401 QString s; 401 QString s;
402 QString insertString; 402 QString insertString;
403 int pageSize= Lview->PageSize(); 403 int pageSize= Lview->PageSize();
404 Lview->clear(); 404 Lview->clear();
405 405
406 for(int fd=0; fd < pageSize - 1;fd++) { 406 for(int fd=0; fd < pageSize - 1;fd++) {
407 f.readLine(s, 256); 407 f.readLine(s, 256);
408 if(useWrap) 408 if(useWrap)
409 s.replace(QRegExp("\n"),""); 409 s.replace(QRegExp("\n"),"");
410 insertString+=s; 410 insertString+=s;
411 Lview->insertLine( s, -1); 411 Lview->insertLine( s, -1);
412 // odebug << s << oendl; 412 // odebug << s << oendl;
413 currentLine++; 413 currentLine++;
414 } 414 }
415 // Lview->insertAt( insertString,0,0, FALSE); 415 // Lview->insertAt( insertString,0,0, FALSE);
416 currentFilePos = f.at(); 416 currentFilePos = f.at();
417 // if( i_pageNum != pages) { 417 // if( i_pageNum != pages) {
418 // Lview->MultiLine_Ex::pageDown( FALSE); 418 // Lview->MultiLine_Ex::pageDown( FALSE);
419 i_pageNum++; 419 i_pageNum++;
420 pageStopArray.resize(i_pageNum + 1); 420 pageStopArray.resize(i_pageNum + 1);
421 // int length = Lview->length(); 421 // int length = Lview->length();
422 422
423 pageStopArray[i_pageNum ] = currentFilePos; 423 pageStopArray[i_pageNum ] = currentFilePos;
424 // qDebug("%d current page is number %d, pagesize %d, length %d, current %d", 424 // odebug << currentFilePos << " current page is number " << i_pageNum
425 // currentFilePos, i_pageNum, pageSize, Lview->length(), pageStopArray[i_pageNum] ); 425 // << ", pagesize " << pageSize << ", length " << Lview->length()
426 // << ", current " << pageStopArray[i_pageNum] << oendl;
426 setStatus(); 427 setStatus();
427 Lview->setCursorPosition( 0, 0, FALSE); 428 Lview->setCursorPosition( 0, 0, FALSE);
428 // } 429 // }
429 430
430 } else { 431 } else {
431 // odebug << "bal" << oendl; 432 // odebug << "bal" << oendl;
432 // if( i_pageNum != pages) { 433 // if( i_pageNum != pages) {
433 434
434 // // int newTop = Lview->Top(); 435 // // int newTop = Lview->Top();
435 // // if(Lview->lastRow() > i) 436 // // if(Lview->lastRow() > i)
436 // Lview->ScrollUp(1); 437 // Lview->ScrollUp(1);
437 // // i_pageNum++; 438 // // i_pageNum++;
438 // setStatus(); 439 // setStatus();
439 // Lview->setCursorPosition( Lview->Top(), 0, FALSE); 440 // Lview->setCursorPosition( Lview->Top(), 0, FALSE);
440 441
441 // } 442 // }
442 443
443 } 444 }
444 Lview->setFocus(); 445 Lview->setFocus();
445 446
446 // odebug << "page number " << i_pageNum << " line number " << currentLine << "" << oendl; 447 // odebug << "page number " << i_pageNum << " line number " << currentLine << "" << oendl;
447} 448}
448 449
449 450
450void Gutenbrowser::BackBtn() { 451void Gutenbrowser::BackBtn() {
451 if( i_pageNum > 0) { 452 if( i_pageNum > 0) {
452 int pageSize= Lview->PageSize(); 453 int pageSize= Lview->PageSize();
453 // int length=Lview->length(); 454 // int length=Lview->length();
454 455
455 i_pageNum--; 456 i_pageNum--;
456 currentFilePos = f.at(); 457 currentFilePos = f.at();
457 458
458 // qDebug("%d move back to %d, current page number %d, %d, length %d", 459 // odebug << currentFilePos << " move back to " << pageStopArray[i_pageNum - 1 ]
459 // currentFilePos, pageStopArray[i_pageNum - 1 ], i_pageNum, pageSize, Lview->length() ); 460 // << ", current page number " << i_pageNum
461 // << ", " << pageSize << ", length " << Lview->length() << oendl;
460 462
461 if( i_pageNum < 2) { 463 if( i_pageNum < 2) {
462 f.at( 0); 464 f.at( 0);
463 } else { 465 } else {
464 if(!f.at( pageStopArray[i_pageNum - 1] )) 466 if(!f.at( pageStopArray[i_pageNum - 1] ))
465 odebug << "File positioned backward did not work" << oendl; 467 odebug << "File positioned backward did not work" << oendl;
466 } 468 }
467 QString s; 469 QString s;
468 // int sizeLine=0; 470 // int sizeLine=0;
469 Lview->clear(); 471 Lview->clear();
470 // QString insertString; 472 // QString insertString;
471 473
472 for(int fd = 0; fd < pageSize ;fd++) { 474 for(int fd = 0; fd < pageSize ;fd++) {
473 // Lview->removeLine( Lview->PageSize() ); 475 // Lview->removeLine( Lview->PageSize() );
474 f.readLine(s, 256); 476 f.readLine(s, 256);
475 if(useWrap) 477 if(useWrap)
476 s.replace(QRegExp("\n"),""); 478 s.replace(QRegExp("\n"),"");
477 currentLine++; 479 currentLine++;
478 // insertString+=s; 480 // insertString+=s;
479 Lview->insertLine( s, -1); 481 Lview->insertLine( s, -1);
480 } 482 }
481 483
482 // Lview->insertAt( insertString,0,0, FALSE); 484 // Lview->insertAt( insertString,0,0, FALSE);
483 485
484 if( !BackButton->autoRepeat() && !BackButton->isDown()) { 486 if( !BackButton->autoRepeat() && !BackButton->isDown()) {
485 QString topR; 487 QString topR;
486 QString lastR; 488 QString lastR;
487 QString pageR; 489 QString pageR;
488 // int sizer = Lview->lastRow() - Lview->topRow(); 490 // int sizer = Lview->lastRow() - Lview->topRow();
489 // int i_topRow = Lview->topRow(); 491 // int i_topRow = Lview->topRow();
490 if( i_pageNum < 1) 492 if( i_pageNum < 1)
491 i_pageNum = 1; 493 i_pageNum = 1;
492 setCaption(QString::number(i_pageNum)); 494 setCaption(QString::number(i_pageNum));
493 } else { 495 } else {
494 // int newTop = Lview->Top(); 496 // int newTop = Lview->Top();
495 // if(Lview->lastRow() > i) 497 // if(Lview->lastRow() > i)
496 Lview->MultiLine_Ex::pageUp( FALSE); 498 Lview->MultiLine_Ex::pageUp( FALSE);
497 // Lview->ScrollDown(1); 499 // Lview->ScrollDown(1);
498 // i_pageNum--; 500 // i_pageNum--;
499 if( i_pageNum < 1) 501 if( i_pageNum < 1)
500 i_pageNum = 1; 502 i_pageNum = 1;
501 setStatus(); 503 setStatus();
502 Lview->setCursorPosition( Lview->Top(), 0, FALSE); 504 Lview->setCursorPosition( Lview->Top(), 0, FALSE);
503 505
504 } 506 }
505 } 507 }
506 Lview->setFocus(); 508 Lview->setFocus();
507} 509}
508 510
509void Gutenbrowser::doBeginBtn() { 511void Gutenbrowser::doBeginBtn() {
510 if(loadCheck) { 512 if(loadCheck) {
511 qApp->processEvents(); 513 qApp->processEvents();
512 BeginBtn(); 514 BeginBtn();
513 } 515 }
514} 516}
515 517
516 // moves text to the very top = 0 518 // moves text to the very top = 0
517void Gutenbrowser::TopBtn() { 519void Gutenbrowser::TopBtn() {
518 520
519 if(loadCheck) { 521 if(loadCheck) {
520 if( i_pageNum != 0) { 522 if( i_pageNum != 0) {
521 odebug << "top" << oendl; 523 odebug << "top" << oendl;
522 qApp->processEvents(); 524 qApp->processEvents();
523 currentLine = 0; 525 currentLine = 0;
524 i_pageNum = 1; 526 i_pageNum = 1;
525 int pageSize = Lview->PageSize() ; 527 int pageSize = Lview->PageSize() ;
526 Lview->clear(); 528 Lview->clear();
527 QString s; 529 QString s;
528 f.at(0); 530 f.at(0);
529 for(int fd=0; fd < pageSize ;fd++) { 531 for(int fd=0; fd < pageSize ;fd++) {
530 f.readLine(s, 256); 532 f.readLine(s, 256);
531 if(useWrap) 533 if(useWrap)
532 s.replace(QRegExp("\n"),""); 534 s.replace(QRegExp("\n"),"");
533 Lview->insertLine(s ,-1); 535 Lview->insertLine(s ,-1);
534 currentLine++; 536 currentLine++;
535 } 537 }
536 Lview->setCursorPosition( 0,0, FALSE); 538 Lview->setCursorPosition( 0,0, FALSE);
537 i_pageNum=1; 539 i_pageNum=1;
538 setStatus(); 540 setStatus();
539 } 541 }
540 Lview->setFocus(); 542 Lview->setFocus();
541 } 543 }
542} 544}
543 545
544 //moves text to the start of the EText 546 //moves text to the start of the EText
545void Gutenbrowser::BeginBtn() { 547void Gutenbrowser::BeginBtn() {
546 i_pageNum = 1; 548 i_pageNum = 1;
547 currentLine = 0; 549 currentLine = 0;
548 QString s_pattern="*END*THE SMALL PRINT"; 550 QString s_pattern="*END*THE SMALL PRINT";
549 QString sPattern2 = "*END THE SMALL PRINT"; 551 QString sPattern2 = "*END THE SMALL PRINT";
550 552
551 int pageSize = Lview->PageSize(); 553 int pageSize = Lview->PageSize();
552 Lview->clear(); 554 Lview->clear();
553 555
554 // int lines = Lview->numLines(); 556 // int lines = Lview->numLines();
555 int pos = 0;//, i = 0; 557 int pos = 0;//, i = 0;
@@ -706,194 +708,195 @@ void Gutenbrowser::Bookmark( int itemId) {
706 pageStopArray.resize(i_pageNum + 1); 708 pageStopArray.resize(i_pageNum + 1);
707 pageStopArray[i_pageNum ] = currentFilePos; 709 pageStopArray[i_pageNum ] = currentFilePos;
708 // odebug << "new page number " << i_pageNum << ", found at " << currentFilePos << "" << oendl; 710 // odebug << "new page number " << i_pageNum << ", found at " << currentFilePos << "" << oendl;
709 } 711 }
710 if(currentFilePos == bookmarkPosition) 712 if(currentFilePos == bookmarkPosition)
711 break; 713 break;
712 } 714 }
713 if(f.atEnd()) 715 if(f.atEnd())
714 f.at(0); 716 f.at(0);
715 else 717 else
716 f.at( bookmarkPosition); 718 f.at( bookmarkPosition);
717 719
718 for(int fd=0; fd < pageSize - 1;fd++) { 720 for(int fd=0; fd < pageSize - 1;fd++) {
719 f.readLine(s, 256); 721 f.readLine(s, 256);
720 lineNo++; 722 lineNo++;
721 if(useWrap) 723 if(useWrap)
722 s.replace(QRegExp("\n"),""); 724 s.replace(QRegExp("\n"),"");
723 Lview->insertLine( s, -1); 725 Lview->insertLine( s, -1);
724 currentLine++; 726 currentLine++;
725 } 727 }
726 728
727 i_pageNum = lineNo/pageSize; 729 i_pageNum = lineNo/pageSize;
728 pageStopArray.resize(i_pageNum + 1); 730 pageStopArray.resize(i_pageNum + 1);
729 731
730 if(showMainList) { 732 if(showMainList) {
731 showMainList=FALSE; 733 showMainList=FALSE;
732 mainList->hide(); 734 mainList->hide();
733 Lview->show(); 735 Lview->show();
734 // qApp->processEvents(); 736 // qApp->processEvents();
735 } 737 }
736 738
737 odebug << "bookmark loaded" << oendl; 739 odebug << "bookmark loaded" << oendl;
738 setCaption(title); 740 setCaption(title);
739} 741}
740 742
741 743
742bool Gutenbrowser::load( const char *fileName) { 744bool Gutenbrowser::load( const char *fileName) {
743 745
744 // QCopEnvelope ( "QPE/System", "busy()" ); 746 // QCopEnvelope ( "QPE/System", "busy()" );
745 // odebug << "Title is already set as "+title << oendl; 747 // odebug << "Title is already set as "+title << oendl;
746 odebug << "sizeHint " << sizeHint().height() << " pageSize " << Lview->PageSize() << "" << oendl; 748 odebug << "sizeHint " << sizeHint().height() << " pageSize " << Lview->PageSize() << "" << oendl;
747 if( Lview->PageSize() < 4) { 749 if( Lview->PageSize() < 4) {
748 750
749 Lview->setMaximumHeight( sizeHint().height() ); 751 Lview->setMaximumHeight( sizeHint().height() );
750 Lview->setMinimumHeight( sizeHint().height() ); 752 Lview->setMinimumHeight( sizeHint().height() );
751 pointSize = Lview->fontInfo().pointSize(); 753 pointSize = Lview->fontInfo().pointSize();
752 odebug << "sizeHint " << sizeHint().height() << " point size " << pointSize << "" << oendl; 754 odebug << "sizeHint " << sizeHint().height() << " point size " << pointSize << "" << oendl;
753 if(pointSize < 10) 755 if(pointSize < 10)
754 Lview->setFixedVisibleLines(19); 756 Lview->setFixedVisibleLines(19);
755 else 757 else
756 Lview->setFixedVisibleLines( ( (sizeHint().height() / pointSize ) * 2) -2); 758 Lview->setFixedVisibleLines( ( (sizeHint().height() / pointSize ) * 2) -2);
757 } 759 }
758 760
759 Config cfg("Gutenbrowser"); 761 Config cfg("Gutenbrowser");
760 cfg.setGroup("General"); 762 cfg.setGroup("General");
761 cfg.writeEntry("Current",fileName); 763 cfg.writeEntry("Current",fileName);
762 currentLine=0; 764 currentLine=0;
763 765
764 file_name=fileName; 766 file_name=fileName;
765 QString o_file = fileName; 767 QString o_file = fileName;
766 768
767 // if (i_pageNum < 1) { 769 // if (i_pageNum < 1) {
768 i_pageNum = 1; 770 i_pageNum = 1;
769 // } 771 // }
770 odebug << "ready to open "+o_file << oendl; 772 odebug << "ready to open "+o_file << oendl;
771 773
772 if(f.isOpen()) f.close(); 774 if(f.isOpen()) f.close();
773 f.setName( o_file); 775 f.setName( o_file);
774 776
775 if ( !f.open( IO_ReadOnly)) { 777 if ( !f.open( IO_ReadOnly)) {
776 QMessageBox::message( (tr("Note")), (tr("File not opened sucessfully.\n" +o_file)) ); 778 QMessageBox::message( (tr("Note")), (tr("File not opened sucessfully.\n" +o_file)) );
777 return false; 779 return false;
778 } 780 }
779 currentFilePos = 0; 781 currentFilePos = 0;
780 pageStopArray.resize(3); 782 pageStopArray.resize(3);
781 pageStopArray[0] = currentFilePos; 783 pageStopArray[0] = currentFilePos;
782 784
783 fileHandle = f.handle(); 785 fileHandle = f.handle();
784 QString insertString; 786 QString insertString;
785 QTextStream t(&f); 787 QTextStream t(&f);
786 QString s; 788 QString s;
787 for(int fd=0; fd < Lview->PageSize() ;fd++) { 789 for(int fd=0; fd < Lview->PageSize() ;fd++) {
788 s=t.readLine(); 790 s=t.readLine();
789 // insertString+=s; 791 // insertString+=s;
790 if(useWrap) 792 if(useWrap)
791 s.replace(QRegExp("\n"),""); 793 s.replace(QRegExp("\n"),"");
792 // s.replace(QRegExp("\r"),""); 794 // s.replace(QRegExp("\r"),"");
793 Lview->insertLine( s,-1); 795 Lview->insertLine( s,-1);
794 currentLine++; 796 currentLine++;
795 } 797 }
796 798
797 // int length = Lview->length(); 799 // int length = Lview->length();
798 currentFilePos = f.at(); 800 currentFilePos = f.at();
799 801
800 pageStopArray[1] = currentFilePos; 802 pageStopArray[1] = currentFilePos;
801 803
802 qDebug("<<<<<<<<<<<%d current page is number %d, length %d, current %d, pageSize %d", 804 odebug << "<<<<<<<<<<<" << currentFilePos << " current page is number " << i_pageNum
803 currentFilePos, i_pageNum, Lview->length(), pageStopArray[i_pageNum], Lview->PageSize() ); 805 << ", length " << Lview->length() << ", current " << pageStopArray[i_pageNum]
806 << ", pageSize " << Lview->PageSize() << oendl;
804 807
805 Lview->setMaxLines(Lview->PageSize()*2); 808 Lview->setMaxLines(Lview->PageSize()*2);
806 odebug << "Gulped " << currentLine << "" << oendl; 809 odebug << "Gulped " << currentLine << "" << oendl;
807 setCaption(title); 810 setCaption(title);
808 Lview->setAutoUpdate( TRUE); 811 Lview->setAutoUpdate( TRUE);
809 812
810 Lview->setCursorPosition(0,0,FALSE); 813 Lview->setCursorPosition(0,0,FALSE);
811 814
812 // pages = (int)(( Lview->numLines() / Lview->editSize() ) / 2 ) +1; 815 // pages = (int)(( Lview->numLines() / Lview->editSize() ) / 2 ) +1;
813 //odebug << "number of pages " << pages << "" << oendl; 816 //odebug << "number of pages " << pages << "" << oendl;
814 817
815 loadCheck = true; 818 loadCheck = true;
816 enableButtons(true); 819 enableButtons(true);
817 if( donateMenu->count() == 3) { 820 if( donateMenu->count() == 3) {
818 donateMenu->insertItem("Current Title", this, SLOT( InfoBarClick() )); 821 donateMenu->insertItem("Current Title", this, SLOT( InfoBarClick() ));
819 } 822 }
820 Lview->setFocus(); 823 Lview->setFocus();
821 824
822 // QCopEnvelope("QPE/System", "notBusy()" ); 825 // QCopEnvelope("QPE/System", "notBusy()" );
823 return true; 826 return true;
824} // end load 827} // end load
825 828
826void Gutenbrowser::Search() { 829void Gutenbrowser::Search() {
827 830
828 // if( searchDlg->isHidden()) 831 // if( searchDlg->isHidden())
829 { 832 {
830 odebug << "Starting search dialog" << oendl; 833 odebug << "Starting search dialog" << oendl;
831 searchDlg = new SearchDialog( this, "Etext Search", true); 834 searchDlg = new SearchDialog( this, "Etext Search", true);
832 searchDlg->setCaption( tr( "Etext Search" )); 835 searchDlg->setCaption( tr( "Etext Search" ));
833 // searchDlg->setLabel( "- searches etext"); 836 // searchDlg->setLabel( "- searches etext");
834 connect( searchDlg,SIGNAL( search_signal()),this,SLOT( search_slot())); 837 connect( searchDlg,SIGNAL( search_signal()),this,SLOT( search_slot()));
835 connect( searchDlg,SIGNAL( search_done_signal()),this,SLOT( searchdone_slot())); 838 connect( searchDlg,SIGNAL( search_done_signal()),this,SLOT( searchdone_slot()));
836 839
837 QString resultString; 840 QString resultString;
838 QString string = searchDlg->searchString; 841 QString string = searchDlg->searchString;
839 Lview->deselect(); 842 Lview->deselect();
840 searchDlg->show(); 843 searchDlg->show();
841 searchDlg->result(); 844 searchDlg->result();
842 } 845 }
843} 846}
844 847
845void Gutenbrowser::search_slot( ) { 848void Gutenbrowser::search_slot( ) {
846 int line, col; 849 int line, col;
847 if (!searchDlg /*&& !loadCheck */) 850 if (!searchDlg /*&& !loadCheck */)
848 return; 851 return;
849 852
850 Lview->getCursorPosition(&line,&col); 853 Lview->getCursorPosition(&line,&col);
851 QString to_find_string=searchDlg->get_text(); 854 QString to_find_string=searchDlg->get_text();
852 855
853 // searchDlg->get_direction();// is true if searching backward 856 // searchDlg->get_direction();// is true if searching backward
854 if ( last_search != 0 && searchDlg->get_direction() ){ 857 if ( last_search != 0 && searchDlg->get_direction() ){
855 col = col - pattern.length() - 1 ; 858 col = col - pattern.length() - 1 ;
856 } 859 }
857 again: 860 again:
858 int result = doSearch( to_find_string , /* searchDlg->case_sensitive()*/ TRUE, searchDlg->forward_search(), line, col); 861 int result = doSearch( to_find_string , /* searchDlg->case_sensitive()*/ TRUE, searchDlg->forward_search(), line, col);
859 if(result == 0){ 862 if(result == 0){
860 if(!searchDlg->get_direction()){ // forward search 863 if(!searchDlg->get_direction()){ // forward search
861 int query = QMessageBox::information( searchDlg, "Find", 864 int query = QMessageBox::information( searchDlg, "Find",
862 "End of document reached.\nContinue from the beginning?", 865 "End of document reached.\nContinue from the beginning?",
863 "Yes", "No", "", 0,1); 866 "Yes", "No", "", 0,1);
864 if (query == 0){ 867 if (query == 0){
865 line = 0; 868 line = 0;
866 col = 0; 869 col = 0;
867 goto again; 870 goto again;
868 } 871 }
869 } else { //backward search 872 } else { //backward search
870 int query = QMessageBox::information( searchDlg, "Find", 873 int query = QMessageBox::information( searchDlg, "Find",
871 "End of document reached.\nContinue from the beginning?", 874 "End of document reached.\nContinue from the beginning?",
872 "Yes", "No", "", 0,1); 875 "Yes", "No", "", 0,1);
873 if (query == 0){ 876 if (query == 0){
874 QString string = Lview->textLine( Lview->numLines() - 1 ); 877 QString string = Lview->textLine( Lview->numLines() - 1 );
875 line = Lview->numLines() - 1; 878 line = Lview->numLines() - 1;
876 lineCheck = line; 879 lineCheck = line;
877 col = string.length(); 880 col = string.length();
878 last_search = -1; //BACKWARD; 881 last_search = -1; //BACKWARD;
879 goto again; 882 goto again;
880 } 883 }
881 } 884 }
882 } else { 885 } else {
883 886
884 //// emit CursorPositionChanged(); textLine 887 //// emit CursorPositionChanged(); textLine
885 } 888 }
886} 889}
887 890
888int Gutenbrowser::doSearch( const QString &s_pattern , bool case_sensitive, bool forward, int line, int col ) { 891int Gutenbrowser::doSearch( const QString &s_pattern , bool case_sensitive, bool forward, int line, int col ) {
889 int i, length; 892 int i, length;
890 int pos = -1; 893 int pos = -1;
891 if(forward) { 894 if(forward) {
892 QString string; 895 QString string;
893 for(i = line; i < Lview->numLines(); i++) { 896 for(i = line; i < Lview->numLines(); i++) {
894 897
895 string = Lview->textLine(i); 898 string = Lview->textLine(i);
896 pos = string.find(s_pattern, i == line ? col : 0, case_sensitive); 899 pos = string.find(s_pattern, i == line ? col : 0, case_sensitive);
897 if( pos != -1) { 900 if( pos != -1) {
898 int top = Lview->Top(); 901 int top = Lview->Top();
899 length = s_pattern.length(); 902 length = s_pattern.length();
diff --git a/noncore/apps/opie-reader/BuffDoc.h b/noncore/apps/opie-reader/BuffDoc.h
index 29d0329..61531c0 100644
--- a/noncore/apps/opie-reader/BuffDoc.h
+++ b/noncore/apps/opie-reader/BuffDoc.h
@@ -1,122 +1,122 @@
1#ifndef __BuffDoc_h 1#ifndef __BuffDoc_h
2#define __BuffDoc_h 2#define __BuffDoc_h
3 3
4#include "useqpe.h" 4#include "useqpe.h"
5#include "ZText.h" 5#include "ZText.h"
6#include "Aportis.h" 6#include "Aportis.h"
7#include "ztxt.h" 7#include "ztxt.h"
8#include "ppm_expander.h" 8#include "ppm_expander.h"
9#include "CDrawBuffer.h" 9#include "CDrawBuffer.h"
10#include "CFilter.h" 10#include "CFilter.h"
11#include <qfontmetrics.h> 11#include <qfontmetrics.h>
12#include <qmessagebox.h> 12#include <qmessagebox.h>
13 13
14class BuffDoc 14class BuffDoc
15{ 15{
16 CDrawBuffer lastword; 16 CDrawBuffer lastword;
17 CSizeBuffer lastsizes, allsizes; 17 CSizeBuffer lastsizes, allsizes;
18 size_t laststartline; 18 size_t laststartline;
19 bool lastispara; 19 bool lastispara;
20 CExpander* exp; 20 CExpander* exp;
21 CFilterChain* filt; 21 CFilterChain* filt;
22 public: 22 public:
23 void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen) 23 void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen)
24 { 24 {
25 if (exp == NULL) 25 if (exp == NULL)
26 { 26 {
27 data = NULL; 27 data = NULL;
28 len = 0; 28 len = 0;
29 } 29 }
30 else 30 else
31 { 31 {
32 exp->setSaveData(data, len, src, srclen); 32 exp->setSaveData(data, len, src, srclen);
33 } 33 }
34 } 34 }
35 void putSaveData(unsigned char*& src, unsigned short& srclen) 35 void putSaveData(unsigned char*& src, unsigned short& srclen)
36 { 36 {
37 if (exp != NULL) 37 if (exp != NULL)
38 { 38 {
39 exp->putSaveData(src, srclen); 39 exp->putSaveData(src, srclen);
40 } 40 }
41 } 41 }
42#ifdef USEQPE 42#ifdef USEQPE
43 void suspend() { if (exp != NULL) exp->suspend(); } 43 void suspend() { if (exp != NULL) exp->suspend(); }
44 void unsuspend() { if (exp != NULL) exp->unsuspend(); } 44 void unsuspend() { if (exp != NULL) exp->unsuspend(); }
45#else 45#else
46 void suspend() {} 46 void suspend() {}
47 void unsuspend() {} 47 void unsuspend() {}
48#endif 48#endif
49 ~BuffDoc() 49 ~BuffDoc()
50 { 50 {
51 delete filt; 51 delete filt;
52 delete exp; 52 delete exp;
53 } 53 }
54 BuffDoc() 54 BuffDoc()
55 { 55 {
56 exp = NULL; 56 exp = NULL;
57 filt = NULL; 57 filt = NULL;
58 lastword.empty(); 58 lastword.empty();
59 // // qDebug("Buffdoc created"); 59 // odebug << "Buffdoc created" << oendl;
60 } 60 }
61 bool empty() { return (exp == NULL); } 61 bool empty() { return (exp == NULL); }
62 void setfilter(CFilterChain* _f) 62 void setfilter(CFilterChain* _f)
63 { 63 {
64 if (filt != NULL) delete filt; 64 if (filt != NULL) delete filt;
65 filt = _f; 65 filt = _f;
66 filt->setsource(exp); 66 filt->setsource(exp);
67 } 67 }
68 CList<Bkmk>* getbkmklist() { return exp->getbkmklist(); } 68 CList<Bkmk>* getbkmklist() { return exp->getbkmklist(); }
69 bool hasrandomaccess() { return (exp == NULL) ? false : exp->hasrandomaccess(); } 69 bool hasrandomaccess() { return (exp == NULL) ? false : exp->hasrandomaccess(); }
70 bool iseol() { return (lastword[0] == '\0'); } 70 bool iseol() { return (lastword[0] == '\0'); }
71 int openfile(QWidget* _parent, const char *src); 71 int openfile(QWidget* _parent, const char *src);
72 tchar getch() 72 tchar getch()
73 { 73 {
74 tchar ch = UEOF; 74 tchar ch = UEOF;
75 CStyle sty; 75 CStyle sty;
76 if (exp != NULL) 76 if (exp != NULL)
77 { 77 {
78 filt->getch(ch, sty); 78 filt->getch(ch, sty);
79 } 79 }
80 return ch; 80 return ch;
81 } 81 }
82 void getch(tchar& ch, CStyle& sty) 82 void getch(tchar& ch, CStyle& sty)
83 { 83 {
84 if (exp != NULL) 84 if (exp != NULL)
85 { 85 {
86 filt->getch(ch, sty); 86 filt->getch(ch, sty);
87 } 87 }
88 else 88 else
89 ch = UEOF; 89 ch = UEOF;
90 } 90 }
91 void setwidth(int w) { if (exp != NULL) exp->setwidth(w); } 91 void setwidth(int w) { if (exp != NULL) exp->setwidth(w); }
92 QImage* getPicture(unsigned long tgt) { return (exp == NULL) ? NULL : exp->getPicture(tgt); } 92 QImage* getPicture(unsigned long tgt) { return (exp == NULL) ? NULL : exp->getPicture(tgt); }
93 unsigned int startSection() { return (exp == NULL) ? 0 : exp->startSection(); } 93 unsigned int startSection() { return (exp == NULL) ? 0 : exp->startSection(); }
94 unsigned int endSection() { return (exp == NULL) ? 0 : exp->endSection(); } 94 unsigned int endSection() { return (exp == NULL) ? 0 : exp->endSection(); }
95 unsigned int locate() { return (exp == NULL) ? 0 : laststartline; } 95 unsigned int locate() { return (exp == NULL) ? 0 : laststartline; }
96 unsigned int explocate() { return (exp == NULL) ? 0 : exp->locate(); } 96 unsigned int explocate() { return (exp == NULL) ? 0 : exp->locate(); }
97 void setContinuous(bool _b) { if (exp != NULL) exp->setContinuous(_b); } 97 void setContinuous(bool _b) { if (exp != NULL) exp->setContinuous(_b); }
98 MarkupType PreferredMarkup() { return (exp == NULL) ? cTEXT : exp->PreferredMarkup(); } 98 MarkupType PreferredMarkup() { return (exp == NULL) ? cTEXT : exp->PreferredMarkup(); }
99 linkType hyperlink(unsigned int n, QString& wrd); 99 linkType hyperlink(unsigned int n, QString& wrd);
100 size_t getHome() { return ((exp != NULL) ? exp->getHome() : 0); } 100 size_t getHome() { return ((exp != NULL) ? exp->getHome() : 0); }
101 void locate(unsigned int n); 101 void locate(unsigned int n);
102 bool getline(CDrawBuffer* buff, int w, unsigned char _border); 102 bool getline(CDrawBuffer* buff, int w, unsigned char _border);
103 bool getline(CDrawBuffer* buff, int w, int cw, unsigned char _border); 103 bool getline(CDrawBuffer* buff, int w, int cw, unsigned char _border);
104 void sizes(unsigned long& fs, unsigned long& ts) { exp->sizes(fs,ts); } 104 void sizes(unsigned long& fs, unsigned long& ts) { exp->sizes(fs,ts); }
105 int getpara(CBuffer& buff) 105 int getpara(CBuffer& buff)
106 { 106 {
107 tchar ch; 107 tchar ch;
108 int i = 0; 108 int i = 0;
109 while ((ch = getch()) != 10 && ch != UEOF) buff[i++] = ch; 109 while ((ch = getch()) != 10 && ch != UEOF) buff[i++] = ch;
110 buff[i] = '\0'; 110 buff[i] = '\0';
111 if (i == 0 && ch == UEOF) i = -1; 111 if (i == 0 && ch == UEOF) i = -1;
112 laststartline = exp->locate(); 112 laststartline = exp->locate();
113 return i; 113 return i;
114 } 114 }
115 void saveposn(size_t posn) { exp->saveposn(posn); } 115 void saveposn(size_t posn) { exp->saveposn(posn); }
116 void writeposn(size_t posn) { exp->writeposn(posn); } 116 void writeposn(size_t posn) { exp->writeposn(posn); }
117 bool forward(size_t& loc) { return exp->forward(loc); } 117 bool forward(size_t& loc) { return exp->forward(loc); }
118 bool back(size_t& loc) { return exp->back(loc); } 118 bool back(size_t& loc) { return exp->back(loc); }
119 bool hasnavigation() { return exp->hasnavigation(); } 119 bool hasnavigation() { return exp->hasnavigation(); }
120}; 120};
121 121
122#endif 122#endif
diff --git a/noncore/apps/opie-reader/CEncoding.h b/noncore/apps/opie-reader/CEncoding.h
index 463fba9..df0104a 100644
--- a/noncore/apps/opie-reader/CEncoding.h
+++ b/noncore/apps/opie-reader/CEncoding.h
@@ -1,74 +1,74 @@
1#ifndef __CENCODING_H 1#ifndef __CENCODING_H
2#define __CENCODING_H 2#define __CENCODING_H
3 3
4#include "CExpander.h" 4#include "CExpander.h"
5 5
6#define MAX_ENCODING 6 6#define MAX_ENCODING 6
7 7
8class CEncoding : public CCharacterSource 8class CEncoding : public CCharacterSource
9{ 9{
10 friend class CFilterChain; 10 friend class CFilterChain;
11 protected: 11 protected:
12 CExpander* parent; 12 CExpander* parent;
13 linkType hyperlink(unsigned int n, QString& t) { return parent->hyperlink(n,t); } 13 linkType hyperlink(unsigned int n, QString& t) { return parent->hyperlink(n,t); }
14public: 14public:
15 CEncoding() : parent(NULL) {} 15 CEncoding() : parent(NULL) {}
16 void setparent(CExpander* p) { parent = p; } 16 void setparent(CExpander* p) { parent = p; }
17 virtual ~CEncoding() {}; 17 virtual ~CEncoding() {};
18}; 18};
19 19
20class CUtf8 : public CEncoding 20class CUtf8 : public CEncoding
21{ 21{
22public: 22public:
23 void getch(tchar& ch, CStyle& sty); 23 void getch(tchar& ch, CStyle& sty);
24}; 24};
25 25
26class CUcs16be : public CEncoding 26class CUcs16be : public CEncoding
27{ 27{
28public: 28public:
29 void getch(tchar& ch, CStyle& sty); 29 void getch(tchar& ch, CStyle& sty);
30}; 30};
31 31
32class CUcs16le : public CEncoding 32class CUcs16le : public CEncoding
33{ 33{
34public: 34public:
35 void getch(tchar& ch, CStyle& sty); 35 void getch(tchar& ch, CStyle& sty);
36}; 36};
37 37
38class Ccp1252 : public CEncoding 38class Ccp1252 : public CEncoding
39{ 39{
40public: 40public:
41 void getch(tchar& ch, CStyle& sty); 41 void getch(tchar& ch, CStyle& sty);
42}; 42};
43 43
44class CPalm : public Ccp1252 44class CPalm : public Ccp1252
45{ 45{
46public: 46public:
47 void getch(tchar& ch, CStyle& sty); 47 void getch(tchar& ch, CStyle& sty);
48}; 48};
49 49
50class CAscii : public CEncoding 50class CAscii : public CEncoding
51{ 51{
52public: 52public:
53 void getch(tchar& ch, CStyle& sty); 53 void getch(tchar& ch, CStyle& sty);
54}; 54};
55 55
56#include "CEncoding_tables.h" 56#include "CEncoding_tables.h"
57 57
58class CGeneral8Bit : public CEncoding 58class CGeneral8Bit : public CEncoding
59{ 59{
60 int m_index; 60 int m_index;
61 public: 61 public:
62 CGeneral8Bit(int _i) : m_index(_i) 62 CGeneral8Bit(int _i) : m_index(_i)
63 { 63 {
64 // qDebug("8Bit:%d", _i); 64// odebug << "8Bit: " << _i << oendl;
65 // qDebug("%s", unicodetable::iterator(_i)->mime); 65// odebug << unicodetable::iterator(_i)->mime << oendl;
66 } 66 }
67 void getch(tchar& ch, CStyle& sty) 67 void getch(tchar& ch, CStyle& sty)
68 { 68 {
69 parent->getch(ch, sty); 69 parent->getch(ch, sty);
70 ch = unicodetable::unicodevalue(m_index, ch); 70 ch = unicodetable::unicodevalue(m_index, ch);
71 } 71 }
72}; 72};
73 73
74#endif 74#endif
diff --git a/noncore/apps/opie-reader/CExpander.h b/noncore/apps/opie-reader/CExpander.h
index 7b21d3e..9fae245 100644
--- a/noncore/apps/opie-reader/CExpander.h
+++ b/noncore/apps/opie-reader/CExpander.h
@@ -1,151 +1,151 @@
1#ifndef __CExpander_h 1#ifndef __CExpander_h
2#define __CExpander_h 2#define __CExpander_h
3 3
4#ifndef _WINDOWS 4#ifndef _WINDOWS
5#include <unistd.h> 5#include <unistd.h>
6#endif 6#endif
7#include <stdio.h> 7#include <stdio.h>
8#include <time.h> 8#include <time.h>
9#include <qmessagebox.h> 9#include <qmessagebox.h>
10#include "useqpe.h" 10#include "useqpe.h"
11#include "config.h" 11#include "config.h"
12#include "StyleConsts.h" 12#include "StyleConsts.h"
13#include "Markups.h" 13#include "Markups.h"
14#include "names.h" 14#include "names.h"
15#include "linktype.h" 15#include "linktype.h"
16 16
17class QImage; 17class QImage;
18class Bkmk; 18class Bkmk;
19 19
20template<class T> 20template<class T>
21class CList; 21class CList;
22 22
23class CCharacterSource 23class CCharacterSource
24{ 24{
25 public: 25 public:
26 virtual void getch(tchar&, CStyle&) = 0; 26 virtual void getch(tchar&, CStyle&) = 0;
27 virtual linkType hyperlink(unsigned int n, QString&) = 0; 27 virtual linkType hyperlink(unsigned int n, QString&) = 0;
28}; 28};
29 29
30class CExpander 30class CExpander
31{ 31{
32 protected: 32 protected:
33 size_t m_homepos; 33 size_t m_homepos;
34 bool m_continuous; 34 bool m_continuous;
35 char* fname; 35 char* fname;
36 bool bSuspended; 36 bool bSuspended;
37 size_t suspos; 37 size_t suspos;
38 time_t sustime; 38 time_t sustime;
39 int m_scrWidth; 39 int m_scrWidth;
40 unsigned long m_currentstart, m_currentend; 40 unsigned long m_currentstart, m_currentend;
41 public: 41 public:
42#ifdef USEQPE 42#ifdef USEQPE
43 virtual void suspend() = 0; 43 virtual void suspend() = 0;
44 virtual void unsuspend() = 0; 44 virtual void unsuspend() = 0;
45#endif 45#endif
46 size_t getHome() { return m_homepos; } 46 size_t getHome() { return m_homepos; }
47 CExpander() : m_homepos(0), fname(NULL), m_scrWidth(240), m_currentstart(1), m_currentend(0) {}; 47 CExpander() : m_homepos(0), fname(NULL), m_scrWidth(240), m_currentstart(1), m_currentend(0) {};
48 virtual ~CExpander() { if (fname != NULL) delete [] fname; }; 48 virtual ~CExpander() { if (fname != NULL) delete [] fname; };
49 int openfile(const char *src) 49 int openfile(const char *src)
50 { 50 {
51 bSuspended = false; 51 bSuspended = false;
52 fname = strdup(src); 52 fname = strdup(src);
53 return OpenFile(src); 53 return OpenFile(src);
54 } 54 }
55 virtual int OpenFile(const char *src) = 0; 55 virtual int OpenFile(const char *src) = 0;
56 virtual unsigned int locate() = 0; 56 virtual unsigned int locate() = 0;
57 virtual void locate(unsigned int n) = 0; 57 virtual void locate(unsigned int n) = 0;
58 virtual bool hasrandomaccess() = 0; 58 virtual bool hasrandomaccess() = 0;
59 virtual void sizes(unsigned long& file, unsigned long& text) = 0; 59 virtual void sizes(unsigned long& file, unsigned long& text) = 0;
60 virtual CList<Bkmk>* getbkmklist() { return NULL; } 60 virtual CList<Bkmk>* getbkmklist() { return NULL; }
61 virtual void getch(tchar& ch, CStyle& sty) 61 virtual void getch(tchar& ch, CStyle& sty)
62 { 62 {
63 int ich = getch(); 63 int ich = getch();
64 ch = (ich == EOF) ? UEOF : ich; 64 ch = (ich == EOF) ? UEOF : ich;
65 sty.unset(); 65 sty.unset();
66 } 66 }
67 virtual int getch() = 0; 67 virtual int getch() = 0;
68 virtual linkType hyperlink(unsigned int n, QString& wrd) 68 virtual linkType hyperlink(unsigned int n, QString& wrd)
69 { 69 {
70 locate(n); 70 locate(n);
71 return eLink; 71 return eLink;
72 } 72 }
73 virtual MarkupType PreferredMarkup() = 0; 73 virtual MarkupType PreferredMarkup() = 0;
74 virtual void saveposn(size_t posn) {} 74 virtual void saveposn(size_t posn) {}
75 virtual void writeposn(size_t posn) {} 75 virtual void writeposn(size_t posn) {}
76 virtual bool forward(size_t& loc) { return false; } 76 virtual bool forward(size_t& loc) { return false; }
77 virtual bool back(size_t& loc) { return false; } 77 virtual bool back(size_t& loc) { return false; }
78 virtual bool hasnavigation() { return false; } 78 virtual bool hasnavigation() { return false; }
79 unsigned long startSection() 79 unsigned long startSection()
80 { 80 {
81 unsigned long current = locate(); 81 unsigned long current = locate();
82 if (m_currentstart > current || current > m_currentend) 82 if (m_currentstart > current || current > m_currentend)
83 { 83 {
84 start2endSection(); 84 start2endSection();
85 } 85 }
86 return m_currentstart; 86 return m_currentstart;
87 } 87 }
88 unsigned long endSection() 88 unsigned long endSection()
89 { 89 {
90 unsigned long current = locate(); 90 unsigned long current = locate();
91 if (m_currentstart > current || current > m_currentend) 91 if (m_currentstart > current || current > m_currentend)
92 { 92 {
93 start2endSection(); 93 start2endSection();
94 } 94 }
95 return m_currentend; 95 return m_currentend;
96 } 96 }
97 virtual void start2endSection() 97 virtual void start2endSection()
98 { 98 {
99 m_currentstart = 0; 99 m_currentstart = 0;
100 unsigned long file; 100 unsigned long file;
101 sizes(file, m_currentend); 101 sizes(file, m_currentend);
102 } 102 }
103 virtual QImage* getPicture(unsigned long tgt) { return NULL; } 103 virtual QImage* getPicture(unsigned long tgt) { return NULL; }
104 void setContinuous(bool _b) { m_continuous = _b; } 104 void setContinuous(bool _b) { m_continuous = _b; }
105#ifdef USEQPE 105#ifdef USEQPE
106 virtual void suspend(FILE*& fin) 106 virtual void suspend(FILE*& fin)
107 { 107 {
108 bSuspended = true; 108 bSuspended = true;
109 suspos = ftell(fin); 109 suspos = ftell(fin);
110 fclose(fin); 110 fclose(fin);
111 fin = NULL; 111 fin = NULL;
112 sustime = time(NULL); 112 sustime = time(NULL);
113 } 113 }
114 virtual void unsuspend(FILE*& fin) 114 virtual void unsuspend(FILE*& fin)
115 { 115 {
116 if (bSuspended) 116 if (bSuspended)
117 { 117 {
118 bSuspended = false; 118 bSuspended = false;
119 int delay = time(NULL) - sustime; 119 int delay = time(NULL) - sustime;
120 if (delay < 10) sleep(10-delay); 120 if (delay < 10) sleep(10-delay);
121 fin = fopen(fname, "rb"); 121 fin = fopen(fname, "rb");
122 for (int i = 0; fin == NULL && i < 5; i++) 122 for (int i = 0; fin == NULL && i < 5; i++)
123 { 123 {
124 sleep(5); 124 sleep(5);
125 fin = fopen(fname, "rb"); 125 fin = fopen(fname, "rb");
126 } 126 }
127 if (fin == NULL) 127 if (fin == NULL)
128 { 128 {
129 QMessageBox::warning(NULL, PROGNAME, "Couldn't reopen file"); 129 QMessageBox::warning(NULL, PROGNAME, "Couldn't reopen file");
130 exit(0); 130 exit(0);
131 } 131 }
132 suspos = fseek(fin, suspos, SEEK_SET); 132 suspos = fseek(fin, suspos, SEEK_SET);
133 } 133 }
134 } 134 }
135#endif 135#endif
136 virtual void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen) 136 virtual void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen)
137 { 137 {
138 len = srclen; 138 len = srclen;
139 data = new unsigned char[len]; 139 data = new unsigned char[len];
140 memcpy(data, src, len); 140 memcpy(data, src, len);
141 } 141 }
142 virtual void putSaveData(unsigned char*& src, unsigned short& srclen) 142 virtual void putSaveData(unsigned char*& src, unsigned short& srclen)
143 { 143 {
144 if (srclen != 0) 144 if (srclen != 0)
145 { 145 {
146 qDebug("Don't know what to do with non-zero save data"); 146 qDebug("Don't know what to do with non-zero save data");
147 } 147 }
148 } 148 }
149 void setwidth(int w) { m_scrWidth = w; } 149 void setwidth(int w) { m_scrWidth = w; }
150}; 150};
151#endif 151#endif
diff --git a/noncore/apps/opie-reader/Filedata.h b/noncore/apps/opie-reader/Filedata.h
index 096dd31..1b85b71 100644
--- a/noncore/apps/opie-reader/Filedata.h
+++ b/noncore/apps/opie-reader/Filedata.h
@@ -1,51 +1,51 @@
1#ifndef __FILEDATA_H 1#ifndef __FILEDATA_H
2#define __FILEDATA_H 2#define __FILEDATA_H
3 3
4#include <time.h> 4#include <time.h>
5 5
6class CFiledata 6class CFiledata
7{ 7{
8 unsigned char* data; 8 unsigned char* data;
9 bool m_own; 9 bool m_own;
10 public: 10 public:
11 CFiledata(tchar* d) 11 CFiledata(tchar* d)
12 { 12 {
13 data = (unsigned char*)d; 13 data = (unsigned char*)d;
14 m_own = false; 14 m_own = false;
15 } 15 }
16 CFiledata(time_t dt, tchar* nm) 16 CFiledata(time_t dt, tchar* nm)
17 { 17 {
18 int nlen = ustrlen(nm)+1; 18 int nlen = ustrlen(nm)+1;
19 data = new unsigned char[sizeof(time_t)+sizeof(tchar)*nlen]; 19 data = new unsigned char[sizeof(time_t)+sizeof(tchar)*nlen];
20 *((time_t *)data) = dt; 20 *((time_t *)data) = dt;
21 memcpy(data+sizeof(time_t), nm, sizeof(tchar)*nlen); 21 memcpy(data+sizeof(time_t), nm, sizeof(tchar)*nlen);
22 m_own = true; 22 m_own = true;
23 } 23 }
24 ~CFiledata() 24 ~CFiledata()
25 { 25 {
26 if (m_own && data != NULL) 26 if (m_own && data != NULL)
27 { 27 {
28 delete [] data; 28 delete [] data;
29 // qDebug("~Filedata: deleting"); 29// odebug << "~Filedata: deleting" << oendl;
30 } 30 }
31 else 31 else
32 { 32 {
33 // qDebug("~Filedata: not deleting"); 33// odebug << "~Filedata: not deleting" << oendl;
34 } 34 }
35 } 35 }
36 tchar* name() const { return (tchar*)(data+sizeof(time_t)); } 36 tchar* name() const { return (tchar*)(data+sizeof(time_t)); }
37 time_t date() { return *((time_t *)data); } 37 time_t date() { return *((time_t *)data); }
38 void setdate(time_t _t) { *((time_t *)data) = _t; } 38 void setdate(time_t _t) { *((time_t *)data) = _t; }
39 unsigned char* content() { return data; } 39 unsigned char* content() { return data; }
40 size_t length() const { return sizeof(time_t)+sizeof(tchar)*(ustrlen(name())+1); } 40 size_t length() const { return sizeof(time_t)+sizeof(tchar)*(ustrlen(name())+1); }
41 bool operator==(const CFiledata& rhs) 41 bool operator==(const CFiledata& rhs)
42 { 42 {
43 return ((length() == rhs.length()) && (memcmp(data, rhs.data, length()) == 0)); 43 return ((length() == rhs.length()) && (memcmp(data, rhs.data, length()) == 0));
44 } 44 }
45 bool samename(const CFiledata& rhs) 45 bool samename(const CFiledata& rhs)
46 { 46 {
47 return (ustrcmp((tchar *)(data+sizeof(time_t)),(tchar *)(rhs.data+sizeof(time_t))) == 0); 47 return (ustrcmp((tchar *)(data+sizeof(time_t)),(tchar *)(rhs.data+sizeof(time_t))) == 0);
48 } 48 }
49}; 49};
50 50
51#endif 51#endif
diff --git a/noncore/apps/opie-reader/FontControl.h b/noncore/apps/opie-reader/FontControl.h
index 5681496..e56b619 100644
--- a/noncore/apps/opie-reader/FontControl.h
+++ b/noncore/apps/opie-reader/FontControl.h
@@ -1,153 +1,153 @@
1#ifndef __FONTCONTROL_H 1#ifndef __FONTCONTROL_H
2#define __FONTCONTROL_H 2#define __FONTCONTROL_H
3 3
4#include <qfontdatabase.h> 4#include <qfontdatabase.h>
5#include <qfontmetrics.h> 5#include <qfontmetrics.h>
6#include "StyleConsts.h" 6#include "StyleConsts.h"
7 7
8class FontControl 8class FontControl
9{ 9{
10 int * m_fontsizes; 10 int * m_fontsizes;
11 int m_size, g_size; 11 int m_size, g_size;
12 QString m_fontname; 12 QString m_fontname;
13 QString m_fixedfontname; 13 QString m_fixedfontname;
14 int m_maxsize; 14 int m_maxsize;
15 bool m_hasCourier; 15 bool m_hasCourier;
16 int m_leading, m_extraspace; 16 int m_leading, m_extraspace;
17 unsigned char m_basesize; 17 unsigned char m_basesize;
18 public: 18 public:
19 void setBaseSize(unsigned char _s) { m_basesize = _s; } 19 void setBaseSize(unsigned char _s) { m_basesize = _s; }
20 unsigned char getBaseSize() { return m_basesize; } 20 unsigned char getBaseSize() { return m_basesize; }
21 int gzoom(); 21 int gzoom();
22 FontControl(QString n = "helvetica", int size = 10) 22 FontControl(QString n = "helvetica", int size = 10)
23 : 23 :
24 m_fontsizes(NULL), m_hasCourier(false), m_leading(0), m_extraspace(0) 24 m_fontsizes(NULL), m_hasCourier(false), m_leading(0), m_extraspace(0)
25 { 25 {
26 ChangeFont(n, size); 26 ChangeFont(n, size);
27 } 27 }
28 ~FontControl() 28 ~FontControl()
29 { 29 {
30 if (m_fontsizes != NULL) delete [] m_fontsizes; 30 if (m_fontsizes != NULL) delete [] m_fontsizes;
31 } 31 }
32 void hasCourier(bool _b, const QString& _nm) 32 void hasCourier(bool _b, const QString& _nm)
33 { 33 {
34 m_hasCourier = _b; 34 m_hasCourier = _b;
35 m_fixedfontname = _nm; 35 m_fixedfontname = _nm;
36 } 36 }
37 QString& fixedfontname() { return m_fixedfontname; } 37 QString& fixedfontname() { return m_fixedfontname; }
38 bool hasCourier() { return m_hasCourier; } 38 bool hasCourier() { return m_hasCourier; }
39 QString name() { return m_fontname; } 39 QString name() { return m_fontname; }
40 int currentsize() { return m_fontsizes[m_size]; } 40 int currentsize() { return m_fontsizes[m_size]; }
41 int getsize(const CStyle& size) 41 int getsize(const CStyle& size)
42 { 42 {
43 int tgt = m_size+size.getFontSize(); 43 int tgt = m_size+size.getFontSize();
44 if (tgt < 0) 44 if (tgt < 0)
45 { 45 {
46 tgt = 0; 46 tgt = 0;
47 } 47 }
48 if (tgt >= m_maxsize) 48 if (tgt >= m_maxsize)
49 { 49 {
50 tgt = m_maxsize - 1; 50 tgt = m_maxsize - 1;
51 } 51 }
52 return m_fontsizes[tgt]; 52 return m_fontsizes[tgt];
53 } 53 }
54 int ascent() 54 int ascent()
55 { 55 {
56 QFont f(name(), currentsize()); 56 QFont f(name(), currentsize());
57 QFontMetrics fm(f); 57 QFontMetrics fm(f);
58 return fm.ascent(); 58 return fm.ascent();
59 } 59 }
60 int ascent(const CStyle& ch) 60 int ascent(const CStyle& ch)
61 { 61 {
62 QFont f(name(), getsize(ch)); 62 QFont f(name(), getsize(ch));
63 QFontMetrics fm(f); 63 QFontMetrics fm(f);
64 return fm.ascent(); 64 return fm.ascent();
65 } 65 }
66 int descent() 66 int descent()
67 { 67 {
68 QFont f(name(), currentsize()); 68 QFont f(name(), currentsize());
69 QFontMetrics fm(f); 69 QFontMetrics fm(f);
70 return fm.descent(); 70 return fm.descent();
71 } 71 }
72 int descent(const CStyle& ch) 72 int descent(const CStyle& ch)
73 { 73 {
74 QFont f(name(), getsize(ch)); 74 QFont f(name(), getsize(ch));
75 QFontMetrics fm(f); 75 QFontMetrics fm(f);
76 return fm.descent(); 76 return fm.descent();
77 } 77 }
78 int lineSpacing() 78 int lineSpacing()
79 { 79 {
80 QFont f(name(), currentsize()); 80 QFont f(name(), currentsize());
81 QFontMetrics fm(f); 81 QFontMetrics fm(f);
82 return fm.lineSpacing(); 82 return fm.lineSpacing();
83 } 83 }
84 int lineSpacing(const CStyle& ch) 84 int lineSpacing(const CStyle& ch)
85 { 85 {
86 QFont f(name(), getsize(ch)); 86 QFont f(name(), getsize(ch));
87 QFontMetrics fm(f); 87 QFontMetrics fm(f);
88 return fm.lineSpacing(); 88 return fm.lineSpacing();
89 } 89 }
90 bool decreasesize() 90 bool decreasesize()
91 { 91 {
92/* 92/*
93 if (--m_size < 0) 93 if (--m_size < 0)
94 { 94 {
95 m_size = 0; 95 m_size = 0;
96 return false; 96 return false;
97 } 97 }
98 else return true; 98 else return true;
99*/ 99*/
100 if (g_size-- == m_size) 100 if (g_size-- == m_size)
101 { 101 {
102 if (--m_size < 0) 102 if (--m_size < 0)
103 { 103 {
104 m_size = 0; 104 m_size = 0;
105 } 105 }
106 } 106 }
107 // qDebug("Font:%d Graphics:%d", m_size, g_size); 107// odebug << "Font:" << m_size << " Graphics:" << g_size << oendl;
108 return true; 108 return true;
109 } 109 }
110 bool increasesize() 110 bool increasesize()
111 { 111 {
112/* 112/*
113 if (++m_size >= m_maxsize) 113 if (++m_size >= m_maxsize)
114 { 114 {
115 m_size = m_maxsize - 1; 115 m_size = m_maxsize - 1;
116 return false; 116 return false;
117 } 117 }
118 else return true; 118 else return true;
119*/ 119*/
120 if (g_size++ == m_size) 120 if (g_size++ == m_size)
121 { 121 {
122 if (++m_size >= m_maxsize) 122 if (++m_size >= m_maxsize)
123 { 123 {
124 m_size = m_maxsize - 1; 124 m_size = m_maxsize - 1;
125 } 125 }
126 } 126 }
127 // qDebug("Font:%d Graphics:%d", m_size, g_size); 127// odebug << "Font:" << m_size << " Graphics:" << g_size << oendl;
128 return true; 128 return true;
129 } 129 }
130 bool ChangeFont(QString& n) 130 bool ChangeFont(QString& n)
131 { 131 {
132 return ChangeFont(n, currentsize()); 132 return ChangeFont(n, currentsize());
133 } 133 }
134 bool ChangeFont(QString& n, int tgt); 134 bool ChangeFont(QString& n, int tgt);
135 void setlead(int _lead) 135 void setlead(int _lead)
136 { 136 {
137 m_leading = _lead; 137 m_leading = _lead;
138 } 138 }
139 int getlead() 139 int getlead()
140 { 140 {
141 return m_leading; 141 return m_leading;
142 } 142 }
143 void setextraspace(int _lead) 143 void setextraspace(int _lead)
144 { 144 {
145 m_extraspace = _lead; 145 m_extraspace = _lead;
146 } 146 }
147 int getextraspace() 147 int getextraspace()
148 { 148 {
149 return m_extraspace; 149 return m_extraspace;
150 } 150 }
151}; 151};
152 152
153#endif 153#endif
diff --git a/noncore/apps/opie-reader/Palm2QImage.cpp b/noncore/apps/opie-reader/Palm2QImage.cpp
index 9339595..b0d4e00 100644
--- a/noncore/apps/opie-reader/Palm2QImage.cpp
+++ b/noncore/apps/opie-reader/Palm2QImage.cpp
@@ -1,308 +1,319 @@
1/* -*- mode: c; indent-tabs-mode: nil; -*- */ 1/* -*- mode: c; indent-tabs-mode: nil; -*- */
2
3/* OPIE */
4#include <opie2/odebug.h>
5
6/* QT */
7#include <qimage.h>
8
9/* STD */
2#include <stdio.h> 10#include <stdio.h>
3#include <stdlib.h> 11#include <stdlib.h>
4#include <string.h> 12#include <string.h>
5#ifndef _WINDOWS 13#ifndef _WINDOWS
6#include <unistd.h> /* for link */ 14#include <unistd.h> /* for link */
7#endif 15#endif
8#include <sys/types.h> 16#include <sys/types.h>
9#include <sys/stat.h> 17#include <sys/stat.h>
10#include <stdarg.h> 18#include <stdarg.h>
11 19
12#include <qimage.h>
13 20
14/***********************************************************************/ 21/***********************************************************************/
15/***********************************************************************/ 22/***********************************************************************/
16/***** *****/ 23/***** *****/
17/***** Code to decode the Palm image format to JPEG *****/ 24/***** Code to decode the Palm image format to JPEG *****/
18/***** *****/ 25/***** *****/
19/***********************************************************************/ 26/***********************************************************************/
20/***********************************************************************/ 27/***********************************************************************/
21 28
22#define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8)|((p)[1])) 29#define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8)|((p)[1]))
23#define READ_BIGENDIAN_LONG(p) (((p)[0] << 24)|((p)[1] << 16)|((p)[2] << 8)|((p)[3])) 30#define READ_BIGENDIAN_LONG(p) (((p)[0] << 24)|((p)[1] << 16)|((p)[2] << 8)|((p)[3]))
24 31
25#define PALM_IS_COMPRESSED_FLAG 0x8000 32#define PALM_IS_COMPRESSED_FLAG 0x8000
26#define PALM_HAS_COLORMAP_FLAG 0x4000 33#define PALM_HAS_COLORMAP_FLAG 0x4000
27#define PALM_HAS_TRANSPARENCY_FLAG 0x2000 34#define PALM_HAS_TRANSPARENCY_FLAG 0x2000
28#define PALM_DIRECT_COLOR_FLAG 0x0400 35#define PALM_DIRECT_COLOR_FLAG 0x0400
29#define PALM_4_BYTE_FIELD_FLAG 0x0200 36#define PALM_4_BYTE_FIELD_FLAG 0x0200
30 37
31#define PALM_COMPRESSION_SCANLINE 0x00 38#define PALM_COMPRESSION_SCANLINE 0x00
32#define PALM_COMPRESSION_RLE 0x01 39#define PALM_COMPRESSION_RLE 0x01
33#define PALM_COMPRESSION_PACKBITS 0x02 40#define PALM_COMPRESSION_PACKBITS 0x02
34#define PALM_COMPRESSION_NONE 0xFF 41#define PALM_COMPRESSION_NONE 0xFF
35 42
36#define PALM_COLORMAP_SIZE 232 43#define PALM_COLORMAP_SIZE 232
37 44
38typedef struct { 45typedef struct {
39 unsigned char red; 46 unsigned char red;
40 unsigned char green; 47 unsigned char green;
41 unsigned char blue; 48 unsigned char blue;
42} ColorMapEntry; 49} ColorMapEntry;
43 50
44static ColorMapEntry Palm8BitColormap[] = { 51static ColorMapEntry Palm8BitColormap[] = {
45 { 255, 255, 255 }, { 255, 204, 255 }, { 255, 153, 255 }, { 255, 102, 255 }, 52 { 255, 255, 255 }, { 255, 204, 255 }, { 255, 153, 255 }, { 255, 102, 255 },
46 { 255, 51, 255 }, { 255, 0, 255 }, { 255, 255, 204 }, { 255, 204, 204 }, 53 { 255, 51, 255 }, { 255, 0, 255 }, { 255, 255, 204 }, { 255, 204, 204 },
47 { 255, 153, 204 }, { 255, 102, 204 }, { 255, 51, 204 }, { 255, 0, 204 }, 54 { 255, 153, 204 }, { 255, 102, 204 }, { 255, 51, 204 }, { 255, 0, 204 },
48 { 255, 255, 153 }, { 255, 204, 153 }, { 255, 153, 153 }, { 255, 102, 153 }, 55 { 255, 255, 153 }, { 255, 204, 153 }, { 255, 153, 153 }, { 255, 102, 153 },
49 { 255, 51, 153 }, { 255, 0, 153 }, { 204, 255, 255 }, { 204, 204, 255 }, 56 { 255, 51, 153 }, { 255, 0, 153 }, { 204, 255, 255 }, { 204, 204, 255 },
50 { 204, 153, 255 }, { 204, 102, 255 }, { 204, 51, 255 }, { 204, 0, 255 }, 57 { 204, 153, 255 }, { 204, 102, 255 }, { 204, 51, 255 }, { 204, 0, 255 },
51 { 204, 255, 204 }, { 204, 204, 204 }, { 204, 153, 204 }, { 204, 102, 204 }, 58 { 204, 255, 204 }, { 204, 204, 204 }, { 204, 153, 204 }, { 204, 102, 204 },
52 { 204, 51, 204 }, { 204, 0, 204 }, { 204, 255, 153 }, { 204, 204, 153 }, 59 { 204, 51, 204 }, { 204, 0, 204 }, { 204, 255, 153 }, { 204, 204, 153 },
53 { 204, 153, 153 }, { 204, 102, 153 }, { 204, 51, 153 }, { 204, 0, 153 }, 60 { 204, 153, 153 }, { 204, 102, 153 }, { 204, 51, 153 }, { 204, 0, 153 },
54 { 153, 255, 255 }, { 153, 204, 255 }, { 153, 153, 255 }, { 153, 102, 255 }, 61 { 153, 255, 255 }, { 153, 204, 255 }, { 153, 153, 255 }, { 153, 102, 255 },
55 { 153, 51, 255 }, { 153, 0, 255 }, { 153, 255, 204 }, { 153, 204, 204 }, 62 { 153, 51, 255 }, { 153, 0, 255 }, { 153, 255, 204 }, { 153, 204, 204 },
56 { 153, 153, 204 }, { 153, 102, 204 }, { 153, 51, 204 }, { 153, 0, 204 }, 63 { 153, 153, 204 }, { 153, 102, 204 }, { 153, 51, 204 }, { 153, 0, 204 },
57 { 153, 255, 153 }, { 153, 204, 153 }, { 153, 153, 153 }, { 153, 102, 153 }, 64 { 153, 255, 153 }, { 153, 204, 153 }, { 153, 153, 153 }, { 153, 102, 153 },
58 { 153, 51, 153 }, { 153, 0, 153 }, { 102, 255, 255 }, { 102, 204, 255 }, 65 { 153, 51, 153 }, { 153, 0, 153 }, { 102, 255, 255 }, { 102, 204, 255 },
59 { 102, 153, 255 }, { 102, 102, 255 }, { 102, 51, 255 }, { 102, 0, 255 }, 66 { 102, 153, 255 }, { 102, 102, 255 }, { 102, 51, 255 }, { 102, 0, 255 },
60 { 102, 255, 204 }, { 102, 204, 204 }, { 102, 153, 204 }, { 102, 102, 204 }, 67 { 102, 255, 204 }, { 102, 204, 204 }, { 102, 153, 204 }, { 102, 102, 204 },
61 { 102, 51, 204 }, { 102, 0, 204 }, { 102, 255, 153 }, { 102, 204, 153 }, 68 { 102, 51, 204 }, { 102, 0, 204 }, { 102, 255, 153 }, { 102, 204, 153 },
62 { 102, 153, 153 }, { 102, 102, 153 }, { 102, 51, 153 }, { 102, 0, 153 }, 69 { 102, 153, 153 }, { 102, 102, 153 }, { 102, 51, 153 }, { 102, 0, 153 },
63 { 51, 255, 255 }, { 51, 204, 255 }, { 51, 153, 255 }, { 51, 102, 255 }, 70 { 51, 255, 255 }, { 51, 204, 255 }, { 51, 153, 255 }, { 51, 102, 255 },
64 { 51, 51, 255 }, { 51, 0, 255 }, { 51, 255, 204 }, { 51, 204, 204 }, 71 { 51, 51, 255 }, { 51, 0, 255 }, { 51, 255, 204 }, { 51, 204, 204 },
65 { 51, 153, 204 }, { 51, 102, 204 }, { 51, 51, 204 }, { 51, 0, 204 }, 72 { 51, 153, 204 }, { 51, 102, 204 }, { 51, 51, 204 }, { 51, 0, 204 },
66 { 51, 255, 153 }, { 51, 204, 153 }, { 51, 153, 153 }, { 51, 102, 153 }, 73 { 51, 255, 153 }, { 51, 204, 153 }, { 51, 153, 153 }, { 51, 102, 153 },
67 { 51, 51, 153 }, { 51, 0, 153 }, { 0, 255, 255 }, { 0, 204, 255 }, 74 { 51, 51, 153 }, { 51, 0, 153 }, { 0, 255, 255 }, { 0, 204, 255 },
68 { 0, 153, 255 }, { 0, 102, 255 }, { 0, 51, 255 }, { 0, 0, 255 }, 75 { 0, 153, 255 }, { 0, 102, 255 }, { 0, 51, 255 }, { 0, 0, 255 },
69 { 0, 255, 204 }, { 0, 204, 204 }, { 0, 153, 204 }, { 0, 102, 204 }, 76 { 0, 255, 204 }, { 0, 204, 204 }, { 0, 153, 204 }, { 0, 102, 204 },
70 { 0, 51, 204 }, { 0, 0, 204 }, { 0, 255, 153 }, { 0, 204, 153 }, 77 { 0, 51, 204 }, { 0, 0, 204 }, { 0, 255, 153 }, { 0, 204, 153 },
71 { 0, 153, 153 }, { 0, 102, 153 }, { 0, 51, 153 }, { 0, 0, 153 }, 78 { 0, 153, 153 }, { 0, 102, 153 }, { 0, 51, 153 }, { 0, 0, 153 },
72 { 255, 255, 102 }, { 255, 204, 102 }, { 255, 153, 102 }, { 255, 102, 102 }, 79 { 255, 255, 102 }, { 255, 204, 102 }, { 255, 153, 102 }, { 255, 102, 102 },
73 { 255, 51, 102 }, { 255, 0, 102 }, { 255, 255, 51 }, { 255, 204, 51 }, 80 { 255, 51, 102 }, { 255, 0, 102 }, { 255, 255, 51 }, { 255, 204, 51 },
74 { 255, 153, 51 }, { 255, 102, 51 }, { 255, 51, 51 }, { 255, 0, 51 }, 81 { 255, 153, 51 }, { 255, 102, 51 }, { 255, 51, 51 }, { 255, 0, 51 },
75 { 255, 255, 0 }, { 255, 204, 0 }, { 255, 153, 0 }, { 255, 102, 0 }, 82 { 255, 255, 0 }, { 255, 204, 0 }, { 255, 153, 0 }, { 255, 102, 0 },
76 { 255, 51, 0 }, { 255, 0, 0 }, { 204, 255, 102 }, { 204, 204, 102 }, 83 { 255, 51, 0 }, { 255, 0, 0 }, { 204, 255, 102 }, { 204, 204, 102 },
77 { 204, 153, 102 }, { 204, 102, 102 }, { 204, 51, 102 }, { 204, 0, 102 }, 84 { 204, 153, 102 }, { 204, 102, 102 }, { 204, 51, 102 }, { 204, 0, 102 },
78 { 204, 255, 51 }, { 204, 204, 51 }, { 204, 153, 51 }, { 204, 102, 51 }, 85 { 204, 255, 51 }, { 204, 204, 51 }, { 204, 153, 51 }, { 204, 102, 51 },
79 { 204, 51, 51 }, { 204, 0, 51 }, { 204, 255, 0 }, { 204, 204, 0 }, 86 { 204, 51, 51 }, { 204, 0, 51 }, { 204, 255, 0 }, { 204, 204, 0 },
80 { 204, 153, 0 }, { 204, 102, 0 }, { 204, 51, 0 }, { 204, 0, 0 }, 87 { 204, 153, 0 }, { 204, 102, 0 }, { 204, 51, 0 }, { 204, 0, 0 },
81 { 153, 255, 102 }, { 153, 204, 102 }, { 153, 153, 102 }, { 153, 102, 102 }, 88 { 153, 255, 102 }, { 153, 204, 102 }, { 153, 153, 102 }, { 153, 102, 102 },
82 { 153, 51, 102 }, { 153, 0, 102 }, { 153, 255, 51 }, { 153, 204, 51 }, 89 { 153, 51, 102 }, { 153, 0, 102 }, { 153, 255, 51 }, { 153, 204, 51 },
83 { 153, 153, 51 }, { 153, 102, 51 }, { 153, 51, 51 }, { 153, 0, 51 }, 90 { 153, 153, 51 }, { 153, 102, 51 }, { 153, 51, 51 }, { 153, 0, 51 },
84 { 153, 255, 0 }, { 153, 204, 0 }, { 153, 153, 0 }, { 153, 102, 0 }, 91 { 153, 255, 0 }, { 153, 204, 0 }, { 153, 153, 0 }, { 153, 102, 0 },
85 { 153, 51, 0 }, { 153, 0, 0 }, { 102, 255, 102 }, { 102, 204, 102 }, 92 { 153, 51, 0 }, { 153, 0, 0 }, { 102, 255, 102 }, { 102, 204, 102 },
86 { 102, 153, 102 }, { 102, 102, 102 }, { 102, 51, 102 }, { 102, 0, 102 }, 93 { 102, 153, 102 }, { 102, 102, 102 }, { 102, 51, 102 }, { 102, 0, 102 },
87 { 102, 255, 51 }, { 102, 204, 51 }, { 102, 153, 51 }, { 102, 102, 51 }, 94 { 102, 255, 51 }, { 102, 204, 51 }, { 102, 153, 51 }, { 102, 102, 51 },
88 { 102, 51, 51 }, { 102, 0, 51 }, { 102, 255, 0 }, { 102, 204, 0 }, 95 { 102, 51, 51 }, { 102, 0, 51 }, { 102, 255, 0 }, { 102, 204, 0 },
89 { 102, 153, 0 }, { 102, 102, 0 }, { 102, 51, 0 }, { 102, 0, 0 }, 96 { 102, 153, 0 }, { 102, 102, 0 }, { 102, 51, 0 }, { 102, 0, 0 },
90 { 51, 255, 102 }, { 51, 204, 102 }, { 51, 153, 102 }, { 51, 102, 102 }, 97 { 51, 255, 102 }, { 51, 204, 102 }, { 51, 153, 102 }, { 51, 102, 102 },
91 { 51, 51, 102 }, { 51, 0, 102 }, { 51, 255, 51 }, { 51, 204, 51 }, 98 { 51, 51, 102 }, { 51, 0, 102 }, { 51, 255, 51 }, { 51, 204, 51 },
92 { 51, 153, 51 }, { 51, 102, 51 }, { 51, 51, 51 }, { 51, 0, 51 }, 99 { 51, 153, 51 }, { 51, 102, 51 }, { 51, 51, 51 }, { 51, 0, 51 },
93 { 51, 255, 0 }, { 51, 204, 0 }, { 51, 153, 0 }, { 51, 102, 0 }, 100 { 51, 255, 0 }, { 51, 204, 0 }, { 51, 153, 0 }, { 51, 102, 0 },
94 { 51, 51, 0 }, { 51, 0, 0 }, { 0, 255, 102 }, { 0, 204, 102 }, 101 { 51, 51, 0 }, { 51, 0, 0 }, { 0, 255, 102 }, { 0, 204, 102 },
95 { 0, 153, 102 }, { 0, 102, 102 }, { 0, 51, 102 }, { 0, 0, 102 }, 102 { 0, 153, 102 }, { 0, 102, 102 }, { 0, 51, 102 }, { 0, 0, 102 },
96 { 0, 255, 51 }, { 0, 204, 51 }, { 0, 153, 51 }, { 0, 102, 51 }, 103 { 0, 255, 51 }, { 0, 204, 51 }, { 0, 153, 51 }, { 0, 102, 51 },
97 { 0, 51, 51 }, { 0, 0, 51 }, { 0, 255, 0 }, { 0, 204, 0 }, 104 { 0, 51, 51 }, { 0, 0, 51 }, { 0, 255, 0 }, { 0, 204, 0 },
98 { 0, 153, 0 }, { 0, 102, 0 }, { 0, 51, 0 }, { 17, 17, 17 }, 105 { 0, 153, 0 }, { 0, 102, 0 }, { 0, 51, 0 }, { 17, 17, 17 },
99 { 34, 34, 34 }, { 68, 68, 68 }, { 85, 85, 85 }, { 119, 119, 119 }, 106 { 34, 34, 34 }, { 68, 68, 68 }, { 85, 85, 85 }, { 119, 119, 119 },
100 { 136, 136, 136 }, { 170, 170, 170 }, { 187, 187, 187 }, { 221, 221, 221 }, 107 { 136, 136, 136 }, { 170, 170, 170 }, { 187, 187, 187 }, { 221, 221, 221 },
101 { 238, 238, 238 }, { 192, 192, 192 }, { 128, 0, 0 }, { 128, 0, 128 }, 108 { 238, 238, 238 }, { 192, 192, 192 }, { 128, 0, 0 }, { 128, 0, 128 },
102 { 0, 128, 0 }, { 0, 128, 128 }, { 0, 0, 0 }, { 0, 0, 0 }, 109 { 0, 128, 0 }, { 0, 128, 128 }, { 0, 0, 0 }, { 0, 0, 0 },
103 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, 110 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
104 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, 111 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
105 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, 112 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
106 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, 113 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
107 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, 114 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
108 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}; 115 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }};
109 116
110static ColorMapEntry Palm1BitColormap[] = {{ 255, 255, 255 }, { 0, 0, 0 }}; 117static ColorMapEntry Palm1BitColormap[] = {{ 255, 255, 255 }, { 0, 0, 0 }};
111 118
112static ColorMapEntry Palm2BitColormap[] = { 119static ColorMapEntry Palm2BitColormap[] = {
113 { 255, 255, 255 }, { 192, 192, 192 }, { 128, 128, 128 }, { 0, 0, 0 }}; 120 { 255, 255, 255 }, { 192, 192, 192 }, { 128, 128, 128 }, { 0, 0, 0 }};
114 121
115static ColorMapEntry Palm4BitColormap[] = { 122static ColorMapEntry Palm4BitColormap[] = {
116 { 255, 255, 255 }, { 238, 238, 238 }, { 221, 221, 221 }, { 204, 204, 204 }, 123 { 255, 255, 255 }, { 238, 238, 238 }, { 221, 221, 221 }, { 204, 204, 204 },
117 { 187, 187, 187 }, { 170, 170, 170 }, { 153, 153, 153 }, { 136, 136, 136 }, 124 { 187, 187, 187 }, { 170, 170, 170 }, { 153, 153, 153 }, { 136, 136, 136 },
118 { 119, 119, 119 }, { 102, 102, 102 }, { 85, 85, 85 }, { 68, 68, 68 }, 125 { 119, 119, 119 }, { 102, 102, 102 }, { 85, 85, 85 }, { 68, 68, 68 },
119 { 51, 51, 51 }, { 34, 34, 34 }, { 17, 17, 17 }, { 0, 0, 0 }}; 126 { 51, 51, 51 }, { 34, 34, 34 }, { 17, 17, 17 }, { 0, 0, 0 }};
120 127
121QImage* Palm2QImage 128QImage* Palm2QImage
122 (unsigned char *image_bytes_in, int byte_count_in) 129 (unsigned char *image_bytes_in, int byte_count_in)
123{ 130{
124 unsigned int width, height, bytes_per_row, flags, next_depth_offset; 131 unsigned int width, height, bytes_per_row, flags, next_depth_offset;
125 unsigned int bits_per_pixel, version, transparent_index, compression_type, i, j, inval, inbit, mask, incount; 132 unsigned int bits_per_pixel, version, transparent_index, compression_type, i, j, inval, inbit, mask, incount;
126 unsigned int palm_red_bits, palm_green_bits, palm_blue_bits; 133 unsigned int palm_red_bits, palm_green_bits, palm_blue_bits;
127 unsigned char *palm_ptr, *x_ptr, *imagedata, *inbyte, *rowbuf, *lastrow, 134 unsigned char *palm_ptr, *x_ptr, *imagedata, *inbyte, *rowbuf, *lastrow,
128 *imagedatastart, *palmimage; 135 *imagedatastart, *palmimage;
129 ColorMapEntry *colormap; 136 ColorMapEntry *colormap;
130 137
131 palmimage = image_bytes_in; 138 palmimage = image_bytes_in;
132 width = READ_BIGENDIAN_SHORT(palmimage + 0); 139 width = READ_BIGENDIAN_SHORT(palmimage + 0);
133 height = READ_BIGENDIAN_SHORT(palmimage + 2); 140 height = READ_BIGENDIAN_SHORT(palmimage + 2);
134 bytes_per_row = READ_BIGENDIAN_SHORT(palmimage + 4); 141 bytes_per_row = READ_BIGENDIAN_SHORT(palmimage + 4);
135 flags = READ_BIGENDIAN_SHORT(palmimage + 6); 142 flags = READ_BIGENDIAN_SHORT(palmimage + 6);
136 bits_per_pixel = palmimage[8]; 143 bits_per_pixel = palmimage[8];
137 version = palmimage[9]; 144 version = palmimage[9];
138 next_depth_offset = READ_BIGENDIAN_SHORT(palmimage + 10); 145 next_depth_offset = READ_BIGENDIAN_SHORT(palmimage + 10);
139 transparent_index = palmimage[12]; 146 transparent_index = palmimage[12];
140 compression_type = palmimage[13]; 147 compression_type = palmimage[13];
141 /* bytes 14 and 15 are reserved by Palm and always 0 */ 148 /* bytes 14 and 15 are reserved by Palm and always 0 */
142 149
143#if 0 150#if 0
144// qDebug ("Palm image is %dx%d, %d bpp, version %d, flags 0x%x, compression %d", width, height, bits_per_pixel, version, flags, compression_type); 151// odebug << "Palm image is " << width << "x" << height
152// << ", " << bits_per_pixel << " bpp, version " << version
153// << ", flags 0x" << flags << ", compression " << compression_type << oendl;
145#endif 154#endif
146 155
147 if (compression_type == PALM_COMPRESSION_PACKBITS) { 156 if (compression_type == PALM_COMPRESSION_PACKBITS) {
148// qDebug ("Image uses packbits compression; not yet supported"); 157// odebug << "Image uses packbits compression; not yet supported" << oendl;
149 return NULL; 158 return NULL;
150 } else if ((compression_type != PALM_COMPRESSION_NONE) && 159 } else if ((compression_type != PALM_COMPRESSION_NONE) &&
151 (compression_type != PALM_COMPRESSION_RLE) && 160 (compression_type != PALM_COMPRESSION_RLE) &&
152 (compression_type != PALM_COMPRESSION_SCANLINE)) { 161 (compression_type != PALM_COMPRESSION_SCANLINE)) {
153// qDebug ("Image uses unknown compression, code 0x%x", compression_type); 162// odebug << "Image uses unknown compression, code 0x" << compression_type << oendl;
154 return NULL; 163 return NULL;
155 } 164 }
156 165
157 /* as of PalmOS 4.0, there are 6 different kinds of Palm pixmaps: 166 /* as of PalmOS 4.0, there are 6 different kinds of Palm pixmaps:
158 167
159 1, 2, or 4 bit grayscale 168 1, 2, or 4 bit grayscale
160 8-bit StaticColor using the Palm standard colormap 169 8-bit StaticColor using the Palm standard colormap
161 8-bit PseudoColor using a user-specified colormap 170 8-bit PseudoColor using a user-specified colormap
162 16-bit DirectColor using 5 bits for red, 6 for green, and 5 for blue 171 16-bit DirectColor using 5 bits for red, 6 for green, and 5 for blue
163 172
164 Each of these can be compressed with one of four compression schemes, 173 Each of these can be compressed with one of four compression schemes,
165 "RLE", "Scanline", "PackBits", or none. 174 "RLE", "Scanline", "PackBits", or none.
166 175
167 We begin by constructing the colormap. 176 We begin by constructing the colormap.
168 */ 177 */
169 178
170 if (flags & PALM_HAS_COLORMAP_FLAG) { 179 if (flags & PALM_HAS_COLORMAP_FLAG) {
171// qDebug("Palm images with custom colormaps are not currently supported.\n"); 180// odebug << "Palm images with custom colormaps are not currently supported." << oendl;
172 return NULL; 181 return NULL;
173 } else if (bits_per_pixel == 1) { 182 } else if (bits_per_pixel == 1) {
174 colormap = Palm1BitColormap; 183 colormap = Palm1BitColormap;
175 imagedatastart = palmimage + 16; 184 imagedatastart = palmimage + 16;
176 } else if (bits_per_pixel == 2) { 185 } else if (bits_per_pixel == 2) {
177 colormap = Palm2BitColormap; 186 colormap = Palm2BitColormap;
178 imagedatastart = palmimage + 16; 187 imagedatastart = palmimage + 16;
179 } else if (bits_per_pixel == 4) { 188 } else if (bits_per_pixel == 4) {
180 colormap = Palm4BitColormap; 189 colormap = Palm4BitColormap;
181 imagedatastart = palmimage + 16; 190 imagedatastart = palmimage + 16;
182 } else if (bits_per_pixel == 8) { 191 } else if (bits_per_pixel == 8) {
183 colormap = Palm8BitColormap; 192 colormap = Palm8BitColormap;
184 imagedatastart = palmimage + 16; 193 imagedatastart = palmimage + 16;
185 } else if (bits_per_pixel == 16 && (flags & PALM_DIRECT_COLOR_FLAG)) { 194 } else if (bits_per_pixel == 16 && (flags & PALM_DIRECT_COLOR_FLAG)) {
186 colormap = NULL; 195 colormap = NULL;
187 palm_red_bits = palmimage[16]; 196 palm_red_bits = palmimage[16];
188 palm_green_bits = palmimage[17]; 197 palm_green_bits = palmimage[17];
189 palm_blue_bits = palmimage[18]; 198 palm_blue_bits = palmimage[18];
190// qDebug("Bits:%d, %d, %d", palm_red_bits, palm_green_bits, palm_blue_bits); 199// odebug << "Bits:" << palm_red_bits << ", " << palm_green_bits << ", " << palm_blue_bits << oendl;
191 if (palm_blue_bits > 8 || palm_green_bits > 8 || palm_red_bits > 8) { 200 if (palm_blue_bits > 8 || palm_green_bits > 8 || palm_red_bits > 8) {
192// qDebug("Can't handle this format DirectColor image -- too wide in some color (%d:%d:%d)\n", palm_red_bits, palm_green_bits, palm_blue_bits); 201// odebug << "Can't handle this format DirectColor image -- too wide in some color ("
202// << palm_red_bits << ":" << palm_green_bits << ":" << palm_blue_bits << oendl;
193 return NULL; 203 return NULL;
194 } 204 }
195 if (bits_per_pixel > (8 * sizeof(unsigned long))) { 205 if (bits_per_pixel > (8 * sizeof(unsigned long))) {
196// qDebug ("Can't handle this format DirectColor image -- too many bits per pixel (%d)\n", bits_per_pixel); 206// odebug << "Can't handle this format DirectColor image -- too many bits per pixel ("
207// << bits_per_pixel << ")" << oendl;
197 return NULL; 208 return NULL;
198 } 209 }
199 imagedatastart = palmimage + 24; 210 imagedatastart = palmimage + 24;
200 } else { 211 } else {
201// qDebug("Unknown bits-per-pixel of %d encountered.\n", bits_per_pixel); 212// odebug << "Unknown bits-per-pixel of " << bits_per_pixel << " encountered" << oendl;
202 return NULL; 213 return NULL;
203 } 214 }
204 215
205#ifndef USEQPE 216#ifndef USEQPE
206 QImage* qimage = new QImage(width, height, 32); 217 QImage* qimage = new QImage(width, height, 32);
207#else 218#else
208 QImage* qimage = new QImage(width, height, 16); 219 QImage* qimage = new QImage(width, height, 16);
209#endif 220#endif
210 221
211 /* row by row, uncompress the Palm image and copy it to the JPEG buffer */ 222 /* row by row, uncompress the Palm image and copy it to the JPEG buffer */
212 rowbuf = new unsigned char[bytes_per_row * width]; 223 rowbuf = new unsigned char[bytes_per_row * width];
213 lastrow = new unsigned char[bytes_per_row * width]; 224 lastrow = new unsigned char[bytes_per_row * width];
214 225
215 for (i=0, palm_ptr = imagedatastart , x_ptr = imagedata; i < height; ++i) { 226 for (i=0, palm_ptr = imagedatastart , x_ptr = imagedata; i < height; ++i) {
216// qDebug("inval:%x palm_ptr:%x x_ptr:%x bpr:%x", inval, palm_ptr, x_ptr, bytes_per_row); 227// odebug << "inval:" << inval << " palm_ptr:" << palm_ptr << " x_ptr:" << x_ptr
228// << " bpr:" << bytes_per_row << oendl;
217 229
218 /* first, uncompress the Palm image */ 230 /* first, uncompress the Palm image */
219 if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_RLE)) { 231 if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_RLE)) {
220 for (j = 0; j < bytes_per_row; ) { 232 for (j = 0; j < bytes_per_row; ) {
221 incount = *palm_ptr++; 233 incount = *palm_ptr++;
222 inval = *palm_ptr++; 234 inval = *palm_ptr++;
223 memset(rowbuf + j, inval, incount); 235 memset(rowbuf + j, inval, incount);
224 j += incount; 236 j += incount;
225 } 237 }
226 } else if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_SCANLINE)) { 238 } else if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_SCANLINE)) {
227 for (j = 0; j < bytes_per_row; j += 8) { 239 for (j = 0; j < bytes_per_row; j += 8) {
228 incount = *palm_ptr++; 240 incount = *palm_ptr++;
229 inval = ((bytes_per_row - j) < 8) ? (bytes_per_row - j) : 8; 241 inval = ((bytes_per_row - j) < 8) ? (bytes_per_row - j) : 8;
230 for (inbit = 0; inbit < inval; inbit += 1) { 242 for (inbit = 0; inbit < inval; inbit += 1) {
231 if (incount & (1 << (7 - inbit))) 243 if (incount & (1 << (7 - inbit)))
232 rowbuf[j + inbit] = *palm_ptr++; 244 rowbuf[j + inbit] = *palm_ptr++;
233 else 245 else
234 rowbuf[j + inbit] = lastrow[j + inbit]; 246 rowbuf[j + inbit] = lastrow[j + inbit];
235 } 247 }
236 } 248 }
237 memcpy (lastrow, rowbuf, bytes_per_row); 249 memcpy (lastrow, rowbuf, bytes_per_row);
238 } else if (((flags & PALM_IS_COMPRESSED_FLAG) && 250 } else if (((flags & PALM_IS_COMPRESSED_FLAG) &&
239 (compression_type == PALM_COMPRESSION_NONE)) || 251 (compression_type == PALM_COMPRESSION_NONE)) ||
240 ((flags & PALM_IS_COMPRESSED_FLAG) == 0)) 252 ((flags & PALM_IS_COMPRESSED_FLAG) == 0))
241 { 253 {
242 memcpy (rowbuf, palm_ptr, bytes_per_row); 254 memcpy (rowbuf, palm_ptr, bytes_per_row);
243 palm_ptr += bytes_per_row; 255 palm_ptr += bytes_per_row;
244 } 256 }
245 else { 257 else {
246 qDebug("Case 4"); 258 odebug << "Case 4" << oendl;
247 qDebug("Is compressed:%s", ((flags & PALM_IS_COMPRESSED_FLAG) == 0) ? "false" : "true"); 259 odebug << "Is compressed:" << (((flags & PALM_IS_COMPRESSED_FLAG) == 0) ? "false" : "true") << oendl;
248 qDebug("Has colourmap:%s", ((flags & PALM_HAS_COLORMAP_FLAG) == 0) ? "false" : "true"); 260 odebug << "Has colourmap:" << (((flags & PALM_HAS_COLORMAP_FLAG) == 0) ? "false" : "true") << oendl;
249 qDebug("Has transparency:%s", ((flags & PALM_HAS_TRANSPARENCY_FLAG) == 0) ? "false" : "true"); 261 odebug << "Has transparency:" << (((flags & PALM_HAS_TRANSPARENCY_FLAG) == 0) ? "false" : "true") << oendl;
250 qDebug("Direct colour:%s", ((flags & PALM_DIRECT_COLOR_FLAG) == 0) ? "false" : "true"); 262 odebug << "Direct colour:" << (((flags & PALM_DIRECT_COLOR_FLAG) == 0) ? "false" : "true") << oendl;
251 qDebug("four byte field:%s", ((flags & PALM_4_BYTE_FIELD_FLAG) == 0) ? "false" : "true"); 263 odebug << "four byte field:" << (((flags & PALM_4_BYTE_FIELD_FLAG) == 0) ? "false" : "true") << oendl;
252 memcpy (rowbuf, palm_ptr, bytes_per_row); 264 memcpy (rowbuf, palm_ptr, bytes_per_row);
253 palm_ptr += bytes_per_row; 265 palm_ptr += bytes_per_row;
254 } 266 }
255 /* next, write it to the GDK bitmap */ 267 /* next, write it to the GDK bitmap */
256 if (colormap) { 268 if (colormap) {
257 mask = (1 << bits_per_pixel) - 1; 269 mask = (1 << bits_per_pixel) - 1;
258 for (inbit = 8 - bits_per_pixel, inbyte = rowbuf, j = 0; j < width; ++j) { 270 for (inbit = 8 - bits_per_pixel, inbyte = rowbuf, j = 0; j < width; ++j) {
259 inval = ((*inbyte) & (mask << inbit)) >> inbit; 271 inval = ((*inbyte) & (mask << inbit)) >> inbit;
260 /* correct for oddity of the 8-bit color Palm pixmap... */ 272 /* correct for oddity of the 8-bit color Palm pixmap... */
261 if ((bits_per_pixel == 8) && (inval == 0xFF)) inval = 231; 273 if ((bits_per_pixel == 8) && (inval == 0xFF)) inval = 231;
262 /* now lookup the correct color and set the pixel in the GTK bitmap */ 274 /* now lookup the correct color and set the pixel in the GTK bitmap */
263 QRgb colour = qRgb(colormap[inval].red, colormap[inval].green, colormap[inval].blue); 275 QRgb colour = qRgb(colormap[inval].red, colormap[inval].green, colormap[inval].blue);
264 qimage->setPixel(j, i, colour); 276 qimage->setPixel(j, i, colour);
265 if (!inbit) { 277 if (!inbit) {
266 ++inbyte; 278 ++inbyte;
267 inbit = 8 - bits_per_pixel; 279 inbit = 8 - bits_per_pixel;
268 } else { 280 } else {
269 inbit -= bits_per_pixel; 281 inbit -= bits_per_pixel;
270 } 282 }
271 } 283 }
272 } else if (!colormap && 284 } else if (!colormap &&
273 bits_per_pixel == 16) { 285 bits_per_pixel == 16) {
274 for (inbyte = rowbuf, j = 0; j < width; ++j) { 286 for (inbyte = rowbuf, j = 0; j < width; ++j) {
275 inval = ((unsigned short)inbyte[0] << (unsigned short)8) | inbyte[1]; 287 inval = ((unsigned short)inbyte[0] << (unsigned short)8) | inbyte[1];
276 288
277/* 289/*
278 qDebug ("pixel is %d,%d (%d:%d:%d)", 290 odebug << "pixel is " << j << "," << i << " ("
279 j, i, 291 << (((inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1)) << (8-palm_red_bits)) << ":"
280 ((inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1)) << (8-palm_red_bits), 292 << (((inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1)) << (8-palm_green_bits)) << ":"
281 ((inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1)) << (8-palm_green_bits), 293 << (((inval >> 0) & ((1 << palm_blue_bits) - 1)) << (8-palm_blue_bits)) << ")" << oendl;
282 ((inval >> 0) & ((1 << palm_blue_bits) - 1)) << (8-palm_blue_bits));
283*/ 294*/
284 QRgb colour = qRgb( 295 QRgb colour = qRgb(
285 ((inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1)) << (8-palm_red_bits), 296 ((inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1)) << (8-palm_red_bits),
286 ((inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1)) << (8-palm_green_bits), 297 ((inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1)) << (8-palm_green_bits),
287 ((inval >> 0) & ((1 << palm_blue_bits) - 1)) << (8-palm_blue_bits)); 298 ((inval >> 0) & ((1 << palm_blue_bits) - 1)) << (8-palm_blue_bits));
288 qimage->setPixel(j, i, colour); 299 qimage->setPixel(j, i, colour);
289 inbyte += 2; 300 inbyte += 2;
290 } 301 }
291 } 302 }
292 } 303 }
293 304
294 delete [] rowbuf; 305 delete [] rowbuf;
295 delete [] lastrow; 306 delete [] lastrow;
296 307
297 return qimage; 308 return qimage;
298} 309}
299 310
300QImage* hRule(int w, int h, unsigned char r, unsigned char g, unsigned char b) 311QImage* hRule(int w, int h, unsigned char r, unsigned char g, unsigned char b)
301{ 312{
302//// qDebug("hrule [%d, %d]", w, h); 313// odebug << "hrule [" << w << ", " << h << "]" << oendl;
303 QPixmap* qimage = new QPixmap(w, h); 314 QPixmap* qimage = new QPixmap(w, h);
304 qimage->fill(QColor(r,g,b)); 315 qimage->fill(QColor(r,g,b));
305 QImage* ret = new QImage(qimage->convertToImage()); 316 QImage* ret = new QImage(qimage->convertToImage());
306 delete qimage; 317 delete qimage;
307 return ret; 318 return ret;
308} 319}
diff --git a/noncore/apps/opie-reader/QTReader.h b/noncore/apps/opie-reader/QTReader.h
index dfbdfb9..f89de63 100644
--- a/noncore/apps/opie-reader/QTReader.h
+++ b/noncore/apps/opie-reader/QTReader.h
@@ -1,272 +1,272 @@
1#ifndef __QTREADER_H 1#ifndef __QTREADER_H
2#define __QTREADER_H 2#define __QTREADER_H
3 3
4//#define _SCROLLPIPE 4//#define _SCROLLPIPE
5 5
6#include <qwidget.h> 6#include <qwidget.h>
7//#include <qpainter.h> 7//#include <qpainter.h>
8#include "my_list.h" 8#include "my_list.h"
9#include "BuffDoc.h" 9#include "BuffDoc.h"
10#include "FontControl.h" 10#include "FontControl.h"
11 11
12//#include <qtimer.h> 12//#include <qtimer.h>
13 13
14class CDrawBuffer; 14class CDrawBuffer;
15//class CBuffer; 15//class CBuffer;
16class QPainter; 16class QPainter;
17class QTimer; 17class QTimer;
18class QPixmap; 18class QPixmap;
19 19
20class QTReader : public QWidget 20class QTReader : public QWidget
21{ 21{
22 Q_OBJECT 22 Q_OBJECT
23 23
24 static tchar pluckernextpart[]; 24 static tchar pluckernextpart[];
25 static tchar jplucknextpart[]; 25 static tchar jplucknextpart[];
26 friend class QTReaderApp; 26 friend class QTReaderApp;
27 void suspend(); 27 void suspend();
28 void increaseScroll(); 28 void increaseScroll();
29 void reduceScroll(); 29 void reduceScroll();
30 void drawText(QPainter& p, int x, int y, tchar* text); 30 void drawText(QPainter& p, int x, int y, tchar* text);
31 int m_delay; 31 int m_delay;
32 unsigned int m_overlap; 32 unsigned int m_overlap;
33 bool m_autoScroll, m_swapmouse; 33 bool m_autoScroll, m_swapmouse;
34 void autoscroll(); 34 void autoscroll();
35 QTimer* timer; 35 QTimer* timer;
36 int m_scrolldy1, m_scrolldy2, m_encd, m_scrollpart; 36 int m_scrolldy1, m_scrolldy2, m_encd, m_scrollpart;
37 void focusInEvent(QFocusEvent*); 37 void focusInEvent(QFocusEvent*);
38 void focusOutEvent(QFocusEvent*); 38 void focusOutEvent(QFocusEvent*);
39 void processmousepositionevent( QMouseEvent* _e ); 39 void processmousepositionevent( QMouseEvent* _e );
40 void processmousewordevent(size_t startpos, size_t startoffset, QMouseEvent* _e, int lineno); 40 void processmousewordevent(size_t startpos, size_t startoffset, QMouseEvent* _e, int lineno);
41 bool ChangeFont(int); 41 bool ChangeFont(int);
42 bool getline(CDrawBuffer*); 42 bool getline(CDrawBuffer*);
43 int m_charWidth; 43 int m_charWidth;
44 int m_charpc; 44 int m_charpc;
45 unsigned char m_border; 45 unsigned char m_border;
46 FontControl m_fontControl; 46 FontControl m_fontControl;
47 void setBaseSize(unsigned char _s) { m_fontControl.setBaseSize(_s); } 47 void setBaseSize(unsigned char _s) { m_fontControl.setBaseSize(_s); }
48 unsigned char getBaseSize() { return m_fontControl.getBaseSize(); } 48 unsigned char getBaseSize() { return m_fontControl.getBaseSize(); }
49#ifdef _SCROLLPIPE 49#ifdef _SCROLLPIPE
50 FILE* m_pipeout; 50 FILE* m_pipeout;
51 QString m_pipetarget; 51 QString m_pipetarget;
52 bool m_isPaused; 52 bool m_isPaused;
53 bool m_pauseAfterEachPara; 53 bool m_pauseAfterEachPara;
54#endif 54#endif
55public: 55public:
56 QTReader( QWidget *parent=0, const char *name=0, WFlags f = 0); 56 QTReader( QWidget *parent=0, const char *name=0, WFlags f = 0);
57 // QTReader( const QString& filename, QWidget *parent=0, const tchar *name=0, WFlags f = 0); 57 // QTReader( const QString& filename, QWidget *parent=0, const tchar *name=0, WFlags f = 0);
58 ~QTReader(); 58 ~QTReader();
59 void zoomin(); 59 void zoomin();
60 void zoomout(); 60 void zoomout();
61 void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen) 61 void setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen)
62 { 62 {
63 buffdoc.setSaveData(data, len, src, srclen); 63 buffdoc.setSaveData(data, len, src, srclen);
64 } 64 }
65 void putSaveData(unsigned char*& src, unsigned short& srclen) 65 void putSaveData(unsigned char*& src, unsigned short& srclen)
66 { 66 {
67 buffdoc.putSaveData(src, srclen); 67 buffdoc.putSaveData(src, srclen);
68 } 68 }
69 bool empty(); 69 bool empty();
70 void setContinuous(bool _b); 70 void setContinuous(bool _b);
71 void toggle_autoscroll(); 71 void toggle_autoscroll();
72 void setautoscroll(bool); 72 void setautoscroll(bool);
73 void disableAutoscroll() { m_autoScroll = false; } 73 void disableAutoscroll() { m_autoScroll = false; }
74 void copy() 74 void copy()
75 { 75 {
76/* 76/*
77 size_t nd = locate(); 77 size_t nd = locate();
78 jumpto(m_mark); 78 jumpto(m_mark);
79 QString text; 79 QString text;
80 while (m_mark < nd) 80 while (m_mark < nd)
81 { 81 {
82 text += buffdoc.getch(); 82 text += buffdoc.getch();
83 m_mark++; 83 m_mark++;
84 } 84 }
85 QApplication::clipboard()->setText(text); 85 QApplication::clipboard()->setText(text);
86 jumpto(nd); 86 jumpto(nd);
87*/ 87*/
88 }; 88 };
89 void clear() {}; 89 void clear() {};
90 void setText(const QString& n, const QString& s) { m_string = n; load_file((const char*)s); }; 90 void setText(const QString& n, const QString& s) { m_string = n; load_file((const char*)s); };
91 /* 91 /*
92 void setText(bool oldfile) 92 void setText(bool oldfile)
93 { 93 {
94 if (oldfile) 94 if (oldfile)
95 { 95 {
96 m_string = m_lastfile; 96 m_string = m_lastfile;
97 load_file((const tchar*)m_string); 97 load_file((const tchar*)m_string);
98 } 98 }
99 else 99 else
100 { 100 {
101 m_string = QString::null; 101 m_string = QString::null;
102 } 102 }
103 }; 103 };
104 */ 104 */
105 void setlead(int _lead) 105 void setlead(int _lead)
106 { 106 {
107 m_fontControl.setlead(_lead); 107 m_fontControl.setlead(_lead);
108 } 108 }
109 int getlead() 109 int getlead()
110 { 110 {
111 return m_fontControl.getlead(); 111 return m_fontControl.getlead();
112 } 112 }
113 void setextraspace(int _lead) 113 void setextraspace(int _lead)
114 { 114 {
115 m_fontControl.setextraspace(_lead); 115 m_fontControl.setextraspace(_lead);
116 } 116 }
117 int getextraspace() 117 int getextraspace()
118 { 118 {
119 return m_fontControl.getextraspace(); 119 return m_fontControl.getextraspace();
120 } 120 }
121 void setpagemode(bool _b) 121 void setpagemode(bool _b)
122 { 122 {
123 m_bpagemode = _b; 123 m_bpagemode = _b;
124 } 124 }
125 void setmono(bool _b) 125 void setmono(bool _b)
126 { 126 {
127 m_bMonoSpaced = _b; 127 m_bMonoSpaced = _b;
128 ChangeFont(m_fontControl.currentsize()); 128 ChangeFont(m_fontControl.currentsize());
129 locate(pagelocate()); 129 locate(pagelocate());
130 } 130 }
131 void setencoding(int _f) 131 void setencoding(int _f)
132 { 132 {
133 m_encd = _f; 133 m_encd = _f;
134 setfilter(getfilter()); 134 setfilter(getfilter());
135 } 135 }
136 MarkupType PreferredMarkup(); 136 MarkupType PreferredMarkup();
137 CEncoding* getencoding() 137 CEncoding* getencoding()
138 { 138 {
139 // qDebug("m_encd:%d", m_encd); 139// odebug << "m_encd:" << m_encd << oendl;
140 switch (m_encd) 140 switch (m_encd)
141 { 141 {
142 case 4: 142 case 4:
143 // qDebug("palm"); 143// odebug << "palm" << oendl;
144 return new CPalm; 144 return new CPalm;
145 case 1: 145 case 1:
146 // qDebug("utf8"); 146// odebug << "utf8" << oendl;
147 return new CUtf8; 147 return new CUtf8;
148 case 2: 148 case 2:
149 // qDebug("ucs16be"); 149// odebug << "ucs16be" << oendl;
150 return new CUcs16be; 150 return new CUcs16be;
151 case 3: 151 case 3:
152 // qDebug("ucs16le"); 152// odebug << "ucs16le" << oendl;
153 return new CUcs16le; 153 return new CUcs16le;
154 case 0: 154 case 0:
155 // qDebug("ascii"); 155// odebug << "ascii" << oendl;
156 return new CAscii; 156 return new CAscii;
157 default: 157 default:
158 return new CGeneral8Bit(m_encd-MAX_ENCODING+1); 158 return new CGeneral8Bit(m_encd-MAX_ENCODING+1);
159 } 159 }
160 } 160 }
161 CFilterChain* getfilter() 161 CFilterChain* getfilter()
162 { 162 {
163 CFilterChain * filt = new CFilterChain(getencoding()); 163 CFilterChain * filt = new CFilterChain(getencoding());
164 if (bstripcr) filt->addfilter(new stripcr); 164 if (bstripcr) filt->addfilter(new stripcr);
165 165
166 if (btextfmt || (bautofmt && (PreferredMarkup() == cTEXT))) filt->addfilter(new textfmt); 166 if (btextfmt || (bautofmt && (PreferredMarkup() == cTEXT))) filt->addfilter(new textfmt);
167 if (bpeanut || (bautofmt && (PreferredMarkup() == cPML))) filt->addfilter(new PeanutFormatter); 167 if (bpeanut || (bautofmt && (PreferredMarkup() == cPML))) filt->addfilter(new PeanutFormatter);
168 if (bstriphtml || (bautofmt && (PreferredMarkup() == cHTML))) filt->addfilter(new striphtml); 168 if (bstriphtml || (bautofmt && (PreferredMarkup() == cHTML))) filt->addfilter(new striphtml);
169 169
170 if (bdehyphen) filt->addfilter(new dehyphen); 170 if (bdehyphen) filt->addfilter(new dehyphen);
171 if (bunindent) filt->addfilter(new unindent); 171 if (bunindent) filt->addfilter(new unindent);
172 if (brepara) filt->addfilter(new repara); 172 if (brepara) filt->addfilter(new repara);
173 if (bonespace) filt->addfilter(new OnePara); 173 if (bonespace) filt->addfilter(new OnePara);
174 if (bindenter) filt->addfilter(new indenter(bindenter)); 174 if (bindenter) filt->addfilter(new indenter(bindenter));
175 if (bdblspce) filt->addfilter(new dblspce); 175 if (bdblspce) filt->addfilter(new dblspce);
176#ifdef REPALM 176#ifdef REPALM
177 if (brepalm) filt->addfilter(new repalm); 177 if (brepalm) filt->addfilter(new repalm);
178#endif 178#endif
179 if (bremap) filt->addfilter(new remap); 179 if (bremap) filt->addfilter(new remap);
180 if (bdepluck) filt->addfilter(new DePluck(pluckernextpart)); 180 if (bdepluck) filt->addfilter(new DePluck(pluckernextpart));
181 if (bdejpluck) filt->addfilter(new DePluck(jplucknextpart)); 181 if (bdejpluck) filt->addfilter(new DePluck(jplucknextpart));
182 if (bmakebold) filt->addfilter(new embolden); 182 if (bmakebold) filt->addfilter(new embolden);
183 if (bfulljust) filt->addfilter(new FullJust); 183 if (bfulljust) filt->addfilter(new FullJust);
184 return filt; 184 return filt;
185 } 185 }
186 186
187 187
188private slots: 188private slots:
189 void goHome(); 189 void goHome();
190 void goBack(); 190 void goBack();
191 void goForward(); 191 void goForward();
192 void doscroll(); 192 void doscroll();
193 void drawIt( QPainter * ); 193 void drawIt( QPainter * );
194 void paintEvent( QPaintEvent * ); 194 void paintEvent( QPaintEvent * );
195// void resizeEvent( QResizeEvent * p ) { update(); } 195// void resizeEvent( QResizeEvent * p ) { update(); }
196 void keyPressEvent(QKeyEvent*); 196 void keyPressEvent(QKeyEvent*);
197 void drawFonts(QPainter*); 197 void drawFonts(QPainter*);
198 private: 198 private:
199 void setTwoTouch(bool _b); 199 void setTwoTouch(bool _b);
200 void init(); 200 void init();
201 void mousePressEvent( QMouseEvent* ); 201 void mousePressEvent( QMouseEvent* );
202 void mouseReleaseEvent( QMouseEvent* ); 202 void mouseReleaseEvent( QMouseEvent* );
203// void mouseDoubleClickEvent( QMouseEvent* ); 203// void mouseDoubleClickEvent( QMouseEvent* );
204 QString m_string, m_fontname; 204 QString m_string, m_fontname;
205 void setfont(); 205 void setfont();
206 //myoutput stuff 206 //myoutput stuff
207 private: 207 private:
208 bool mouseUpOn; 208 bool mouseUpOn;
209 linkType getcurrentpos(int x, int y, size_t& start, size_t& offset, size_t& tgt); 209 linkType getcurrentpos(int x, int y, size_t& start, size_t& offset, size_t& tgt);
210 bool m_twotouch, m_touchone; 210 bool m_twotouch, m_touchone;
211 size_t m_startpos, m_startoffset; 211 size_t m_startpos, m_startoffset;
212 void dopageup(unsigned int); 212 void dopageup(unsigned int);
213 void dopageup(); 213 void dopageup();
214 void lineDown(); 214 void lineDown();
215 void lineUp(); 215 void lineUp();
216 void dopagedn(); 216 void dopagedn();
217 long real_delay(); 217 long real_delay();
218 int m_textsize; 218 int m_textsize;
219 int m_lastwidth, m_lastheight; 219 int m_lastwidth, m_lastheight;
220 CBufferFace<CDrawBuffer*> textarray; 220 CBufferFace<CDrawBuffer*> textarray;
221 CBufferFace<size_t> locnarray; 221 CBufferFace<size_t> locnarray;
222 unsigned int numlines; 222 unsigned int numlines;
223// bool m_showlast; 223// bool m_showlast;
224 bool bstripcr, btextfmt, bstriphtml, bdehyphen, bdepluck, bdejpluck, bunindent, brepara, bdblspce, btight, bmakebold, bremap, bpeanut, bautofmt, bonespace, bfulljust; 224 bool bstripcr, btextfmt, bstriphtml, bdehyphen, bdepluck, bdejpluck, bunindent, brepara, bdblspce, btight, bmakebold, bremap, bpeanut, bautofmt, bonespace, bfulljust;
225#ifdef REPALM 225#ifdef REPALM
226 bool brepalm; 226 bool brepalm;
227#endif 227#endif
228 bool m_bpagemode, m_bMonoSpaced, m_continuousDocument; 228 bool m_bpagemode, m_bMonoSpaced, m_continuousDocument;
229 unsigned char bindenter; 229 unsigned char bindenter;
230 QString m_lastfile; 230 QString m_lastfile;
231 size_t m_lastposn; 231 size_t m_lastposn;
232 public: 232 public:
233 bool bDoUpdates; 233 bool bDoUpdates;
234 void NavUp(); 234 void NavUp();
235 void NavDown(); 235 void NavDown();
236 tchar getch() { return buffdoc.getch(); } 236 tchar getch() { return buffdoc.getch(); }
237 bool synch(size_t, size_t); 237 bool synch(size_t, size_t);
238 bool tight; 238 bool tight;
239 bool load_file(const char *newfile, unsigned int lcn=0); 239 bool load_file(const char *newfile, unsigned int lcn=0);
240 BuffDoc buffdoc; 240 BuffDoc buffdoc;
241 CList<Bkmk>* getbkmklist() { return buffdoc.getbkmklist(); } 241 CList<Bkmk>* getbkmklist() { return buffdoc.getbkmklist(); }
242 bool locate(unsigned long n); 242 bool locate(unsigned long n);
243 void jumpto(unsigned long n) { buffdoc.unsuspend(); buffdoc.locate(n); } 243 void jumpto(unsigned long n) { buffdoc.unsuspend(); buffdoc.locate(n); }
244 unsigned long locate() { buffdoc.unsuspend(); return buffdoc.locate(); } 244 unsigned long locate() { buffdoc.unsuspend(); return buffdoc.locate(); }
245 unsigned long explocate() { buffdoc.unsuspend(); return buffdoc.explocate(); } 245 unsigned long explocate() { buffdoc.unsuspend(); return buffdoc.explocate(); }
246 unsigned long pagelocate() { return locnarray[0]; } 246 unsigned long pagelocate() { return locnarray[0]; }
247 unsigned long mylastpos; 247 unsigned long mylastpos;
248 void setfilter(CFilterChain *f) { buffdoc.unsuspend(); buffdoc.setfilter(f); locate(pagelocate()); } 248 void setfilter(CFilterChain *f) { buffdoc.unsuspend(); buffdoc.setfilter(f); locate(pagelocate()); }
249 void restore() { jumpto(mylastpos); } 249 void restore() { jumpto(mylastpos); }
250 void goUp(); 250 void goUp();
251 void refresh() { locate(pagelocate()); } 251 void refresh() { locate(pagelocate()); }
252 void goDown(); 252 void goDown();
253 // bool bold; 253 // bool bold;
254 int textsize() { return m_textsize; } 254 int textsize() { return m_textsize; }
255 void textsize(int ts) { m_textsize = ts; } 255 void textsize(int ts) { m_textsize = ts; }
256 bool fillbuffer(int ru = 0, int ht = 0, int newht = -1); 256 bool fillbuffer(int ru = 0, int ht = 0, int newht = -1);
257 unsigned int screenlines(); 257 unsigned int screenlines();
258 void sizes(unsigned long& fs, unsigned long& ts) { buffdoc.unsuspend(); buffdoc.sizes(fs,ts); } 258 void sizes(unsigned long& fs, unsigned long& ts) { buffdoc.unsuspend(); buffdoc.sizes(fs,ts); }
259 static const char *fonts[]; 259 static const char *fonts[];
260// unsigned int *fontsizes; 260// unsigned int *fontsizes;
261 int m_ascent, m_descent, m_linespacing; 261 int m_ascent, m_descent, m_linespacing;
262 QFontMetrics* m_fm; 262 QFontMetrics* m_fm;
263 QString firstword(); 263 QString firstword();
264 264
265 signals: 265 signals:
266 void OnRedraw(); 266 void OnRedraw();
267 void OnWordSelected(const QString&, size_t, const QString&); 267 void OnWordSelected(const QString&, size_t, const QString&);
268 void OnShowPicture(QImage&); 268 void OnShowPicture(QImage&);
269 void OnURLSelected(const QString&); 269 void OnURLSelected(const QString&);
270}; 270};
271 271
272#endif 272#endif
diff --git a/noncore/apps/opie-reader/QTReaderApp.h b/noncore/apps/opie-reader/QTReaderApp.h
index ab6f60e..fe3eebf 100644
--- a/noncore/apps/opie-reader/QTReaderApp.h
+++ b/noncore/apps/opie-reader/QTReaderApp.h
@@ -1,442 +1,442 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qt Palmtop Environment. 4** This file is part of Qt Palmtop Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#ifndef __QTREADERAPP_H 20#ifndef __QTREADERAPP_H
21#define __QTREADERAPP_H 21#define __QTREADERAPP_H
22 22
23//#define _SCROLLPIPE 23//#define _SCROLLPIPE
24//#define __ISEARCH 24//#define __ISEARCH
25 25
26//#define MAX_ENCODING 6 26//#define MAX_ENCODING 6
27#define MAX_ACTIONS 5 27#define MAX_ACTIONS 5
28 28
29#include "useqpe.h" 29#include "useqpe.h"
30#include <sys/timeb.h> 30#include <sys/timeb.h>
31#include <qmainwindow.h> 31#include <qmainwindow.h>
32#include "CExpander.h" 32#include "CExpander.h"
33#include "CEncoding.h" 33#include "CEncoding.h"
34#include <qlist.h> 34#include <qlist.h>
35//#include <qpe/filemanager.h> 35//#include <qpe/filemanager.h>
36#include <qmap.h> 36#include <qmap.h>
37#include <qlineedit.h> 37#include <qlineedit.h>
38#include <qstack.h> 38#include <qstack.h>
39#include <qlistbox.h> 39#include <qlistbox.h>
40//#include "Queue.h" 40//#include "Queue.h"
41 41
42class QWidgetStack; 42class QWidgetStack;
43class QToolButton; 43class QToolButton;
44class QPopupMenu; 44class QPopupMenu;
45class QToolBar; 45class QToolBar;
46#ifdef USEQPE 46#ifdef USEQPE
47class QToolBar; 47class QToolBar;
48class QMenuBar; 48class QMenuBar;
49#endif 49#endif
50class CBkmkSelector; 50class CBkmkSelector;
51class QProgressBar; 51class QProgressBar;
52class QAction; 52class QAction;
53class CAnnoEdit; 53class CAnnoEdit;
54class QFloatBar; 54class QFloatBar;
55class CDrawBuffer; 55class CDrawBuffer;
56class QTReader; 56class QTReader;
57class QImage; 57class QImage;
58class Config; 58class Config;
59 59
60enum ActionTypes 60enum ActionTypes
61{ 61{
62 cesNone = 0, 62 cesNone = 0,
63 cesOpenFile, 63 cesOpenFile,
64 cesAutoScroll, 64 cesAutoScroll,
65 cesActionMark, 65 cesActionMark,
66 cesActionAnno, 66 cesActionAnno,
67 cesFullScreen, 67 cesFullScreen,
68 cesZoomIn, 68 cesZoomIn,
69 cesZoomOut, 69 cesZoomOut,
70 cesBack, 70 cesBack,
71 cesForward, 71 cesForward,
72 cesHome, 72 cesHome,
73 cesPageUp, 73 cesPageUp,
74 cesPageDown, 74 cesPageDown,
75 cesLineUp, 75 cesLineUp,
76 cesLineDown, 76 cesLineDown,
77 cesStartDoc, 77 cesStartDoc,
78 cesEndDoc 78 cesEndDoc
79}; 79};
80/* 80/*
81*m_preferences_action, *m_close_action *m_info_action, *m_touch_action, 81*m_preferences_action, *m_close_action *m_info_action, *m_touch_action,
82*m_find_action, *m_jump_action, *m_setfont_action *m_goto_action, 82*m_find_action, *m_jump_action, *m_setfont_action *m_goto_action,
83*m_delete_action; *m_autogen_action, *m_clear_action, *m_save_action; 83*m_delete_action; *m_autogen_action, *m_clear_action, *m_save_action;
84*m_tidy_action, *m_startBlock_action, *m_endBlock_action; 84*m_tidy_action, *m_startBlock_action, *m_endBlock_action;
85*m_setenc_action, *m_setmono_action; 85*m_setenc_action, *m_setmono_action;
86*/ 86*/
87enum ToolbarPolicy 87enum ToolbarPolicy
88{ 88{
89 cesSingle = 0, 89 cesSingle = 0,
90 cesMenuTool, 90 cesMenuTool,
91 cesMultiple 91 cesMultiple
92}; 92};
93 93
94enum regedit_type 94enum regedit_type
95{ 95{
96 cAutoGen, 96 cAutoGen,
97 cAddBkmk, 97 cAddBkmk,
98 cJump, 98 cJump,
99 cMonoSpace, 99 cMonoSpace,
100 cSetTarget, 100 cSetTarget,
101#ifdef _SCROLLPIPE 101#ifdef _SCROLLPIPE
102 cSetPipeTarget, 102 cSetPipeTarget,
103#endif 103#endif
104 cSetConfigName, 104 cSetConfigName,
105 cMargin, 105 cMargin,
106 cExtraSpace, 106 cExtraSpace,
107 cExtraLead 107 cExtraLead
108}; 108};
109 109
110enum bkmk_action 110enum bkmk_action
111{ 111{
112 cOpenFile, 112 cOpenFile,
113 cGotoBkmk, 113 cGotoBkmk,
114 cDelBkmk, 114 cDelBkmk,
115 cRmBkmkFile, 115 cRmBkmkFile,
116 cLdConfig, 116 cLdConfig,
117 cRmConfig, 117 cRmConfig,
118 cExportLinks 118 cExportLinks
119}; 119};
120 120
121enum fontselector_action 121enum fontselector_action
122{ 122{
123 cChooseFont, 123 cChooseFont,
124 cChooseEncoding 124 cChooseEncoding
125}; 125};
126 126
127#ifdef __ISEARCH 127#ifdef __ISEARCH
128struct searchrecord 128struct searchrecord
129{ 129{
130 QString s; 130 QString s;
131 size_t pos; 131 size_t pos;
132 searchrecord(const QString& _s, size_t _pos) : s(_s), pos(_pos) {} 132 searchrecord(const QString& _s, size_t _pos) : s(_s), pos(_pos) {}
133}; 133};
134#endif 134#endif
135 135
136class infowin; 136class infowin;
137class GraphicWin; 137class GraphicWin;
138 138
139class QTReaderApp : public QMainWindow 139class QTReaderApp : public QMainWindow
140{ 140{
141 Q_OBJECT 141 Q_OBJECT
142 142
143 unsigned long m_savedpos; 143 unsigned long m_savedpos;
144 int m_debounce; 144 int m_debounce;
145 timeb m_lastkeytime; 145 timeb m_lastkeytime;
146 bool m_annoIsEditing; 146 bool m_annoIsEditing;
147 bool m_propogatefontchange, m_bFloatingDialog; 147 bool m_propogatefontchange, m_bFloatingDialog;
148 bool m_url_clipboard, m_url_localfile, m_url_globalfile; 148 bool m_url_clipboard, m_url_localfile, m_url_globalfile;
149 fontselector_action m_fontAction; 149 fontselector_action m_fontAction;
150 void doAction(ActionTypes a, QKeyEvent* e); 150 void doAction(ActionTypes a, QKeyEvent* e);
151 151
152 public: 152 public:
153 QTReaderApp( QWidget *parent = 0, const char *name = 0, WFlags f = 0 ); 153 QTReaderApp( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
154 ~QTReaderApp(); 154 ~QTReaderApp();
155 155
156 void handlekey(QKeyEvent* e); 156 void handlekey(QKeyEvent* e);
157 void hideEvent(QHideEvent*) 157 void hideEvent(QHideEvent*)
158 { 158 {
159 suspend(); 159 suspend();
160 } 160 }
161 161
162 void suspend(); 162 void suspend();
163 void openFile( const QString & ); 163 void openFile( const QString & );
164 164
165 void setScrollState(bool _b); 165 void setScrollState(bool _b);
166 166
167 protected: 167 protected:
168 void setfontHelper(const QString& lcn, int size = 0); 168 void setfontHelper(const QString& lcn, int size = 0);
169 QAction* m_bkmkAvail, *m_actFullscreen; 169 QAction* m_bkmkAvail, *m_actFullscreen;
170 CAnnoEdit* m_annoWin; 170 CAnnoEdit* m_annoWin;
171 Bkmk* m_anno; 171 Bkmk* m_anno;
172// void resizeEvent(QResizeEvent* e); 172// void resizeEvent(QResizeEvent* e);
173 void closeEvent( QCloseEvent *e ); 173 void closeEvent( QCloseEvent *e );
174 void readbkmks(); 174 void readbkmks();
175 void do_mono(const QString&); 175 void do_mono(const QString&);
176 void do_jump(const QString&); 176 void do_jump(const QString&);
177 void do_settarget(const QString&); 177 void do_settarget(const QString&);
178#ifdef _SCROLLPIPE 178#ifdef _SCROLLPIPE
179 //void do_setpipetarget(const QString&); 179// void do_setpipetarget(const QString&);
180#endif 180#endif
181 void do_saveconfig(const QString&, bool); 181 void do_saveconfig(const QString&, bool);
182 bool readconfig(const QString&, bool); 182 bool readconfig(const QString&, bool);
183 bool PopulateConfig(const char*); 183 bool PopulateConfig(const char*);
184 ActionTypes ActNameToInt(const QString&); 184 ActionTypes ActNameToInt(const QString&);
185 bool m_doAnnotation; 185 bool m_doAnnotation;
186 bool m_doDictionary; 186 bool m_doDictionary;
187 bool m_doClipboard; 187 bool m_doClipboard;
188 bool m_fullscreen; 188 bool m_fullscreen;
189 bool m_loadedconfig; 189 bool m_loadedconfig;
190 public: 190 public:
191 void saveprefs(); 191 void saveprefs();
192public slots: 192public slots:
193 void setDocument(const QString&); 193 void setDocument(const QString&);
194private slots: 194private slots:
195#ifdef _SCRIPT 195#ifdef _SCRIPT
196// void RunScript(); 196// void RunScript();
197#endif 197#endif
198 void SaveConfig(); 198 void SaveConfig();
199 void LoadConfig(); 199 void LoadConfig();
200 void TidyConfig(); 200 void TidyConfig();
201 void ExportLinks(); 201 void ExportLinks();
202 void zoomin(); 202 void zoomin();
203 void zoomout(); 203 void zoomout();
204 void chooseencoding(); 204 void chooseencoding();
205 void setfullscreen(bool sfs); 205 void setfullscreen(bool sfs);
206// void setcontinuous(bool sfs); 206// void setcontinuous(bool sfs);
207 void setTwoTouch(bool _b); 207 void setTwoTouch(bool _b);
208 void restoreFocus(); 208 void restoreFocus();
209 void OnAnnotation(bool _b) 209 void OnAnnotation(bool _b)
210 { 210 {
211 m_doAnnotation = _b; 211 m_doAnnotation = _b;
212 } 212 }
213 void OnDictionary(bool _b) 213 void OnDictionary(bool _b)
214 { 214 {
215 m_doDictionary = _b; 215 m_doDictionary = _b;
216 } 216 }
217 void OnClipboard(bool _b) 217 void OnClipboard(bool _b)
218 { 218 {
219 m_doClipboard = _b; 219 m_doClipboard = _b;
220 } 220 }
221 void OnWordSelected(const QString&, size_t, const QString&); 221 void OnWordSelected(const QString&, size_t, const QString&);
222 void OnURLSelected(const QString& href); 222 void OnURLSelected(const QString& href);
223 void showgraphic(QImage&); 223 void showgraphic(QImage&);
224 void addAnno(const QString&, const QString&, size_t); 224 void addAnno(const QString&, const QString&, size_t);
225 void addAnno(const QString&, const QString&); 225 void addAnno(const QString&, const QString&);
226 void addanno(); 226 void addanno();
227 void showAnnotation(); 227 void showAnnotation();
228 void do_setencoding(int i); 228 void do_setencoding(int i);
229 void do_setfont(const QString&); 229 void do_setfont(const QString&);
230 void buttonActionSelected(QAction*); 230 void buttonActionSelected(QAction*);
231 //void msgHandler(const QCString&, const QByteArray&); 231// void msgHandler(const QCString&, const QByteArray&);
232 void monospace(bool); 232 void monospace(bool);
233 void jump(); 233 void jump();
234 void settarget(); 234 void settarget();
235#ifdef _SCROLLPIPE 235#ifdef _SCROLLPIPE
236 //void setpipetarget(); 236// void setpipetarget();
237 //void setpause(bool); 237// void setpause(bool);
238#endif 238#endif
239 //void setspacing(); 239// void setspacing();
240 void setfont(); 240 void setfont();
241 void clearBkmkList(); 241 void clearBkmkList();
242 void listBkmkFiles(); 242 void listBkmkFiles();
243 void editMark(); 243 void editMark();
244 void autoScroll(bool); 244 void autoScroll(bool);
245 void addbkmk(); 245 void addbkmk();
246 void savebkmks(); 246 void savebkmks();
247 //void importFiles(); 247// void importFiles();
248 void showprefs(); 248 void showprefs();
249 void showtoolbarprefs(); 249 void showtoolbarprefs();
250 void infoClose(); 250 void infoClose();
251 // void oldFile(); 251 // void oldFile();
252 void showinfo(); 252 void showinfo();
253 253
254// void indentplus(); 254// void indentplus();
255// void indentminus(); 255// void indentminus();
256 256
257 void fileOpen(); 257 void fileOpen();
258 void fileClose(); 258 void fileClose();
259 259
260 void editCopy(); 260 void editCopy();
261 void editFind(); 261 void editFind();
262 262
263 void gotoStart(); 263 void gotoStart();
264 void gotoEnd(); 264 void gotoEnd();
265 265
266 void pageup(); 266 void pageup();
267 void pagedn(); 267 void pagedn();
268 268
269 void findNext(); 269 void findNext();
270 void findClose(); 270 void findClose();
271 271
272 void regClose(); 272 void regClose();
273 273
274#ifdef __ISEARCH 274#ifdef __ISEARCH
275// void search( const QString& ); 275// void search( const QString& );
276#else 276#else
277 void search(); 277 void search();
278#endif 278#endif
279 279
280 void showEditTools(); 280 void showEditTools();
281 281
282// void stripcr(bool); 282// void stripcr(bool);
283// void setfulljust(bool); 283// void setfulljust(bool);
284// void onespace(bool); 284// void onespace(bool);
285#ifdef REPALM 285#ifdef REPALM
286// void repalm(bool); 286// void repalm(bool);
287#endif 287#endif
288// void peanut(bool _b); 288// void peanut(bool _b);
289// void remap(bool); 289// void remap(bool);
290// void embolden(bool); 290// void embolden(bool);
291// void autofmt(bool); 291// void autofmt(bool);
292// void textfmt(bool); 292// void textfmt(bool);
293// void striphtml(bool); 293// void striphtml(bool);
294// void dehyphen(bool); 294// void dehyphen(bool);
295// void depluck(bool); 295// void depluck(bool);
296// void dejpluck(bool); 296// void dejpluck(bool);
297// void unindent(bool); 297// void unindent(bool);
298// void repara(bool); 298// void repara(bool);
299// void dblspce(bool); 299// void dblspce(bool);
300 void pagemode(bool); 300 void pagemode(bool);
301 // void gotobkmk(const QString& bm); 301 // void gotobkmk(const QString& bm);
302 void gotobkmk(int); 302 void gotobkmk(int);
303 void cancelbkmk(); 303 void cancelbkmk();
304 void do_gotomark(); 304 void do_gotomark();
305 void do_delmark(); 305 void do_delmark();
306 void do_autogen(); 306 void do_autogen();
307 void do_regaction(); 307 void do_regaction();
308 void OnRedraw(); 308 void OnRedraw();
309 309
310 private: 310 private:
311 void writeUrl(const QString& file, const QString& href); 311 void writeUrl(const QString& file, const QString& href);
312 QAction *m_preferences_action, *m_open_action, *m_close_action; 312 QAction *m_preferences_action, *m_open_action, *m_close_action;
313 QAction *m_info_action, *m_touch_action, *m_find_action, *m_start_action; 313 QAction *m_info_action, *m_touch_action, *m_find_action, *m_start_action;
314 QAction *m_end_action, *m_jump_action, *m_pageline_action; 314 QAction *m_end_action, *m_jump_action, *m_pageline_action;
315 QAction *m_pageup_action, *m_pagedn_action, *m_back_action; 315 QAction *m_pageup_action, *m_pagedn_action, *m_back_action;
316 QAction *m_home_action, *m_forward_action, *m_zoomin_action; 316 QAction *m_home_action, *m_forward_action, *m_zoomin_action;
317 QAction *m_zoomout_action, *m_setfont_action, *m_mark_action; 317 QAction *m_zoomout_action, *m_setfont_action, *m_mark_action;
318 QAction *m_annotate_action, *m_goto_action, *m_delete_action; 318 QAction *m_annotate_action, *m_goto_action, *m_delete_action;
319 QAction *m_autogen_action, *m_clear_action, *m_save_action; 319 QAction *m_autogen_action, *m_clear_action, *m_save_action;
320 QAction *m_tidy_action, *m_startBlock_action, *m_endBlock_action; 320 QAction *m_tidy_action, *m_startBlock_action, *m_endBlock_action;
321 QAction *m_setenc_action, *m_setmono_action, *m_saveconfig_action; 321 QAction *m_setenc_action, *m_setmono_action, *m_saveconfig_action;
322 QAction *m_loadconfig_action, *m_toolbarprefs_action, *m_tidyconfig_action; 322 QAction *m_loadconfig_action, *m_toolbarprefs_action, *m_tidyconfig_action;
323 QAction *m_exportlinks_action; 323 QAction *m_exportlinks_action;
324 void addtoolbars(Config* config); 324 void addtoolbars(Config* config);
325 ToolbarPolicy m_tbpol, m_tbpolsave; 325 ToolbarPolicy m_tbpol, m_tbpolsave;
326 ToolBarDock m_tbposition; 326 ToolBarDock m_tbposition;
327 bool m_tbmove, m_tbmovesave; 327 bool m_tbmove, m_tbmovesave;
328 QToolBar* filebar(); 328 QToolBar* filebar();
329 QToolBar* viewbar(); 329 QToolBar* viewbar();
330 QToolBar* navbar(); 330 QToolBar* navbar();
331 QToolBar* markbar(); 331 QToolBar* markbar();
332 void hidetoolbars(); 332 void hidetoolbars();
333 void addfilebar(Config* _config, const QString& key, QAction* a); 333 void addfilebar(Config* _config, const QString& key, QAction* a);
334 void addviewbar(Config* _config, const QString& key, QAction* a); 334 void addviewbar(Config* _config, const QString& key, QAction* a);
335 void addnavbar(Config* _config, const QString& key, QAction* a); 335 void addnavbar(Config* _config, const QString& key, QAction* a);
336 void addmarkbar(Config* _config, const QString& key, QAction* a); 336 void addmarkbar(Config* _config, const QString& key, QAction* a);
337 bool checkbar(Config* _config, const QString& key); 337 bool checkbar(Config* _config, const QString& key);
338#ifdef _SCRIPT 338#ifdef _SCRIPT
339 void SaveScript(const char* sname); 339 void SaveScript(const char* sname);
340#endif 340#endif
341/* 341/*
342 void setstate(unsigned char* _sd, unsigned short _sdlen); 342 void setstate(unsigned char* _sd, unsigned short _sdlen);
343 void getstate(unsigned char*& data, unsigned short& len); 343 void getstate(unsigned char*& data, unsigned short& len);
344*/ 344*/
345 void fileOpen2(); 345 void fileOpen2();
346 void readfilelist(); 346 void readfilelist();
347 void savefilelist(); 347 void savefilelist();
348 void updatefileinfo(); 348 void updatefileinfo();
349 bool openfrombkmk(Bkmk*); 349 bool openfrombkmk(Bkmk*);
350 QString m_targetapp, m_targetmsg; 350 QString m_targetapp, m_targetmsg;
351 bool listbkmk(CList<Bkmk>*, const QString& _lab = QString::null); 351 bool listbkmk(CList<Bkmk>*, const QString& _lab = QString::null);
352 QString usefilebrowser(); 352 QString usefilebrowser();
353 void do_regedit(); 353 void do_regedit();
354 void colorChanged( const QColor &c ); 354 void colorChanged( const QColor &c );
355 void clear(); 355 void clear();
356 void updateCaption(); 356 void updateCaption();
357 void do_autogen(const QString&); 357 void do_autogen(const QString&);
358 void do_addbkmk(const QString&); 358 void do_addbkmk(const QString&);
359 bool findNextBookmark(size_t start); 359 bool findNextBookmark(size_t start);
360 360
361 private: 361 private:
362 362
363 QAction* m_scrollButton; 363 QAction* m_scrollButton;
364 364
365 QAction* m_buttonAction[MAX_ACTIONS]; 365 QAction* m_buttonAction[MAX_ACTIONS];
366 366
367 CBkmkSelector* bkmkselector; 367 CBkmkSelector* bkmkselector;
368 368
369 ActionTypes m_spaceTarget, m_escapeTarget, m_returnTarget, m_leftTarget, m_rightTarget, 369 ActionTypes m_spaceTarget, m_escapeTarget, m_returnTarget, m_leftTarget, m_rightTarget,
370 m_upTarget, m_downTarget; 370 m_upTarget, m_downTarget;
371 bool m_leftScroll, m_rightScroll, m_upScroll, m_downScroll; 371 bool m_leftScroll, m_rightScroll, m_upScroll, m_downScroll;
372 bool m_bcloseDisabled, m_disableesckey; 372 bool m_bcloseDisabled, m_disableesckey;
373 size_t searchStart; 373 size_t searchStart;
374#ifdef __ISEARCH 374#ifdef __ISEARCH
375 QStack<searchrecord>* searchStack; 375 QStack<searchrecord>* searchStack;
376 bool dosearch(size_t start, CDrawBuffer& test, const QString& arg); 376 bool dosearch(size_t start, CDrawBuffer& test, const QString& arg);
377#else 377#else
378 bool dosearch(size_t start, CDrawBuffer& test, const QRegExp& arg); 378 bool dosearch(size_t start, CDrawBuffer& test, const QRegExp& arg);
379#endif 379#endif
380 QWidgetStack *editorStack; 380 QWidgetStack *editorStack;
381 QTReader* reader; 381 QTReader* reader;
382 QComboBox* m_fontSelector; 382 QComboBox* m_fontSelector;
383// QToolBar /* *menu,*/ *fileBar; 383// QToolBar /* *menu,*/ *fileBar;
384 QToolBar *menubar, *fileBar, *navBar, *viewBar, *markBar; 384 QToolBar *menubar, *fileBar, *navBar, *viewBar, *markBar;
385#ifdef USEQPE 385#ifdef USEQPE
386 QMenuBar *mb; 386 QMenuBar *mb;
387#else 387#else
388 QMenuBar *mb; 388 QMenuBar *mb;
389#endif 389#endif
390 QFloatBar *searchBar, *regBar/*, *m_fontBar*/; 390 QFloatBar *searchBar, *regBar/*, *m_fontBar*/;
391 QToolBar /* *searchBar, *regBar,*/ *m_fontBar; 391 QToolBar /* *searchBar, *regBar,*/ *m_fontBar;
392 QLineEdit *searchEdit, *regEdit; 392 QLineEdit *searchEdit, *regEdit;
393 bool searchVisible; 393 bool searchVisible;
394 bool regVisible; 394 bool regVisible;
395 bool m_fontVisible, m_twoTouch; 395 bool m_fontVisible, m_twoTouch;
396 bool bFromDocView; 396 bool bFromDocView;
397 static unsigned long m_uid; 397 static unsigned long m_uid;
398 long unsigned get_unique_id() { return m_uid++; } 398 long unsigned get_unique_id() { return m_uid++; }
399 /* 399 /*
400 void resizeEvent( QResizeEvent * r) 400 void resizeEvent( QResizeEvent * r)
401 { 401 {
402// qDebug("resize:(%u,%u)", r->oldSize().width(), r->oldSize().height()); 402// odebug << "resize:(" << r->oldSize().width() << "," << r->oldSize().height() << ")" << oendl;
403// qDebug("resize:(%u,%u)", r->size().width(), r->size().height()); 403// odebug << "resize:(" << r->size().width() << "," << r->size().height() << ")" << oendl;
404 // bgroup->move( width()-bgroup->width(), 0 ); 404 // bgroup->move( width()-bgroup->width(), 0 );
405 } 405 }
406 */ 406 */
407 CList<Bkmk>* pBkmklist; 407 CList<Bkmk>* pBkmklist;
408 CList<Bkmk>* pOpenlist; 408 CList<Bkmk>* pOpenlist;
409 infowin* m_infoWin; 409 infowin* m_infoWin;
410 GraphicWin* m_graphicwin; 410 GraphicWin* m_graphicwin;
411 QProgressBar* pbar; 411 QProgressBar* pbar;
412 bool m_fBkmksChanged; 412 bool m_fBkmksChanged;
413// int m_nRegAction; 413// int m_nRegAction;
414 regedit_type m_nRegAction; 414 regedit_type m_nRegAction;
415 bkmk_action m_nBkmkAction; 415 bkmk_action m_nBkmkAction;
416 QString m_autogenstr; 416 QString m_autogenstr;
417 bool m_dontSave; 417 bool m_dontSave;
418}; 418};
419 419
420//const int cAutoGen = 0; 420//const int cAutoGen = 0;
421//const int cAddBkmk = 1; 421//const int cAddBkmk = 1;
422//const int cDelBkmk = 2; 422//const int cDelBkmk = 2;
423//const int cGotoBkmk = 3; 423//const int cGotoBkmk = 3;
424//const int cRmBkmkFile = 4; 424//const int cRmBkmkFile = 4;
425//const int cJump = 5; 425//const int cJump = 5;
426//const int cMonoSpace = 6; 426//const int cMonoSpace = 6;
427//const int cOverlap = 7; 427//const int cOverlap = 7;
428//const int cSetTarget = 8; 428//const int cSetTarget = 8;
429//const int cOpenFile = 9; 429//const int cOpenFile = 9;
430//const int cSetPipeTarget = 10; 430//const int cSetPipeTarget = 10;
431//const int cSetConfigName = 11; 431//const int cSetConfigName = 11;
432//const int cMargin = 12; 432//const int cMargin = 12;
433//const int cExtraSpace = 14; 433//const int cExtraSpace = 14;
434//const int cExtraLead = 15; 434//const int cExtraLead = 15;
435//const int cGfxSize = 16; 435//const int cGfxSize = 16;
436//const int cChooseFont = 2; 436//const int cChooseFont = 2;
437//const int cChooseEncoding = 1; 437//const int cChooseEncoding = 1;
438 438
439#endif 439#endif
440 440
441 441
442 442
diff --git a/noncore/apps/tinykate/libkate/document/katedocument.h b/noncore/apps/tinykate/libkate/document/katedocument.h
index 9d8ec6a..969be87 100644
--- a/noncore/apps/tinykate/libkate/document/katedocument.h
+++ b/noncore/apps/tinykate/libkate/document/katedocument.h
@@ -1,278 +1,278 @@
1/*************************************************************************** 1/***************************************************************************
2 katedocument.h - description 2 katedocument.h - description
3 ------------------- 3 -------------------
4 begin : Mon Jan 15 2001 4 begin : Mon Jan 15 2001
5 copyright : (C) 2001 by Christoph "Crossfire" Cullmann 5 copyright : (C) 2001 by Christoph "Crossfire" Cullmann
6 (C) 2002 by Joseph Wenninger 6 (C) 2002 by Joseph Wenninger
7 email : crossfire@babylon2k.de 7 email : crossfire@babylon2k.de
8 jowenn@kde.org 8 jowenn@kde.org
9 9
10***************************************************************************/ 10***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * * 13 * *
14 * This program is free software; you can redistribute it and/or modify * 14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by * 15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or * 16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. * 17 * (at your option) any later version. *
18 * * 18 * *
19 ***************************************************************************/ 19 ***************************************************************************/
20 20
21/* 21/*
22 Copyright (C) 1998, 1999 Jochen Wilhelmy 22 Copyright (C) 1998, 1999 Jochen Wilhelmy
23 digisnap@cs.tu-berlin.de 23 digisnap@cs.tu-berlin.de
24 24
25 This library is free software; you can redistribute it and/or 25 This library is free software; you can redistribute it and/or
26 modify it under the terms of the GNU Library General Public 26 modify it under the terms of the GNU Library General Public
27 License as published by the Free Software Foundation; either 27 License as published by the Free Software Foundation; either
28 version 2 of the License, or (at your option) any later version. 28 version 2 of the License, or (at your option) any later version.
29 29
30 This library is distributed in the hope that it will be useful, 30 This library is distributed in the hope that it will be useful,
31 but WITHOUT ANY WARRANTY; without even the implied warranty of 31 but WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 Library General Public License for more details. 33 Library General Public License for more details.
34 34
35 You should have received a copy of the GNU Library General Public License 35 You should have received a copy of the GNU Library General Public License
36 along with this library; see the file COPYING.LIB. If not, write to 36 along with this library; see the file COPYING.LIB. If not, write to
37 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 37 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
38 Boston, MA 02111-1307, USA. 38 Boston, MA 02111-1307, USA.
39*/ 39*/
40 40
41#ifndef kate_document_h 41#ifndef kate_document_h
42#define kate_document_h 42#define kate_document_h
43 43
44 44
45#include <qobject.h> 45#include <qobject.h>
46#include <qlist.h> 46#include <qlist.h>
47#include <qcolor.h> 47#include <qcolor.h>
48#include <qfont.h> 48#include <qfont.h>
49#include <qfontmetrics.h> 49#include <qfontmetrics.h>
50#include <qdatetime.h> 50#include <qdatetime.h>
51#include <qfileinfo.h> 51#include <qfileinfo.h>
52 52
53#include "../view/kateview.h" 53#include "../view/kateview.h"
54#include "katehighlight.h" 54#include "katehighlight.h"
55#include "katebuffer.h" 55#include "katebuffer.h"
56#include "katetextline.h" 56#include "katetextline.h"
57 57
58 58
59#include <qptrdict.h> 59#include <qptrdict.h>
60 60
61class KateCmd; 61class KateCmd;
62 62
63class CachedFontMetrics : public QFontMetrics { 63class CachedFontMetrics : public QFontMetrics {
64private: 64private:
65 short *warray[256]; 65 short *warray[256];
66public: 66public:
67 CachedFontMetrics(const QFont& f) : QFontMetrics(f) { 67 CachedFontMetrics(const QFont& f) : QFontMetrics(f) {
68 for (int i=0; i<256; i++) warray[i]=0; 68 for (int i=0; i<256; i++) warray[i]=0;
69 } 69 }
70 ~CachedFontMetrics() { 70 ~CachedFontMetrics() {
71 for (int i=0; i<256; i++) 71 for (int i=0; i<256; i++)
72 if (warray[i]) delete[] warray[i]; 72 if (warray[i]) delete[] warray[i];
73 } 73 }
74 int width(QChar c) { 74 int width(QChar c) {
75 uchar cell=c.cell(); 75 uchar cell=c.cell();
76 uchar row=c.row(); 76 uchar row=c.row();
77 short *wa=warray[row]; 77 short *wa=warray[row];
78 if (!wa) { 78 if (!wa) {
79 // qDebug("create row: %d",row); 79 // odebug << "create row: " << row << oendl;
80 wa=warray[row]=new short[256]; 80 wa=warray[row]=new short[256];
81 for (int i=0; i<256; i++) wa[i]=-1; 81 for (int i=0; i<256; i++) wa[i]=-1;
82 } 82 }
83 if (wa[cell]<0) wa[cell]=(short) QFontMetrics::width(c); 83 if (wa[cell]<0) wa[cell]=(short) QFontMetrics::width(c);
84 return (int)wa[cell]; 84 return (int)wa[cell];
85 } 85 }
86 int width(QString s) { return QFontMetrics::width(s); } 86 int width(QString s) { return QFontMetrics::width(s); }
87}; 87};
88 88
89class Attribute { 89class Attribute {
90 public: 90 public:
91 Attribute() { ; }; 91 Attribute() { ; };
92 92
93 QColor col; 93 QColor col;
94 QColor selCol; 94 QColor selCol;
95 bool bold; 95 bool bold;
96 bool italic; 96 bool italic;
97}; 97};
98 98
99class KateAction { 99class KateAction {
100 public: 100 public:
101 enum Action {replace, wordWrap, wordUnWrap, newLine, delLine, 101 enum Action {replace, wordWrap, wordUnWrap, newLine, delLine,
102 insLine, killLine};//, doubleLine, removeLine}; 102 insLine, killLine};//, doubleLine, removeLine};
103 103
104 KateAction(Action, PointStruc &cursor, int len = 0, 104 KateAction(Action, PointStruc &cursor, int len = 0,
105 const QString &text = QString::null); 105 const QString &text = QString::null);
106 106
107 Action action; 107 Action action;
108 PointStruc cursor; 108 PointStruc cursor;
109 int len; 109 int len;
110 QString text; 110 QString text;
111 KateAction *next; 111 KateAction *next;
112}; 112};
113 113
114class KateActionGroup { 114class KateActionGroup {
115 public: 115 public:
116 // the undo group types 116 // the undo group types
117 enum { ugNone, // 117 enum { ugNone, //
118 ugPaste, // paste 118 ugPaste, // paste
119 ugDelBlock, // delete/replace selected text 119 ugDelBlock, // delete/replace selected text
120 ugIndent, // indent 120 ugIndent, // indent
121 ugUnindent, // unindent 121 ugUnindent, // unindent
122 ugComment, // comment 122 ugComment, // comment
123 ugUncomment, // uncomment 123 ugUncomment, // uncomment
124 ugReplace, // text search/replace 124 ugReplace, // text search/replace
125 ugSpell, // spell check 125 ugSpell, // spell check
126 ugInsChar, // char type/deleting 126 ugInsChar, // char type/deleting
127 ugDelChar, // '' '' 127 ugDelChar, // '' ''
128 ugInsLine, // line insert/delete 128 ugInsLine, // line insert/delete
129 ugDelLine // '' '' 129 ugDelLine // '' ''
130 }; 130 };
131 131
132 KateActionGroup(PointStruc &aStart, int type = ugNone); 132 KateActionGroup(PointStruc &aStart, int type = ugNone);
133 ~KateActionGroup(); 133 ~KateActionGroup();
134 void insertAction(KateAction *); 134 void insertAction(KateAction *);
135 135
136 static const char * typeName(int type); 136 static const char * typeName(int type);
137 137
138 PointStruc start; 138 PointStruc start;
139 PointStruc end; 139 PointStruc end;
140 KateAction *action; 140 KateAction *action;
141 int undoType; 141 int undoType;
142}; 142};
143 143
144/** 144/**
145 The text document. It contains the textlines, controls the 145 The text document. It contains the textlines, controls the
146 document changing operations and does undo/redo. WARNING: do not change 146 document changing operations and does undo/redo. WARNING: do not change
147 the text contents directly in methods where this is not explicitly 147 the text contents directly in methods where this is not explicitly
148 permitted. All changes have to be made with some basic operations, 148 permitted. All changes have to be made with some basic operations,
149 which are recorded by the undo/redo system. 149 which are recorded by the undo/redo system.
150 @see TextLine 150 @see TextLine
151 @author Jochen Wilhelmy 151 @author Jochen Wilhelmy
152*/ 152*/
153class KateDocument: public Kate::Document 153class KateDocument: public Kate::Document
154{ 154{
155 Q_OBJECT 155 Q_OBJECT
156 friend class KateViewInternal; 156 friend class KateViewInternal;
157 friend class KateView; 157 friend class KateView;
158 friend class KateIconBorder; 158 friend class KateIconBorder;
159 159
160 public: 160 public:
161 KateDocument(bool bSingleViewMode=false, bool bBrowserView=false, QWidget *parentWidget = 0, const char *widgetName = 0, QObject * = 0, const char * = 0); 161 KateDocument(bool bSingleViewMode=false, bool bBrowserView=false, QWidget *parentWidget = 0, const char *widgetName = 0, QObject * = 0, const char * = 0);
162 ~KateDocument(); 162 ~KateDocument();
163 163
164 protected: 164 protected:
165 QFont myFont, myFontBold, myFontItalic, myFontBI; 165 QFont myFont, myFontBold, myFontItalic, myFontBI;
166 CachedFontMetrics myFontMetrics, myFontMetricsBold, myFontMetricsItalic, myFontMetricsBI; 166 CachedFontMetrics myFontMetrics, myFontMetricsBold, myFontMetricsItalic, myFontMetricsBI;
167 167
168 public: 168 public:
169 void setFont (QFont font); 169 void setFont (QFont font);
170 QFont getFont () { return myFont; }; 170 QFont getFont () { return myFont; };
171 CachedFontMetrics getFontMetrics () { return myFontMetrics; }; 171 CachedFontMetrics getFontMetrics () { return myFontMetrics; };
172 172
173 virtual bool saveFile(); 173 virtual bool saveFile();
174 174
175 virtual KTextEditor::View *createView( QWidget *parent, const char *name ); 175 virtual KTextEditor::View *createView( QWidget *parent, const char *name );
176 virtual QString textLine( int line ) const; 176 virtual QString textLine( int line ) const;
177 177
178 virtual void insertLine( const QString &s, int line = -1 ); 178 virtual void insertLine( const QString &s, int line = -1 );
179 179
180 void insert_Line(const QString& s,int line=-1, bool update=true); 180 void insert_Line(const QString& s,int line=-1, bool update=true);
181 void remove_Line(int line,bool update=true); 181 void remove_Line(int line,bool update=true);
182 void replaceLine(const QString& s,int line=-1); 182 void replaceLine(const QString& s,int line=-1);
183 virtual void insertAt( const QString &s, int line, int col, bool mark = FALSE ); 183 virtual void insertAt( const QString &s, int line, int col, bool mark = FALSE );
184 virtual void removeLine( int line ); 184 virtual void removeLine( int line );
185 virtual int length() const; 185 virtual int length() const;
186 186
187 virtual void setSelection( int row_from, int col_from, int row_to, int col_t ); 187 virtual void setSelection( int row_from, int col_from, int row_to, int col_t );
188 virtual bool hasSelection() const; 188 virtual bool hasSelection() const;
189 virtual QString selection() const; 189 virtual QString selection() const;
190 190
191 // only to make part work, don't change it ! 191 // only to make part work, don't change it !
192 bool m_bSingleViewMode; 192 bool m_bSingleViewMode;
193 193
194// public interface 194// public interface
195 /** 195 /**
196 * gets the number of lines 196 * gets the number of lines
197 */ 197 */
198 virtual int numLines() const; 198 virtual int numLines() const;
199 199
200 /** 200 /**
201 * gets the last line number (numLines() -1) 201 * gets the last line number (numLines() -1)
202 */ 202 */
203 int lastLine() const {return numLines()-1;} 203 int lastLine() const {return numLines()-1;}
204 204
205 /** 205 /**
206 gets the given line 206 gets the given line
207 @return the TextLine object at the given line 207 @return the TextLine object at the given line
208 @see TextLine 208 @see TextLine
209 */ 209 */
210 TextLine::Ptr getTextLine(int line) const; 210 TextLine::Ptr getTextLine(int line) const;
211 211
212 /** 212 /**
213 get the length in pixels of the given line 213 get the length in pixels of the given line
214 */ 214 */
215 int textLength(int line); 215 int textLength(int line);
216 216
217 void setTabWidth(int); 217 void setTabWidth(int);
218 int tabWidth() {return tabChars;} 218 int tabWidth() {return tabChars;}
219 void setReadOnly(bool); 219 void setReadOnly(bool);
220 bool isReadOnly() const; 220 bool isReadOnly() const;
221 void setNewDoc( bool ); 221 void setNewDoc( bool );
222 bool isNewDoc() const; 222 bool isNewDoc() const;
223 virtual void setReadWrite( bool ){}; 223 virtual void setReadWrite( bool ){};
224 virtual bool isReadWrite() const {return true;} 224 virtual bool isReadWrite() const {return true;}
225 virtual void setModified(bool); 225 virtual void setModified(bool);
226 virtual bool isModified() const; 226 virtual bool isModified() const;
227 void setSingleSelection(bool ss) {m_singleSelection = ss;} 227 void setSingleSelection(bool ss) {m_singleSelection = ss;}
228 bool singleSelection() {return m_singleSelection;} 228 bool singleSelection() {return m_singleSelection;}
229 229
230 void readConfig(); 230 void readConfig();
231 void writeConfig(); 231 void writeConfig();
232 void readSessionConfig(KateConfig *); 232 void readSessionConfig(KateConfig *);
233 void writeSessionConfig(KateConfig *); 233 void writeSessionConfig(KateConfig *);
234 234
235 bool hasBrowserExtension() const { return m_bBrowserView; } 235 bool hasBrowserExtension() const { return m_bBrowserView; }
236 236
237 protected: 237 protected:
238 bool m_bBrowserView; 238 bool m_bBrowserView;
239 239
240 signals: 240 signals:
241 void selectionChanged(); 241 void selectionChanged();
242 void highlightChanged(); 242 void highlightChanged();
243 void modifiedChanged (); 243 void modifiedChanged ();
244 void preHighlightChanged(long); 244 void preHighlightChanged(long);
245 245
246 // search stuff 246 // search stuff
247 protected: 247 protected:
248 static QStringList searchForList; 248 static QStringList searchForList;
249 static QStringList replaceWithList; 249 static QStringList replaceWithList;
250 static uint uniqueID; 250 static uint uniqueID;
251 251
252 // highlight stuff 252 // highlight stuff
253 public: 253 public:
254 Highlight *highlight() {return m_highlight;} 254 Highlight *highlight() {return m_highlight;}
255 int highlightNum() {return hlManager->findHl(m_highlight);} 255 int highlightNum() {return hlManager->findHl(m_highlight);}
256 int numAttribs() {return m_numAttribs;} 256 int numAttribs() {return m_numAttribs;}
257 Attribute *attribs() {return m_attribs;} 257 Attribute *attribs() {return m_attribs;}
258 void setDontChangeHlOnSave(); 258 void setDontChangeHlOnSave();
259 259
260 protected: 260 protected:
261 void setHighlight(int n); 261 void setHighlight(int n);
262 void makeAttribs(); 262 void makeAttribs();
263 void updateFontData(); 263 void updateFontData();
264 264
265 protected slots: 265 protected slots:
266 void hlChanged(); 266 void hlChanged();
267 267
268// view interaction 268// view interaction
269 public: 269 public:
270 virtual void addView(KTextEditor::View *); 270 virtual void addView(KTextEditor::View *);
271 virtual void removeView(KTextEditor::View *); 271 virtual void removeView(KTextEditor::View *);
272 bool ownedView(KateView *); 272 bool ownedView(KateView *);
273 bool isLastView(int numViews); 273 bool isLastView(int numViews);
274 274
275 int getTextLineCount() {return numLines();} 275 int getTextLineCount() {return numLines();}
276 276
277 int textWidth(const TextLine::Ptr &, int cursorX); 277 int textWidth(const TextLine::Ptr &, int cursorX);
278 int textWidth(PointStruc &cursor); 278 int textWidth(PointStruc &cursor);
@@ -441,130 +441,130 @@ class KateDocument: public Kate::Document
441 int tagStart; 441 int tagStart;
442 int tagEnd; 442 int tagEnd;
443 int undoCount; //counts merged undo steps 443 int undoCount; //counts merged undo steps
444 444
445 QWidget *pseudoModal; //the replace prompt is pseudo modal 445 QWidget *pseudoModal; //the replace prompt is pseudo modal
446 446
447 public: 447 public:
448 /** Tjecks if the file on disk is newer than document contents. 448 /** Tjecks if the file on disk is newer than document contents.
449 If forceReload is true, the document is reloaded without asking the user, 449 If forceReload is true, the document is reloaded without asking the user,
450 otherwise [default] the user is asked what to do. */ 450 otherwise [default] the user is asked what to do. */
451 void isModOnHD(bool forceReload=false); 451 void isModOnHD(bool forceReload=false);
452 452
453 uint docID () {return myDocID;}; 453 uint docID () {return myDocID;};
454 QString docName () {return myDocName;}; 454 QString docName () {return myDocName;};
455 455
456 void setDocName (QString docName); 456 void setDocName (QString docName);
457 void setDocFile (QString docFile); 457 void setDocFile (QString docFile);
458 458
459 public slots: 459 public slots:
460 /** Reloads the current document from disk if possible */ 460 /** Reloads the current document from disk if possible */
461 void reloadFile(); 461 void reloadFile();
462 462
463 private slots: 463 private slots:
464 void slotModChanged (); 464 void slotModChanged ();
465 465
466 private: 466 private:
467 /** updates mTime to reflect file on fs. 467 /** updates mTime to reflect file on fs.
468 called from constructor and from saveFile. */ 468 called from constructor and from saveFile. */
469 void setMTime(); 469 void setMTime();
470 uint myDocID; 470 uint myDocID;
471 QFileInfo* fileInfo; 471 QFileInfo* fileInfo;
472 QDateTime mTime; 472 QDateTime mTime;
473 QString myDocName; 473 QString myDocName;
474 474
475 QString m_url; 475 QString m_url;
476 QString m_file; 476 QString m_file;
477 void openURL(const QString &filename); 477 void openURL(const QString &filename);
478 private: 478 private:
479 KateCmd *myCmd; 479 KateCmd *myCmd;
480 480
481 public: 481 public:
482 KateCmd *cmd () { return myCmd; }; 482 KateCmd *cmd () { return myCmd; };
483 483
484 private: 484 private:
485 QString myEncoding; 485 QString myEncoding;
486 486
487 public: 487 public:
488 void setEncoding (QString e) { myEncoding = e; }; 488 void setEncoding (QString e) { myEncoding = e; };
489 QString encoding() { return myEncoding; }; 489 QString encoding() { return myEncoding; };
490 490
491 void setWordWrap (bool on); 491 void setWordWrap (bool on);
492 bool wordWrap () { return myWordWrap; }; 492 bool wordWrap () { return myWordWrap; };
493 493
494 void setWordWrapAt (uint col); 494 void setWordWrapAt (uint col);
495 uint wordWrapAt () { return myWordWrapAt; }; 495 uint wordWrapAt () { return myWordWrapAt; };
496 496
497 signals: 497 signals:
498 void modStateChanged (KateDocument *doc); 498 void modStateChanged (KateDocument *doc);
499 void nameChanged (KateDocument *doc); 499 void nameChanged (KateDocument *doc);
500 500
501 public: 501 public:
502 QList<Kate::Mark> marks (); 502 QList<Kate::Mark> marks ();
503 503
504 public slots: 504 public slots:
505 // clear buffer/filename - update the views 505 // clear buffer/filename - update the views
506 void flush (); 506 void flush ();
507 507
508 signals: 508 signals:
509 /** 509 /**
510 The file has been saved (perhaps the name has changed). The main window 510 The file has been saved (perhaps the name has changed). The main window
511 can use this to change its caption 511 can use this to change its caption
512 */ 512 */
513 void fileNameChanged (); 513 void fileNameChanged ();
514 514
515 public: 515 public:
516 //end of line settings 516 //end of line settings
517 enum Eol_settings {eolUnix=0,eolDos=1,eolMacintosh=2}; 517 enum Eol_settings {eolUnix=0,eolDos=1,eolMacintosh=2};
518 518
519 // for the DCOP interface 519 // for the DCOP interface
520 public: 520 public:
521 void open (const QString &name=0); 521 void open (const QString &name=0);
522 522
523 public: 523 public:
524 // wrap the text of the document at the column col 524 // wrap the text of the document at the column col
525 void wrapText (uint col); 525 void wrapText (uint col);
526 526
527 public slots: 527 public slots:
528 void applyWordWrap (); 528 void applyWordWrap ();
529 529
530 private: 530 private:
531 531
532 class KateDocPrivate 532 class KateDocPrivate
533 { 533 {
534 public: 534 public:
535 bool hlSetByUser; 535 bool hlSetByUser;
536 }; 536 };
537 537
538 538
539// BCI: Add a real d-pointer in the next BIC release 539// BCI: Add a real d-pointer in the next BIC release
540static QPtrDict<KateDocPrivate>* d_ptr; 540static QPtrDict<KateDocPrivate>* d_ptr;
541static void cleanup_d_ptr() 541static void cleanup_d_ptr()
542 { 542 {
543 delete d_ptr; 543 delete d_ptr;
544 } 544 }
545 545
546KateDocPrivate* d( const KateDocument* foo ) 546KateDocPrivate* d( const KateDocument* foo )
547 { 547 {
548 if ( !d_ptr ) { 548 if ( !d_ptr ) {
549 d_ptr = new QPtrDict<KateDocPrivate>; 549 d_ptr = new QPtrDict<KateDocPrivate>;
550 //qAddPostRoutine( cleanup_d_ptr ); 550 //qAddPostRoutine( cleanup_d_ptr );
551 } 551 }
552 KateDocPrivate* ret = d_ptr->find( (void*) foo ); 552 KateDocPrivate* ret = d_ptr->find( (void*) foo );
553 if ( ! ret ) { 553 if ( ! ret ) {
554 ret = new KateDocPrivate; 554 ret = new KateDocPrivate;
555 d_ptr->replace( (void*) foo, ret ); 555 d_ptr->replace( (void*) foo, ret );
556 } 556 }
557 return ret; 557 return ret;
558 } 558 }
559 559
560void delete_d( const KateDocument* foo ) 560void delete_d( const KateDocument* foo )
561 { 561 {
562 if ( d_ptr ) 562 if ( d_ptr )
563 d_ptr->remove( (void*) foo ); 563 d_ptr->remove( (void*) foo );
564 } 564 }
565 565
566}; 566};
567 567
568#endif 568#endif
569 569
570 570
diff --git a/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp b/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp
index a2c680f..78635b2 100644
--- a/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp
+++ b/noncore/apps/tinykate/libkate/qt3back/qregexp3.cpp
@@ -1,150 +1,156 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QRegExp class 4** Implementation of QRegExp class
5** 5**
6** Created : 950126 6** Created : 950126
7** 7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software 17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the 18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file. 19** packaging of this file.
20** 20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition 21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License 22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software. 23** Agreement provided with the Software.
24** 24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27** 27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for 28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements. 29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information. 30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information. 31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32** 32**
33** Contact info@trolltech.com if any conditions of this licensing are 33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you. 34** not clear to you.
35** 35**
36**********************************************************************/ 36**********************************************************************/
37#if QT_VERSION >=300 37#if QT_VERSION >=300
38#error QRegExp3 is now in QT 3 use QRegExp instead 38#error QRegExp3 is now in QT 3 use QRegExp instead
39#endif 39#endif
40 40
41#include "qarray.h"
42#include "qbitarray.h"
43#include "qcache.h"
44#include "qintdict.h"
45#include "qmap.h"
46#if QT_VERSION < 300 41#if QT_VERSION < 300
47#include "./qregexp3.h" 42#include "./qregexp3.h"
48#else 43#else
49#include "qregexp.h" 44#include "qregexp.h"
50#endif 45#endif
51#include "qstring.h"
52#include "qtl.h"
53#include "qvector.h"
54 46
47/* OPIE */
48#include <opie2/odebug.h>
49
50/* QT */
51#include <qarray.h>
52#include <qbitarray.h>
53#include <qcache.h>
54#include <qintdict.h>
55#include <qmap.h>
56#include <qstring.h>
57#include <qtl.h>
58#include <qvector.h>
59
60/* STD */
55#include <limits.h> 61#include <limits.h>
56 62
57/* 63/*
58 WARNING! Be sure to read qregexp.tex before modifying this file. 64 WARNING! Be sure to read qregexp.tex before modifying this file.
59*/ 65*/
60 66
61/*! 67/*!
62 \class QRegExp3 qregexp.h 68 \class QRegExp3 qregexp.h
63 69
64 \brief The QRegExp class provides pattern matching using regular expressions. 70 \brief The QRegExp class provides pattern matching using regular expressions.
65 71
66 \ingroup tools 72 \ingroup tools
67 \ingroup misc 73 \ingroup misc
68 \ingroup shared 74 \ingroup shared
69 75
70 76
71 Regular expressions, "regexps", provide a way to find patterns 77 Regular expressions, "regexps", provide a way to find patterns
72 within text. This is useful in many contexts, for example: 78 within text. This is useful in many contexts, for example:
73 79
74 <ol> 80 <ol>
75 <li>\e Validation. A regexp can be used to check whether a piece of 81 <li>\e Validation. A regexp can be used to check whether a piece of
76 text meets some criteria, e.g. is an integer or contains no 82 text meets some criteria, e.g. is an integer or contains no
77 whitespace. 83 whitespace.
78 <li>\e Searching. Regexps provide a much more powerful means of 84 <li>\e Searching. Regexps provide a much more powerful means of
79 searching text than simple string matching does. For example we can 85 searching text than simple string matching does. For example we can
80 create a regexp which says "find one of the words 'mail', 'letter' 86 create a regexp which says "find one of the words 'mail', 'letter'
81 or 'correspondence' but not any of the words 'email', 'mailman' 87 or 'correspondence' but not any of the words 'email', 'mailman'
82 'mailer', 'letterbox' etc." 88 'mailer', 'letterbox' etc."
83 <li><em>Search and Replace.</em> A regexp can be used to replace a 89 <li><em>Search and Replace.</em> A regexp can be used to replace a
84 pattern with a piece of text, for example replace all occurrences of 90 pattern with a piece of text, for example replace all occurrences of
85 '&' with '\&amp;' except where the '&' is already followed by 91 '&' with '\&amp;' except where the '&' is already followed by
86 'amp;'. 92 'amp;'.
87 <li><em>String Splitting.</em> A regexp can be used to identify 93 <li><em>String Splitting.</em> A regexp can be used to identify
88 where a string should be split into its component fields, e.g. 94 where a string should be split into its component fields, e.g.
89 splitting tab delimited strings. 95 splitting tab delimited strings.
90 </ol> 96 </ol>
91 97
92 We present a very brief introduction to regexps, a description of 98 We present a very brief introduction to regexps, a description of
93 Qt's regexp language, some code examples, and finally the function 99 Qt's regexp language, some code examples, and finally the function
94 documentation. QRegExp is modelled on Perl's regexp engine and fully 100 documentation. QRegExp is modelled on Perl's regexp engine and fully
95 supports Unicode. QRegExp may also be used in the weaker 'wildcard' 101 supports Unicode. QRegExp may also be used in the weaker 'wildcard'
96 (globbing) mode which works in a similar way to command shells. A 102 (globbing) mode which works in a similar way to command shells. A
97 good text on regexps is <i>Mastering Regular Expressions: Powerful 103 good text on regexps is <i>Mastering Regular Expressions: Powerful
98 Techniques for Perl and Other Tools</i> by Jeffrey E. Friedl, ISBN 104 Techniques for Perl and Other Tools</i> by Jeffrey E. Friedl, ISBN
99 1565922573. 105 1565922573.
100 106
101 Experienced regexp users may prefer to skip the introduction and 107 Experienced regexp users may prefer to skip the introduction and
102 go directly to the relevant information: 108 go directly to the relevant information:
103 109
104 <ul> 110 <ul>
105 <li><a href="#characters-and-abbreviations-for-sets-of-characters"> 111 <li><a href="#characters-and-abbreviations-for-sets-of-characters">
106 Characters and Abbreviations for Sets of Characters</a> 112 Characters and Abbreviations for Sets of Characters</a>
107 <li><a href="#sets-of-characters">Sets of Characters</a> 113 <li><a href="#sets-of-characters">Sets of Characters</a>
108 <li><a href="#quantifiers">Quantifiers</a> 114 <li><a href="#quantifiers">Quantifiers</a>
109 <li><a href="#capturing-text">Capturing Text</a> 115 <li><a href="#capturing-text">Capturing Text</a>
110 <li><a href="#assertions">Assertions</a> 116 <li><a href="#assertions">Assertions</a>
111 <li><a href="#wildcard-matching">Wildcard Matching (globbing)</a> 117 <li><a href="#wildcard-matching">Wildcard Matching (globbing)</a>
112 <li><a href="#perl-users">Notes for Perl Users</a> 118 <li><a href="#perl-users">Notes for Perl Users</a>
113 <li><a href="#code-examples">Code Examples</a> 119 <li><a href="#code-examples">Code Examples</a>
114 <li><a href="#member-function-documentation">Member Function Documentation</a> 120 <li><a href="#member-function-documentation">Member Function Documentation</a>
115 </ul> 121 </ul>
116 122
117 <b>Introduction</b> 123 <b>Introduction</b>
118 124
119 Regexps are built up from expressions, quantifiers and assertions. 125 Regexps are built up from expressions, quantifiers and assertions.
120 The simplest form of expression is simply a character, e.g. <b>x</b> 126 The simplest form of expression is simply a character, e.g. <b>x</b>
121 or <b>5</b>. An expression can also be a set of characters. For 127 or <b>5</b>. An expression can also be a set of characters. For
122 example, <b>[ABCD]</b>, will match an <b>A</b> or a <b>B</b> or a 128 example, <b>[ABCD]</b>, will match an <b>A</b> or a <b>B</b> or a
123 <b>C</b> or a <b>D</b>. As a shorthand we could write this as 129 <b>C</b> or a <b>D</b>. As a shorthand we could write this as
124 <b>[A-D]</b>. If we want to match any of the captital letters in the 130 <b>[A-D]</b>. If we want to match any of the captital letters in the
125 English alphabet we can write <b>[A-Z]</b>. A quantifier tells the 131 English alphabet we can write <b>[A-Z]</b>. A quantifier tells the
126 regexp engine how many occurrences of the expression we want, e.g. 132 regexp engine how many occurrences of the expression we want, e.g.
127 <b>x{1,1}</b> means match an <b>x</b> which occurs at least once and 133 <b>x{1,1}</b> means match an <b>x</b> which occurs at least once and
128 at most once. We'll look at assertions and more complex expressions 134 at most once. We'll look at assertions and more complex expressions
129 later. Note that regexps cannot be used to check for balanced 135 later. Note that regexps cannot be used to check for balanced
130 brackets or tags (unless you know the maximum level of nesting). 136 brackets or tags (unless you know the maximum level of nesting).
131 137
132 138
133 We'll start by writing a regexp to match integers in the range 0 to 139 We'll start by writing a regexp to match integers in the range 0 to
134 99. We will require at least one digit so we will start with 140 99. We will require at least one digit so we will start with
135 <b>[0-9]{1,1}</b> which means match a digit exactly once. This 141 <b>[0-9]{1,1}</b> which means match a digit exactly once. This
136 regexp alone will match integers in the range 0 to 9. To match one 142 regexp alone will match integers in the range 0 to 9. To match one
137 or two digits we can increase the maximum number of occurrences so 143 or two digits we can increase the maximum number of occurrences so
138 the regexp becomes <b>[0-9]{1,2}</b> meaning match a digit at least 144 the regexp becomes <b>[0-9]{1,2}</b> meaning match a digit at least
139 once and at most twice. However, this regexp as it stands will not 145 once and at most twice. However, this regexp as it stands will not
140 match correctly. This regexp will match one or two digits \e within 146 match correctly. This regexp will match one or two digits \e within
141 a string. To ensure that we match against the whole string we must 147 a string. To ensure that we match against the whole string we must
142 use the anchor assertions. We need <b>^</b> (caret) which when it is 148 use the anchor assertions. We need <b>^</b> (caret) which when it is
143 the first character in the regexp means that the regexp must match 149 the first character in the regexp means that the regexp must match
144 from the beginning of the string. And we also need <b>$</b> (dollar) 150 from the beginning of the string. And we also need <b>$</b> (dollar)
145 which when it is the last character in the regexp means that the 151 which when it is the last character in the regexp means that the
146 regexp must match until the end of the string. So now our regexp is 152 regexp must match until the end of the string. So now our regexp is
147 <b>^[0-9]{1,2}$</b>. Note that assertions do not match any 153 <b>^[0-9]{1,2}$</b>. Note that assertions do not match any
148 characters. 154 characters.
149 155
150 If you've seen regexps elsewhere they may have looked different from 156 If you've seen regexps elsewhere they may have looked different from
@@ -422,3346 +428,3346 @@
422 '#define' followed by at least one whitespace followed by at least 428 '#define' followed by at least one whitespace followed by at least
423 one word character optionally followed by whitespace. This regexp 429 one word character optionally followed by whitespace. This regexp
424 will match define's that exist but have no value, i.e. it will not 430 will match define's that exist but have no value, i.e. it will not
425 match '#define INTMAX 32767' but it will match '#define <u>DEBUG</u>'. 431 match '#define INTMAX 32767' but it will match '#define <u>DEBUG</u>'.
426 432
427 </ul> 433 </ul>
428 434
429 <a name="wildcard-matching"><b>Wildcard Matching (globbing)</b></a> 435 <a name="wildcard-matching"><b>Wildcard Matching (globbing)</b></a>
430 436
431 Most command shells such as \e bash or \e cmd support "file 437 Most command shells such as \e bash or \e cmd support "file
432 globbing", the ability to identify a group of files by using 438 globbing", the ability to identify a group of files by using
433 wildcards. Wildcard matching is much simpler than full regexps and 439 wildcards. Wildcard matching is much simpler than full regexps and
434 has only four features: 440 has only four features:
435 441
436 <ul> 442 <ul>
437 443
438 <li><b>c</b> Any character represents itself apart from those 444 <li><b>c</b> Any character represents itself apart from those
439 mentioned below. Thus <b>c</b> matches the character \e c. 445 mentioned below. Thus <b>c</b> matches the character \e c.
440 446
441 <li><b>?</b> This matches any single character. It is the same as 447 <li><b>?</b> This matches any single character. It is the same as
442 <b>.</b> in full regexps. 448 <b>.</b> in full regexps.
443 449
444 <li><b>*</b> This matches zero or more of any characters. It is the 450 <li><b>*</b> This matches zero or more of any characters. It is the
445 same as <b>.*</b> in full regexps. 451 same as <b>.*</b> in full regexps.
446 452
447 <li><b>[...]</b> Sets of characters can be represented in square 453 <li><b>[...]</b> Sets of characters can be represented in square
448 brackets the same as for full regexps. 454 brackets the same as for full regexps.
449 455
450 <!-- JASMIN: Are the character classes, \w, etc supported in 456 <!-- JASMIN: Are the character classes, \w, etc supported in
451 wildcards? --> 457 wildcards? -->
452 458
453 </ul> 459 </ul>
454 460
455 For example if we are in wildcard mode and have strings which 461 For example if we are in wildcard mode and have strings which
456 contain filenames we could identify HTML files with <b>*.html</b>. 462 contain filenames we could identify HTML files with <b>*.html</b>.
457 This will match zero or more characters followed by a dot followed 463 This will match zero or more characters followed by a dot followed
458 by 'h', 't', 'm' and 'l'. 464 by 'h', 't', 'm' and 'l'.
459 465
460 <a name="perl-users"><b>Notes for Perl Users</b></a> 466 <a name="perl-users"><b>Notes for Perl Users</b></a>
461 467
462 Most of the character class abbreviations supported by Perl are 468 Most of the character class abbreviations supported by Perl are
463 supported by QRegExp, see 469 supported by QRegExp, see
464 <a href="#characters-and-abbreviations-for-sets-of-characters"> 470 <a href="#characters-and-abbreviations-for-sets-of-characters">
465 characters and abbreviations for sets of characters</a>. 471 characters and abbreviations for sets of characters</a>.
466 472
467 QRegExp's quantifiers are the same as Perl's greedy quantifiers. 473 QRegExp's quantifiers are the same as Perl's greedy quantifiers.
468 Non-greedy matching cannot be applied to individual quantifiers, but 474 Non-greedy matching cannot be applied to individual quantifiers, but
469 can be applied to all the quantifiers in the pattern. For example, 475 can be applied to all the quantifiers in the pattern. For example,
470 to match the Perl regex <b>ro+?m</b> requires: 476 to match the Perl regex <b>ro+?m</b> requires:
471 \code 477 \code
472 QRegExp rx( "ro+m" ); 478 QRegExp rx( "ro+m" );
473 rx.setMinimal( TRUE ); 479 rx.setMinimal( TRUE );
474 \endcode 480 \endcode
475 481
476 The equivalent of Perl's <tt>/i</tt> option is 482 The equivalent of Perl's <tt>/i</tt> option is
477 setCaseSensitive(FALSE). 483 setCaseSensitive(FALSE).
478 484
479 Perl's <tt>/g</tt> option can be emulated using a 485 Perl's <tt>/g</tt> option can be emulated using a
480 <a href="#cap_in_a_loop">loop</a>. 486 <a href="#cap_in_a_loop">loop</a>.
481 487
482 In QRegExp <b>.</b> matches any character, therefore all QRegExp 488 In QRegExp <b>.</b> matches any character, therefore all QRegExp
483 regexps have the equivalent of Perl's <tt>/s</tt> option. QRegExp 489 regexps have the equivalent of Perl's <tt>/s</tt> option. QRegExp
484 does not have an equivalent to Perl's <tt>/m</tt> option, but this 490 does not have an equivalent to Perl's <tt>/m</tt> option, but this
485 can be emulated in various ways for example by splitting the input 491 can be emulated in various ways for example by splitting the input
486 into lines or by looping with a regexp that searches for newlines. 492 into lines or by looping with a regexp that searches for newlines.
487 493
488 Because QRegExp is string oriented there are no \A, \Z or \z 494 Because QRegExp is string oriented there are no \A, \Z or \z
489 assertions. The \G assertion is not supported but can be emulated in 495 assertions. The \G assertion is not supported but can be emulated in
490 a loop. 496 a loop.
491 497
492 Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp 498 Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp
493 equivalents for $`, $' or $+. $1, $2 etc correspond to 499 equivalents for $`, $' or $+. $1, $2 etc correspond to
494 cap(1) or capturedTexts()[1], cap(2) or capturedTexts()[2], etc. 500 cap(1) or capturedTexts()[1], cap(2) or capturedTexts()[2], etc.
495 501
496 To substitute a pattern use QString::replace(). 502 To substitute a pattern use QString::replace().
497 503
498 Perl's extended <tt>/x</tt> syntax is not supported, nor are regexp 504 Perl's extended <tt>/x</tt> syntax is not supported, nor are regexp
499 comments (?#comment) or directives, e.g. (?i). 505 comments (?#comment) or directives, e.g. (?i).
500 506
501 Both zero-width positive and zero-width negative lookahead 507 Both zero-width positive and zero-width negative lookahead
502 assertions (?=pattern) and (?!pattern) are supported with the same 508 assertions (?=pattern) and (?!pattern) are supported with the same
503 syntax as Perl. Perl's lookbehind assertions, "independent" 509 syntax as Perl. Perl's lookbehind assertions, "independent"
504 subexpressions and conditional expressions are not supported. 510 subexpressions and conditional expressions are not supported.
505 511
506 Non-capturing parenthesis are also supported, with the same 512 Non-capturing parenthesis are also supported, with the same
507 (?:pattern) syntax. 513 (?:pattern) syntax.
508 514
509 See QStringList::split() and QStringList::join() for equivalents to 515 See QStringList::split() and QStringList::join() for equivalents to
510 Perl's split and join functions. 516 Perl's split and join functions.
511 517
512 Note: because C++ transforms \\'s they must be written \e twice in 518 Note: because C++ transforms \\'s they must be written \e twice in
513 code, e.g. <b>\\</b><b>b</b> must be written <b>\\</b><b>\\</b><b>b</b>. 519 code, e.g. <b>\\</b><b>b</b> must be written <b>\\</b><b>\\</b><b>b</b>.
514 520
515 <a name="code-examples"><b>Code Examples</b></a> 521 <a name="code-examples"><b>Code Examples</b></a>
516 522
517 \code 523 \code
518 QRegExp rx( "^\\d\\d?$" );// Match integers 0 to 99 524 QRegExp rx( "^\\d\\d?$" ); // Match integers 0 to 99
519 rx.search( "123" ); // Returns -1 (no match) 525 rx.search( "123" ); // Returns -1 (no match)
520 rx.search( "-6" ); // Returns -1 (no match) 526 rx.search( "-6" ); // Returns -1 (no match)
521 rx.search( "6" ); // Returns 0 (matched as position 0) 527 rx.search( "6" ); // Returns 0 (matched as position 0)
522 \endcode 528 \endcode
523 529
524 The third string matches '<u>6</u>'. This is a simple validation 530 The third string matches '<u>6</u>'. This is a simple validation
525 regexp for integers in the range 0 to 99. 531 regexp for integers in the range 0 to 99.
526 532
527 \code 533 \code
528 QRegExp rx( "^\\S+$" );// Match strings which have no whitespace 534 QRegExp rx( "^\\S+$" ); // Match strings which have no whitespace
529 rx.search( "Hello world" );// Returns -1 (no match) 535 rx.search( "Hello world" ); // Returns -1 (no match)
530 rx.search( "This_is-OK" );// Returns 0 (matched at position 0) 536 rx.search( "This_is-OK" ); // Returns 0 (matched at position 0)
531 \endcode 537 \endcode
532 538
533 The second string matches '<u>This_is-OK</u>'. We've used the 539 The second string matches '<u>This_is-OK</u>'. We've used the
534 character set abbreviation '\S' (non-whitespace) and the anchors to 540 character set abbreviation '\S' (non-whitespace) and the anchors to
535 match strings which contain no whitespace. 541 match strings which contain no whitespace.
536 542
537 In the following example we match strings containing 'mail' or 543 In the following example we match strings containing 'mail' or
538 'letter' or 'correspondence' but only match whole words i.e. not 544 'letter' or 'correspondence' but only match whole words i.e. not
539 'email' 545 'email'
540 546
541 \code 547 \code
542 QRegExp rx( "\\b(mail|letter|correspondence)\\b" ); 548 QRegExp rx( "\\b(mail|letter|correspondence)\\b" );
543 rx.search( "I sent you an email" ); // Returns -1 (no match) 549 rx.search( "I sent you an email" ); // Returns -1 (no match)
544 rx.search( "Please write the letter" ); // Returns 17 (matched at position 17) 550 rx.search( "Please write the letter" ); // Returns 17 (matched at position 17)
545 \endcode 551 \endcode
546 552
547 The second string matches "Please write the <u>letter</u>". The word 553 The second string matches "Please write the <u>letter</u>". The word
548 'letter' is also captured (because of the parenthesis). We can see 554 'letter' is also captured (because of the parenthesis). We can see
549 what text we've captured like this: 555 what text we've captured like this:
550 556
551 \code 557 \code
552 QString captured = rx.cap( 1 ); // captured contains "letter" 558 QString captured = rx.cap( 1 ); // captured contains "letter"
553 \endcode 559 \endcode
554 560
555 This will capture the text from the first set of capturing 561 This will capture the text from the first set of capturing
556 parenthesis (counting capturing left parenthesis from left to 562 parenthesis (counting capturing left parenthesis from left to
557 right). The parenthesis are counted from 1 since cap( 0 ) is the 563 right). The parenthesis are counted from 1 since cap( 0 ) is the
558 whole matched regexp (equivalent to '&' in most regexp engines). 564 whole matched regexp (equivalent to '&' in most regexp engines).
559 565
560 \code 566 \code
561 QRegExp rx( "&(?!amp;)" ); // Match ampersands but not &amp; 567 QRegExp rx( "&(?!amp;)" ); // Match ampersands but not &amp;
562 QString line1 = "This & that"; 568 QString line1 = "This & that";
563 line1.replace( rx, "&amp;" ); 569 line1.replace( rx, "&amp;" );
564 // line1 == "This &amp; that" 570 // line1 == "This &amp; that"
565 QString line2 = "His &amp; hers & theirs"; 571 QString line2 = "His &amp; hers & theirs";
566 line2.replace( rx, "&amp;" ); 572 line2.replace( rx, "&amp;" );
567 // line2 == "His &amp; hers &amp; theirs" 573 // line2 == "His &amp; hers &amp; theirs"
568 \endcode 574 \endcode
569 575
570 Here we've passed the QRegExp to QString's replace() function to 576 Here we've passed the QRegExp to QString's replace() function to
571 replace the matched text with new text. 577 replace the matched text with new text.
572 578
573 \code 579 \code
574 QString str = "One Eric another Eirik, and an Ericsson. How many Eiriks, Eric?"; 580 QString str = "One Eric another Eirik, and an Ericsson. How many Eiriks, Eric?";
575 QRegExp rx( "\\b(Eric|Eirik)\\b" );// Match Eric or Eirik 581 QRegExp rx( "\\b(Eric|Eirik)\\b" ); // Match Eric or Eirik
576 int pos = 0; // Where we are in the string 582 int pos = 0; // Where we are in the string
577 int count = 0; // How many Eric and Eirik's we've counted 583 int count = 0; // How many Eric and Eirik's we've counted
578 while ( pos >= 0 ) { 584 while ( pos >= 0 ) {
579 pos = rx.search( str, pos ); 585 pos = rx.search( str, pos );
580 if ( pos >= 0 ) { 586 if ( pos >= 0 ) {
581 pos++;// Move along in str 587 pos++; // Move along in str
582 count++;// Count our Eric or Eirik 588 count++; // Count our Eric or Eirik
583 } 589 }
584 } 590 }
585 \endcode 591 \endcode
586 592
587 We've used the search() function to repeatedly match the regexp in 593 We've used the search() function to repeatedly match the regexp in
588 the string. Note that instead of moving forward by one character at 594 the string. Note that instead of moving forward by one character at
589 a time <tt>pos++</tt> we could have written <tt>pos += 595 a time <tt>pos++</tt> we could have written <tt>pos +=
590 rx.matchedLength()</tt> to skip over the already matched string. The 596 rx.matchedLength()</tt> to skip over the already matched string. The
591 count will equal 3, matching 'One <u>Eric</u> another <u>Eirik</u>, 597 count will equal 3, matching 'One <u>Eric</u> another <u>Eirik</u>,
592 and an Ericsson. How many Eiriks, <u>Eric</u>?'; it doesn't match 598 and an Ericsson. How many Eiriks, <u>Eric</u>?'; it doesn't match
593 'Ericsson' or 'Eiriks' because they are not bounded by non-word 599 'Ericsson' or 'Eiriks' because they are not bounded by non-word
594 boundaries. 600 boundaries.
595 601
596 One common use of regexps is to split lines of delimited data into 602 One common use of regexps is to split lines of delimited data into
597 their component fields. 603 their component fields.
598 604
599 \code 605 \code
600 str = "Trolltech AS\twww.trolltech.com\tNorway"; 606 str = "Trolltech AS\twww.trolltech.com\tNorway";
601 QString company, web, country; 607 QString company, web, country;
602 rx.setPattern( "^([^\t]+)\t([^\t]+)\t([^\t]+)$" ); 608 rx.setPattern( "^([^\t]+)\t([^\t]+)\t([^\t]+)$" );
603 if ( rx.search( str ) != -1 ) { 609 if ( rx.search( str ) != -1 ) {
604 company = rx.cap( 1 ); 610 company = rx.cap( 1 );
605 web= rx.cap( 2 ); 611 web = rx.cap( 2 );
606 country = rx.cap( 3 ); 612 country = rx.cap( 3 );
607 } 613 }
608 \endcode 614 \endcode
609 615
610 In this example our input lines have the format company name, web 616 In this example our input lines have the format company name, web
611 address and country. Unfortunately the regexp is rather long and not 617 address and country. Unfortunately the regexp is rather long and not
612 very versatile -- the code will break if we add any more fields. A 618 very versatile -- the code will break if we add any more fields. A
613 simpler and better solution is to look for the separator, '\t' in 619 simpler and better solution is to look for the separator, '\t' in
614 this case, and take the surrounding text. The QStringList split() 620 this case, and take the surrounding text. The QStringList split()
615 function can take a separator string or regexp as an argument and 621 function can take a separator string or regexp as an argument and
616 split a string accordingly. 622 split a string accordingly.
617 623
618 \code 624 \code
619 QStringList field = QStringList::split( "\t", str ); 625 QStringList field = QStringList::split( "\t", str );
620 \endcode 626 \endcode
621 627
622 Here field[0] is the company, field[1] the web address and so on. 628 Here field[0] is the company, field[1] the web address and so on.
623 629
624 To immitate the matching of a shell we can use wildcard mode. 630 To immitate the matching of a shell we can use wildcard mode.
625 631
626 \code 632 \code
627 QRegExp rx( "*.html" );// Invalid regexp: * doesn't quantify anything 633 QRegExp rx( "*.html" ); // Invalid regexp: * doesn't quantify anything
628 rx.setWildcard( TRUE );// Now its a valid wildcard regexp 634 rx.setWildcard( TRUE ); // Now its a valid wildcard regexp
629 rx.search( "index.html" );// Returns 0 (matched at position 0) 635 rx.search( "index.html" ); // Returns 0 (matched at position 0)
630 rx.search( "default.htm" );// Returns -1 (no match) 636 rx.search( "default.htm" ); // Returns -1 (no match)
631 rx.search( "readme.txt" );// Returns -1 (no match) 637 rx.search( "readme.txt" ); // Returns -1 (no match)
632 \endcode 638 \endcode
633 639
634 Wildcard matching can be convenient because of its simplicity, but 640 Wildcard matching can be convenient because of its simplicity, but
635 any wildcard regex can be defined using full regexps, e.g. 641 any wildcard regex can be defined using full regexps, e.g.
636 <b>.*\.html$</b>. Notice that we can't match both \c .html and \c 642 <b>.*\.html$</b>. Notice that we can't match both \c .html and \c
637 .htm files with a wildcard unless we use <b>*.htm*</b> which will 643 .htm files with a wildcard unless we use <b>*.htm*</b> which will
638 also match 'test.html.bak'. A full regexp gives us the precision we 644 also match 'test.html.bak'. A full regexp gives us the precision we
639 need, <b>.*\.html?$</b>. 645 need, <b>.*\.html?$</b>.
640 646
641 QRegExp can match case insensitively using setCaseSensitive(), and 647 QRegExp can match case insensitively using setCaseSensitive(), and
642 can use non-greedy matching, see setMinimal(). By default QRegExp 648 can use non-greedy matching, see setMinimal(). By default QRegExp
643 uses full regexps but this can be changed with setWildcard(). 649 uses full regexps but this can be changed with setWildcard().
644 Searching can be forward with search() or backward with searchRev(). 650 Searching can be forward with search() or backward with searchRev().
645 Captured text can be accessed using capturedTexts() which returns a 651 Captured text can be accessed using capturedTexts() which returns a
646 string list of all captured strings, or using cap() which returns 652 string list of all captured strings, or using cap() which returns
647 the captured string for the given index. The pos() function takes a 653 the captured string for the given index. The pos() function takes a
648 match index and returns the position in the string where the match 654 match index and returns the position in the string where the match
649 was made (or -1 if there was no match). 655 was made (or -1 if there was no match).
650 656
651 \sa QRegExpValidator QString QStringList 657 \sa QRegExpValidator QString QStringList
652 658
653 <a name="member-function-documentation"/> 659 <a name="member-function-documentation"/>
654*/ 660*/
655 661
656static const int NumBadChars = 128; 662static const int NumBadChars = 128;
657#define BadChar( ch ) ( (ch).cell() % NumBadChars ) 663#define BadChar( ch ) ( (ch).cell() % NumBadChars )
658 664
659static const int NoOccurrence = INT_MAX; 665static const int NoOccurrence = INT_MAX;
660static const int EmptyCapture = INT_MAX; 666static const int EmptyCapture = INT_MAX;
661static const int InftyLen = INT_MAX; 667static const int InftyLen = INT_MAX;
662static const int InftyRep = 1000; 668static const int InftyRep = 1000;
663static const int EOS = -1; 669static const int EOS = -1;
664 670
665#ifndef QT_NO_REGEXP_OPTIM 671#ifndef QT_NO_REGEXP_OPTIM
666static int engCount = 0; 672static int engCount = 0;
667static QArray<int> *noOccurrences = 0; 673static QArray<int> *noOccurrences = 0;
668static QArray<int> *firstOccurrenceAtZero = 0; 674static QArray<int> *firstOccurrenceAtZero = 0;
669#endif 675#endif
670 676
671/* 677/*
672 Merges two QArrays of ints and puts the result into the first one. 678 Merges two QArrays of ints and puts the result into the first one.
673*/ 679*/
674static void mergeInto( QArray<int> *a, const QArray<int>& b ) 680static void mergeInto( QArray<int> *a, const QArray<int>& b )
675{ 681{
676 int asize = a->size(); 682 int asize = a->size();
677 int bsize = b.size(); 683 int bsize = b.size();
678 if ( asize == 0 ) { 684 if ( asize == 0 ) {
679 *a = b.copy(); 685 *a = b.copy();
680#ifndef QT_NO_REGEXP_OPTIM 686#ifndef QT_NO_REGEXP_OPTIM
681 } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) { 687 } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) {
682 a->resize( asize + 1 ); 688 a->resize( asize + 1 );
683 (*a)[asize] = b[0]; 689 (*a)[asize] = b[0];
684#endif 690#endif
685 } else if ( bsize >= 1 ) { 691 } else if ( bsize >= 1 ) {
686 int csize = asize + bsize; 692 int csize = asize + bsize;
687 QArray<int> c( csize ); 693 QArray<int> c( csize );
688 int i = 0, j = 0, k = 0; 694 int i = 0, j = 0, k = 0;
689 while ( i < asize ) { 695 while ( i < asize ) {
690 if ( j < bsize ) { 696 if ( j < bsize ) {
691 if ( (*a)[i] == b[j] ) { 697 if ( (*a)[i] == b[j] ) {
692 i++; 698 i++;
693 csize--; 699 csize--;
694 } else if ( (*a)[i] < b[j] ) { 700 } else if ( (*a)[i] < b[j] ) {
695 c[k++] = (*a)[i++]; 701 c[k++] = (*a)[i++];
696 } else { 702 } else {
697 c[k++] = b[j++]; 703 c[k++] = b[j++];
698 } 704 }
699 } else { 705 } else {
700 memcpy( c.data() + k, (*a).data() + i, 706 memcpy( c.data() + k, (*a).data() + i,
701 (asize - i) * sizeof(int) ); 707 (asize - i) * sizeof(int) );
702 break; 708 break;
703 } 709 }
704 } 710 }
705 c.resize( csize ); 711 c.resize( csize );
706 if ( j < bsize ) 712 if ( j < bsize )
707 memcpy( c.data() + k, b.data() + j, (bsize - j) * sizeof(int) ); 713 memcpy( c.data() + k, b.data() + j, (bsize - j) * sizeof(int) );
708 *a = c; 714 *a = c;
709 } 715 }
710} 716}
711 717
712/* 718/*
713 Merges two disjoint QMaps of (int, int) pairs and puts the result into the 719 Merges two disjoint QMaps of (int, int) pairs and puts the result into the
714 first one. 720 first one.
715*/ 721*/
716static void mergeInto( QMap<int, int> *a, const QMap<int, int>& b ) 722static void mergeInto( QMap<int, int> *a, const QMap<int, int>& b )
717{ 723{
718 QMap<int, int>::ConstIterator it; 724 QMap<int, int>::ConstIterator it;
719 for ( it = b.begin(); it != b.end(); ++it ) 725 for ( it = b.begin(); it != b.end(); ++it )
720 a->insert( it.key(), *it ); 726 a->insert( it.key(), *it );
721} 727}
722 728
723/* 729/*
724 Returns the value associated to key k in QMap m of (int, int) pairs, or 0 if 730 Returns the value associated to key k in QMap m of (int, int) pairs, or 0 if
725 no such value is explicitly present. 731 no such value is explicitly present.
726*/ 732*/
727static int at( const QMap<int, int>& m, int k ) 733static int at( const QMap<int, int>& m, int k )
728{ 734{
729 QMap<int, int>::ConstIterator it = m.find( k ); 735 QMap<int, int>::ConstIterator it = m.find( k );
730 if ( it == m.end() ) 736 if ( it == m.end() )
731 return 0; 737 return 0;
732 else 738 else
733 return *it; 739 return *it;
734} 740}
735 741
736#ifndef QT_NO_REGEXP_WILDCARD 742#ifndef QT_NO_REGEXP_WILDCARD
737/* 743/*
738 Translates a wildcard pattern to an equivalent regular expression pattern 744 Translates a wildcard pattern to an equivalent regular expression pattern
739 (e.g., *.cpp to .*\.cpp). 745 (e.g., *.cpp to .*\.cpp).
740*/ 746*/
741static QString wc2rx( const QString& wc ) 747static QString wc2rx( const QString& wc )
742{ 748{
743 int wclen = wc.length(); 749 int wclen = wc.length();
744 QString rx = QString::fromLatin1( "" ); 750 QString rx = QString::fromLatin1( "" );
745 int i = 0; 751 int i = 0;
746 while ( i < wclen ) { 752 while ( i < wclen ) {
747 QChar c = wc[i++]; 753 QChar c = wc[i++];
748 switch ( c.unicode() ) { 754 switch ( c.unicode() ) {
749 case '*': 755 case '*':
750 rx += QString::fromLatin1( ".*" ); 756 rx += QString::fromLatin1( ".*" );
751 break; 757 break;
752 case '?': 758 case '?':
753 rx += QChar( '.' ); 759 rx += QChar( '.' );
754 break; 760 break;
755 case '$': 761 case '$':
756 case '(': 762 case '(':
757 case ')': 763 case ')':
758 case '+': 764 case '+':
759 case '.': 765 case '.':
760 case '\\': 766 case '\\':
761 case '^': 767 case '^':
762 case '{': 768 case '{':
763 case '|': 769 case '|':
764 case '}': 770 case '}':
765 rx += QChar( '\\' ); 771 rx += QChar( '\\' );
766 rx += c; 772 rx += c;
767 break; 773 break;
768 case '[': 774 case '[':
769 rx += c; 775 rx += c;
770 if ( wc[i] == QChar('^') ) 776 if ( wc[i] == QChar('^') )
771 rx += wc[i++]; 777 rx += wc[i++];
772 if ( i < wclen ) { 778 if ( i < wclen ) {
773 if ( rx[i] == ']' ) 779 if ( rx[i] == ']' )
774 rx += wc[i++]; 780 rx += wc[i++];
775 while ( i < wclen && wc[i] != QChar(']') ) { 781 while ( i < wclen && wc[i] != QChar(']') ) {
776 if ( wc[i] == '\\' ) 782 if ( wc[i] == '\\' )
777 rx += QChar( '\\' ); 783 rx += QChar( '\\' );
778 rx += wc[i++]; 784 rx += wc[i++];
779 } 785 }
780 } 786 }
781 break; 787 break;
782 default: 788 default:
783 rx += c; 789 rx += c;
784 } 790 }
785 } 791 }
786 return rx; 792 return rx;
787} 793}
788#endif 794#endif
789 795
790/* 796/*
791 The class QRegExpEngine encapsulates a modified nondeterministic finite 797 The class QRegExpEngine encapsulates a modified nondeterministic finite
792 automaton (NFA). 798 automaton (NFA).
793*/ 799*/
794class QRegExpEngine : public QShared 800class QRegExpEngine : public QShared
795{ 801{
796public: 802public:
797#ifndef QT_NO_REGEXP_CCLASS 803#ifndef QT_NO_REGEXP_CCLASS
798 /* 804 /*
799 The class CharClass represents a set of characters, such as can be found 805 The class CharClass represents a set of characters, such as can be found
800 in regular expressions (e.g., [a-z] denotes the set {a, b, ..., z}). 806 in regular expressions (e.g., [a-z] denotes the set {a, b, ..., z}).
801 */ 807 */
802 class CharClass 808 class CharClass
803 { 809 {
804 public: 810 public:
805 CharClass(); 811 CharClass();
806 CharClass( const CharClass& cc ) { operator=( cc ); } 812 CharClass( const CharClass& cc ) { operator=( cc ); }
807 813
808 CharClass& operator=( const CharClass& cc ); 814 CharClass& operator=( const CharClass& cc );
809 815
810 void clear(); 816 void clear();
811 bool negative() const { return n; } 817 bool negative() const { return n; }
812 void setNegative( bool negative ); 818 void setNegative( bool negative );
813 void addCategories( int cats ); 819 void addCategories( int cats );
814 void addRange( ushort from, ushort to ); 820 void addRange( ushort from, ushort to );
815 void addSingleton( ushort ch ) { addRange( ch, ch ); } 821 void addSingleton( ushort ch ) { addRange( ch, ch ); }
816 822
817 bool in( QChar ch ) const; 823 bool in( QChar ch ) const;
818#ifndef QT_NO_REGEXP_OPTIM 824#ifndef QT_NO_REGEXP_OPTIM
819 const QArray<int>& firstOccurrence() const { return occ1; } 825 const QArray<int>& firstOccurrence() const { return occ1; }
820#endif 826#endif
821 827
822#if defined(QT_DEBUG) 828#if defined(QT_DEBUG)
823 void dump() const; 829 void dump() const;
824#endif 830#endif
825 831
826 private: 832 private:
827 /* 833 /*
828 The struct Range represents a range of characters (e.g., [0-9] denotes 834 The struct Range represents a range of characters (e.g., [0-9] denotes
829 range 48 to 57). 835 range 48 to 57).
830 */ 836 */
831 struct Range 837 struct Range
832 { 838 {
833 ushort from; // 48 839 ushort from; // 48
834 ushort to; // 57 840 ushort to; // 57
835 }; 841 };
836 842
837 int c; // character classes 843 int c; // character classes
838 QArray<Range> r; // character ranges 844 QArray<Range> r; // character ranges
839 bool n; // negative? 845 bool n; // negative?
840#ifndef QT_NO_REGEXP_OPTIM 846#ifndef QT_NO_REGEXP_OPTIM
841 QArray<int> occ1; // first-occurrence array 847 QArray<int> occ1; // first-occurrence array
842#endif 848#endif
843 }; 849 };
844#else 850#else
845 struct CharClass 851 struct CharClass
846 { 852 {
847 int x; // dummy 853 int x; // dummy
848 854
849#ifndef QT_NO_REGEXP_OPTIM 855#ifndef QT_NO_REGEXP_OPTIM
850 const QArray<int>& firstOccurrence() const { 856 const QArray<int>& firstOccurrence() const {
851 return *firstOccurrenceAtZero; 857 return *firstOccurrenceAtZero;
852 } 858 }
853#endif 859#endif
854 }; 860 };
855#endif 861#endif
856 862
857 QRegExpEngine( bool caseSensitive ) { setup( caseSensitive ); } 863 QRegExpEngine( bool caseSensitive ) { setup( caseSensitive ); }
858 QRegExpEngine( const QString& rx, bool caseSensitive ); 864 QRegExpEngine( const QString& rx, bool caseSensitive );
859#ifndef QT_NO_REGEXP_OPTIM 865#ifndef QT_NO_REGEXP_OPTIM
860 ~QRegExpEngine(); 866 ~QRegExpEngine();
861#endif 867#endif
862 868
863 bool isValid() const { return valid; } 869 bool isValid() const { return valid; }
864 bool caseSensitive() const { return cs; } 870 bool caseSensitive() const { return cs; }
865 int numCaptures() const { return realncap; } 871 int numCaptures() const { return realncap; }
866 QArray<int> match( const QString& str, int pos, bool minimal, 872 QArray<int> match( const QString& str, int pos, bool minimal,
867 bool oneTest ); 873 bool oneTest );
868 int matchedLength() const { return mmMatchedLen; } 874 int matchedLength() const { return mmMatchedLen; }
869 875
870 int createState( QChar ch ); 876 int createState( QChar ch );
871 int createState( const CharClass& cc ); 877 int createState( const CharClass& cc );
872#ifndef QT_NO_REGEXP_BACKREF 878#ifndef QT_NO_REGEXP_BACKREF
873 int createState( int bref ); 879 int createState( int bref );
874#endif 880#endif
875 881
876 void addCatTransitions( const QArray<int>& from, const QArray<int>& to ); 882 void addCatTransitions( const QArray<int>& from, const QArray<int>& to );
877#ifndef QT_NO_REGEXP_CAPTURE 883#ifndef QT_NO_REGEXP_CAPTURE
878 void addPlusTransitions( const QArray<int>& from, const QArray<int>& to, 884 void addPlusTransitions( const QArray<int>& from, const QArray<int>& to,
879 int atom ); 885 int atom );
880#endif 886#endif
881 887
882#ifndef QT_NO_REGEXP_ANCHOR_ALT 888#ifndef QT_NO_REGEXP_ANCHOR_ALT
883 int anchorAlternation( int a, int b ); 889 int anchorAlternation( int a, int b );
884 int anchorConcatenation( int a, int b ); 890 int anchorConcatenation( int a, int b );
885#else 891#else
886 int anchorAlternation( int a, int b ) { return a & b; } 892 int anchorAlternation( int a, int b ) { return a & b; }
887 int anchorConcatenation( int a, int b ) { return a | b; } 893 int anchorConcatenation( int a, int b ) { return a | b; }
888#endif 894#endif
889 void addAnchors( int from, int to, int a ); 895 void addAnchors( int from, int to, int a );
890 896
891#ifndef QT_NO_REGEXP_OPTIM 897#ifndef QT_NO_REGEXP_OPTIM
892 void setupGoodStringHeuristic( int earlyStart, int lateStart, 898 void setupGoodStringHeuristic( int earlyStart, int lateStart,
893 const QString& str ); 899 const QString& str );
894 void setupBadCharHeuristic( int minLen, const QArray<int>& firstOcc ); 900 void setupBadCharHeuristic( int minLen, const QArray<int>& firstOcc );
895 void heuristicallyChooseHeuristic(); 901 void heuristicallyChooseHeuristic();
896#endif 902#endif
897 903
898#if defined(QT_DEBUG) 904#if defined(QT_DEBUG)
899 void dump() const; 905 void dump() const;
900#endif 906#endif
901 907
902private: 908private:
903 enum { CharClassBit = 0x10000, BackRefBit = 0x20000 }; 909 enum { CharClassBit = 0x10000, BackRefBit = 0x20000 };
904 910
905 /* 911 /*
906 The struct State represents one state in a modified NFA. The input 912 The struct State represents one state in a modified NFA. The input
907 characters matched are stored in the state instead of on the transitions, 913 characters matched are stored in the state instead of on the transitions,
908 something possible for an automaton constructed from a regular expression. 914 something possible for an automaton constructed from a regular expression.
909 */ 915 */
910 struct State 916 struct State
911 { 917 {
912#ifndef QT_NO_REGEXP_CAPTURE 918#ifndef QT_NO_REGEXP_CAPTURE
913 int atom; // which atom does this state belong to? 919 int atom; // which atom does this state belong to?
914#endif 920#endif
915 int match; // what does it match? (see CharClassBit and BackRefBit) 921 int match; // what does it match? (see CharClassBit and BackRefBit)
916 QArray<int> outs; // out-transitions 922 QArray<int> outs; // out-transitions
917 QMap<int, int> *reenter; // atoms reentered when transiting out 923 QMap<int, int> *reenter; // atoms reentered when transiting out
918 QMap<int, int> *anchors; // anchors met when transiting out 924 QMap<int, int> *anchors; // anchors met when transiting out
919 925
920#ifndef QT_NO_REGEXP_CAPTURE 926#ifndef QT_NO_REGEXP_CAPTURE
921 State( int a, int m ) 927 State( int a, int m )
922 : atom( a ), match( m ), reenter( 0 ), anchors( 0 ) { } 928 : atom( a ), match( m ), reenter( 0 ), anchors( 0 ) { }
923#else 929#else
924 State( int m ) 930 State( int m )
925 : match( m ), reenter( 0 ), anchors( 0 ) { } 931 : match( m ), reenter( 0 ), anchors( 0 ) { }
926#endif 932#endif
927 ~State() { delete reenter; delete anchors; } 933 ~State() { delete reenter; delete anchors; }
928 }; 934 };
929 935
930#ifndef QT_NO_REGEXP_LOOKAHEAD 936#ifndef QT_NO_REGEXP_LOOKAHEAD
931 /* 937 /*
932 The struct Lookahead represents a lookahead a la Perl (e.g., (?=foo) and 938 The struct Lookahead represents a lookahead a la Perl (e.g., (?=foo) and
933 (?!bar)). 939 (?!bar)).
934 */ 940 */
935 struct Lookahead 941 struct Lookahead
936 { 942 {
937 QRegExpEngine *eng; // NFA representing the embedded regular expression 943 QRegExpEngine *eng; // NFA representing the embedded regular expression
938 bool neg; // negative lookahead? 944 bool neg; // negative lookahead?
939 945
940 Lookahead( QRegExpEngine *eng0, bool neg0 ) 946 Lookahead( QRegExpEngine *eng0, bool neg0 )
941 : eng( eng0 ), neg( neg0 ) { } 947 : eng( eng0 ), neg( neg0 ) { }
942 ~Lookahead() { delete eng; } 948 ~Lookahead() { delete eng; }
943 }; 949 };
944#endif 950#endif
945 951
946#ifndef QT_NO_REGEXP_CAPTURE 952#ifndef QT_NO_REGEXP_CAPTURE
947 /* 953 /*
948 The struct Atom represents one node in the hierarchy of regular expression 954 The struct Atom represents one node in the hierarchy of regular expression
949 atoms. 955 atoms.
950 */ 956 */
951 struct Atom 957 struct Atom
952 { 958 {
953 int parent; // index of parent in array of atoms 959 int parent; // index of parent in array of atoms
954 int capture; // index of capture, from 1 to ncap 960 int capture; // index of capture, from 1 to ncap
955 }; 961 };
956#endif 962#endif
957 963
958#ifndef QT_NO_REGEXP_ANCHOR_ALT 964#ifndef QT_NO_REGEXP_ANCHOR_ALT
959 /* 965 /*
960 The struct AnchorAlternation represents a pair of anchors with OR 966 The struct AnchorAlternation represents a pair of anchors with OR
961 semantics. 967 semantics.
962 */ 968 */
963 struct AnchorAlternation 969 struct AnchorAlternation
964 { 970 {
965 int a; // this anchor... 971 int a; // this anchor...
966 int b; // ...or this one 972 int b; // ...or this one
967 }; 973 };
968#endif 974#endif
969 975
970 enum { InitialState = 0, FinalState = 1 }; 976 enum { InitialState = 0, FinalState = 1 };
971 void setup( bool caseSensitive ); 977 void setup( bool caseSensitive );
972 int setupState( int match ); 978 int setupState( int match );
973 979
974 /* 980 /*
975 Let's hope that 13 lookaheads and 14 back-references are enough. 981 Let's hope that 13 lookaheads and 14 back-references are enough.
976 */ 982 */
977 enum { MaxLookaheads = 13, MaxBackRefs = 14 }; 983 enum { MaxLookaheads = 13, MaxBackRefs = 14 };
978 enum { Anchor_Dollar = 0x00000001, Anchor_Caret = 0x00000002, 984 enum { Anchor_Dollar = 0x00000001, Anchor_Caret = 0x00000002,
979 Anchor_Word = 0x00000004, Anchor_NonWord = 0x00000008, 985 Anchor_Word = 0x00000004, Anchor_NonWord = 0x00000008,
980 Anchor_FirstLookahead = 0x00000010, 986 Anchor_FirstLookahead = 0x00000010,
981 Anchor_BackRef1Empty = Anchor_FirstLookahead << MaxLookaheads, 987 Anchor_BackRef1Empty = Anchor_FirstLookahead << MaxLookaheads,
982 Anchor_BackRef0Empty = Anchor_BackRef1Empty >> 1, 988 Anchor_BackRef0Empty = Anchor_BackRef1Empty >> 1,
983 Anchor_Alternation = Anchor_BackRef1Empty << MaxBackRefs, 989 Anchor_Alternation = Anchor_BackRef1Empty << MaxBackRefs,
984 990
985 Anchor_LookaheadMask = ( Anchor_FirstLookahead - 1 ) ^ 991 Anchor_LookaheadMask = ( Anchor_FirstLookahead - 1 ) ^
986 ( (Anchor_FirstLookahead << MaxLookaheads) - 1 ) }; 992 ( (Anchor_FirstLookahead << MaxLookaheads) - 1 ) };
987#ifndef QT_NO_REGEXP_CAPTURE 993#ifndef QT_NO_REGEXP_CAPTURE
988 int startAtom( bool capture ); 994 int startAtom( bool capture );
989 void finishAtom( int atom ) { cf = f[atom].parent; } 995 void finishAtom( int atom ) { cf = f[atom].parent; }
990#endif 996#endif
991 997
992#ifndef QT_NO_REGEXP_LOOKAHEAD 998#ifndef QT_NO_REGEXP_LOOKAHEAD
993 int addLookahead( QRegExpEngine *eng, bool negative ); 999 int addLookahead( QRegExpEngine *eng, bool negative );
994#endif 1000#endif
995 1001
996#ifndef QT_NO_REGEXP_CAPTURE 1002#ifndef QT_NO_REGEXP_CAPTURE
997 bool isBetterCapture( const int *begin1, const int *end1, const int *begin2, 1003 bool isBetterCapture( const int *begin1, const int *end1, const int *begin2,
998 const int *end2 ); 1004 const int *end2 );
999#endif 1005#endif
1000 bool testAnchor( int i, int a, const int *capBegin ); 1006 bool testAnchor( int i, int a, const int *capBegin );
1001 1007
1002#ifndef QT_NO_REGEXP_OPTIM 1008#ifndef QT_NO_REGEXP_OPTIM
1003 bool goodStringMatch(); 1009 bool goodStringMatch();
1004 bool badCharMatch(); 1010 bool badCharMatch();
1005#else 1011#else
1006 bool bruteMatch(); 1012 bool bruteMatch();
1007#endif 1013#endif
1008 bool matchHere(); 1014 bool matchHere();
1009 1015
1010 QVector<State> s; // array of states 1016 QVector<State> s; // array of states
1011 int ns; // number of states 1017 int ns; // number of states
1012#ifndef QT_NO_REGEXP_CAPTURE 1018#ifndef QT_NO_REGEXP_CAPTURE
1013 QArray<Atom> f; // atom hierarchy 1019 QArray<Atom> f; // atom hierarchy
1014 int nf; // number of atoms 1020 int nf; // number of atoms
1015 int cf; // current atom 1021 int cf; // current atom
1016#endif 1022#endif
1017 int realncap; // number of captures, seen from the outside 1023 int realncap; // number of captures, seen from the outside
1018 int ncap; // number of captures, seen from the inside 1024 int ncap; // number of captures, seen from the inside
1019#ifndef QT_NO_REGEXP_CCLASS 1025#ifndef QT_NO_REGEXP_CCLASS
1020 QVector<CharClass> cl; // array of character classes 1026 QVector<CharClass> cl; // array of character classes
1021#endif 1027#endif
1022#ifndef QT_NO_REGEXP_LOOKAHEAD 1028#ifndef QT_NO_REGEXP_LOOKAHEAD
1023 QVector<Lookahead> ahead; // array of lookaheads 1029 QVector<Lookahead> ahead; // array of lookaheads
1024#endif 1030#endif
1025#ifndef QT_NO_REGEXP_ANCHOR_ALT 1031#ifndef QT_NO_REGEXP_ANCHOR_ALT
1026 QArray<AnchorAlternation> aa; // array of (a, b) pairs of anchors 1032 QArray<AnchorAlternation> aa; // array of (a, b) pairs of anchors
1027#endif 1033#endif
1028#ifndef QT_NO_REGEXP_OPTIM 1034#ifndef QT_NO_REGEXP_OPTIM
1029 bool caretAnchored; // does the regexp start with ^? 1035 bool caretAnchored; // does the regexp start with ^?
1030#endif 1036#endif
1031 bool valid; // is the regular expression valid? 1037 bool valid; // is the regular expression valid?
1032 bool cs; // case sensitive? 1038 bool cs; // case sensitive?
1033#ifndef QT_NO_REGEXP_BACKREF 1039#ifndef QT_NO_REGEXP_BACKREF
1034 int nbrefs; // number of back-references 1040 int nbrefs; // number of back-references
1035#endif 1041#endif
1036 1042
1037#ifndef QT_NO_REGEXP_OPTIM 1043#ifndef QT_NO_REGEXP_OPTIM
1038 bool useGoodStringHeuristic; // use goodStringMatch? otherwise badCharMatch 1044 bool useGoodStringHeuristic; // use goodStringMatch? otherwise badCharMatch
1039 1045
1040 int goodEarlyStart; // the index where goodStr can first occur in a match 1046 int goodEarlyStart; // the index where goodStr can first occur in a match
1041 int goodLateStart; // the index where goodStr can last occur in a match 1047 int goodLateStart; // the index where goodStr can last occur in a match
1042 QString goodStr; // the string that any match has to contain 1048 QString goodStr; // the string that any match has to contain
1043 1049
1044 int minl; // the minimum length of a match 1050 int minl; // the minimum length of a match
1045 QArray<int> occ1; // first-occurrence array 1051 QArray<int> occ1; // first-occurrence array
1046#endif 1052#endif
1047 1053
1048 /* 1054 /*
1049 The class Box is an abstraction for a regular expression fragment. It can 1055 The class Box is an abstraction for a regular expression fragment. It can
1050 also be seen as one node in the syntax tree of a regular expression with 1056 also be seen as one node in the syntax tree of a regular expression with
1051 synthetized attributes. 1057 synthetized attributes.
1052 1058
1053 It's interface is ugly for performance reasons. 1059 It's interface is ugly for performance reasons.
1054 */ 1060 */
1055 class Box 1061 class Box
1056 { 1062 {
1057 public: 1063 public:
1058 Box( QRegExpEngine *engine ); 1064 Box( QRegExpEngine *engine );
1059 Box( const Box& b ) { operator=( b ); } 1065 Box( const Box& b ) { operator=( b ); }
1060 1066
1061 Box& operator=( const Box& b ); 1067 Box& operator=( const Box& b );
1062 1068
1063 void clear() { operator=(Box(eng)); } 1069 void clear() { operator=(Box(eng)); }
1064 void set( QChar ch ); 1070 void set( QChar ch );
1065 void set( const CharClass& cc ); 1071 void set( const CharClass& cc );
1066#ifndef QT_NO_REGEXP_BACKREF 1072#ifndef QT_NO_REGEXP_BACKREF
1067 void set( int bref ); 1073 void set( int bref );
1068#endif 1074#endif
1069 1075
1070 void cat( const Box& b ); 1076 void cat( const Box& b );
1071 void orx( const Box& b ); 1077 void orx( const Box& b );
1072 void plus( int atom ); 1078 void plus( int atom );
1073 void opt(); 1079 void opt();
1074 void catAnchor( int a ); 1080 void catAnchor( int a );
1075#ifndef QT_NO_REGEXP_OPTIM 1081#ifndef QT_NO_REGEXP_OPTIM
1076 void setupHeuristics(); 1082 void setupHeuristics();
1077#endif 1083#endif
1078 1084
1079#if defined(QT_DEBUG) 1085#if defined(QT_DEBUG)
1080 void dump() const; 1086 void dump() const;
1081#endif 1087#endif
1082 1088
1083 private: 1089 private:
1084 void addAnchorsToEngine( const Box& to ) const; 1090 void addAnchorsToEngine( const Box& to ) const;
1085 1091
1086 QRegExpEngine *eng; // the automaton under construction 1092 QRegExpEngine *eng; // the automaton under construction
1087 QArray<int> ls; // the left states (firstpos) 1093 QArray<int> ls; // the left states (firstpos)
1088 QArray<int> rs; // the right states (lastpos) 1094 QArray<int> rs; // the right states (lastpos)
1089 QMap<int, int> lanchors; // the left anchors 1095 QMap<int, int> lanchors; // the left anchors
1090 QMap<int, int> ranchors; // the right anchors 1096 QMap<int, int> ranchors; // the right anchors
1091 int skipanchors; // the anchors to match if the box is skipped 1097 int skipanchors; // the anchors to match if the box is skipped
1092 1098
1093#ifndef QT_NO_REGEXP_OPTIM 1099#ifndef QT_NO_REGEXP_OPTIM
1094 int earlyStart; // the index where str can first occur 1100 int earlyStart; // the index where str can first occur
1095 int lateStart; // the index where str can last occur 1101 int lateStart; // the index where str can last occur
1096 QString str; // a string that has to occur in any match 1102 QString str; // a string that has to occur in any match
1097 QString leftStr; // a string occurring at the left of this box 1103 QString leftStr; // a string occurring at the left of this box
1098 QString rightStr; // a string occurring at the right of this box 1104 QString rightStr; // a string occurring at the right of this box
1099 int maxl; // the maximum length of this box (possibly InftyLen) 1105 int maxl; // the maximum length of this box (possibly InftyLen)
1100#endif 1106#endif
1101 1107
1102 int minl; // the minimum length of this box 1108 int minl; // the minimum length of this box
1103#ifndef QT_NO_REGEXP_OPTIM 1109#ifndef QT_NO_REGEXP_OPTIM
1104 QArray<int> occ1; // first-occurrence array 1110 QArray<int> occ1; // first-occurrence array
1105#endif 1111#endif
1106 }; 1112 };
1107 friend class Box; 1113 friend class Box;
1108 1114
1109 /* 1115 /*
1110 This is the lexical analyzer for regular expressions. 1116 This is the lexical analyzer for regular expressions.
1111 */ 1117 */
1112 enum { Tok_Eos, Tok_Dollar, Tok_LeftParen, Tok_MagicLeftParen, 1118 enum { Tok_Eos, Tok_Dollar, Tok_LeftParen, Tok_MagicLeftParen,
1113 Tok_PosLookahead, Tok_NegLookahead, Tok_RightParen, Tok_CharClass, 1119 Tok_PosLookahead, Tok_NegLookahead, Tok_RightParen, Tok_CharClass,
1114 Tok_Caret, Tok_Quantifier, Tok_Bar, Tok_Word, Tok_NonWord, 1120 Tok_Caret, Tok_Quantifier, Tok_Bar, Tok_Word, Tok_NonWord,
1115 Tok_Char = 0x10000, Tok_BackRef = 0x20000 }; 1121 Tok_Char = 0x10000, Tok_BackRef = 0x20000 };
1116 int getChar(); 1122 int getChar();
1117 int getEscape(); 1123 int getEscape();
1118#ifndef QT_NO_REGEXP_INTERVAL 1124#ifndef QT_NO_REGEXP_INTERVAL
1119 int getRep( int def ); 1125 int getRep( int def );
1120#endif 1126#endif
1121#ifndef QT_NO_REGEXP_LOOKAHEAD 1127#ifndef QT_NO_REGEXP_LOOKAHEAD
1122 void skipChars( int n ); 1128 void skipChars( int n );
1123#endif 1129#endif
1124 void startTokenizer( const QChar *rx, int len ); 1130 void startTokenizer( const QChar *rx, int len );
1125 int getToken(); 1131 int getToken();
1126 1132
1127 const QChar *yyIn; // a pointer to the input regular expression pattern 1133 const QChar *yyIn; // a pointer to the input regular expression pattern
1128 int yyPos0; // the position of yyTok in the input pattern 1134 int yyPos0; // the position of yyTok in the input pattern
1129 int yyPos; // the position of the next character to read 1135 int yyPos; // the position of the next character to read
1130 int yyLen; // the length of yyIn 1136 int yyLen; // the length of yyIn
1131 int yyCh; // the last character read 1137 int yyCh; // the last character read
1132 CharClass *yyCharClass; // attribute for Tok_CharClass tokens 1138 CharClass *yyCharClass; // attribute for Tok_CharClass tokens
1133 int yyMinRep; // attribute for Tok_Quantifier 1139 int yyMinRep; // attribute for Tok_Quantifier
1134 int yyMaxRep; // ditto 1140 int yyMaxRep; // ditto
1135 bool yyError; // syntax error or overflow during parsing? 1141 bool yyError; // syntax error or overflow during parsing?
1136 1142
1137 /* 1143 /*
1138 This is the syntactic analyzer for regular expressions. 1144 This is the syntactic analyzer for regular expressions.
1139 */ 1145 */
1140 int parse( const QChar *rx, int len ); 1146 int parse( const QChar *rx, int len );
1141 void parseAtom( Box *box ); 1147 void parseAtom( Box *box );
1142 void parseFactor( Box *box ); 1148 void parseFactor( Box *box );
1143 void parseTerm( Box *box ); 1149 void parseTerm( Box *box );
1144 void parseExpression( Box *box ); 1150 void parseExpression( Box *box );
1145 1151
1146 int yyTok; // the last token read 1152 int yyTok; // the last token read
1147 bool yyMayCapture; // set this to FALSE to disable capturing 1153 bool yyMayCapture; // set this to FALSE to disable capturing
1148 1154
1149 /* 1155 /*
1150 This is the engine state during matching. 1156 This is the engine state during matching.
1151 */ 1157 */
1152 const QString *mmStr; // a pointer to the input QString 1158 const QString *mmStr; // a pointer to the input QString
1153 const QChar *mmIn; // a pointer to the input string data 1159 const QChar *mmIn; // a pointer to the input string data
1154 int mmPos; // the current position in the string 1160 int mmPos; // the current position in the string
1155 int mmLen; // the length of the input string 1161 int mmLen; // the length of the input string
1156 bool mmMinimal; // minimal matching? 1162 bool mmMinimal; // minimal matching?
1157 QArray<int> mmCaptured; // an array of pairs (start, len) 1163 QArray<int> mmCaptured; // an array of pairs (start, len)
1158 QArray<int> mmCapturedNoMatch; // an array of pairs (-1, -1) 1164 QArray<int> mmCapturedNoMatch; // an array of pairs (-1, -1)
1159 QArray<int> mmBigArray; // big QArray<int> array 1165 QArray<int> mmBigArray; // big QArray<int> array
1160 int *mmInNextStack; // is state is mmNextStack? 1166 int *mmInNextStack; // is state is mmNextStack?
1161 int *mmCurStack; // stack of current states 1167 int *mmCurStack; // stack of current states
1162 int *mmNextStack; // stack of next states 1168 int *mmNextStack; // stack of next states
1163 int *mmCurCapBegin; // start of current states' captures 1169 int *mmCurCapBegin; // start of current states' captures
1164 int *mmNextCapBegin; // start of next states' captures 1170 int *mmNextCapBegin; // start of next states' captures
1165 int *mmCurCapEnd; // end of current states' captures 1171 int *mmCurCapEnd; // end of current states' captures
1166 int *mmNextCapEnd; // end of next states' captures 1172 int *mmNextCapEnd; // end of next states' captures
1167 int *mmTempCapBegin; // start of temporary captures 1173 int *mmTempCapBegin; // start of temporary captures
1168 int *mmTempCapEnd; // end of temporary captures 1174 int *mmTempCapEnd; // end of temporary captures
1169 int *mmCapBegin; // start of captures for a next state 1175 int *mmCapBegin; // start of captures for a next state
1170 int *mmCapEnd; // end of captures for a next state 1176 int *mmCapEnd; // end of captures for a next state
1171 int *mmSlideTab; // bump-along slide table for bad-character heuristic 1177 int *mmSlideTab; // bump-along slide table for bad-character heuristic
1172 int mmSlideTabSize; // size of slide table 1178 int mmSlideTabSize; // size of slide table
1173#ifndef QT_NO_REGEXP_BACKREF 1179#ifndef QT_NO_REGEXP_BACKREF
1174 QIntDict<int> mmSleeping; // dictionary of back-reference sleepers 1180 QIntDict<int> mmSleeping; // dictionary of back-reference sleepers
1175#endif 1181#endif
1176 int mmMatchedLen; // length of match or of matched string for partial match 1182 int mmMatchedLen; // length of match or of matched string for partial match
1177}; 1183};
1178 1184
1179QRegExpEngine::QRegExpEngine( const QString& rx, bool caseSensitive ) 1185QRegExpEngine::QRegExpEngine( const QString& rx, bool caseSensitive )
1180#ifndef QT_NO_REGEXP_BACKREF 1186#ifndef QT_NO_REGEXP_BACKREF
1181 : mmSleeping( 101 ) 1187 : mmSleeping( 101 )
1182#endif 1188#endif
1183{ 1189{
1184 setup( caseSensitive ); 1190 setup( caseSensitive );
1185 valid = ( parse(rx.unicode(), rx.length()) == (int) rx.length() ); 1191 valid = ( parse(rx.unicode(), rx.length()) == (int) rx.length() );
1186} 1192}
1187 1193
1188#ifndef QT_NO_REGEXP_OPTIM 1194#ifndef QT_NO_REGEXP_OPTIM
1189QRegExpEngine::~QRegExpEngine() 1195QRegExpEngine::~QRegExpEngine()
1190{ 1196{
1191 if ( --engCount == 0 ) { 1197 if ( --engCount == 0 ) {
1192 delete noOccurrences; 1198 delete noOccurrences;
1193 noOccurrences = 0; 1199 noOccurrences = 0;
1194 delete firstOccurrenceAtZero; 1200 delete firstOccurrenceAtZero;
1195 firstOccurrenceAtZero = 0; 1201 firstOccurrenceAtZero = 0;
1196 } 1202 }
1197} 1203}
1198#endif 1204#endif
1199 1205
1200/* 1206/*
1201 Tries to match in str and returns an array of (begin, length) pairs for 1207 Tries to match in str and returns an array of (begin, length) pairs for
1202 captured text. If there is no match, all pairs are (-1, -1). 1208 captured text. If there is no match, all pairs are (-1, -1).
1203*/ 1209*/
1204QArray<int> QRegExpEngine::match( const QString& str, int pos, bool minimal, 1210QArray<int> QRegExpEngine::match( const QString& str, int pos, bool minimal,
1205 bool oneTest ) 1211 bool oneTest )
1206{ 1212{
1207 mmStr = &str; 1213 mmStr = &str;
1208 mmIn = str.unicode(); 1214 mmIn = str.unicode();
1209 if ( mmIn == 0 ) 1215 if ( mmIn == 0 )
1210 mmIn = &QChar::null; 1216 mmIn = &QChar::null;
1211 mmPos = pos; 1217 mmPos = pos;
1212 mmLen = str.length(); 1218 mmLen = str.length();
1213 mmMinimal = minimal; 1219 mmMinimal = minimal;
1214 mmMatchedLen = 0; 1220 mmMatchedLen = 0;
1215 1221
1216 bool matched = FALSE; 1222 bool matched = FALSE;
1217 if ( valid && mmPos >= 0 && mmPos <= mmLen ) { 1223 if ( valid && mmPos >= 0 && mmPos <= mmLen ) {
1218#ifndef QT_NO_REGEXP_OPTIM 1224#ifndef QT_NO_REGEXP_OPTIM
1219 if ( mmPos <= mmLen - minl ) { 1225 if ( mmPos <= mmLen - minl ) {
1220 if ( caretAnchored || oneTest ) 1226 if ( caretAnchored || oneTest )
1221 matched = matchHere(); 1227 matched = matchHere();
1222 else if ( useGoodStringHeuristic ) 1228 else if ( useGoodStringHeuristic )
1223 matched = goodStringMatch(); 1229 matched = goodStringMatch();
1224 else 1230 else
1225 matched = badCharMatch(); 1231 matched = badCharMatch();
1226 } 1232 }
1227#else 1233#else
1228 matched = oneTest ? matchHere() : bruteMatch(); 1234 matched = oneTest ? matchHere() : bruteMatch();
1229#endif 1235#endif
1230 } 1236 }
1231 1237
1232 if ( matched ) { 1238 if ( matched ) {
1233 mmCaptured.detach(); 1239 mmCaptured.detach();
1234 mmCaptured[0] = mmPos; 1240 mmCaptured[0] = mmPos;
1235 mmCaptured[1] = mmMatchedLen; 1241 mmCaptured[1] = mmMatchedLen;
1236 for ( int j = 0; j < realncap; j++ ) { 1242 for ( int j = 0; j < realncap; j++ ) {
1237 int len = mmCapEnd[j] - mmCapBegin[j]; 1243 int len = mmCapEnd[j] - mmCapBegin[j];
1238 mmCaptured[2 + 2 * j] = len > 0 ? mmPos + mmCapBegin[j] : 0; 1244 mmCaptured[2 + 2 * j] = len > 0 ? mmPos + mmCapBegin[j] : 0;
1239 mmCaptured[2 + 2 * j + 1] = len; 1245 mmCaptured[2 + 2 * j + 1] = len;
1240 } 1246 }
1241 return mmCaptured; 1247 return mmCaptured;
1242 } else { 1248 } else {
1243 return mmCapturedNoMatch; 1249 return mmCapturedNoMatch;
1244 } 1250 }
1245} 1251}
1246 1252
1247/* 1253/*
1248 The three following functions add one state to the automaton and return the 1254 The three following functions add one state to the automaton and return the
1249 number of the state. 1255 number of the state.
1250*/ 1256*/
1251 1257
1252int QRegExpEngine::createState( QChar ch ) 1258int QRegExpEngine::createState( QChar ch )
1253{ 1259{
1254 return setupState( ch.unicode() ); 1260 return setupState( ch.unicode() );
1255} 1261}
1256 1262
1257int QRegExpEngine::createState( const CharClass& cc ) 1263int QRegExpEngine::createState( const CharClass& cc )
1258{ 1264{
1259#ifndef QT_NO_REGEXP_CCLASS 1265#ifndef QT_NO_REGEXP_CCLASS
1260 int n = cl.size(); 1266 int n = cl.size();
1261 cl.resize( n + 1 ); 1267 cl.resize( n + 1 );
1262 cl.insert( n, new CharClass(cc) ); 1268 cl.insert( n, new CharClass(cc) );
1263 return setupState( CharClassBit | n ); 1269 return setupState( CharClassBit | n );
1264#else 1270#else
1265 Q_UNUSED( cc ); 1271 Q_UNUSED( cc );
1266 return setupState( CharClassBit ); 1272 return setupState( CharClassBit );
1267#endif 1273#endif
1268} 1274}
1269 1275
1270#ifndef QT_NO_REGEXP_BACKREF 1276#ifndef QT_NO_REGEXP_BACKREF
1271int QRegExpEngine::createState( int bref ) 1277int QRegExpEngine::createState( int bref )
1272{ 1278{
1273 if ( bref > nbrefs ) { 1279 if ( bref > nbrefs ) {
1274 nbrefs = bref; 1280 nbrefs = bref;
1275 if ( nbrefs > MaxBackRefs ) { 1281 if ( nbrefs > MaxBackRefs ) {
1276 yyError = TRUE; 1282 yyError = TRUE;
1277 return 0; 1283 return 0;
1278 } 1284 }
1279 } 1285 }
1280 return setupState( BackRefBit | bref ); 1286 return setupState( BackRefBit | bref );
1281} 1287}
1282#endif 1288#endif
1283 1289
1284/* 1290/*
1285 The two following functions add a transition between all pairs of states 1291 The two following functions add a transition between all pairs of states
1286 (i, j) where i is fond in from, and j is found in to. 1292 (i, j) where i is fond in from, and j is found in to.
1287 1293
1288 Cat-transitions are distinguished from plus-transitions for capturing. 1294 Cat-transitions are distinguished from plus-transitions for capturing.
1289*/ 1295*/
1290 1296
1291void QRegExpEngine::addCatTransitions( const QArray<int>& from, 1297void QRegExpEngine::addCatTransitions( const QArray<int>& from,
1292 const QArray<int>& to ) 1298 const QArray<int>& to )
1293{ 1299{
1294 for ( int i = 0; i < (int) from.size(); i++ ) { 1300 for ( int i = 0; i < (int) from.size(); i++ ) {
1295 State *st = s[from[i]]; 1301 State *st = s[from[i]];
1296 mergeInto( &st->outs, to ); 1302 mergeInto( &st->outs, to );
1297 } 1303 }
1298} 1304}
1299 1305
1300#ifndef QT_NO_REGEXP_CAPTURE 1306#ifndef QT_NO_REGEXP_CAPTURE
1301void QRegExpEngine::addPlusTransitions( const QArray<int>& from, 1307void QRegExpEngine::addPlusTransitions( const QArray<int>& from,
1302 const QArray<int>& to, int atom ) 1308 const QArray<int>& to, int atom )
1303{ 1309{
1304 for ( int i = 0; i < (int) from.size(); i++ ) { 1310 for ( int i = 0; i < (int) from.size(); i++ ) {
1305 State *st = s[from[i]]; 1311 State *st = s[from[i]];
1306 QArray<int> oldOuts = st->outs.copy(); 1312 QArray<int> oldOuts = st->outs.copy();
1307 mergeInto( &st->outs, to ); 1313 mergeInto( &st->outs, to );
1308 if ( f[atom].capture >= 0 ) { 1314 if ( f[atom].capture >= 0 ) {
1309 if ( st->reenter == 0 ) 1315 if ( st->reenter == 0 )
1310 st->reenter = new QMap<int, int>; 1316 st->reenter = new QMap<int, int>;
1311 for ( int j = 0; j < (int) to.size(); j++ ) { 1317 for ( int j = 0; j < (int) to.size(); j++ ) {
1312 if ( !st->reenter->contains(to[j]) && 1318 if ( !st->reenter->contains(to[j]) &&
1313 oldOuts.bsearch(to[j]) < 0 ) 1319 oldOuts.bsearch(to[j]) < 0 )
1314 st->reenter->insert( to[j], atom ); 1320 st->reenter->insert( to[j], atom );
1315 } 1321 }
1316 } 1322 }
1317 } 1323 }
1318} 1324}
1319#endif 1325#endif
1320 1326
1321#ifndef QT_NO_REGEXP_ANCHOR_ALT 1327#ifndef QT_NO_REGEXP_ANCHOR_ALT
1322/* 1328/*
1323 Returns an anchor that means a OR b. 1329 Returns an anchor that means a OR b.
1324*/ 1330*/
1325int QRegExpEngine::anchorAlternation( int a, int b ) 1331int QRegExpEngine::anchorAlternation( int a, int b )
1326{ 1332{
1327 if ( ((a & b) == a || (a & b) == b) && ((a | b) & Anchor_Alternation) == 0 ) 1333 if ( ((a & b) == a || (a & b) == b) && ((a | b) & Anchor_Alternation) == 0 )
1328 return a & b; 1334 return a & b;
1329 1335
1330 int n = aa.size(); 1336 int n = aa.size();
1331 aa.resize( n + 1 ); 1337 aa.resize( n + 1 );
1332 aa[n].a = a; 1338 aa[n].a = a;
1333 aa[n].b = b; 1339 aa[n].b = b;
1334 return Anchor_Alternation | n; 1340 return Anchor_Alternation | n;
1335} 1341}
1336 1342
1337/* 1343/*
1338 Returns an anchor that means a AND b. 1344 Returns an anchor that means a AND b.
1339*/ 1345*/
1340int QRegExpEngine::anchorConcatenation( int a, int b ) 1346int QRegExpEngine::anchorConcatenation( int a, int b )
1341{ 1347{
1342 if ( ((a | b) & Anchor_Alternation) == 0 ) 1348 if ( ((a | b) & Anchor_Alternation) == 0 )
1343 return a | b; 1349 return a | b;
1344 if ( (b & Anchor_Alternation) != 0 ) 1350 if ( (b & Anchor_Alternation) != 0 )
1345 qSwap( a, b ); 1351 qSwap( a, b );
1346 int aprime = anchorConcatenation( aa[a ^ Anchor_Alternation].a, b ); 1352 int aprime = anchorConcatenation( aa[a ^ Anchor_Alternation].a, b );
1347 int bprime = anchorConcatenation( aa[a ^ Anchor_Alternation].b, b ); 1353 int bprime = anchorConcatenation( aa[a ^ Anchor_Alternation].b, b );
1348 return anchorAlternation( aprime, bprime ); 1354 return anchorAlternation( aprime, bprime );
1349} 1355}
1350#endif 1356#endif
1351 1357
1352/* 1358/*
1353 Adds anchor a on a transition caracterised by its from state and its to state. 1359 Adds anchor a on a transition caracterised by its from state and its to state.
1354*/ 1360*/
1355void QRegExpEngine::addAnchors( int from, int to, int a ) 1361void QRegExpEngine::addAnchors( int from, int to, int a )
1356{ 1362{
1357 State *st = s[from]; 1363 State *st = s[from];
1358 if ( st->anchors == 0 ) 1364 if ( st->anchors == 0 )
1359 st->anchors = new QMap<int, int>; 1365 st->anchors = new QMap<int, int>;
1360 if ( st->anchors->contains(to) ) 1366 if ( st->anchors->contains(to) )
1361 a = anchorAlternation( (*st->anchors)[to], a ); 1367 a = anchorAlternation( (*st->anchors)[to], a );
1362 st->anchors->insert( to, a ); 1368 st->anchors->insert( to, a );
1363} 1369}
1364 1370
1365#ifndef QT_NO_REGEXP_OPTIM 1371#ifndef QT_NO_REGEXP_OPTIM
1366/* 1372/*
1367 The two following functions provide the engine with the information needed by 1373 The two following functions provide the engine with the information needed by
1368 its matching heuristics. 1374 its matching heuristics.
1369*/ 1375*/
1370 1376
1371void QRegExpEngine::setupGoodStringHeuristic( int earlyStart, int lateStart, 1377void QRegExpEngine::setupGoodStringHeuristic( int earlyStart, int lateStart,
1372 const QString& str ) 1378 const QString& str )
1373{ 1379{
1374 goodEarlyStart = earlyStart; 1380 goodEarlyStart = earlyStart;
1375 goodLateStart = lateStart; 1381 goodLateStart = lateStart;
1376 goodStr = cs ? str : str.lower(); 1382 goodStr = cs ? str : str.lower();
1377} 1383}
1378 1384
1379void QRegExpEngine::setupBadCharHeuristic( int minLen, 1385void QRegExpEngine::setupBadCharHeuristic( int minLen,
1380 const QArray<int>& firstOcc ) 1386 const QArray<int>& firstOcc )
1381{ 1387{
1382 minl = minLen; 1388 minl = minLen;
1383 occ1 = cs ? firstOcc : *firstOccurrenceAtZero; 1389 occ1 = cs ? firstOcc : *firstOccurrenceAtZero;
1384} 1390}
1385 1391
1386/* 1392/*
1387 This function chooses between the good-string and the bad-character 1393 This function chooses between the good-string and the bad-character
1388 heuristics. It computes two scores and chooses the heuristic with the highest 1394 heuristics. It computes two scores and chooses the heuristic with the highest
1389 score. 1395 score.
1390 1396
1391 Here are some common-sense constraints on the scores that should be respected 1397 Here are some common-sense constraints on the scores that should be respected
1392 if the formulas are ever modified: (1) If goodStr is empty, the good-string 1398 if the formulas are ever modified: (1) If goodStr is empty, the good-string
1393 heuristic scores 0. (2) If the search is case insensitive, the good-string 1399 heuristic scores 0. (2) If the search is case insensitive, the good-string
1394 heuristic should be used, unless it scores 0. (Case insensitivity 1400 heuristic should be used, unless it scores 0. (Case insensitivity
1395 turns all entries of occ1 to 0.) (3) If (goodLateStart - goodEarlyStart) is 1401 turns all entries of occ1 to 0.) (3) If (goodLateStart - goodEarlyStart) is
1396 big, the good-string heuristic should score less. 1402 big, the good-string heuristic should score less.
1397*/ 1403*/
1398void QRegExpEngine::heuristicallyChooseHeuristic() 1404void QRegExpEngine::heuristicallyChooseHeuristic()
1399{ 1405{
1400 int i; 1406 int i;
1401 1407
1402 if ( minl == 0 ) 1408 if ( minl == 0 )
1403 return; 1409 return;
1404 1410
1405 /* 1411 /*
1406 Magic formula: The good string has to constitute a good proportion of the 1412 Magic formula: The good string has to constitute a good proportion of the
1407 minimum-length string, and appear at a more-or-less known index. 1413 minimum-length string, and appear at a more-or-less known index.
1408 */ 1414 */
1409 int goodStringScore = ( 64 * goodStr.length() / minl ) - 1415 int goodStringScore = ( 64 * goodStr.length() / minl ) -
1410 ( goodLateStart - goodEarlyStart ); 1416 ( goodLateStart - goodEarlyStart );
1411 1417
1412 /* 1418 /*
1413 Less magic formula: We pick a couple of characters at random, and check 1419 Less magic formula: We pick a couple of characters at random, and check
1414 whether they are good or bad. 1420 whether they are good or bad.
1415 */ 1421 */
1416 int badCharScore = 0; 1422 int badCharScore = 0;
1417 int step = QMAX( 1, NumBadChars / 32 ); 1423 int step = QMAX( 1, NumBadChars / 32 );
1418 for ( i = 1; i < NumBadChars; i += step ) { 1424 for ( i = 1; i < NumBadChars; i += step ) {
1419 if ( occ1[i] == NoOccurrence ) 1425 if ( occ1[i] == NoOccurrence )
1420 badCharScore += minl; 1426 badCharScore += minl;
1421 else 1427 else
1422 badCharScore += occ1[i]; 1428 badCharScore += occ1[i];
1423 } 1429 }
1424 badCharScore /= minl; 1430 badCharScore /= minl;
1425 1431
1426 useGoodStringHeuristic = ( goodStringScore > badCharScore ); 1432 useGoodStringHeuristic = ( goodStringScore > badCharScore );
1427} 1433}
1428#endif 1434#endif
1429 1435
1430#if defined(QT_DEBUG) 1436#if defined(QT_DEBUG)
1431void QRegExpEngine::dump() const 1437void QRegExpEngine::dump() const
1432{ 1438{
1433 int i, j; 1439 int i, j;
1434 qDebug( "Case %ssensitive engine", cs ? "" : "in" ); 1440 odebug << "Case " << (cs ? "" : "in") << "sensitive engine" << oendl;
1435 qDebug( " States" ); 1441 odebug << " States" << oendl;
1436 for ( i = 0; i < ns; i++ ) { 1442 for ( i = 0; i < ns; i++ ) {
1437 qDebug( " %d%s", i, 1443 odebug << " " << i
1438 i == InitialState ? " (initial)" : 1444 << (i == InitialState ? " (initial)" : i == FinalState ? " (final)" : "") << oendl;
1439 i == FinalState ? " (final)" : "" ); 1445
1440#ifndef QT_NO_REGEXP_CAPTURE 1446#ifndef QT_NO_REGEXP_CAPTURE
1441 qDebug( " in atom %d", s[i]->atom ); 1447 odebug << " in atom " << s[i]->atom << oendl;
1442#endif 1448#endif
1443 int m = s[i]->match; 1449 int m = s[i]->match;
1444 if ( (m & CharClassBit) != 0 ) { 1450 if ( (m & CharClassBit) != 0 ) {
1445 qDebug( " match character class %d", m ^ CharClassBit ); 1451 odebug << " match character class " << (m ^ CharClassBit) << oendl;
1446#ifndef QT_NO_REGEXP_CCLASS 1452#ifndef QT_NO_REGEXP_CCLASS
1447 cl[m ^ CharClassBit]->dump(); 1453 cl[m ^ CharClassBit]->dump();
1448#else 1454#else
1449 qDebug( " negative character class" ); 1455 odebug << " negative character class" << oendl;
1450#endif 1456#endif
1451 } else if ( (m & BackRefBit) != 0 ) { 1457 } else if ( (m & BackRefBit) != 0 ) {
1452 qDebug( " match back-reference %d", m ^ BackRefBit ); 1458 odebug << " match back-reference " << (m ^ BackRefBit) << oendl;
1453 } else if ( m >= 0x20 && m <= 0x7e ) { 1459 } else if ( m >= 0x20 && m <= 0x7e ) {
1454 qDebug( " match 0x%.4x (%c)", m, m ); 1460 odebug << " match " << QString().sprintf( "0x%.4x", m) << " (" << m << ")" << oendl;
1455 } else { 1461
1456 qDebug( " match 0x%.4x", m ); 1462 } else {
1457 } 1463 odebug << " match " << QString().sprintf( "0x%.4x", m) << oendl;
1458 for ( j = 0; j < (int) s[i]->outs.size(); j++ ) { 1464 }
1459 int next = s[i]->outs[j]; 1465 for ( j = 0; j < (int) s[i]->outs.size(); j++ ) {
1460 qDebug( " -> %d", next ); 1466 int next = s[i]->outs[j];
1461 if ( s[i]->reenter != 0 && s[i]->reenter->contains(next) ) 1467 odebug << " -> " << next << oendl;
1462 qDebug( " [reenter %d]", (*s[i]->reenter)[next] ); 1468 if ( s[i]->reenter != 0 && s[i]->reenter->contains(next) )
1463 if ( s[i]->anchors != 0 && at(*s[i]->anchors, next) != 0 ) 1469 odebug << " [reenter " << (*s[i]->reenter)[next] << "]" << oendl;
1464 qDebug( " [anchors 0x%.8x]", (*s[i]->anchors)[next] ); 1470 if ( s[i]->anchors != 0 && at(*s[i]->anchors, next) != 0 )
1465 } 1471 odebug << " [anchors " << QString().sprintf( "0x%.8x]", (*s[i]->anchors)[next] ) << oendl;
1472 }
1466 } 1473 }
1467#ifndef QT_NO_REGEXP_CAPTURE 1474#ifndef QT_NO_REGEXP_CAPTURE
1468 if ( nf > 0 ) { 1475 if ( nf > 0 ) {
1469 qDebug( " Atom Parent Capture" ); 1476 odebug << " Atom Parent Capture" << oendl;
1470 for ( i = 0; i < nf; i++ ) 1477 for ( i = 0; i < nf; i++ )
1471 qDebug( " %6d %6d %6d", i, f[i].parent, f[i].capture ); 1478 odebug << QString().sprintf(" %6d %6d %6d", i, f[i].parent, f[i].capture ) << oendl;
1472 } 1479 }
1473#endif 1480#endif
1474#ifndef QT_NO_REGEXP_ANCHOR_ALT 1481#ifndef QT_NO_REGEXP_ANCHOR_ALT
1475 for ( i = 0; i < (int) aa.size(); i++ ) 1482 for ( i = 0; i < (int) aa.size(); i++ )
1476 qDebug( " Anchor alternation 0x%.8x: 0x%.8x 0x%.9x", i, aa[i].a, 1483 odebug << QString().sprintf(" Anchor alternation 0x%.8x: 0x%.8x 0x%.9x", i, aa[i].a, aa[i].b ) << oendl;
1477 aa[i].b );
1478#endif 1484#endif
1479} 1485}
1480#endif 1486#endif
1481 1487
1482void QRegExpEngine::setup( bool caseSensitive ) 1488void QRegExpEngine::setup( bool caseSensitive )
1483{ 1489{
1484#ifndef QT_NO_REGEXP_OPTIM 1490#ifndef QT_NO_REGEXP_OPTIM
1485 if ( engCount++ == 0 ) { 1491 if ( engCount++ == 0 ) {
1486 noOccurrences = new QArray<int>( NumBadChars ); 1492 noOccurrences = new QArray<int>( NumBadChars );
1487 firstOccurrenceAtZero = new QArray<int>( NumBadChars ); 1493 firstOccurrenceAtZero = new QArray<int>( NumBadChars );
1488 noOccurrences->fill( NoOccurrence ); 1494 noOccurrences->fill( NoOccurrence );
1489 firstOccurrenceAtZero->fill( 0 ); 1495 firstOccurrenceAtZero->fill( 0 );
1490 } 1496 }
1491#endif 1497#endif
1492 s.setAutoDelete( TRUE ); 1498 s.setAutoDelete( TRUE );
1493 s.resize( 32 ); 1499 s.resize( 32 );
1494 ns = 0; 1500 ns = 0;
1495#ifndef QT_NO_REGEXP_CAPTURE 1501#ifndef QT_NO_REGEXP_CAPTURE
1496 f.resize( 32 ); 1502 f.resize( 32 );
1497 nf = 0; 1503 nf = 0;
1498 cf = -1; 1504 cf = -1;
1499#endif 1505#endif
1500 realncap = 0; 1506 realncap = 0;
1501 ncap = 0; 1507 ncap = 0;
1502#ifndef QT_NO_REGEXP_CCLASS 1508#ifndef QT_NO_REGEXP_CCLASS
1503 cl.setAutoDelete( TRUE ); 1509 cl.setAutoDelete( TRUE );
1504#endif 1510#endif
1505#ifndef QT_NO_REGEXP_LOOKAHEAD 1511#ifndef QT_NO_REGEXP_LOOKAHEAD
1506 ahead.setAutoDelete( TRUE ); 1512 ahead.setAutoDelete( TRUE );
1507#endif 1513#endif
1508#ifndef QT_NO_REGEXP_OPTIM 1514#ifndef QT_NO_REGEXP_OPTIM
1509 caretAnchored = TRUE; 1515 caretAnchored = TRUE;
1510#endif 1516#endif
1511 valid = FALSE; 1517 valid = FALSE;
1512 cs = caseSensitive; 1518 cs = caseSensitive;
1513#ifndef QT_NO_REGEXP_BACKREF 1519#ifndef QT_NO_REGEXP_BACKREF
1514 nbrefs = 0; 1520 nbrefs = 0;
1515#endif 1521#endif
1516#ifndef QT_NO_REGEXP_OPTIM 1522#ifndef QT_NO_REGEXP_OPTIM
1517 useGoodStringHeuristic = FALSE; 1523 useGoodStringHeuristic = FALSE;
1518 minl = 0; 1524 minl = 0;
1519 occ1 = *firstOccurrenceAtZero; 1525 occ1 = *firstOccurrenceAtZero;
1520#endif 1526#endif
1521 mmCapturedNoMatch.fill( -1, 2 ); 1527 mmCapturedNoMatch.fill( -1, 2 );
1522} 1528}
1523 1529
1524int QRegExpEngine::setupState( int match ) 1530int QRegExpEngine::setupState( int match )
1525{ 1531{
1526 if ( (ns & (ns + 1)) == 0 && ns + 1 >= (int) s.size() ) 1532 if ( (ns & (ns + 1)) == 0 && ns + 1 >= (int) s.size() )
1527 s.resize( (ns + 1) << 1 ); 1533 s.resize( (ns + 1) << 1 );
1528#ifndef QT_NO_REGEXP_CAPTURE 1534#ifndef QT_NO_REGEXP_CAPTURE
1529 s.insert( ns, new State(cf, match) ); 1535 s.insert( ns, new State(cf, match) );
1530#else 1536#else
1531 s.insert( ns, new State(match) ); 1537 s.insert( ns, new State(match) );
1532#endif 1538#endif
1533 return ns++; 1539 return ns++;
1534} 1540}
1535 1541
1536#ifndef QT_NO_REGEXP_CAPTURE 1542#ifndef QT_NO_REGEXP_CAPTURE
1537/* 1543/*
1538 Functions startAtom() and finishAtom() should be called to delimit atoms. 1544 Functions startAtom() and finishAtom() should be called to delimit atoms.
1539 When a state is created, it is assigned to the current atom. The information 1545 When a state is created, it is assigned to the current atom. The information
1540 is later used for capturing. 1546 is later used for capturing.
1541*/ 1547*/
1542int QRegExpEngine::startAtom( bool capture ) 1548int QRegExpEngine::startAtom( bool capture )
1543{ 1549{
1544 if ( (nf & (nf + 1)) == 0 && nf + 1 >= (int) f.size() ) 1550 if ( (nf & (nf + 1)) == 0 && nf + 1 >= (int) f.size() )
1545 f.resize( (nf + 1) << 1 ); 1551 f.resize( (nf + 1) << 1 );
1546 f[nf].parent = cf; 1552 f[nf].parent = cf;
1547 cf = nf++; 1553 cf = nf++;
1548 f[cf].capture = capture ? ncap++ : -1; 1554 f[cf].capture = capture ? ncap++ : -1;
1549 return cf; 1555 return cf;
1550} 1556}
1551#endif 1557#endif
1552 1558
1553#ifndef QT_NO_REGEXP_LOOKAHEAD 1559#ifndef QT_NO_REGEXP_LOOKAHEAD
1554/* 1560/*
1555 Creates a lookahead anchor. 1561 Creates a lookahead anchor.
1556*/ 1562*/
1557int QRegExpEngine::addLookahead( QRegExpEngine *eng, bool negative ) 1563int QRegExpEngine::addLookahead( QRegExpEngine *eng, bool negative )
1558{ 1564{
1559 int n = ahead.size(); 1565 int n = ahead.size();
1560 if ( n == MaxLookaheads ) { 1566 if ( n == MaxLookaheads ) {
1561 yyError = TRUE; 1567 yyError = TRUE;
1562 return 0; 1568 return 0;
1563 } 1569 }
1564 ahead.resize( n + 1 ); 1570 ahead.resize( n + 1 );
1565 ahead.insert( n, new Lookahead(eng, negative) ); 1571 ahead.insert( n, new Lookahead(eng, negative) );
1566 return Anchor_FirstLookahead << n; 1572 return Anchor_FirstLookahead << n;
1567} 1573}
1568#endif 1574#endif
1569 1575
1570#ifndef QT_NO_REGEXP_CAPTURE 1576#ifndef QT_NO_REGEXP_CAPTURE
1571/* 1577/*
1572 We want the longest leftmost captures. 1578 We want the longest leftmost captures.
1573*/ 1579*/
1574bool QRegExpEngine::isBetterCapture( const int *begin1, const int *end1, 1580bool QRegExpEngine::isBetterCapture( const int *begin1, const int *end1,
1575 const int *begin2, const int *end2 ) 1581 const int *begin2, const int *end2 )
1576{ 1582{
1577 for ( int i = 0; i < ncap; i++ ) { 1583 for ( int i = 0; i < ncap; i++ ) {
1578 int delta = begin2[i] - begin1[i]; // it has to start early... 1584 int delta = begin2[i] - begin1[i]; // it has to start early...
1579 if ( delta == 0 ) 1585 if ( delta == 0 )
1580 delta = end1[i] - end2[i]; // ...and end late (like a party) 1586 delta = end1[i] - end2[i]; // ...and end late (like a party)
1581 1587
1582 if ( delta != 0 ) 1588 if ( delta != 0 )
1583 return delta > 0; 1589 return delta > 0;
1584 } 1590 }
1585 return FALSE; 1591 return FALSE;
1586} 1592}
1587#endif 1593#endif
1588 1594
1589/* 1595/*
1590 Returns TRUE if anchor a matches at position mmPos + i in the input string, 1596 Returns TRUE if anchor a matches at position mmPos + i in the input string,
1591 otherwise FALSE. 1597 otherwise FALSE.
1592*/ 1598*/
1593bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin ) 1599bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin )
1594{ 1600{
1595 int j; 1601 int j;
1596 1602
1597#ifndef QT_NO_REGEXP_ANCHOR_ALT 1603#ifndef QT_NO_REGEXP_ANCHOR_ALT
1598 if ( (a & Anchor_Alternation) != 0 ) { 1604 if ( (a & Anchor_Alternation) != 0 ) {
1599 return testAnchor( i, aa[a ^ Anchor_Alternation].a, capBegin ) || 1605 return testAnchor( i, aa[a ^ Anchor_Alternation].a, capBegin ) ||
1600 testAnchor( i, aa[a ^ Anchor_Alternation].b, capBegin ); 1606 testAnchor( i, aa[a ^ Anchor_Alternation].b, capBegin );
1601 } 1607 }
1602#endif 1608#endif
1603 1609
1604 if ( (a & Anchor_Caret) != 0 ) { 1610 if ( (a & Anchor_Caret) != 0 ) {
1605 if ( mmPos + i != 0 ) 1611 if ( mmPos + i != 0 )
1606 return FALSE; 1612 return FALSE;
1607 } 1613 }
1608 if ( (a & Anchor_Dollar) != 0 ) { 1614 if ( (a & Anchor_Dollar) != 0 ) {
1609 if ( mmPos + i != mmLen ) 1615 if ( mmPos + i != mmLen )
1610 return FALSE; 1616 return FALSE;
1611 } 1617 }
1612#ifndef QT_NO_REGEXP_ESCAPE 1618#ifndef QT_NO_REGEXP_ESCAPE
1613 if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) { 1619 if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) {
1614 bool before = FALSE, after = FALSE; 1620 bool before = FALSE, after = FALSE;
1615 if ( mmPos + i != 0 ) 1621 if ( mmPos + i != 0 )
1616 before = mmIn[mmPos + i - 1].isLetterOrNumber(); 1622 before = mmIn[mmPos + i - 1].isLetterOrNumber();
1617 if ( mmPos + i != mmLen ) 1623 if ( mmPos + i != mmLen )
1618 after = mmIn[mmPos + i].isLetterOrNumber(); 1624 after = mmIn[mmPos + i].isLetterOrNumber();
1619 if ( (a & Anchor_Word) != 0 && (before == after) ) 1625 if ( (a & Anchor_Word) != 0 && (before == after) )
1620 return FALSE; 1626 return FALSE;
1621 if ( (a & Anchor_NonWord) != 0 && (before != after) ) 1627 if ( (a & Anchor_NonWord) != 0 && (before != after) )
1622 return FALSE; 1628 return FALSE;
1623 } 1629 }
1624#endif 1630#endif
1625#ifndef QT_NO_REGEXP_LOOKAHEAD 1631#ifndef QT_NO_REGEXP_LOOKAHEAD
1626 bool catchx = TRUE; 1632 bool catchx = TRUE;
1627 1633
1628 if ( (a & Anchor_LookaheadMask) != 0 ) { 1634 if ( (a & Anchor_LookaheadMask) != 0 ) {
1629 QConstString cstr = QConstString( (QChar *) mmIn + mmPos + i, 1635 QConstString cstr = QConstString( (QChar *) mmIn + mmPos + i,
1630 mmLen - mmPos - i ); 1636 mmLen - mmPos - i );
1631 for ( j = 0; j < (int) ahead.size(); j++ ) { 1637 for ( j = 0; j < (int) ahead.size(); j++ ) {
1632 if ( (a & (Anchor_FirstLookahead << j)) != 0 ) { 1638 if ( (a & (Anchor_FirstLookahead << j)) != 0 ) {
1633 catchx = ( ahead[j]->eng->match(cstr.string(), 0, TRUE, 1639 catchx = ( ahead[j]->eng->match(cstr.string(), 0, TRUE,
1634 TRUE)[0] == 0 ); 1640 TRUE)[0] == 0 );
1635 if ( catchx == ahead[j]->neg ) 1641 if ( catchx == ahead[j]->neg )
1636 return FALSE; 1642 return FALSE;
1637 } 1643 }
1638 } 1644 }
1639 } 1645 }
1640#endif 1646#endif
1641#ifndef QT_NO_REGEXP_CAPTURE 1647#ifndef QT_NO_REGEXP_CAPTURE
1642#ifndef QT_NO_REGEXP_BACKREF 1648#ifndef QT_NO_REGEXP_BACKREF
1643 for ( j = 0; j < nbrefs; j++ ) { 1649 for ( j = 0; j < nbrefs; j++ ) {
1644 if ( (a & (Anchor_BackRef1Empty << j)) != 0 ) { 1650 if ( (a & (Anchor_BackRef1Empty << j)) != 0 ) {
1645 if ( capBegin[j] != EmptyCapture ) 1651 if ( capBegin[j] != EmptyCapture )
1646 return FALSE; 1652 return FALSE;
1647 } 1653 }
1648 } 1654 }
1649#endif 1655#endif
1650#endif 1656#endif
1651 return TRUE; 1657 return TRUE;
1652} 1658}
1653 1659
1654#ifndef QT_NO_REGEXP_OPTIM 1660#ifndef QT_NO_REGEXP_OPTIM
1655/* 1661/*
1656 The three following functions are what Jeffrey Friedl would call transmissions 1662 The three following functions are what Jeffrey Friedl would call transmissions
1657 (or bump-alongs). Using one or the other should make no difference, except 1663 (or bump-alongs). Using one or the other should make no difference, except
1658 in performance. 1664 in performance.
1659*/ 1665*/
1660 1666
1661bool QRegExpEngine::goodStringMatch() 1667bool QRegExpEngine::goodStringMatch()
1662{ 1668{
1663 int k = mmPos + goodEarlyStart; 1669 int k = mmPos + goodEarlyStart;
1664 1670
1665 while ( (k = mmStr->find(goodStr, k, cs)) != -1 ) { 1671 while ( (k = mmStr->find(goodStr, k, cs)) != -1 ) {
1666 int from = k - goodLateStart; 1672 int from = k - goodLateStart;
1667 int to = k - goodEarlyStart; 1673 int to = k - goodEarlyStart;
1668 if ( from > mmPos ) 1674 if ( from > mmPos )
1669 mmPos = from; 1675 mmPos = from;
1670 1676
1671 while ( mmPos <= to ) { 1677 while ( mmPos <= to ) {
1672 if ( matchHere() ) 1678 if ( matchHere() )
1673 return TRUE; 1679 return TRUE;
1674 mmPos++; 1680 mmPos++;
1675 } 1681 }
1676 k++; 1682 k++;
1677 } 1683 }
1678 return FALSE; 1684 return FALSE;
1679} 1685}
1680 1686
1681bool QRegExpEngine::badCharMatch() 1687bool QRegExpEngine::badCharMatch()
1682{ 1688{
1683 int slideHead = 0; 1689 int slideHead = 0;
1684 int slideNext = 0; 1690 int slideNext = 0;
1685 int i; 1691 int i;
1686 int lastPos = mmLen - minl; 1692 int lastPos = mmLen - minl;
1687 memset( mmSlideTab, 0, mmSlideTabSize * sizeof(int) ); 1693 memset( mmSlideTab, 0, mmSlideTabSize * sizeof(int) );
1688 1694
1689 /* 1695 /*
1690 Set up the slide table, used for the bad-character heuristic, using 1696 Set up the slide table, used for the bad-character heuristic, using
1691 the table of first occurrence of each character. 1697 the table of first occurrence of each character.
1692 */ 1698 */
1693 for ( i = 0; i < minl; i++ ) { 1699 for ( i = 0; i < minl; i++ ) {
1694 int sk = occ1[BadChar(mmIn[mmPos + i])]; 1700 int sk = occ1[BadChar(mmIn[mmPos + i])];
1695 if ( sk == NoOccurrence ) 1701 if ( sk == NoOccurrence )
1696 sk = i + 1; 1702 sk = i + 1;
1697 if ( sk > 0 ) { 1703 if ( sk > 0 ) {
1698 int k = i + 1 - sk; 1704 int k = i + 1 - sk;
1699 if ( k < 0 ) { 1705 if ( k < 0 ) {
1700 sk = i + 1; 1706 sk = i + 1;
1701 k = 0; 1707 k = 0;
1702 } 1708 }
1703 if ( sk > mmSlideTab[k] ) 1709 if ( sk > mmSlideTab[k] )
1704 mmSlideTab[k] = sk; 1710 mmSlideTab[k] = sk;
1705 } 1711 }
1706 } 1712 }
1707 1713
1708 if ( mmPos > lastPos ) 1714 if ( mmPos > lastPos )
1709 return FALSE; 1715 return FALSE;
1710 1716
1711 while ( TRUE ) { 1717 while ( TRUE ) {
1712 if ( ++slideNext >= mmSlideTabSize ) 1718 if ( ++slideNext >= mmSlideTabSize )
1713 slideNext = 0; 1719 slideNext = 0;
1714 if ( mmSlideTab[slideHead] > 0 ) { 1720 if ( mmSlideTab[slideHead] > 0 ) {
1715 if ( mmSlideTab[slideHead] - 1 > mmSlideTab[slideNext] ) 1721 if ( mmSlideTab[slideHead] - 1 > mmSlideTab[slideNext] )
1716 mmSlideTab[slideNext] = mmSlideTab[slideHead] - 1; 1722 mmSlideTab[slideNext] = mmSlideTab[slideHead] - 1;
1717 mmSlideTab[slideHead] = 0; 1723 mmSlideTab[slideHead] = 0;
1718 } else { 1724 } else {
1719 if ( matchHere() ) 1725 if ( matchHere() )
1720 return TRUE; 1726 return TRUE;
1721 } 1727 }
1722 1728
1723 if ( mmPos == lastPos ) 1729 if ( mmPos == lastPos )
1724 break; 1730 break;
1725 1731
1726 /* 1732 /*
1727 Update the slide table. This code has much in common with the 1733 Update the slide table. This code has much in common with the
1728 initialization code. 1734 initialization code.
1729 */ 1735 */
1730 int sk = occ1[BadChar(mmIn[mmPos + minl])]; 1736 int sk = occ1[BadChar(mmIn[mmPos + minl])];
1731 if ( sk == NoOccurrence ) { 1737 if ( sk == NoOccurrence ) {
1732 mmSlideTab[slideNext] = minl; 1738 mmSlideTab[slideNext] = minl;
1733 } else if ( sk > 0 ) { 1739 } else if ( sk > 0 ) {
1734 int k = slideNext + minl - sk; 1740 int k = slideNext + minl - sk;
1735 if ( k >= mmSlideTabSize ) 1741 if ( k >= mmSlideTabSize )
1736 k -= mmSlideTabSize; 1742 k -= mmSlideTabSize;
1737 if ( sk > mmSlideTab[k] ) 1743 if ( sk > mmSlideTab[k] )
1738 mmSlideTab[k] = sk; 1744 mmSlideTab[k] = sk;
1739 } 1745 }
1740 slideHead = slideNext; 1746 slideHead = slideNext;
1741 mmPos++; 1747 mmPos++;
1742 } 1748 }
1743 return FALSE; 1749 return FALSE;
1744} 1750}
1745#else 1751#else
1746bool QRegExpEngine::bruteMatch() 1752bool QRegExpEngine::bruteMatch()
1747{ 1753{
1748 while ( mmPos <= mmLen ) { 1754 while ( mmPos <= mmLen ) {
1749 if ( matchHere() ) 1755 if ( matchHere() )
1750 return TRUE; 1756 return TRUE;
1751 mmPos++; 1757 mmPos++;
1752 } 1758 }
1753 return FALSE; 1759 return FALSE;
1754} 1760}
1755#endif 1761#endif
1756 1762
1757/* 1763/*
1758 Here's the core of the engine. It tries to do a match here and now. 1764 Here's the core of the engine. It tries to do a match here and now.
1759*/ 1765*/
1760bool QRegExpEngine::matchHere() 1766bool QRegExpEngine::matchHere()
1761{ 1767{
1762 int ncur = 1, nnext = 0; 1768 int ncur = 1, nnext = 0;
1763 int i = 0, j, k, m; 1769 int i = 0, j, k, m;
1764 bool match = FALSE; 1770 bool match = FALSE;
1765 1771
1766 mmMatchedLen = -1; 1772 mmMatchedLen = -1;
1767 mmCurStack[0] = InitialState; 1773 mmCurStack[0] = InitialState;
1768 1774
1769#ifndef QT_NO_REGEXP_CAPTURE 1775#ifndef QT_NO_REGEXP_CAPTURE
1770 if ( ncap > 0 ) { 1776 if ( ncap > 0 ) {
1771 for ( j = 0; j < ncap; j++ ) { 1777 for ( j = 0; j < ncap; j++ ) {
1772 mmCurCapBegin[j] = EmptyCapture; 1778 mmCurCapBegin[j] = EmptyCapture;
1773 mmCurCapEnd[j] = EmptyCapture; 1779 mmCurCapEnd[j] = EmptyCapture;
1774 } 1780 }
1775 } 1781 }
1776#endif 1782#endif
1777 1783
1778#ifndef QT_NO_REGEXP_BACKREF 1784#ifndef QT_NO_REGEXP_BACKREF
1779 int *zzZ = 0; 1785 int *zzZ = 0;
1780 1786
1781 while ( (ncur > 0 || mmSleeping.count() > 0) && i <= mmLen - mmPos && 1787 while ( (ncur > 0 || mmSleeping.count() > 0) && i <= mmLen - mmPos &&
1782 !match ) 1788 !match )
1783#else 1789#else
1784 while ( ncur > 0 && i <= mmLen - mmPos && !match ) 1790 while ( ncur > 0 && i <= mmLen - mmPos && !match )
1785#endif 1791#endif
1786 { 1792 {
1787 int ch = ( i < mmLen - mmPos ) ? mmIn[mmPos + i].unicode() : 0; 1793 int ch = ( i < mmLen - mmPos ) ? mmIn[mmPos + i].unicode() : 0;
1788 for ( j = 0; j < ncur; j++ ) { 1794 for ( j = 0; j < ncur; j++ ) {
1789 int cur = mmCurStack[j]; 1795 int cur = mmCurStack[j];
1790 State *scur = s[cur]; 1796 State *scur = s[cur];
1791 QArray<int>& outs = scur->outs; 1797 QArray<int>& outs = scur->outs;
1792 for ( k = 0; k < (int) outs.size(); k++ ) { 1798 for ( k = 0; k < (int) outs.size(); k++ ) {
1793 int next = outs[k]; 1799 int next = outs[k];
1794 State *snext = s[next]; 1800 State *snext = s[next];
1795 bool in = TRUE; 1801 bool in = TRUE;
1796#ifndef QT_NO_REGEXP_BACKREF 1802#ifndef QT_NO_REGEXP_BACKREF
1797 int needSomeSleep = 0; 1803 int needSomeSleep = 0;
1798#endif 1804#endif
1799 1805
1800 /* 1806 /*
1801 First, check if the anchors are anchored properly. 1807 First, check if the anchors are anchored properly.
1802 */ 1808 */
1803 if ( scur->anchors != 0 ) { 1809 if ( scur->anchors != 0 ) {
1804 int a = at( *scur->anchors, next ); 1810 int a = at( *scur->anchors, next );
1805 if ( a != 0 && !testAnchor(i, a, mmCurCapBegin + j * ncap) ) 1811 if ( a != 0 && !testAnchor(i, a, mmCurCapBegin + j * ncap) )
1806 in = FALSE; 1812 in = FALSE;
1807 } 1813 }
1808 /* 1814 /*
1809 If indeed they are, check if the input character is correct 1815 If indeed they are, check if the input character is correct
1810 for this transition. 1816 for this transition.
1811 */ 1817 */
1812 if ( in ) { 1818 if ( in ) {
1813 m = snext->match; 1819 m = snext->match;
1814 if ( (m & (CharClassBit | BackRefBit)) == 0 ) { 1820 if ( (m & (CharClassBit | BackRefBit)) == 0 ) {
1815 if ( cs ) 1821 if ( cs )
1816 in = ( m == ch ); 1822 in = ( m == ch );
1817 else 1823 else
1818 in = ( QChar(m).lower() == QChar(ch).lower() ); 1824 in = ( QChar(m).lower() == QChar(ch).lower() );
1819 } else if ( next == FinalState ) { 1825 } else if ( next == FinalState ) {
1820 mmMatchedLen = i; 1826 mmMatchedLen = i;
1821 match = mmMinimal; 1827 match = mmMinimal;
1822 in = TRUE; 1828 in = TRUE;
1823 } else if ( (m & CharClassBit) != 0 ) { 1829 } else if ( (m & CharClassBit) != 0 ) {
1824#ifndef QT_NO_REGEXP_CCLASS 1830#ifndef QT_NO_REGEXP_CCLASS
1825 const CharClass *cc = cl[m ^ CharClassBit]; 1831 const CharClass *cc = cl[m ^ CharClassBit];
1826 if ( cs ) 1832 if ( cs )
1827 in = cc->in( ch ); 1833 in = cc->in( ch );
1828 else if ( cc->negative() ) 1834 else if ( cc->negative() )
1829 in = cc->in( QChar(ch).lower() ) && 1835 in = cc->in( QChar(ch).lower() ) &&
1830 cc->in( QChar(ch).upper() ); 1836 cc->in( QChar(ch).upper() );
1831 else 1837 else
1832 in = cc->in( QChar(ch).lower() ) || 1838 in = cc->in( QChar(ch).lower() ) ||
1833 cc->in( QChar(ch).upper() ); 1839 cc->in( QChar(ch).upper() );
1834#endif 1840#endif
1835#ifndef QT_NO_REGEXP_BACKREF 1841#ifndef QT_NO_REGEXP_BACKREF
1836 } else { /* ( (m & BackRefBit) != 0 ) */ 1842 } else { /* ( (m & BackRefBit) != 0 ) */
1837 int bref = m ^ BackRefBit; 1843 int bref = m ^ BackRefBit;
1838 int ell = j * ncap + ( bref - 1 ); 1844 int ell = j * ncap + ( bref - 1 );
1839 1845
1840 in = bref <= ncap && mmCurCapBegin[ell] != EmptyCapture; 1846 in = bref <= ncap && mmCurCapBegin[ell] != EmptyCapture;
1841 if ( in ) { 1847 if ( in ) {
1842 if ( cs ) 1848 if ( cs )
1843 in = ( mmIn[mmPos + mmCurCapBegin[ell]] 1849 in = ( mmIn[mmPos + mmCurCapBegin[ell]]
1844 == QChar(ch) ); 1850 == QChar(ch) );
1845 else 1851 else
1846 in = ( mmIn[mmPos + mmCurCapBegin[ell]].lower() 1852 in = ( mmIn[mmPos + mmCurCapBegin[ell]].lower()
1847 == QChar(ch).lower() ); 1853 == QChar(ch).lower() );
1848 } 1854 }
1849 1855
1850 if ( in ) { 1856 if ( in ) {
1851 int delta; 1857 int delta;
1852 if ( mmCurCapEnd[ell] == EmptyCapture ) 1858 if ( mmCurCapEnd[ell] == EmptyCapture )
1853 delta = i - mmCurCapBegin[ell]; 1859 delta = i - mmCurCapBegin[ell];
1854 else 1860 else
1855 delta = mmCurCapEnd[ell] - mmCurCapBegin[ell]; 1861 delta = mmCurCapEnd[ell] - mmCurCapBegin[ell];
1856 1862
1857 in = ( delta <= mmLen - mmPos ); 1863 in = ( delta <= mmLen - mmPos );
1858 if ( in && delta > 1 ) { 1864 if ( in && delta > 1 ) {
1859 int n; 1865 int n;
1860 if ( cs ) { 1866 if ( cs ) {
1861 for ( n = 1; n < delta; n++ ) { 1867 for ( n = 1; n < delta; n++ ) {
1862 if ( mmIn[mmPos + 1868 if ( mmIn[mmPos +
1863 mmCurCapBegin[ell] + n] != 1869 mmCurCapBegin[ell] + n] !=
1864 mmIn[mmPos + i + n] ) 1870 mmIn[mmPos + i + n] )
1865 break; 1871 break;
1866 } 1872 }
1867 } else { 1873 } else {
1868 for ( n = 1; n < delta; n++ ) { 1874 for ( n = 1; n < delta; n++ ) {
1869 QChar a = mmIn[mmPos + 1875 QChar a = mmIn[mmPos +
1870 mmCurCapBegin[ell] + n]; 1876 mmCurCapBegin[ell] + n];
1871 QChar b = mmIn[mmPos + i + n]; 1877 QChar b = mmIn[mmPos + i + n];
1872 if ( a.lower() != b.lower() ) 1878 if ( a.lower() != b.lower() )
1873 break; 1879 break;
1874 } 1880 }
1875 } 1881 }
1876 in = ( n == delta ); 1882 in = ( n == delta );
1877 if ( in ) 1883 if ( in )
1878 needSomeSleep = delta - 1; 1884 needSomeSleep = delta - 1;
1879 } 1885 }
1880 } 1886 }
1881#endif 1887#endif
1882 } 1888 }
1883 } 1889 }
1884 1890
1885 /* 1891 /*
1886 All is right. We must now update our data structures. 1892 All is right. We must now update our data structures.
1887 */ 1893 */
1888 if ( in ) { 1894 if ( in ) {
1889#ifndef QT_NO_REGEXP_CAPTURE 1895#ifndef QT_NO_REGEXP_CAPTURE
1890 int *capBegin, *capEnd; 1896 int *capBegin, *capEnd;
1891#endif 1897#endif
1892 /* 1898 /*
1893 If the next state was not encountered yet, all is fine. 1899 If the next state was not encountered yet, all is fine.
1894 */ 1900 */
1895 if ( (m = mmInNextStack[next]) == -1 ) { 1901 if ( (m = mmInNextStack[next]) == -1 ) {
1896 m = nnext++; 1902 m = nnext++;
1897 mmNextStack[m] = next; 1903 mmNextStack[m] = next;
1898 mmInNextStack[next] = m; 1904 mmInNextStack[next] = m;
1899#ifndef QT_NO_REGEXP_CAPTURE 1905#ifndef QT_NO_REGEXP_CAPTURE
1900 capBegin = mmNextCapBegin + m * ncap; 1906 capBegin = mmNextCapBegin + m * ncap;
1901 capEnd = mmNextCapEnd + m * ncap; 1907 capEnd = mmNextCapEnd + m * ncap;
1902 1908
1903 /* 1909 /*
1904 Otherwise, we'll first maintain captures in temporary 1910 Otherwise, we'll first maintain captures in temporary
1905 arrays, and decide at the end whether it's best to keep 1911 arrays, and decide at the end whether it's best to keep
1906 the previous capture zones or the new ones. 1912 the previous capture zones or the new ones.
1907 */ 1913 */
1908 } else { 1914 } else {
1909 capBegin = mmTempCapBegin; 1915 capBegin = mmTempCapBegin;
1910 capEnd = mmTempCapEnd; 1916 capEnd = mmTempCapEnd;
1911#endif 1917#endif
1912 } 1918 }
1913 1919
1914#ifndef QT_NO_REGEXP_CAPTURE 1920#ifndef QT_NO_REGEXP_CAPTURE
1915 /* 1921 /*
1916 Updating the capture zones is much of a task. 1922 Updating the capture zones is much of a task.
1917 */ 1923 */
1918 if ( ncap > 0 ) { 1924 if ( ncap > 0 ) {
1919 memcpy( capBegin, mmCurCapBegin + j * ncap, 1925 memcpy( capBegin, mmCurCapBegin + j * ncap,
1920 ncap * sizeof(int) ); 1926 ncap * sizeof(int) );
1921 memcpy( capEnd, mmCurCapEnd + j * ncap, 1927 memcpy( capEnd, mmCurCapEnd + j * ncap,
1922 ncap * sizeof(int) ); 1928 ncap * sizeof(int) );
1923 int c = scur->atom, n = snext->atom; 1929 int c = scur->atom, n = snext->atom;
1924 int p = -1, q = -1; 1930 int p = -1, q = -1;
1925 int cap; 1931 int cap;
1926 1932
1927 /* 1933 /*
1928 Lemma 1. For any x in the range [0..nf), we have 1934 Lemma 1. For any x in the range [0..nf), we have
1929 f[x].parent < x. 1935 f[x].parent < x.
1930 1936
1931 Proof. By looking at startAtom(), it is clear that 1937 Proof. By looking at startAtom(), it is clear that
1932 cf < nf holds all the time, and thus that 1938 cf < nf holds all the time, and thus that
1933 f[nf].parent < nf. 1939 f[nf].parent < nf.
1934 */ 1940 */
1935 1941
1936 /* 1942 /*
1937 If we are reentering an atom, we empty all capture 1943 If we are reentering an atom, we empty all capture
1938 zones inside it. 1944 zones inside it.
1939 */ 1945 */
1940 if ( scur->reenter != 0 && 1946 if ( scur->reenter != 0 &&
1941 (q = at(*scur->reenter, next)) != 0 ) { 1947 (q = at(*scur->reenter, next)) != 0 ) {
1942 QBitArray b; 1948 QBitArray b;
1943 b.fill( FALSE, nf ); 1949 b.fill( FALSE, nf );
1944 b.setBit( q, TRUE ); 1950 b.setBit( q, TRUE );
1945 for ( int ell = q + 1; ell < nf; ell++ ) { 1951 for ( int ell = q + 1; ell < nf; ell++ ) {
1946 if ( b.testBit(f[ell].parent) ) { 1952 if ( b.testBit(f[ell].parent) ) {
1947 b.setBit( ell, TRUE ); 1953 b.setBit( ell, TRUE );
1948 cap = f[ell].capture; 1954 cap = f[ell].capture;
1949 if ( cap >= 0 ) { 1955 if ( cap >= 0 ) {
1950 capBegin[cap] = EmptyCapture; 1956 capBegin[cap] = EmptyCapture;
1951 capEnd[cap] = EmptyCapture; 1957 capEnd[cap] = EmptyCapture;
1952 } 1958 }
1953 } 1959 }
1954 } 1960 }
1955 p = f[q].parent; 1961 p = f[q].parent;
1956 1962
1957 /* 1963 /*
1958 Otherwise, close the capture zones we are leaving. 1964 Otherwise, close the capture zones we are leaving.
1959 We are leaving f[c].capture, f[f[c].parent].capture, 1965 We are leaving f[c].capture, f[f[c].parent].capture,
1960 f[f[f[c].parent].parent].capture, ..., until 1966 f[f[f[c].parent].parent].capture, ..., until
1961 f[x].capture, with x such that f[x].parent is the 1967 f[x].capture, with x such that f[x].parent is the
1962 youngest common ancestor for c and n. 1968 youngest common ancestor for c and n.
1963 1969
1964 We go up along c's and n's ancestry until we find x. 1970 We go up along c's and n's ancestry until we find x.
1965 */ 1971 */
1966 } else { 1972 } else {
1967 p = c; 1973 p = c;
1968 q = n; 1974 q = n;
1969 while ( p != q ) { 1975 while ( p != q ) {
1970 if ( p > q ) { 1976 if ( p > q ) {
1971 cap = f[p].capture; 1977 cap = f[p].capture;
1972 if ( cap >= 0 ) { 1978 if ( cap >= 0 ) {
1973 if ( capBegin[cap] == i ) { 1979 if ( capBegin[cap] == i ) {
1974 capBegin[cap] = EmptyCapture; 1980 capBegin[cap] = EmptyCapture;
1975 capEnd[cap] = EmptyCapture; 1981 capEnd[cap] = EmptyCapture;
1976 } else { 1982 } else {
1977 capEnd[cap] = i; 1983 capEnd[cap] = i;
1978 } 1984 }
1979 } 1985 }
1980 p = f[p].parent; 1986 p = f[p].parent;
1981 } else { 1987 } else {
1982 q = f[q].parent; 1988 q = f[q].parent;
1983 } 1989 }
1984 } 1990 }
1985 } 1991 }
1986 1992
1987 /* 1993 /*
1988 In any case, we now open the capture zones we are 1994 In any case, we now open the capture zones we are
1989 entering. We work upwards from n until we reach p 1995 entering. We work upwards from n until we reach p
1990 (the parent of the atom we reenter or the youngest 1996 (the parent of the atom we reenter or the youngest
1991 common ancestor). 1997 common ancestor).
1992 */ 1998 */
1993 while ( n > p ) { 1999 while ( n > p ) {
1994 cap = f[n].capture; 2000 cap = f[n].capture;
1995 if ( cap >= 0 ) { 2001 if ( cap >= 0 ) {
1996 capBegin[cap] = i; 2002 capBegin[cap] = i;
1997 capEnd[cap] = EmptyCapture; 2003 capEnd[cap] = EmptyCapture;
1998 } 2004 }
1999 n = f[n].parent; 2005 n = f[n].parent;
2000 } 2006 }
2001 /* 2007 /*
2002 If the next state was already in mmNextStack, we must 2008 If the next state was already in mmNextStack, we must
2003 choose carefully which capture zones we want to keep. 2009 choose carefully which capture zones we want to keep.
2004 */ 2010 */
2005 if ( capBegin == mmTempCapBegin && 2011 if ( capBegin == mmTempCapBegin &&
2006 isBetterCapture(capBegin, capEnd, 2012 isBetterCapture(capBegin, capEnd,
2007 mmNextCapBegin + m * ncap, 2013 mmNextCapBegin + m * ncap,
2008 mmNextCapEnd + m * ncap) ) { 2014 mmNextCapEnd + m * ncap) ) {
2009 memcpy( mmNextCapBegin + m * ncap, capBegin, 2015 memcpy( mmNextCapBegin + m * ncap, capBegin,
2010 ncap * sizeof(int) ); 2016 ncap * sizeof(int) );
2011 memcpy( mmNextCapEnd + m * ncap, capEnd, 2017 memcpy( mmNextCapEnd + m * ncap, capEnd,
2012 ncap * sizeof(int) ); 2018 ncap * sizeof(int) );
2013 } 2019 }
2014 } 2020 }
2015#ifndef QT_NO_REGEXP_BACKREF 2021#ifndef QT_NO_REGEXP_BACKREF
2016 /* 2022 /*
2017 We are done with updating the capture zones. It's now 2023 We are done with updating the capture zones. It's now
2018 time to put the next state to sleep, if it needs to, and 2024 time to put the next state to sleep, if it needs to, and
2019 to remove it from mmNextStack. 2025 to remove it from mmNextStack.
2020 */ 2026 */
2021 if ( needSomeSleep > 0 ) { 2027 if ( needSomeSleep > 0 ) {
2022 zzZ = new int[1 + 2 * ncap]; 2028 zzZ = new int[1 + 2 * ncap];
2023 zzZ[0] = next; 2029 zzZ[0] = next;
2024 if ( ncap > 0 ) { 2030 if ( ncap > 0 ) {
2025 memcpy( zzZ + 1, capBegin, ncap * sizeof(int) ); 2031 memcpy( zzZ + 1, capBegin, ncap * sizeof(int) );
2026 memcpy( zzZ + 1 + ncap, capEnd, 2032 memcpy( zzZ + 1 + ncap, capEnd,
2027 ncap * sizeof(int) ); 2033 ncap * sizeof(int) );
2028 } 2034 }
2029 mmInNextStack[mmNextStack[--nnext]] = -1; 2035 mmInNextStack[mmNextStack[--nnext]] = -1;
2030 mmSleeping.insert( i + needSomeSleep, zzZ ); 2036 mmSleeping.insert( i + needSomeSleep, zzZ );
2031 } 2037 }
2032#endif 2038#endif
2033#endif 2039#endif
2034 } 2040 }
2035 } 2041 }
2036 } 2042 }
2037#ifndef QT_NO_REGEXP_CAPTURE 2043#ifndef QT_NO_REGEXP_CAPTURE
2038 /* 2044 /*
2039 If we reached the final state, hurray! Copy the captured zone. 2045 If we reached the final state, hurray! Copy the captured zone.
2040 */ 2046 */
2041 if ( ncap > 0 && (m = mmInNextStack[FinalState]) != -1 ) { 2047 if ( ncap > 0 && (m = mmInNextStack[FinalState]) != -1 ) {
2042 memcpy( mmCapBegin, mmNextCapBegin + m * ncap, ncap * sizeof(int) ); 2048 memcpy( mmCapBegin, mmNextCapBegin + m * ncap, ncap * sizeof(int) );
2043 memcpy( mmCapEnd, mmNextCapEnd + m * ncap, ncap * sizeof(int) ); 2049 memcpy( mmCapEnd, mmNextCapEnd + m * ncap, ncap * sizeof(int) );
2044 } 2050 }
2045#ifndef QT_NO_REGEXP_BACKREF 2051#ifndef QT_NO_REGEXP_BACKREF
2046 /* 2052 /*
2047 It's time to wake up the sleepers. 2053 It's time to wake up the sleepers.
2048 */ 2054 */
2049 if ( mmSleeping.count() > 0 ) { 2055 if ( mmSleeping.count() > 0 ) {
2050 while ( (zzZ = mmSleeping.take(i)) != 0 ) { 2056 while ( (zzZ = mmSleeping.take(i)) != 0 ) {
2051 int next = zzZ[0]; 2057 int next = zzZ[0];
2052 int *capBegin = zzZ + 1; 2058 int *capBegin = zzZ + 1;
2053 int *capEnd = zzZ + 1 + ncap; 2059 int *capEnd = zzZ + 1 + ncap;
2054 bool copyOver = TRUE; 2060 bool copyOver = TRUE;
2055 2061
2056 if ( (m = mmInNextStack[zzZ[0]]) == -1 ) { 2062 if ( (m = mmInNextStack[zzZ[0]]) == -1 ) {
2057 m = nnext++; 2063 m = nnext++;
2058 mmNextStack[m] = next; 2064 mmNextStack[m] = next;
2059 mmInNextStack[next] = m; 2065 mmInNextStack[next] = m;
2060 } else { 2066 } else {
2061 copyOver = isBetterCapture( mmNextCapBegin + m * ncap, 2067 copyOver = isBetterCapture( mmNextCapBegin + m * ncap,
2062 mmNextCapEnd + m * ncap, 2068 mmNextCapEnd + m * ncap,
2063 capBegin, capEnd ); 2069 capBegin, capEnd );
2064 } 2070 }
2065 if ( copyOver ) { 2071 if ( copyOver ) {
2066 memcpy( mmNextCapBegin + m * ncap, capBegin, 2072 memcpy( mmNextCapBegin + m * ncap, capBegin,
2067 ncap * sizeof(int) ); 2073 ncap * sizeof(int) );
2068 memcpy( mmNextCapEnd + m * ncap, capEnd, 2074 memcpy( mmNextCapEnd + m * ncap, capEnd,
2069 ncap * sizeof(int) ); 2075 ncap * sizeof(int) );
2070 } 2076 }
2071 delete[] zzZ; 2077 delete[] zzZ;
2072 } 2078 }
2073 } 2079 }
2074#endif 2080#endif
2075#endif 2081#endif
2076 for ( j = 0; j < nnext; j++ ) 2082 for ( j = 0; j < nnext; j++ )
2077 mmInNextStack[mmNextStack[j]] = -1; 2083 mmInNextStack[mmNextStack[j]] = -1;
2078 2084
2079 qSwap( mmCurStack, mmNextStack ); 2085 qSwap( mmCurStack, mmNextStack );
2080#ifndef QT_NO_REGEXP_CAPTURE 2086#ifndef QT_NO_REGEXP_CAPTURE
2081 qSwap( mmCurCapBegin, mmNextCapBegin ); 2087 qSwap( mmCurCapBegin, mmNextCapBegin );
2082 qSwap( mmCurCapEnd, mmNextCapEnd ); 2088 qSwap( mmCurCapEnd, mmNextCapEnd );
2083#endif 2089#endif
2084 ncur = nnext; 2090 ncur = nnext;
2085 nnext = 0; 2091 nnext = 0;
2086 i++; 2092 i++;
2087 } 2093 }
2088 2094
2089#ifndef QT_NO_REGEXP_BACKREF 2095#ifndef QT_NO_REGEXP_BACKREF
2090 /* 2096 /*
2091 If minimal matching is enabled, we might have some sleepers left. 2097 If minimal matching is enabled, we might have some sleepers left.
2092 */ 2098 */
2093 while ( !mmSleeping.isEmpty() ) { 2099 while ( !mmSleeping.isEmpty() ) {
2094 zzZ = mmSleeping.take( *QIntDictIterator<int>(mmSleeping) ); 2100 zzZ = mmSleeping.take( *QIntDictIterator<int>(mmSleeping) );
2095 delete[] zzZ; 2101 delete[] zzZ;
2096 } 2102 }
2097#endif 2103#endif
2098 2104
2099 match = ( mmMatchedLen >= 0 ); 2105 match = ( mmMatchedLen >= 0 );
2100 if ( !match ) 2106 if ( !match )
2101 mmMatchedLen = i - 1; 2107 mmMatchedLen = i - 1;
2102 return match; 2108 return match;
2103} 2109}
2104 2110
2105#ifndef QT_NO_REGEXP_CCLASS 2111#ifndef QT_NO_REGEXP_CCLASS
2106 2112
2107QRegExpEngine::CharClass::CharClass() 2113QRegExpEngine::CharClass::CharClass()
2108 : c( 0 ), n( FALSE ) 2114 : c( 0 ), n( FALSE )
2109#ifndef QT_NO_REGEXP_OPTIM 2115#ifndef QT_NO_REGEXP_OPTIM
2110 , occ1( *noOccurrences ) 2116 , occ1( *noOccurrences )
2111#endif 2117#endif
2112{ 2118{
2113} 2119}
2114 2120
2115QRegExpEngine::CharClass& QRegExpEngine::CharClass::operator=( 2121QRegExpEngine::CharClass& QRegExpEngine::CharClass::operator=(
2116 const CharClass& cc ) 2122 const CharClass& cc )
2117{ 2123{
2118 c = cc.c; 2124 c = cc.c;
2119 r = cc.r.copy(); 2125 r = cc.r.copy();
2120 n = cc.n; 2126 n = cc.n;
2121#ifndef QT_NO_REGEXP_OPTIM 2127#ifndef QT_NO_REGEXP_OPTIM
2122 occ1 = cc.occ1; 2128 occ1 = cc.occ1;
2123#endif 2129#endif
2124 return *this; 2130 return *this;
2125} 2131}
2126 2132
2127void QRegExpEngine::CharClass::clear() 2133void QRegExpEngine::CharClass::clear()
2128{ 2134{
2129 c = 0; 2135 c = 0;
2130 r.resize( 0 ); 2136 r.resize( 0 );
2131 n = FALSE; 2137 n = FALSE;
2132} 2138}
2133 2139
2134void QRegExpEngine::CharClass::setNegative( bool negative ) 2140void QRegExpEngine::CharClass::setNegative( bool negative )
2135{ 2141{
2136 n = negative; 2142 n = negative;
2137#ifndef QT_NO_REGEXP_OPTIM 2143#ifndef QT_NO_REGEXP_OPTIM
2138 occ1 = *firstOccurrenceAtZero; 2144 occ1 = *firstOccurrenceAtZero;
2139#endif 2145#endif
2140} 2146}
2141 2147
2142void QRegExpEngine::CharClass::addCategories( int cats ) 2148void QRegExpEngine::CharClass::addCategories( int cats )
2143{ 2149{
2144 c |= cats; 2150 c |= cats;
2145#ifndef QT_NO_REGEXP_OPTIM 2151#ifndef QT_NO_REGEXP_OPTIM
2146 occ1 = *firstOccurrenceAtZero; 2152 occ1 = *firstOccurrenceAtZero;
2147#endif 2153#endif
2148} 2154}
2149 2155
2150void QRegExpEngine::CharClass::addRange( ushort from, ushort to ) 2156void QRegExpEngine::CharClass::addRange( ushort from, ushort to )
2151{ 2157{
2152 if ( from > to ) 2158 if ( from > to )
2153 qSwap( from, to ); 2159 qSwap( from, to );
2154 int n = r.size(); 2160 int n = r.size();
2155 r.resize( n + 1 ); 2161 r.resize( n + 1 );
2156 r[n].from = from; 2162 r[n].from = from;
2157 r[n].to = to; 2163 r[n].to = to;
2158 2164
2159#ifndef QT_NO_REGEXP_OPTIM 2165#ifndef QT_NO_REGEXP_OPTIM
2160 int i; 2166 int i;
2161 2167
2162 if ( to - from < NumBadChars ) { 2168 if ( to - from < NumBadChars ) {
2163 occ1.detach(); 2169 occ1.detach();
2164 if ( from % NumBadChars <= to % NumBadChars ) { 2170 if ( from % NumBadChars <= to % NumBadChars ) {
2165 for ( i = from % NumBadChars; i <= to % NumBadChars; i++ ) 2171 for ( i = from % NumBadChars; i <= to % NumBadChars; i++ )
2166 occ1[i] = 0; 2172 occ1[i] = 0;
2167 } else {
2168 for ( i = 0; i <= to % NumBadChars; i++ )
2169 occ1[i] = 0;
2170 for ( i = from % NumBadChars; i < NumBadChars; i++ )
2171 occ1[i] = 0;
2172 }
2173 } else { 2173 } else {
2174 occ1 = *firstOccurrenceAtZero; 2174 for ( i = 0; i <= to % NumBadChars; i++ )
2175 occ1[i] = 0;
2176 for ( i = from % NumBadChars; i < NumBadChars; i++ )
2177 occ1[i] = 0;
2178 }
2179 } else {
2180 occ1 = *firstOccurrenceAtZero;
2175 } 2181 }
2176#endif 2182#endif
2177} 2183}
2178 2184
2179bool QRegExpEngine::CharClass::in( QChar ch ) const 2185bool QRegExpEngine::CharClass::in( QChar ch ) const
2180{ 2186{
2181#ifndef QT_NO_REGEXP_OPTIM 2187#ifndef QT_NO_REGEXP_OPTIM
2182 if ( occ1[BadChar(ch)] == NoOccurrence ) 2188 if ( occ1[BadChar(ch)] == NoOccurrence )
2183 return n; 2189 return n;
2184#endif 2190#endif
2185 2191
2186 if ( c != 0 && (c & (1 << (int) ch.category())) != 0 ) 2192 if ( c != 0 && (c & (1 << (int) ch.category())) != 0 )
2187 return !n; 2193 return !n;
2188 for ( int i = 0; i < (int) r.size(); i++ ) { 2194 for ( int i = 0; i < (int) r.size(); i++ ) {
2189 if ( ch.unicode() >= r[i].from && ch.unicode() <= r[i].to ) 2195 if ( ch.unicode() >= r[i].from && ch.unicode() <= r[i].to )
2190 return !n; 2196 return !n;
2191 } 2197 }
2192 return n; 2198 return n;
2193} 2199}
2194 2200
2195#if defined(QT_DEBUG) 2201#if defined(QT_DEBUG)
2196void QRegExpEngine::CharClass::dump() const 2202void QRegExpEngine::CharClass::dump() const
2197{ 2203{
2198 int i; 2204 int i;
2199 qDebug( " %stive character class", n ? "nega" : "posi" ); 2205 odebug << " " << (n ? "nega" : "posi") << "tive character class" << oendl;
2200#ifndef QT_NO_REGEXP_CCLASS 2206#ifndef QT_NO_REGEXP_CCLASS
2201 if ( c != 0 ) 2207 if ( c != 0 )
2202 qDebug( " categories 0x%.8x", c ); 2208 odebug << QString().sprintf(" categories 0x%.8x", c ) << oendl;
2203#endif 2209#endif
2204 for ( i = 0; i < (int) r.size(); i++ ) 2210 for ( i = 0; i < (int) r.size(); i++ )
2205 qDebug( " 0x%.4x through 0x%.4x", r[i].from, r[i].to ); 2211 odebug << QString().sprintf(" 0x%.4x through 0x%.4x", r[i].from, r[i].to ) << oendl;
2206} 2212}
2207#endif 2213#endif
2208#endif 2214#endif
2209 2215
2210QRegExpEngine::Box::Box( QRegExpEngine *engine ) 2216QRegExpEngine::Box::Box( QRegExpEngine *engine )
2211 : eng( engine ), skipanchors( 0 ) 2217 : eng( engine ), skipanchors( 0 )
2212#ifndef QT_NO_REGEXP_OPTIM 2218#ifndef QT_NO_REGEXP_OPTIM
2213 , earlyStart( 0 ), lateStart( 0 ), maxl( 0 ), occ1( *noOccurrences ) 2219 , earlyStart( 0 ), lateStart( 0 ), maxl( 0 ), occ1( *noOccurrences )
2214#endif 2220#endif
2215{ 2221{
2216 minl = 0; 2222 minl = 0;
2217} 2223}
2218 2224
2219QRegExpEngine::Box& QRegExpEngine::Box::operator=( const Box& b ) 2225QRegExpEngine::Box& QRegExpEngine::Box::operator=( const Box& b )
2220{ 2226{
2221 eng = b.eng; 2227 eng = b.eng;
2222 ls = b.ls; 2228 ls = b.ls;
2223 rs = b.rs; 2229 rs = b.rs;
2224 lanchors = b.lanchors; 2230 lanchors = b.lanchors;
2225 ranchors = b.ranchors; 2231 ranchors = b.ranchors;
2226 skipanchors = b.skipanchors; 2232 skipanchors = b.skipanchors;
2227#ifndef QT_NO_REGEXP_OPTIM 2233#ifndef QT_NO_REGEXP_OPTIM
2228 earlyStart = b.earlyStart; 2234 earlyStart = b.earlyStart;
2229 lateStart = b.lateStart; 2235 lateStart = b.lateStart;
2230 str = b.str; 2236 str = b.str;
2231 leftStr = b.leftStr; 2237 leftStr = b.leftStr;
2232 rightStr = b.rightStr; 2238 rightStr = b.rightStr;
2233 maxl = b.maxl; 2239 maxl = b.maxl;
2234 occ1 = b.occ1; 2240 occ1 = b.occ1;
2235#endif 2241#endif
2236 minl = b.minl; 2242 minl = b.minl;
2237 return *this; 2243 return *this;
2238} 2244}
2239 2245
2240void QRegExpEngine::Box::set( QChar ch ) 2246void QRegExpEngine::Box::set( QChar ch )
2241{ 2247{
2242 ls.resize( 1 ); 2248 ls.resize( 1 );
2243 ls[0] = eng->createState( ch ); 2249 ls[0] = eng->createState( ch );
2244 rs = ls; 2250 rs = ls;
2245 rs.detach(); 2251 rs.detach();
2246#ifndef QT_NO_REGEXP_OPTIM 2252#ifndef QT_NO_REGEXP_OPTIM
2247 str = ch; 2253 str = ch;
2248 leftStr = ch; 2254 leftStr = ch;
2249 rightStr = ch; 2255 rightStr = ch;
2250 maxl = 1; 2256 maxl = 1;
2251 occ1.detach(); 2257 occ1.detach();
2252 occ1[BadChar(ch)] = 0; 2258 occ1[BadChar(ch)] = 0;
2253#endif 2259#endif
2254 minl = 1; 2260 minl = 1;
2255} 2261}
2256 2262
2257void QRegExpEngine::Box::set( const CharClass& cc ) 2263void QRegExpEngine::Box::set( const CharClass& cc )
2258{ 2264{
2259 ls.resize( 1 ); 2265 ls.resize( 1 );
2260 ls[0] = eng->createState( cc ); 2266 ls[0] = eng->createState( cc );
2261 rs = ls; 2267 rs = ls;
2262 rs.detach(); 2268 rs.detach();
2263#ifndef QT_NO_REGEXP_OPTIM 2269#ifndef QT_NO_REGEXP_OPTIM
2264 maxl = 1; 2270 maxl = 1;
2265 occ1 = cc.firstOccurrence(); 2271 occ1 = cc.firstOccurrence();
2266#endif 2272#endif
2267 minl = 1; 2273 minl = 1;
2268} 2274}
2269 2275
2270#ifndef QT_NO_REGEXP_BACKREF 2276#ifndef QT_NO_REGEXP_BACKREF
2271void QRegExpEngine::Box::set( int bref ) 2277void QRegExpEngine::Box::set( int bref )
2272{ 2278{
2273 ls.resize( 1 ); 2279 ls.resize( 1 );
2274 ls[0] = eng->createState( bref ); 2280 ls[0] = eng->createState( bref );
2275 rs = ls; 2281 rs = ls;
2276 rs.detach(); 2282 rs.detach();
2277 if ( bref >= 1 && bref <= MaxBackRefs ) 2283 if ( bref >= 1 && bref <= MaxBackRefs )
2278 skipanchors = Anchor_BackRef0Empty << bref; 2284 skipanchors = Anchor_BackRef0Empty << bref;
2279#ifndef QT_NO_REGEXP_OPTIM 2285#ifndef QT_NO_REGEXP_OPTIM
2280 maxl = InftyLen; 2286 maxl = InftyLen;
2281#endif 2287#endif
2282 minl = 0; 2288 minl = 0;
2283} 2289}
2284#endif 2290#endif
2285 2291
2286void QRegExpEngine::Box::cat( const Box& b ) 2292void QRegExpEngine::Box::cat( const Box& b )
2287{ 2293{
2288 eng->addCatTransitions( rs, b.ls ); 2294 eng->addCatTransitions( rs, b.ls );
2289 addAnchorsToEngine( b ); 2295 addAnchorsToEngine( b );
2290 if ( minl == 0 ) { 2296 if ( minl == 0 ) {
2291 mergeInto( &lanchors, b.lanchors ); 2297 mergeInto( &lanchors, b.lanchors );
2292 if ( skipanchors != 0 ) { 2298 if ( skipanchors != 0 ) {
2293 for ( int i = 0; i < (int) b.ls.size(); i++ ) { 2299 for ( int i = 0; i < (int) b.ls.size(); i++ ) {
2294 int a = eng->anchorConcatenation( at(lanchors, b.ls[i]), 2300 int a = eng->anchorConcatenation( at(lanchors, b.ls[i]),
2295 skipanchors ); 2301 skipanchors );
2296 lanchors.insert( b.ls[i], a ); 2302 lanchors.insert( b.ls[i], a );
2297 } 2303 }
2298 } 2304 }
2299 mergeInto( &ls, b.ls ); 2305 mergeInto( &ls, b.ls );
2300 } 2306 }
2301 if ( b.minl == 0 ) { 2307 if ( b.minl == 0 ) {
2302 mergeInto( &ranchors, b.ranchors ); 2308 mergeInto( &ranchors, b.ranchors );
2303 if ( b.skipanchors != 0 ) { 2309 if ( b.skipanchors != 0 ) {
2304 for ( int i = 0; i < (int) rs.size(); i++ ) { 2310 for ( int i = 0; i < (int) rs.size(); i++ ) {
2305 int a = eng->anchorConcatenation( at(ranchors, rs[i]), 2311 int a = eng->anchorConcatenation( at(ranchors, rs[i]),
2306 b.skipanchors ); 2312 b.skipanchors );
2307 ranchors.insert( rs[i], a ); 2313 ranchors.insert( rs[i], a );
2308 } 2314 }
2309 } 2315 }
2310 mergeInto( &rs, b.rs ); 2316 mergeInto( &rs, b.rs );
2311 } else { 2317 } else {
2312 ranchors = b.ranchors; 2318 ranchors = b.ranchors;
2313 rs = b.rs; 2319 rs = b.rs;
2314 } 2320 }
2315 2321
2316#ifndef QT_NO_REGEXP_OPTIM 2322#ifndef QT_NO_REGEXP_OPTIM
2317 if ( maxl != InftyLen ) { 2323 if ( maxl != InftyLen ) {
2318 if ( rightStr.length() + b.leftStr.length() > 2324 if ( rightStr.length() + b.leftStr.length() >
2319 QMAX(str.length(), b.str.length()) ) { 2325 QMAX(str.length(), b.str.length()) ) {
2320 earlyStart = minl - rightStr.length(); 2326 earlyStart = minl - rightStr.length();
2321 lateStart = maxl - rightStr.length(); 2327 lateStart = maxl - rightStr.length();
2322 str = rightStr + b.leftStr; 2328 str = rightStr + b.leftStr;
2323 } else if ( b.str.length() > str.length() ) { 2329 } else if ( b.str.length() > str.length() ) {
2324 earlyStart = minl + b.earlyStart; 2330 earlyStart = minl + b.earlyStart;
2325 lateStart = maxl + b.lateStart; 2331 lateStart = maxl + b.lateStart;
2326 str = b.str; 2332 str = b.str;
2327 } 2333 }
2328 } 2334 }
2329 2335
2330 if ( (int) leftStr.length() == maxl ) 2336 if ( (int) leftStr.length() == maxl )
2331 leftStr += b.leftStr; 2337 leftStr += b.leftStr;
2332 if ( (int) b.rightStr.length() == b.maxl ) 2338 if ( (int) b.rightStr.length() == b.maxl )
2333 rightStr += b.rightStr; 2339 rightStr += b.rightStr;
2334 else 2340 else
2335 rightStr = b.rightStr; 2341 rightStr = b.rightStr;
2336 2342
2337 if ( maxl == InftyLen || b.maxl == InftyLen ) 2343 if ( maxl == InftyLen || b.maxl == InftyLen )
2338 maxl = InftyLen; 2344 maxl = InftyLen;
2339 else 2345 else
2340 maxl += b.maxl; 2346 maxl += b.maxl;
2341 2347
2342 occ1.detach(); 2348 occ1.detach();
2343 for ( int i = 0; i < NumBadChars; i++ ) { 2349 for ( int i = 0; i < NumBadChars; i++ ) {
2344 if ( b.occ1[i] != NoOccurrence && minl + b.occ1[i] < occ1[i] ) 2350 if ( b.occ1[i] != NoOccurrence && minl + b.occ1[i] < occ1[i] )
2345 occ1[i] = minl + b.occ1[i]; 2351 occ1[i] = minl + b.occ1[i];
2346 } 2352 }
2347#endif 2353#endif
2348 2354
2349 minl += b.minl; 2355 minl += b.minl;
2350 if ( minl == 0 ) 2356 if ( minl == 0 )
2351 skipanchors = eng->anchorConcatenation( skipanchors, b.skipanchors ); 2357 skipanchors = eng->anchorConcatenation( skipanchors, b.skipanchors );
2352 else 2358 else
2353 skipanchors = 0; 2359 skipanchors = 0;
2354} 2360}
2355 2361
2356void QRegExpEngine::Box::orx( const Box& b ) 2362void QRegExpEngine::Box::orx( const Box& b )
2357{ 2363{
2358 mergeInto( &ls, b.ls ); 2364 mergeInto( &ls, b.ls );
2359 mergeInto( &lanchors, b.lanchors ); 2365 mergeInto( &lanchors, b.lanchors );
2360 mergeInto( &rs, b.rs ); 2366 mergeInto( &rs, b.rs );
2361 mergeInto( &ranchors, b.ranchors ); 2367 mergeInto( &ranchors, b.ranchors );
2362 skipanchors = eng->anchorAlternation( skipanchors, b.skipanchors ); 2368 skipanchors = eng->anchorAlternation( skipanchors, b.skipanchors );
2363 2369
2364#ifndef QT_NO_REGEXP_OPTIM 2370#ifndef QT_NO_REGEXP_OPTIM
2365 occ1.detach(); 2371 occ1.detach();
2366 for ( int i = 0; i < NumBadChars; i++ ) { 2372 for ( int i = 0; i < NumBadChars; i++ ) {
2367 if ( occ1[i] > b.occ1[i] ) 2373 if ( occ1[i] > b.occ1[i] )
2368 occ1[i] = b.occ1[i]; 2374 occ1[i] = b.occ1[i];
2369 } 2375 }
2370 earlyStart = 0; 2376 earlyStart = 0;
2371 lateStart = 0; 2377 lateStart = 0;
2372 str = QString::null; 2378 str = QString::null;
2373 leftStr = QString::null; 2379 leftStr = QString::null;
2374 rightStr = QString::null; 2380 rightStr = QString::null;
2375 if ( b.maxl > maxl ) 2381 if ( b.maxl > maxl )
2376 maxl = b.maxl; 2382 maxl = b.maxl;
2377#endif 2383#endif
2378 if ( b.minl < minl ) 2384 if ( b.minl < minl )
2379 minl = b.minl; 2385 minl = b.minl;
2380} 2386}
2381 2387
2382void QRegExpEngine::Box::plus( int atom ) 2388void QRegExpEngine::Box::plus( int atom )
2383{ 2389{
2384#ifndef QT_NO_REGEXP_CAPTURE 2390#ifndef QT_NO_REGEXP_CAPTURE
2385 eng->addPlusTransitions( rs, ls, atom ); 2391 eng->addPlusTransitions( rs, ls, atom );
2386#else 2392#else
2387 Q_UNUSED( atom ); 2393 Q_UNUSED( atom );
2388 eng->addCatTransitions( rs, ls ); 2394 eng->addCatTransitions( rs, ls );
2389#endif 2395#endif
2390 addAnchorsToEngine( *this ); 2396 addAnchorsToEngine( *this );
2391#ifndef QT_NO_REGEXP_OPTIM 2397#ifndef QT_NO_REGEXP_OPTIM
2392 maxl = InftyLen; 2398 maxl = InftyLen;
2393#endif 2399#endif
2394} 2400}
2395 2401
2396void QRegExpEngine::Box::opt() 2402void QRegExpEngine::Box::opt()
2397{ 2403{
2398#ifndef QT_NO_REGEXP_OPTIM 2404#ifndef QT_NO_REGEXP_OPTIM
2399 earlyStart = 0; 2405 earlyStart = 0;
2400 lateStart = 0; 2406 lateStart = 0;
2401 str = QString::null; 2407 str = QString::null;
2402 leftStr = QString::null; 2408 leftStr = QString::null;
2403 rightStr = QString::null; 2409 rightStr = QString::null;
2404#endif 2410#endif
2405 skipanchors = 0; 2411 skipanchors = 0;
2406 minl = 0; 2412 minl = 0;
2407} 2413}
2408 2414
2409void QRegExpEngine::Box::catAnchor( int a ) 2415void QRegExpEngine::Box::catAnchor( int a )
2410{ 2416{
2411 if ( a != 0 ) { 2417 if ( a != 0 ) {
2412 for ( int i = 0; i < (int) rs.size(); i++ ) { 2418 for ( int i = 0; i < (int) rs.size(); i++ ) {
2413 a = eng->anchorConcatenation( at(ranchors, rs[i]), a ); 2419 a = eng->anchorConcatenation( at(ranchors, rs[i]), a );
2414 ranchors.insert( rs[i], a ); 2420 ranchors.insert( rs[i], a );
2415 } 2421 }
2416 if ( minl == 0 ) 2422 if ( minl == 0 )
2417 skipanchors = eng->anchorConcatenation( skipanchors, a ); 2423 skipanchors = eng->anchorConcatenation( skipanchors, a );
2418 } 2424 }
2419} 2425}
2420 2426
2421#ifndef QT_NO_REGEXP_OPTIM 2427#ifndef QT_NO_REGEXP_OPTIM
2422void QRegExpEngine::Box::setupHeuristics() 2428void QRegExpEngine::Box::setupHeuristics()
2423{ 2429{
2424 eng->setupGoodStringHeuristic( earlyStart, lateStart, str ); 2430 eng->setupGoodStringHeuristic( earlyStart, lateStart, str );
2425 2431
2426 /* 2432 /*
2427 A regular expression such as 112|1 has occ1['2'] = 2 and minl = 1 at this 2433 A regular expression such as 112|1 has occ1['2'] = 2 and minl = 1 at this
2428 point. An entry of occ1 has to be at most minl or infinity for the rest 2434 point. An entry of occ1 has to be at most minl or infinity for the rest
2429 of the algorithm to go well. 2435 of the algorithm to go well.
2430 2436
2431 We waited until here before normalizing these cases (instead of doing it 2437 We waited until here before normalizing these cases (instead of doing it
2432 in Box::orx()) because sometimes things improve by themselves; consider 2438 in Box::orx()) because sometimes things improve by themselves; consider
2433 (112|1)34. 2439 (112|1)34.
2434 */ 2440 */
2435 for ( int i = 0; i < NumBadChars; i++ ) { 2441 for ( int i = 0; i < NumBadChars; i++ ) {
2436 if ( occ1[i] != NoOccurrence && occ1[i] >= minl ) 2442 if ( occ1[i] != NoOccurrence && occ1[i] >= minl )
2437 occ1[i] = minl; 2443 occ1[i] = minl;
2438 } 2444 }
2439 eng->setupBadCharHeuristic( minl, occ1 ); 2445 eng->setupBadCharHeuristic( minl, occ1 );
2440 2446
2441 eng->heuristicallyChooseHeuristic(); 2447 eng->heuristicallyChooseHeuristic();
2442} 2448}
2443#endif 2449#endif
2444 2450
2445#if defined(QT_DEBUG) 2451#if defined(QT_DEBUG)
2446void QRegExpEngine::Box::dump() const 2452void QRegExpEngine::Box::dump() const
2447{ 2453{
2448 int i; 2454 int i;
2449 qDebug( "Box of at least %d character%s", minl, minl == 1 ? "" : "s" ); 2455 odebug << "Box of at least " << minl << " character" << (minl == 1 ? "" : "s") << oendl;
2450 qDebug( " Left states:" ); 2456 odebug << " Left states:" << oendl;
2451 for ( i = 0; i < (int) ls.size(); i++ ) { 2457 for ( i = 0; i < (int) ls.size(); i++ ) {
2452 if ( at(lanchors, ls[i]) == 0 ) 2458 if ( at(lanchors, ls[i]) == 0 )
2453 qDebug( " %d", ls[i] ); 2459 odebug << " " << ls[i] << oendl;
2454 else 2460 else
2455 qDebug( " %d [anchors 0x%.8x]", ls[i], lanchors[ls[i]] ); 2461 odebug << " " << ls[i] << QString().sprintf(" [anchors 0x%.8x]", lanchors[ls[i]]) << oendl;
2456 } 2462 }
2457 qDebug( " Right states:" ); 2463 odebug << " Right states:" << oendl;
2458 for ( i = 0; i < (int) rs.size(); i++ ) { 2464 for ( i = 0; i < (int) rs.size(); i++ ) {
2459 if ( at(ranchors, ls[i]) == 0 ) 2465 if ( at(ranchors, ls[i]) == 0 )
2460 qDebug( " %d", rs[i] ); 2466 odebug << " " << rs[i] << oendl;
2461 else 2467 else
2462 qDebug( " %d [anchors 0x%.8x]", rs[i], ranchors[rs[i]] ); 2468 odebug << " " << rs[i] << QString().sprintf(" [anchors 0x%.8x]", ranchors[rs[i]]) << oendl;
2463 } 2469 }
2464 qDebug( " Skip anchors: 0x%.8x", skipanchors ); 2470 odebug << QString().sprintf(" Skip anchors: 0x%.8x", skipanchors) << oendl;
2465} 2471}
2466#endif 2472#endif
2467 2473
2468void QRegExpEngine::Box::addAnchorsToEngine( const Box& to ) const 2474void QRegExpEngine::Box::addAnchorsToEngine( const Box& to ) const
2469{ 2475{
2470 for ( int i = 0; i < (int) to.ls.size(); i++ ) { 2476 for ( int i = 0; i < (int) to.ls.size(); i++ ) {
2471 for ( int j = 0; j < (int) rs.size(); j++ ) { 2477 for ( int j = 0; j < (int) rs.size(); j++ ) {
2472 int a = eng->anchorConcatenation( at(ranchors, rs[j]), 2478 int a = eng->anchorConcatenation( at(ranchors, rs[j]),
2473 at(to.lanchors, to.ls[i]) ); 2479 at(to.lanchors, to.ls[i]) );
2474 eng->addAnchors( rs[j], to.ls[i], a ); 2480 eng->addAnchors( rs[j], to.ls[i], a );
2475 } 2481 }
2476 } 2482 }
2477} 2483}
2478 2484
2479int QRegExpEngine::getChar() 2485int QRegExpEngine::getChar()
2480{ 2486{
2481 return ( yyPos == yyLen ) ? EOS : yyIn[yyPos++].unicode(); 2487 return ( yyPos == yyLen ) ? EOS : yyIn[yyPos++].unicode();
2482} 2488}
2483 2489
2484int QRegExpEngine::getEscape() 2490int QRegExpEngine::getEscape()
2485{ 2491{
2486#ifndef QT_NO_REGEXP_ESCAPE 2492#ifndef QT_NO_REGEXP_ESCAPE
2487 const char tab[] = "afnrtv"; // no b, as \b means word boundary 2493 const char tab[] = "afnrtv"; // no b, as \b means word boundary
2488 const char backTab[] = "\a\f\n\r\t\v"; 2494 const char backTab[] = "\a\f\n\r\t\v";
2489 ushort low; 2495 ushort low;
2490 int i; 2496 int i;
2491#endif 2497#endif
2492 ushort val; 2498 ushort val;
2493 int prevCh = yyCh; 2499 int prevCh = yyCh;
2494 2500
2495 if ( prevCh == EOS ) { 2501 if ( prevCh == EOS ) {
2496 yyError = TRUE; 2502 yyError = TRUE;
2497 return Tok_Char | '\\'; 2503 return Tok_Char | '\\';
2498 } 2504 }
2499 yyCh = getChar(); 2505 yyCh = getChar();
2500#ifndef QT_NO_REGEXP_ESCAPE 2506#ifndef QT_NO_REGEXP_ESCAPE
2501 if ( (prevCh & ~0xff) == 0 ) { 2507 if ( (prevCh & ~0xff) == 0 ) {
2502 const char *p = strchr( tab, prevCh ); 2508 const char *p = strchr( tab, prevCh );
2503 if ( p != 0 ) 2509 if ( p != 0 )
2504 return Tok_Char | backTab[p - tab]; 2510 return Tok_Char | backTab[p - tab];
2505 } 2511 }
2506#endif 2512#endif
2507 2513
2508 switch ( prevCh ) { 2514 switch ( prevCh ) {
2509#ifndef QT_NO_REGEXP_ESCAPE 2515#ifndef QT_NO_REGEXP_ESCAPE
2510 case '0': 2516 case '0':
2511 val = 0; 2517 val = 0;
2512 for ( i = 0; i < 3; i++ ) { 2518 for ( i = 0; i < 3; i++ ) {
2513 if ( yyCh >= '0' && yyCh <= '7' ) 2519 if ( yyCh >= '0' && yyCh <= '7' )
2514 val = ( val << 3 ) | ( yyCh - '0' ); 2520 val = ( val << 3 ) | ( yyCh - '0' );
2515 else 2521 else
2516 break; 2522 break;
2517 yyCh = getChar(); 2523 yyCh = getChar();
2518 } 2524 }
2519 if ( (val & ~0377) != 0 ) 2525 if ( (val & ~0377) != 0 )
2520 yyError = TRUE; 2526 yyError = TRUE;
2521 return Tok_Char | val; 2527 return Tok_Char | val;
2522#endif 2528#endif
2523#ifndef QT_NO_REGEXP_ESCAPE 2529#ifndef QT_NO_REGEXP_ESCAPE
2524 case 'B': 2530 case 'B':
2525 return Tok_NonWord; 2531 return Tok_NonWord;
2526#endif 2532#endif
2527#ifndef QT_NO_REGEXP_CCLASS 2533#ifndef QT_NO_REGEXP_CCLASS
2528 case 'D': 2534 case 'D':
2529 // see QChar::isDigit() 2535 // see QChar::isDigit()
2530 yyCharClass->addCategories( 0x7fffffef ); 2536 yyCharClass->addCategories( 0x7fffffef );
2531 return Tok_CharClass; 2537 return Tok_CharClass;
2532 case 'S': 2538 case 'S':
2533 // see QChar::isSpace() 2539 // see QChar::isSpace()
2534 yyCharClass->addCategories( 0x7ffff87f ); 2540 yyCharClass->addCategories( 0x7ffff87f );
2535 yyCharClass->addRange( 0x0000, 0x0008 ); 2541 yyCharClass->addRange( 0x0000, 0x0008 );
2536 yyCharClass->addRange( 0x000e, 0x001f ); 2542 yyCharClass->addRange( 0x000e, 0x001f );
2537 yyCharClass->addRange( 0x007f, 0x009f ); 2543 yyCharClass->addRange( 0x007f, 0x009f );
2538 return Tok_CharClass; 2544 return Tok_CharClass;
2539 case 'W': 2545 case 'W':
2540 // see QChar::isLetterOrNumber() 2546 // see QChar::isLetterOrNumber()
2541 yyCharClass->addCategories( 0x7ff07f8f ); 2547 yyCharClass->addCategories( 0x7ff07f8f );
2542 return Tok_CharClass; 2548 return Tok_CharClass;
2543#endif 2549#endif
2544#ifndef QT_NO_REGEXP_ESCAPE 2550#ifndef QT_NO_REGEXP_ESCAPE
2545 case 'b': 2551 case 'b':
2546 return Tok_Word; 2552 return Tok_Word;
2547#endif 2553#endif
2548#ifndef QT_NO_REGEXP_CCLASS 2554#ifndef QT_NO_REGEXP_CCLASS
2549 case 'd': 2555 case 'd':
2550 // see QChar::isDigit() 2556 // see QChar::isDigit()
2551 yyCharClass->addCategories( 0x00000010 ); 2557 yyCharClass->addCategories( 0x00000010 );
2552 return Tok_CharClass; 2558 return Tok_CharClass;
2553 case 's': 2559 case 's':
2554 // see QChar::isSpace() 2560 // see QChar::isSpace()
2555 yyCharClass->addCategories( 0x00000380 ); 2561 yyCharClass->addCategories( 0x00000380 );
2556 yyCharClass->addRange( 0x0009, 0x000d ); 2562 yyCharClass->addRange( 0x0009, 0x000d );
2557 return Tok_CharClass; 2563 return Tok_CharClass;
2558 case 'w': 2564 case 'w':
2559 // see QChar::isLetterOrNumber() 2565 // see QChar::isLetterOrNumber()
2560 yyCharClass->addCategories( 0x000f8070 ); 2566 yyCharClass->addCategories( 0x000f8070 );
2561 return Tok_CharClass; 2567 return Tok_CharClass;
2562#endif 2568#endif
2563#ifndef QT_NO_REGEXP_ESCAPE 2569#ifndef QT_NO_REGEXP_ESCAPE
2564 case 'x': 2570 case 'x':
2565 val = 0; 2571 val = 0;
2566 for ( i = 0; i < 4; i++ ) { 2572 for ( i = 0; i < 4; i++ ) {
2567 low = QChar( yyCh ).lower(); 2573 low = QChar( yyCh ).lower();
2568 if ( low >= '0' && low <= '9' ) 2574 if ( low >= '0' && low <= '9' )
2569 val = ( val << 4 ) | ( low - '0' ); 2575 val = ( val << 4 ) | ( low - '0' );
2570 else if ( low >= 'a' && low <= 'f' ) 2576 else if ( low >= 'a' && low <= 'f' )
2571 val = ( val << 4 ) | ( low - 'a' + 10 ); 2577 val = ( val << 4 ) | ( low - 'a' + 10 );
2572 else 2578 else
2573 break; 2579 break;
2574 yyCh = getChar(); 2580 yyCh = getChar();
2575 } 2581 }
2576 return Tok_Char | val; 2582 return Tok_Char | val;
2577#endif 2583#endif
2578 default: 2584 default:
2579 if ( prevCh >= '1' && prevCh <= '9' ) { 2585 if ( prevCh >= '1' && prevCh <= '9' ) {
2580#ifndef QT_NO_REGEXP_BACKREF 2586#ifndef QT_NO_REGEXP_BACKREF
2581 val = prevCh - '0'; 2587 val = prevCh - '0';
2582 while ( yyCh >= '0' && yyCh <= '9' ) { 2588 while ( yyCh >= '0' && yyCh <= '9' ) {
2583 val = ( val *= 10 ) | ( yyCh - '0' ); 2589 val = ( val *= 10 ) | ( yyCh - '0' );
2584 yyCh = getChar(); 2590 yyCh = getChar();
2585 } 2591 }
2586 return Tok_BackRef | val; 2592 return Tok_BackRef | val;
2587#else 2593#else
2588 yyError = TRUE; 2594 yyError = TRUE;
2589#endif 2595#endif
2590 } 2596 }
2591 return Tok_Char | prevCh; 2597 return Tok_Char | prevCh;
2592 } 2598 }
2593} 2599}
2594 2600
2595#ifndef QT_NO_REGEXP_INTERVAL 2601#ifndef QT_NO_REGEXP_INTERVAL
2596int QRegExpEngine::getRep( int def ) 2602int QRegExpEngine::getRep( int def )
2597{ 2603{
2598 if ( yyCh >= '0' && yyCh <= '9' ) { 2604 if ( yyCh >= '0' && yyCh <= '9' ) {
2599 int rep = 0; 2605 int rep = 0;
2600 do { 2606 do {
2601 rep = 10 * rep + yyCh - '0'; 2607 rep = 10 * rep + yyCh - '0';
2602 if ( rep >= InftyRep ) { 2608 if ( rep >= InftyRep ) {
2603 yyError = TRUE; 2609 yyError = TRUE;
2604 rep = def; 2610 rep = def;
2605 } 2611 }
2606 yyCh = getChar(); 2612 yyCh = getChar();
2607 } while ( yyCh >= '0' && yyCh <= '9' ); 2613 } while ( yyCh >= '0' && yyCh <= '9' );
2608 return rep; 2614 return rep;
2609 } else { 2615 } else {
2610 return def; 2616 return def;
2611 } 2617 }
2612} 2618}
2613#endif 2619#endif
2614 2620
2615#ifndef QT_NO_REGEXP_LOOKAHEAD 2621#ifndef QT_NO_REGEXP_LOOKAHEAD
2616void QRegExpEngine::skipChars( int n ) 2622void QRegExpEngine::skipChars( int n )
2617{ 2623{
2618 if ( n > 0 ) { 2624 if ( n > 0 ) {
2619 yyPos += n - 1; 2625 yyPos += n - 1;
2620 yyCh = getChar(); 2626 yyCh = getChar();
2621 } 2627 }
2622} 2628}
2623#endif 2629#endif
2624 2630
2625void QRegExpEngine::startTokenizer( const QChar *rx, int len ) 2631void QRegExpEngine::startTokenizer( const QChar *rx, int len )
2626{ 2632{
2627 yyIn = rx; 2633 yyIn = rx;
2628 yyPos0 = 0; 2634 yyPos0 = 0;
2629 yyPos = 0; 2635 yyPos = 0;
2630 yyLen = len; 2636 yyLen = len;
2631 yyCh = getChar(); 2637 yyCh = getChar();
2632 yyCharClass = new CharClass; 2638 yyCharClass = new CharClass;
2633 yyMinRep = 0; 2639 yyMinRep = 0;
2634 yyMaxRep = 0; 2640 yyMaxRep = 0;
2635 yyError = FALSE; 2641 yyError = FALSE;
2636} 2642}
2637 2643
2638int QRegExpEngine::getToken() 2644int QRegExpEngine::getToken()
2639{ 2645{
2640#ifndef QT_NO_REGEXP_CCLASS 2646#ifndef QT_NO_REGEXP_CCLASS
2641 ushort pendingCh = 0; 2647 ushort pendingCh = 0;
2642 bool charPending; 2648 bool charPending;
2643 bool rangePending; 2649 bool rangePending;
2644 int tok; 2650 int tok;
2645#endif 2651#endif
2646 int prevCh = yyCh; 2652 int prevCh = yyCh;
2647 2653
2648 yyPos0 = yyPos - 1; 2654 yyPos0 = yyPos - 1;
2649#ifndef QT_NO_REGEXP_CCLASS 2655#ifndef QT_NO_REGEXP_CCLASS
2650 yyCharClass->clear(); 2656 yyCharClass->clear();
2651#endif 2657#endif
2652 yyMinRep = 0; 2658 yyMinRep = 0;
2653 yyMaxRep = 0; 2659 yyMaxRep = 0;
2654 yyCh = getChar(); 2660 yyCh = getChar();
2655 switch ( prevCh ) { 2661 switch ( prevCh ) {
2656 case EOS: 2662 case EOS:
2657 yyPos0 = yyPos; 2663 yyPos0 = yyPos;
2658 return Tok_Eos; 2664 return Tok_Eos;
2659 case '$': 2665 case '$':
2660 return Tok_Dollar; 2666 return Tok_Dollar;
2661 case '(': 2667 case '(':
2662 if ( yyCh == '?' ) { 2668 if ( yyCh == '?' ) {
2663 prevCh = getChar(); 2669 prevCh = getChar();
2664 yyCh = getChar(); 2670 yyCh = getChar();
2665 switch ( prevCh ) { 2671 switch ( prevCh ) {
2666#ifndef QT_NO_REGEXP_LOOKAHEAD 2672#ifndef QT_NO_REGEXP_LOOKAHEAD
2667 case '!': 2673 case '!':
2668 return Tok_NegLookahead; 2674 return Tok_NegLookahead;
2669 case '=': 2675 case '=':
2670 return Tok_PosLookahead; 2676 return Tok_PosLookahead;
2671#endif 2677#endif
2672 case ':': 2678 case ':':
2673 return Tok_MagicLeftParen; 2679 return Tok_MagicLeftParen;
2674 default: 2680 default:
2675 yyError = TRUE; 2681 yyError = TRUE;
2676 return Tok_MagicLeftParen; 2682 return Tok_MagicLeftParen;
2677 } 2683 }
2678 } else { 2684 } else {
2679 return Tok_LeftParen; 2685 return Tok_LeftParen;
2680 } 2686 }
2681 case ')': 2687 case ')':
2682 return Tok_RightParen; 2688 return Tok_RightParen;
2683 case '*': 2689 case '*':
2684 yyMinRep = 0; 2690 yyMinRep = 0;
2685 yyMaxRep = InftyRep; 2691 yyMaxRep = InftyRep;
2686 return Tok_Quantifier; 2692 return Tok_Quantifier;
2687 case '+': 2693 case '+':
2688 yyMinRep = 1; 2694 yyMinRep = 1;
2689 yyMaxRep = InftyRep; 2695 yyMaxRep = InftyRep;
2690 return Tok_Quantifier; 2696 return Tok_Quantifier;
2691 case '.': 2697 case '.':
2692#ifndef QT_NO_REGEXP_CCLASS 2698#ifndef QT_NO_REGEXP_CCLASS
2693 yyCharClass->setNegative( TRUE ); 2699 yyCharClass->setNegative( TRUE );
2694#endif 2700#endif
2695 return Tok_CharClass; 2701 return Tok_CharClass;
2696 case '?': 2702 case '?':
2697 yyMinRep = 0; 2703 yyMinRep = 0;
2698 yyMaxRep = 1; 2704 yyMaxRep = 1;
2699 return Tok_Quantifier; 2705 return Tok_Quantifier;
2700 case '[': 2706 case '[':
2701#ifndef QT_NO_REGEXP_CCLASS 2707#ifndef QT_NO_REGEXP_CCLASS
2702 if ( yyCh == '^' ) { 2708 if ( yyCh == '^' ) {
2703 yyCharClass->setNegative( TRUE ); 2709 yyCharClass->setNegative( TRUE );
2704 yyCh = getChar(); 2710 yyCh = getChar();
2705 } 2711 }
2706 charPending = FALSE; 2712 charPending = FALSE;
2707 rangePending = FALSE; 2713 rangePending = FALSE;
2708 do { 2714 do {
2709 if ( yyCh == '-' && charPending && !rangePending ) { 2715 if ( yyCh == '-' && charPending && !rangePending ) {
2710 rangePending = TRUE; 2716 rangePending = TRUE;
2711 yyCh = getChar(); 2717 yyCh = getChar();
2712 } else { 2718 } else {
2713 if ( charPending && !rangePending ) { 2719 if ( charPending && !rangePending ) {
2714 yyCharClass->addSingleton( pendingCh ); 2720 yyCharClass->addSingleton( pendingCh );
2715 charPending = FALSE; 2721 charPending = FALSE;
2716 } 2722 }
2717 if ( yyCh == '\\' ) { 2723 if ( yyCh == '\\' ) {
2718 yyCh = getChar(); 2724 yyCh = getChar();
2719 tok = getEscape(); 2725 tok = getEscape();
2720 if ( tok == Tok_Word ) 2726 if ( tok == Tok_Word )
2721 tok = '\b'; 2727 tok = '\b';
2722 } else { 2728 } else {
2723 tok = Tok_Char | yyCh; 2729 tok = Tok_Char | yyCh;
2724 yyCh = getChar(); 2730 yyCh = getChar();
2725 } 2731 }
2726 if ( tok == Tok_CharClass ) { 2732 if ( tok == Tok_CharClass ) {
2727 if ( rangePending ) { 2733 if ( rangePending ) {
2728 yyCharClass->addSingleton( '-' ); 2734 yyCharClass->addSingleton( '-' );
2729 yyCharClass->addSingleton( pendingCh ); 2735 yyCharClass->addSingleton( pendingCh );
2730 charPending = FALSE; 2736 charPending = FALSE;
2731 rangePending = FALSE; 2737 rangePending = FALSE;
2732 } 2738 }
2733 } else if ( (tok & Tok_Char) != 0 ) { 2739 } else if ( (tok & Tok_Char) != 0 ) {
2734 if ( rangePending ) { 2740 if ( rangePending ) {
2735 yyCharClass->addRange( pendingCh, tok ^ Tok_Char ); 2741 yyCharClass->addRange( pendingCh, tok ^ Tok_Char );
2736 charPending = FALSE; 2742 charPending = FALSE;
2737 rangePending = FALSE; 2743 rangePending = FALSE;
2738 } else { 2744 } else {
2739 pendingCh = tok ^ Tok_Char; 2745 pendingCh = tok ^ Tok_Char;
2740 charPending = TRUE; 2746 charPending = TRUE;
2741 } 2747 }
2742 } else { 2748 } else {
2743 yyError = TRUE; 2749 yyError = TRUE;
2744 } 2750 }
2745 } 2751 }
2746 } while ( yyCh != ']' && yyCh != EOS ); 2752 } while ( yyCh != ']' && yyCh != EOS );
2747 if ( rangePending ) 2753 if ( rangePending )
2748 yyCharClass->addSingleton( '-' ); 2754 yyCharClass->addSingleton( '-' );
2749 if ( charPending ) 2755 if ( charPending )
2750 yyCharClass->addSingleton( pendingCh ); 2756 yyCharClass->addSingleton( pendingCh );
2751 if ( yyCh == EOS ) 2757 if ( yyCh == EOS )
2752 yyError = TRUE; 2758 yyError = TRUE;
2753 else 2759 else
2754 yyCh = getChar(); 2760 yyCh = getChar();
2755 return Tok_CharClass; 2761 return Tok_CharClass;
2756#else 2762#else
2757 yyError = TRUE; 2763 yyError = TRUE;
2758 return Tok_Char | '['; 2764 return Tok_Char | '[';
2759#endif 2765#endif
2760 case '\\': 2766 case '\\':
2761 return getEscape(); 2767 return getEscape();
2762 case ']': 2768 case ']':
2763 yyError = TRUE; 2769 yyError = TRUE;
2764 return Tok_Char | ']'; 2770 return Tok_Char | ']';
2765 case '^': 2771 case '^':
2766 return Tok_Caret; 2772 return Tok_Caret;
2767#ifndef QT_NO_REGEXP_INTERVAL 2773#ifndef QT_NO_REGEXP_INTERVAL
2768 case '{': 2774 case '{':
2769 yyMinRep = getRep( 0 ); 2775 yyMinRep = getRep( 0 );
2770 yyMaxRep = yyMinRep; 2776 yyMaxRep = yyMinRep;
2771 if ( yyCh == ',' ) { 2777 if ( yyCh == ',' ) {
2772 yyCh = getChar(); 2778 yyCh = getChar();
2773 yyMaxRep = getRep( InftyRep ); 2779 yyMaxRep = getRep( InftyRep );
2774 } 2780 }
2775 if ( yyMaxRep < yyMinRep ) 2781 if ( yyMaxRep < yyMinRep )
2776 qSwap( yyMinRep, yyMaxRep ); 2782 qSwap( yyMinRep, yyMaxRep );
2777 if ( yyCh != '}' ) 2783 if ( yyCh != '}' )
2778 yyError = TRUE; 2784 yyError = TRUE;
2779 yyCh = getChar(); 2785 yyCh = getChar();
2780 return Tok_Quantifier; 2786 return Tok_Quantifier;
2781#else 2787#else
2782 yyError = TRUE; 2788 yyError = TRUE;
2783 return Tok_Char | '{'; 2789 return Tok_Char | '{';
2784#endif 2790#endif
2785 case '|': 2791 case '|':
2786 return Tok_Bar; 2792 return Tok_Bar;
2787 case '}': 2793 case '}':
2788 yyError = TRUE; 2794 yyError = TRUE;
2789 return Tok_Char | '}'; 2795 return Tok_Char | '}';
2790 default: 2796 default:
2791 return Tok_Char | prevCh; 2797 return Tok_Char | prevCh;
2792 } 2798 }
2793} 2799}
2794 2800
2795int QRegExpEngine::parse( const QChar *pattern, int len ) 2801int QRegExpEngine::parse( const QChar *pattern, int len )
2796{ 2802{
2797 valid = TRUE; 2803 valid = TRUE;
2798 startTokenizer( pattern, len ); 2804 startTokenizer( pattern, len );
2799 yyTok = getToken(); 2805 yyTok = getToken();
2800#ifndef QT_NO_REGEXP_CAPTURE 2806#ifndef QT_NO_REGEXP_CAPTURE
2801 yyMayCapture = TRUE; 2807 yyMayCapture = TRUE;
2802#else 2808#else
2803 yyMayCapture = FALSE; 2809 yyMayCapture = FALSE;
2804#endif 2810#endif
2805 2811
2806#ifndef QT_NO_REGEXP_CAPTURE 2812#ifndef QT_NO_REGEXP_CAPTURE
2807 int atom = startAtom( FALSE ); 2813 int atom = startAtom( FALSE );
2808#endif 2814#endif
2809 CharClass anything; 2815 CharClass anything;
2810 Box box( this ); // create InitialState 2816 Box box( this ); // create InitialState
2811 box.set( anything ); 2817 box.set( anything );
2812 Box rightBox( this ); // create FinalState 2818 Box rightBox( this ); // create FinalState
2813 rightBox.set( anything ); 2819 rightBox.set( anything );
2814 2820
2815 Box middleBox( this ); 2821 Box middleBox( this );
2816 parseExpression( &middleBox ); 2822 parseExpression( &middleBox );
2817#ifndef QT_NO_REGEXP_CAPTURE 2823#ifndef QT_NO_REGEXP_CAPTURE
2818 finishAtom( atom ); 2824 finishAtom( atom );
2819#endif 2825#endif
2820#ifndef QT_NO_REGEXP_OPTIM 2826#ifndef QT_NO_REGEXP_OPTIM
2821 middleBox.setupHeuristics(); 2827 middleBox.setupHeuristics();
2822#endif 2828#endif
2823 box.cat( middleBox ); 2829 box.cat( middleBox );
2824 box.cat( rightBox ); 2830 box.cat( rightBox );
2825 delete yyCharClass; 2831 delete yyCharClass;
2826 yyCharClass = 0; 2832 yyCharClass = 0;
2827 2833
2828 realncap = ncap; 2834 realncap = ncap;
2829#ifndef QT_NO_REGEXP_BACKREF 2835#ifndef QT_NO_REGEXP_BACKREF
2830 if ( nbrefs > ncap ) 2836 if ( nbrefs > ncap )
2831 ncap = nbrefs; 2837 ncap = nbrefs;
2832#endif 2838#endif
2833 2839
2834 mmCaptured.resize( 2 + 2 * realncap ); 2840 mmCaptured.resize( 2 + 2 * realncap );
2835 mmCapturedNoMatch.fill( -1, 2 + 2 * realncap ); 2841 mmCapturedNoMatch.fill( -1, 2 + 2 * realncap );
2836 2842
2837 /* 2843 /*
2838 We use one QArray<int> for all the big data used a lot in matchHere() and 2844 We use one QArray<int> for all the big data used a lot in matchHere() and
2839 friends. 2845 friends.
2840 */ 2846 */
2841#ifndef QT_NO_REGEXP_OPTIM 2847#ifndef QT_NO_REGEXP_OPTIM
2842 mmSlideTabSize = QMAX( minl + 1, 16 ); 2848 mmSlideTabSize = QMAX( minl + 1, 16 );
2843#else 2849#else
2844 mmSlideTabSize = 0; 2850 mmSlideTabSize = 0;
2845#endif 2851#endif
2846 mmBigArray.resize( (3 + 4 * ncap) * ns + 4 * ncap + mmSlideTabSize ); 2852 mmBigArray.resize( (3 + 4 * ncap) * ns + 4 * ncap + mmSlideTabSize );
2847 2853
2848 mmInNextStack = mmBigArray.data(); 2854 mmInNextStack = mmBigArray.data();
2849 memset( mmInNextStack, -1, ns * sizeof(int) ); 2855 memset( mmInNextStack, -1, ns * sizeof(int) );
2850 mmCurStack = mmInNextStack + ns; 2856 mmCurStack = mmInNextStack + ns;
2851 mmNextStack = mmInNextStack + 2 * ns; 2857 mmNextStack = mmInNextStack + 2 * ns;
2852 2858
2853 mmCurCapBegin = mmInNextStack + 3 * ns; 2859 mmCurCapBegin = mmInNextStack + 3 * ns;
2854 mmNextCapBegin = mmCurCapBegin + ncap * ns; 2860 mmNextCapBegin = mmCurCapBegin + ncap * ns;
2855 mmCurCapEnd = mmCurCapBegin + 2 * ncap * ns; 2861 mmCurCapEnd = mmCurCapBegin + 2 * ncap * ns;
2856 mmNextCapEnd = mmCurCapBegin + 3 * ncap * ns; 2862 mmNextCapEnd = mmCurCapBegin + 3 * ncap * ns;
2857 2863
2858 mmTempCapBegin = mmCurCapBegin + 4 * ncap * ns; 2864 mmTempCapBegin = mmCurCapBegin + 4 * ncap * ns;
2859 mmTempCapEnd = mmTempCapBegin + ncap; 2865 mmTempCapEnd = mmTempCapBegin + ncap;
2860 mmCapBegin = mmTempCapBegin + 2 * ncap; 2866 mmCapBegin = mmTempCapBegin + 2 * ncap;
2861 mmCapEnd = mmTempCapBegin + 3 * ncap; 2867 mmCapEnd = mmTempCapBegin + 3 * ncap;
2862 2868
2863 mmSlideTab = mmTempCapBegin + 4 * ncap; 2869 mmSlideTab = mmTempCapBegin + 4 * ncap;
2864 2870
2865 if ( yyError ) 2871 if ( yyError )
2866 return -1; 2872 return -1;
2867 2873
2868#ifndef QT_NO_REGEXP_OPTIM 2874#ifndef QT_NO_REGEXP_OPTIM
2869 State *sinit = s[InitialState]; 2875 State *sinit = s[InitialState];
2870 caretAnchored = ( sinit->anchors != 0 ); 2876 caretAnchored = ( sinit->anchors != 0 );
2871 if ( caretAnchored ) { 2877 if ( caretAnchored ) {
2872 QMap<int, int>& anchors = *sinit->anchors; 2878 QMap<int, int>& anchors = *sinit->anchors;
2873 QMap<int, int>::ConstIterator a; 2879 QMap<int, int>::ConstIterator a;
2874 for ( a = anchors.begin(); a != anchors.end(); ++a ) { 2880 for ( a = anchors.begin(); a != anchors.end(); ++a ) {
2875#ifndef QT_NO_REGEXP_ANCHOR_ALT 2881#ifndef QT_NO_REGEXP_ANCHOR_ALT
2876 if ( (*a & Anchor_Alternation) != 0 ) 2882 if ( (*a & Anchor_Alternation) != 0 )
2877 break; 2883 break;
2878#endif 2884#endif
2879 if ( (*a & Anchor_Caret) == 0 ) { 2885 if ( (*a & Anchor_Caret) == 0 ) {
2880 caretAnchored = FALSE; 2886 caretAnchored = FALSE;
2881 break; 2887 break;
2882 } 2888 }
2883 } 2889 }
2884 } 2890 }
2885#endif 2891#endif
2886 return yyPos0; 2892 return yyPos0;
2887} 2893}
2888 2894
2889void QRegExpEngine::parseAtom( Box *box ) 2895void QRegExpEngine::parseAtom( Box *box )
2890{ 2896{
2891#ifndef QT_NO_REGEXP_LOOKAHEAD 2897#ifndef QT_NO_REGEXP_LOOKAHEAD
2892 QRegExpEngine *eng = 0; 2898 QRegExpEngine *eng = 0;
2893 bool neg; 2899 bool neg;
2894 int len; 2900 int len;
2895#endif 2901#endif
2896 2902
2897 switch ( yyTok ) { 2903 switch ( yyTok ) {
2898 case Tok_Dollar: 2904 case Tok_Dollar:
2899 box->catAnchor( Anchor_Dollar ); 2905 box->catAnchor( Anchor_Dollar );
2900 break; 2906 break;
2901 case Tok_Caret: 2907 case Tok_Caret:
2902 box->catAnchor( Anchor_Caret ); 2908 box->catAnchor( Anchor_Caret );
2903 break; 2909 break;
2904#ifndef QT_NO_REGEXP_LOOKAHEAD 2910#ifndef QT_NO_REGEXP_LOOKAHEAD
2905 case Tok_PosLookahead: 2911 case Tok_PosLookahead:
2906 case Tok_NegLookahead: 2912 case Tok_NegLookahead:
2907 neg = ( yyTok == Tok_NegLookahead ); 2913 neg = ( yyTok == Tok_NegLookahead );
2908 eng = new QRegExpEngine( cs ); 2914 eng = new QRegExpEngine( cs );
2909 len = eng->parse( yyIn + yyPos - 1, yyLen - yyPos + 1 ); 2915 len = eng->parse( yyIn + yyPos - 1, yyLen - yyPos + 1 );
2910 if ( len >= 0 ) 2916 if ( len >= 0 )
2911 skipChars( len ); 2917 skipChars( len );
2912 else 2918 else
2913 yyError = TRUE; 2919 yyError = TRUE;
2914 box->catAnchor( addLookahead(eng, neg) ); 2920 box->catAnchor( addLookahead(eng, neg) );
2915 yyTok = getToken(); 2921 yyTok = getToken();
2916 if ( yyTok != Tok_RightParen ) 2922 if ( yyTok != Tok_RightParen )
2917 yyError = TRUE; 2923 yyError = TRUE;
2918 break; 2924 break;
2919#endif 2925#endif
2920#ifndef QT_NO_REGEXP_ESCAPE 2926#ifndef QT_NO_REGEXP_ESCAPE
2921 case Tok_Word: 2927 case Tok_Word:
2922 box->catAnchor( Anchor_Word ); 2928 box->catAnchor( Anchor_Word );
2923 break; 2929 break;
2924 case Tok_NonWord: 2930 case Tok_NonWord:
2925 box->catAnchor( Anchor_NonWord ); 2931 box->catAnchor( Anchor_NonWord );
2926 break; 2932 break;
2927#endif 2933#endif
2928 case Tok_LeftParen: 2934 case Tok_LeftParen:
2929 case Tok_MagicLeftParen: 2935 case Tok_MagicLeftParen:
2930 yyTok = getToken(); 2936 yyTok = getToken();
2931 parseExpression( box ); 2937 parseExpression( box );
2932 if ( yyTok != Tok_RightParen ) 2938 if ( yyTok != Tok_RightParen )
2933 yyError = TRUE; 2939 yyError = TRUE;
2934 break; 2940 break;
2935 case Tok_CharClass: 2941 case Tok_CharClass:
2936 box->set( *yyCharClass ); 2942 box->set( *yyCharClass );
2937 break; 2943 break;
2938 default: 2944 default:
2939 if ( (yyTok & Tok_Char) != 0 ) 2945 if ( (yyTok & Tok_Char) != 0 )
2940 box->set( QChar(yyTok ^ Tok_Char) ); 2946 box->set( QChar(yyTok ^ Tok_Char) );
2941#ifndef QT_NO_REGEXP_BACKREF 2947#ifndef QT_NO_REGEXP_BACKREF
2942 else if ( (yyTok & Tok_BackRef) != 0 ) 2948 else if ( (yyTok & Tok_BackRef) != 0 )
2943 box->set( yyTok ^ Tok_BackRef ); 2949 box->set( yyTok ^ Tok_BackRef );
2944#endif 2950#endif
2945 else 2951 else
2946 yyError = TRUE; 2952 yyError = TRUE;
2947 } 2953 }
2948 yyTok = getToken(); 2954 yyTok = getToken();
2949} 2955}
2950 2956
2951void QRegExpEngine::parseFactor( Box *box ) 2957void QRegExpEngine::parseFactor( Box *box )
2952{ 2958{
2953#ifndef QT_NO_REGEXP_CAPTURE 2959#ifndef QT_NO_REGEXP_CAPTURE
2954 int atom = startAtom( yyMayCapture && yyTok == Tok_LeftParen ); 2960 int atom = startAtom( yyMayCapture && yyTok == Tok_LeftParen );
2955#else 2961#else
2956 static const int atom = 0; 2962 static const int atom = 0;
2957#endif 2963#endif
2958 2964
2959#ifndef QT_NO_REGEXP_INTERVAL 2965#ifndef QT_NO_REGEXP_INTERVAL
2960#define YYREDO() \ 2966#define YYREDO() \
2961 yyIn = in, yyPos0 = pos0, yyPos = pos, yyLen = len, yyCh = ch, \ 2967 yyIn = in, yyPos0 = pos0, yyPos = pos, yyLen = len, yyCh = ch, \
2962 *yyCharClass = charClass, yyMinRep = 0, yyMaxRep = 0, yyTok = tok 2968 *yyCharClass = charClass, yyMinRep = 0, yyMaxRep = 0, yyTok = tok
2963 2969
2964 const QChar *in = yyIn; 2970 const QChar *in = yyIn;
2965 int pos0 = yyPos0; 2971 int pos0 = yyPos0;
2966 int pos = yyPos; 2972 int pos = yyPos;
2967 int len = yyLen; 2973 int len = yyLen;
2968 int ch = yyCh; 2974 int ch = yyCh;
2969 CharClass charClass; 2975 CharClass charClass;
2970 if ( yyTok == Tok_CharClass ) 2976 if ( yyTok == Tok_CharClass )
2971 charClass = *yyCharClass; 2977 charClass = *yyCharClass;
2972 int tok = yyTok; 2978 int tok = yyTok;
2973 bool mayCapture = yyMayCapture; 2979 bool mayCapture = yyMayCapture;
2974#endif 2980#endif
2975 2981
2976 parseAtom( box ); 2982 parseAtom( box );
2977#ifndef QT_NO_REGEXP_CAPTURE 2983#ifndef QT_NO_REGEXP_CAPTURE
2978 finishAtom( atom ); 2984 finishAtom( atom );
2979#endif 2985#endif
2980 2986
2981 if ( yyTok == Tok_Quantifier ) { 2987 if ( yyTok == Tok_Quantifier ) {
2982 if ( yyMaxRep == InftyRep ) { 2988 if ( yyMaxRep == InftyRep ) {
2983 box->plus( atom ); 2989 box->plus( atom );
2984#ifndef QT_NO_REGEXP_INTERVAL 2990#ifndef QT_NO_REGEXP_INTERVAL
2985 } else if ( yyMaxRep == 0 ) { 2991 } else if ( yyMaxRep == 0 ) {
2986 box->clear(); 2992 box->clear();
2987#endif 2993#endif
2988 } 2994 }
2989 if ( yyMinRep == 0 ) 2995 if ( yyMinRep == 0 )
2990 box->opt(); 2996 box->opt();
2991 2997
2992#ifndef QT_NO_REGEXP_INTERVAL 2998#ifndef QT_NO_REGEXP_INTERVAL
2993 yyMayCapture = FALSE; 2999 yyMayCapture = FALSE;
2994 int alpha = ( yyMinRep == 0 ) ? 0 : yyMinRep - 1; 3000 int alpha = ( yyMinRep == 0 ) ? 0 : yyMinRep - 1;
2995 int beta = ( yyMaxRep == InftyRep ) ? 0 : yyMaxRep - ( alpha + 1 ); 3001 int beta = ( yyMaxRep == InftyRep ) ? 0 : yyMaxRep - ( alpha + 1 );
2996 3002
2997 Box rightBox( this ); 3003 Box rightBox( this );
2998 int i; 3004 int i;
2999 3005
3000 for ( i = 0; i < beta; i++ ) { 3006 for ( i = 0; i < beta; i++ ) {
3001 YYREDO(); 3007 YYREDO();
3002 Box leftBox( this ); 3008 Box leftBox( this );
3003 parseAtom( &leftBox ); 3009 parseAtom( &leftBox );
3004 leftBox.cat( rightBox ); 3010 leftBox.cat( rightBox );
3005 leftBox.opt(); 3011 leftBox.opt();
3006 rightBox = leftBox; 3012 rightBox = leftBox;
3007 } 3013 }
3008 for ( i = 0; i < alpha; i++ ) { 3014 for ( i = 0; i < alpha; i++ ) {
3009 YYREDO(); 3015 YYREDO();
3010 Box leftBox( this ); 3016 Box leftBox( this );
3011 parseAtom( &leftBox ); 3017 parseAtom( &leftBox );
3012 leftBox.cat( rightBox ); 3018 leftBox.cat( rightBox );
3013 rightBox = leftBox; 3019 rightBox = leftBox;
3014 } 3020 }
3015 rightBox.cat( *box ); 3021 rightBox.cat( *box );
3016 *box = rightBox; 3022 *box = rightBox;
3017#endif 3023#endif
3018 yyTok = getToken(); 3024 yyTok = getToken();
3019#ifndef QT_NO_REGEXP_INTERVAL 3025#ifndef QT_NO_REGEXP_INTERVAL
3020 yyMayCapture = mayCapture; 3026 yyMayCapture = mayCapture;
3021#endif 3027#endif
3022 } 3028 }
3023#undef YYREDO 3029#undef YYREDO
3024} 3030}
3025 3031
3026void QRegExpEngine::parseTerm( Box *box ) 3032void QRegExpEngine::parseTerm( Box *box )
3027{ 3033{
3028#ifndef QT_NO_REGEXP_OPTIM 3034#ifndef QT_NO_REGEXP_OPTIM
3029 if ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar ) 3035 if ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar )
3030 parseFactor( box ); 3036 parseFactor( box );
3031#endif 3037#endif
3032 while ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar ) { 3038 while ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar ) {
3033 Box rightBox( this ); 3039 Box rightBox( this );
3034 parseFactor( &rightBox ); 3040 parseFactor( &rightBox );
3035 box->cat( rightBox ); 3041 box->cat( rightBox );
3036 } 3042 }
3037} 3043}
3038 3044
3039void QRegExpEngine::parseExpression( Box *box ) 3045void QRegExpEngine::parseExpression( Box *box )
3040{ 3046{
3041 parseTerm( box ); 3047 parseTerm( box );
3042 while ( yyTok == Tok_Bar ) { 3048 while ( yyTok == Tok_Bar ) {
3043 Box rightBox( this ); 3049 Box rightBox( this );
3044 yyTok = getToken(); 3050 yyTok = getToken();
3045 parseTerm( &rightBox ); 3051 parseTerm( &rightBox );
3046 box->orx( rightBox ); 3052 box->orx( rightBox );
3047 } 3053 }
3048} 3054}
3049 3055
3050/* 3056/*
3051 The class QRegExpPrivate contains the private data of a regular expression 3057 The class QRegExpPrivate contains the private data of a regular expression
3052 other than the automaton. It makes it possible for many QRegExp objects to 3058 other than the automaton. It makes it possible for many QRegExp objects to
3053 use the same QRegExpEngine object with different QRegExpPrivate objects. 3059 use the same QRegExpEngine object with different QRegExpPrivate objects.
3054*/ 3060*/
3055struct QRegExpPrivate 3061struct QRegExpPrivate
3056{ 3062{
3057 QString pattern; // regular-expression or wildcard pattern 3063 QString pattern; // regular-expression or wildcard pattern
3058 QString rxpattern; // regular-expression pattern 3064 QString rxpattern; // regular-expression pattern
3059#ifndef QT_NO_REGEXP_WILDCARD 3065#ifndef QT_NO_REGEXP_WILDCARD
3060 bool wc; // wildcard mode? 3066 bool wc; // wildcard mode?
3061#endif 3067#endif
3062 bool min; // minimal matching? (instead of maximal) 3068 bool min; // minimal matching? (instead of maximal)
3063#ifndef QT_NO_REGEXP_CAPTURE 3069#ifndef QT_NO_REGEXP_CAPTURE
3064 QString t; // last string passed to QRegExp::search() or searchRev() 3070 QString t; // last string passed to QRegExp::search() or searchRev()
3065 QStringList capturedCache; // what QRegExp::capturedTexts() returned last 3071 QStringList capturedCache; // what QRegExp::capturedTexts() returned last
3066#endif 3072#endif
3067 QArray<int> captured; // what QRegExpEngine::search() returned last 3073 QArray<int> captured; // what QRegExpEngine::search() returned last
3068 3074
3069 QRegExpPrivate() { captured.fill( -1, 2 ); } 3075 QRegExpPrivate() { captured.fill( -1, 2 ); }
3070}; 3076};
3071 3077
3072#ifndef QT_NO_REGEXP_OPTIM 3078#ifndef QT_NO_REGEXP_OPTIM
3073static QCache<QRegExpEngine> *engineCache = 0; 3079static QCache<QRegExpEngine> *engineCache = 0;
3074#endif 3080#endif
3075 3081
3076static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive ) 3082static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive )
3077{ 3083{
3078#ifndef QT_NO_REGEXP_OPTIM 3084#ifndef QT_NO_REGEXP_OPTIM
3079 if ( engineCache != 0 ) { 3085 if ( engineCache != 0 ) {
3080 QRegExpEngine *eng = engineCache->take( pattern ); 3086 QRegExpEngine *eng = engineCache->take( pattern );
3081 if ( eng == 0 || eng->caseSensitive() != caseSensitive ) { 3087 if ( eng == 0 || eng->caseSensitive() != caseSensitive ) {
3082 delete eng; 3088 delete eng;
3083 } else { 3089 } else {
3084 eng->ref(); 3090 eng->ref();
3085 return eng; 3091 return eng;
3086 } 3092 }
3087 } 3093 }
3088#endif 3094#endif
3089 return new QRegExpEngine( pattern, caseSensitive ); 3095 return new QRegExpEngine( pattern, caseSensitive );
3090} 3096}
3091 3097
3092static void derefEngine( QRegExpEngine *eng, const QString& pattern ) 3098static void derefEngine( QRegExpEngine *eng, const QString& pattern )
3093{ 3099{
3094 if ( eng != 0 && eng->deref() ) { 3100 if ( eng != 0 && eng->deref() ) {
3095#ifndef QT_NO_REGEXP_OPTIM 3101#ifndef QT_NO_REGEXP_OPTIM
3096 if ( engineCache == 0 ) { 3102 if ( engineCache == 0 ) {
3097 engineCache = new QCache<QRegExpEngine>; 3103 engineCache = new QCache<QRegExpEngine>;
3098 engineCache->setAutoDelete( TRUE ); 3104 engineCache->setAutoDelete( TRUE );
3099 } 3105 }
3100 if ( !pattern.isNull() && 3106 if ( !pattern.isNull() &&
3101 engineCache->insert(pattern, eng, 4 + pattern.length() / 4) ) 3107 engineCache->insert(pattern, eng, 4 + pattern.length() / 4) )
3102 return; 3108 return;
3103#else 3109#else
3104 Q_UNUSED( pattern ); 3110 Q_UNUSED( pattern );
3105#endif 3111#endif
3106 delete eng; 3112 delete eng;
3107 } 3113 }
3108} 3114}
3109 3115
3110/*! 3116/*!
3111 Constructs an empty regexp. 3117 Constructs an empty regexp.
3112 3118
3113 \sa isValid() 3119 \sa isValid()
3114*/ 3120*/
3115QRegExp3::QRegExp3() 3121QRegExp3::QRegExp3()
3116{ 3122{
3117 eng = new QRegExpEngine( TRUE ); 3123 eng = new QRegExpEngine( TRUE );
3118 priv = new QRegExpPrivate; 3124 priv = new QRegExpPrivate;
3119 priv->pattern = QString::null; 3125 priv->pattern = QString::null;
3120#ifndef QT_NO_REGEXP_WILDCARD 3126#ifndef QT_NO_REGEXP_WILDCARD
3121 priv->wc = FALSE; 3127 priv->wc = FALSE;
3122#endif 3128#endif
3123 priv->min = FALSE; 3129 priv->min = FALSE;
3124 compile( TRUE ); 3130 compile( TRUE );
3125} 3131}
3126 3132
3127/*! 3133/*!
3128 Constructs a regular expression object for the given \a pattern 3134 Constructs a regular expression object for the given \a pattern
3129 string. The pattern must be given using wildcard notation if \a 3135 string. The pattern must be given using wildcard notation if \a
3130 wildcard is TRUE (default is FALSE). The pattern is case sensitive, 3136 wildcard is TRUE (default is FALSE). The pattern is case sensitive,
3131 unless \a caseSensitive is FALSE. Matching is greedy (maximal), but 3137 unless \a caseSensitive is FALSE. Matching is greedy (maximal), but
3132 can be changed by calling setMinimal(). 3138 can be changed by calling setMinimal().
3133 3139
3134 \sa setPattern() setCaseSensitive() setWildcard() setMinimal() 3140 \sa setPattern() setCaseSensitive() setWildcard() setMinimal()
3135*/ 3141*/
3136QRegExp3::QRegExp3( const QString& pattern, bool caseSensitive, bool wildcard ) 3142QRegExp3::QRegExp3( const QString& pattern, bool caseSensitive, bool wildcard )
3137{ 3143{
3138 eng = 0; 3144 eng = 0;
3139 priv = new QRegExpPrivate; 3145 priv = new QRegExpPrivate;
3140 priv->pattern = pattern; 3146 priv->pattern = pattern;
3141#ifndef QT_NO_REGEXP_WILDCARD 3147#ifndef QT_NO_REGEXP_WILDCARD
3142 priv->wc = wildcard; 3148 priv->wc = wildcard;
3143#endif 3149#endif
3144 priv->min = FALSE; 3150 priv->min = FALSE;
3145 compile( caseSensitive ); 3151 compile( caseSensitive );
3146} 3152}
3147 3153
3148/*! 3154/*!
3149 Constructs a regular expression as a copy of \a rx. 3155 Constructs a regular expression as a copy of \a rx.
3150 3156
3151 \sa operator=() 3157 \sa operator=()
3152*/ 3158*/
3153QRegExp3::QRegExp3( const QRegExp3& rx ) 3159QRegExp3::QRegExp3( const QRegExp3& rx )
3154{ 3160{
3155 eng = 0; 3161 eng = 0;
3156 priv = new QRegExpPrivate; 3162 priv = new QRegExpPrivate;
3157 operator=( rx ); 3163 operator=( rx );
3158} 3164}
3159 3165
3160/*! 3166/*!
3161 Destroys the regular expression and cleans up its internal data. 3167 Destroys the regular expression and cleans up its internal data.
3162*/ 3168*/
3163QRegExp3::~QRegExp3() 3169QRegExp3::~QRegExp3()
3164{ 3170{
3165 derefEngine( eng, priv->rxpattern ); 3171 derefEngine( eng, priv->rxpattern );
3166 delete priv; 3172 delete priv;
3167} 3173}
3168 3174
3169/*! 3175/*!
3170 Copies the regular expression \a rx and returns a reference to the copy. 3176 Copies the regular expression \a rx and returns a reference to the copy.
3171 The case sensitivity, wildcard and minimal matching options are copied as 3177 The case sensitivity, wildcard and minimal matching options are copied as
3172 well. 3178 well.
3173*/ 3179*/
3174QRegExp3& QRegExp3::operator=( const QRegExp3& rx ) 3180QRegExp3& QRegExp3::operator=( const QRegExp3& rx )
3175{ 3181{
3176 rx.eng->ref(); 3182 rx.eng->ref();
3177 derefEngine( eng, priv->rxpattern ); 3183 derefEngine( eng, priv->rxpattern );
3178 eng = rx.eng; 3184 eng = rx.eng;
3179 priv->pattern = rx.priv->pattern; 3185 priv->pattern = rx.priv->pattern;
3180 priv->rxpattern = rx.priv->rxpattern; 3186 priv->rxpattern = rx.priv->rxpattern;
3181#ifndef QT_NO_REGEXP_WILDCARD 3187#ifndef QT_NO_REGEXP_WILDCARD
3182 priv->wc = rx.priv->wc; 3188 priv->wc = rx.priv->wc;
3183#endif 3189#endif
3184 priv->min = rx.priv->min; 3190 priv->min = rx.priv->min;
3185#ifndef QT_NO_REGEXP_CAPTURE 3191#ifndef QT_NO_REGEXP_CAPTURE
3186 priv->t = rx.priv->t; 3192 priv->t = rx.priv->t;
3187 priv->capturedCache = rx.priv->capturedCache; 3193 priv->capturedCache = rx.priv->capturedCache;
3188#endif 3194#endif
3189 priv->captured = rx.priv->captured; 3195 priv->captured = rx.priv->captured;
3190 return *this; 3196 return *this;
3191} 3197}
3192 3198
3193/*! 3199/*!
3194 Returns TRUE if this regular expression is equal to \a rx, otherwise 3200 Returns TRUE if this regular expression is equal to \a rx, otherwise
3195 returns FALSE. 3201 returns FALSE.
3196 3202
3197 Two QRegExp3 objects are equal if they have the same pattern strings 3203 Two QRegExp3 objects are equal if they have the same pattern strings
3198 and the same settings for case sensitivity, wildcard and minimal 3204 and the same settings for case sensitivity, wildcard and minimal
3199 matching. 3205 matching.
3200*/ 3206*/
3201bool QRegExp3::operator==( const QRegExp3& rx ) const 3207bool QRegExp3::operator==( const QRegExp3& rx ) const
3202{ 3208{
3203 return priv->pattern == rx.priv->pattern && 3209 return priv->pattern == rx.priv->pattern &&
3204 eng->caseSensitive() == rx.eng->caseSensitive() && 3210 eng->caseSensitive() == rx.eng->caseSensitive() &&
3205#ifndef QT_NO_REGEXP_WILDCARD 3211#ifndef QT_NO_REGEXP_WILDCARD
3206 priv->wc == rx.priv->wc && 3212 priv->wc == rx.priv->wc &&
3207#endif 3213#endif
3208 priv->min == rx.priv->min; 3214 priv->min == rx.priv->min;
3209} 3215}
3210 3216
3211/*! \fn bool QRegExp3::operator!=( const QRegExp& rx ) const 3217/*! \fn bool QRegExp3::operator!=( const QRegExp& rx ) const
3212 3218
3213 Returns TRUE if this regular expression is not equal to \a rx, otherwise 3219 Returns TRUE if this regular expression is not equal to \a rx, otherwise
3214 FALSE. 3220 FALSE.
3215 3221
3216 \sa operator==() 3222 \sa operator==()
3217*/ 3223*/
3218 3224
3219/*! 3225/*!
3220 Returns TRUE if the pattern string is empty, otherwise FALSE. 3226 Returns TRUE if the pattern string is empty, otherwise FALSE.
3221 3227
3222 If you call match() with an empty pattern on an empty string it will 3228 If you call match() with an empty pattern on an empty string it will
3223 return TRUE otherwise it returns FALSE since match() operates over the 3229 return TRUE otherwise it returns FALSE since match() operates over the
3224 whole string. If you call search() with an empty pattern on \e any 3230 whole string. If you call search() with an empty pattern on \e any
3225 string it will return the start position (0 by default) since it will 3231 string it will return the start position (0 by default) since it will
3226 match at the start position, because the empty pattern matches the 3232 match at the start position, because the empty pattern matches the
3227 'emptiness' at the start of the string, and the length of the match 3233 'emptiness' at the start of the string, and the length of the match
3228 returned by matchedLength() will be 0. 3234 returned by matchedLength() will be 0.
3229 3235
3230 See QString::isEmpty(). 3236 See QString::isEmpty().
3231*/ 3237*/
3232 3238
3233bool QRegExp3::isEmpty() const 3239bool QRegExp3::isEmpty() const
3234{ 3240{
3235 return priv->pattern.isEmpty(); 3241 return priv->pattern.isEmpty();
3236} 3242}
3237 3243
3238/*! 3244/*!
3239 Returns TRUE if the regular expression is valid, or FALSE if it's invalid. An 3245 Returns TRUE if the regular expression is valid, or FALSE if it's invalid. An
3240 invalid regular expression never matches. 3246 invalid regular expression never matches.
3241 3247
3242 The pattern <b>[a-z</b> is an example of an invalid pattern, since it lacks 3248 The pattern <b>[a-z</b> is an example of an invalid pattern, since it lacks
3243 a closing square bracket. 3249 a closing square bracket.
3244 3250
3245 Note that the validity of a regexp may also depend on the setting of 3251 Note that the validity of a regexp may also depend on the setting of
3246 the wildcard flag, for example <b>*.html</b> is a valid wildcard 3252 the wildcard flag, for example <b>*.html</b> is a valid wildcard
3247 regexp but an invalid full regexp. 3253 regexp but an invalid full regexp.
3248*/ 3254*/
3249bool QRegExp3::isValid() const 3255bool QRegExp3::isValid() const
3250{ 3256{
3251 return eng->isValid(); 3257 return eng->isValid();
3252} 3258}
3253 3259
3254/*! 3260/*!
3255 Returns the pattern string of the regular expression. The pattern has either 3261 Returns the pattern string of the regular expression. The pattern has either
3256 regular expression syntax or wildcard syntax, depending on wildcard(). 3262 regular expression syntax or wildcard syntax, depending on wildcard().
3257 3263
3258 \sa setPattern() 3264 \sa setPattern()
3259*/ 3265*/
3260QString QRegExp3::pattern() const 3266QString QRegExp3::pattern() const
3261{ 3267{
3262 return priv->pattern; 3268 return priv->pattern;
3263} 3269}
3264 3270
3265/*! 3271/*!
3266 Sets the pattern string to \a pattern and returns a reference to this regular 3272 Sets the pattern string to \a pattern and returns a reference to this regular
3267 expression. The case sensitivity, wildcard and minimal matching options are 3273 expression. The case sensitivity, wildcard and minimal matching options are
3268 not changed. 3274 not changed.
3269 3275
3270 \sa pattern() 3276 \sa pattern()
3271*/ 3277*/
3272void QRegExp3::setPattern( const QString& pattern ) 3278void QRegExp3::setPattern( const QString& pattern )
3273{ 3279{
3274 if ( priv->pattern != pattern ) { 3280 if ( priv->pattern != pattern ) {
3275 priv->pattern = pattern; 3281 priv->pattern = pattern;
3276 compile( caseSensitive() ); 3282 compile( caseSensitive() );
3277 } 3283 }
3278} 3284}
3279 3285
3280/*! 3286/*!
3281 Returns TRUE if case sensitivity is enabled, otherwise FALSE. The default is 3287 Returns TRUE if case sensitivity is enabled, otherwise FALSE. The default is
3282 TRUE. 3288 TRUE.
3283 3289
3284 \sa setCaseSensitive() 3290 \sa setCaseSensitive()
3285*/ 3291*/
3286bool QRegExp3::caseSensitive() const 3292bool QRegExp3::caseSensitive() const
3287{ 3293{
3288 return eng->caseSensitive(); 3294 return eng->caseSensitive();
3289} 3295}
3290 3296
3291/*! 3297/*!
3292 Sets case sensitive matching to \a sensitive. 3298 Sets case sensitive matching to \a sensitive.
3293 3299
3294 If \a sensitive is TRUE, <b>\\</b><b>.txt$</b> matches 3300 If \a sensitive is TRUE, <b>\\</b><b>.txt$</b> matches
3295 <tt>readme.txt</tt> but not <tt>README.TXT</tt>. 3301 <tt>readme.txt</tt> but not <tt>README.TXT</tt>.
3296 3302
3297 \sa caseSensitive() 3303 \sa caseSensitive()
3298*/ 3304*/
3299void QRegExp3::setCaseSensitive( bool sensitive ) 3305void QRegExp3::setCaseSensitive( bool sensitive )
3300{ 3306{
3301 if ( sensitive != eng->caseSensitive() ) 3307 if ( sensitive != eng->caseSensitive() )
3302 compile( sensitive ); 3308 compile( sensitive );
3303} 3309}
3304 3310
3305#ifndef QT_NO_REGEXP_WILDCARD 3311#ifndef QT_NO_REGEXP_WILDCARD
3306/*! 3312/*!
3307 Returns TRUE if wildcard mode is enabled, otherwise FALSE. The default is 3313 Returns TRUE if wildcard mode is enabled, otherwise FALSE. The default is
3308 FALSE. 3314 FALSE.
3309 3315
3310 \sa setWildcard() 3316 \sa setWildcard()
3311*/ 3317*/
3312bool QRegExp3::wildcard() const 3318bool QRegExp3::wildcard() const
3313{ 3319{
3314 return priv->wc; 3320 return priv->wc;
3315} 3321}
3316 3322
3317/*! Sets the wildcard mode for the regular expression. The default is FALSE. 3323/*! Sets the wildcard mode for the regular expression. The default is FALSE.
3318 3324
3319 Setting \a wildcard to TRUE enables simple shell-like wildcard 3325 Setting \a wildcard to TRUE enables simple shell-like wildcard
3320 matching. 3326 matching.
3321 (See <a href="#wildcard-matching">wildcard matching (globbing)</a>.) 3327 (See <a href="#wildcard-matching">wildcard matching (globbing)</a>.)
3322 3328
3323 For example, <b>r*.txt</b> matches the string <tt>readme.txt</tt> in wildcard 3329 For example, <b>r*.txt</b> matches the string <tt>readme.txt</tt> in wildcard
3324 mode, but does not match <tt>readme</tt>. 3330 mode, but does not match <tt>readme</tt>.
3325 3331
3326 \sa wildcard() 3332 \sa wildcard()
3327*/ 3333*/
3328void QRegExp3::setWildcard( bool wildcard ) 3334void QRegExp3::setWildcard( bool wildcard )
3329{ 3335{
3330 if ( wildcard != priv->wc ) { 3336 if ( wildcard != priv->wc ) {
3331 priv->wc = wildcard; 3337 priv->wc = wildcard;
3332 compile( caseSensitive() ); 3338 compile( caseSensitive() );
3333 } 3339 }
3334} 3340}
3335#endif 3341#endif
3336 3342
3337/*! Returns TRUE if minimal (non-greedy) matching is enabled, otherwise 3343/*! Returns TRUE if minimal (non-greedy) matching is enabled, otherwise
3338 returns FALSE. 3344 returns FALSE.
3339 3345
3340 \sa setMinimal() 3346 \sa setMinimal()
3341*/ 3347*/
3342bool QRegExp3::minimal() const 3348bool QRegExp3::minimal() const
3343{ 3349{
3344 return priv->min; 3350 return priv->min;
3345} 3351}
3346 3352
3347/*! 3353/*!
3348 Enables or disables minimal matching. If \a minimal is FALSE, matching is 3354 Enables or disables minimal matching. If \a minimal is FALSE, matching is
3349 greedy (maximal) which is the default. 3355 greedy (maximal) which is the default.
3350 3356
3351 For example, suppose we have the input string "We must be \<b>bold\</b>, 3357 For example, suppose we have the input string "We must be \<b>bold\</b>,
3352 very \<b>bold\</b>!" and the pattern <b>\<b>.*\</b></b>. With 3358 very \<b>bold\</b>!" and the pattern <b>\<b>.*\</b></b>. With
3353 the default greedy (maximal) matching, the match is 3359 the default greedy (maximal) matching, the match is
3354 "We must be <u>\<b>bold\</b>, very \<b>bold\</b></u>!". But with 3360 "We must be <u>\<b>bold\</b>, very \<b>bold\</b></u>!". But with
3355 minimal (non-greedy) matching the first match is: 3361 minimal (non-greedy) matching the first match is:
3356 "We must be <u>\<b>bold\</b></u>, very \<b>bold\</b>!" and the 3362 "We must be <u>\<b>bold\</b></u>, very \<b>bold\</b>!" and the
3357 second match is 3363 second match is
3358 "We must be \<b>bold\</b>, very <u>\<b>bold\</b></u>!". 3364 "We must be \<b>bold\</b>, very <u>\<b>bold\</b></u>!".
3359 In practice we might use the pattern <b>\<b>[^\<]+\</b></b>, 3365 In practice we might use the pattern <b>\<b>[^\<]+\</b></b>,
3360 although this will still fail for nested tags. 3366 although this will still fail for nested tags.
3361 3367
3362 \sa minimal() 3368 \sa minimal()
3363*/ 3369*/
3364void QRegExp3::setMinimal( bool minimal ) 3370void QRegExp3::setMinimal( bool minimal )
3365{ 3371{
3366 priv->min = minimal; 3372 priv->min = minimal;
3367} 3373}
3368 3374
3369/*! 3375/*!
3370 Returns TRUE if \a str is matched exactly by this regular expression 3376 Returns TRUE if \a str is matched exactly by this regular expression
3371 otherwise it returns FALSE. You can determine how much of the string was 3377 otherwise it returns FALSE. You can determine how much of the string was
3372 matched by calling matchedLength(). 3378 matched by calling matchedLength().
3373 3379
3374 For a given regexp string, R, <tt>match("R")</tt> is the equivalent 3380 For a given regexp string, R, <tt>match("R")</tt> is the equivalent
3375 of <tt>search("^R$")</tt> since match() effectively encloses the 3381 of <tt>search("^R$")</tt> since match() effectively encloses the
3376 regexp in the start of string and end of string anchors. 3382 regexp in the start of string and end of string anchors.
3377 3383
3378 For example, if the regular expression is <b>blue</b>, then match() 3384 For example, if the regular expression is <b>blue</b>, then match()
3379 returns TRUE only for input <tt>blue</tt>. For inputs 3385 returns TRUE only for input <tt>blue</tt>. For inputs
3380 <tt>bluebell</tt>, <tt>blutak</tt> and <tt>lightblue</tt>, match() 3386 <tt>bluebell</tt>, <tt>blutak</tt> and <tt>lightblue</tt>, match()
3381 returns FALSE and matchedLength() will return 4, 3 and 0 respectively. 3387 returns FALSE and matchedLength() will return 4, 3 and 0 respectively.
3382 3388
3383 \sa search() searchRev() QRegExpValidator 3389 \sa search() searchRev() QRegExpValidator
3384*/ 3390*/
3385bool QRegExp3::exactMatch( const QString& str ) 3391bool QRegExp3::exactMatch( const QString& str )
3386{ 3392{
3387#ifndef QT_NO_REGEXP_CAPTURE 3393#ifndef QT_NO_REGEXP_CAPTURE
3388 priv->t = str; 3394 priv->t = str;
3389 priv->capturedCache.clear(); 3395 priv->capturedCache.clear();
3390#endif 3396#endif
3391 3397
3392 priv->captured = eng->match( str, 0, priv->min, TRUE ); 3398 priv->captured = eng->match( str, 0, priv->min, TRUE );
3393 if ( priv->captured[1] == (int) str.length() ) { 3399 if ( priv->captured[1] == (int) str.length() ) {
3394 return TRUE; 3400 return TRUE;
3395 } else { 3401 } else {
3396 priv->captured.detach(); 3402 priv->captured.detach();
3397 priv->captured[0] = 0; 3403 priv->captured[0] = 0;
3398 priv->captured[1] = eng->matchedLength(); 3404 priv->captured[1] = eng->matchedLength();
3399 return FALSE; 3405 return FALSE;
3400 } 3406 }
3401} 3407}
3402 3408
3403/*! \overload 3409/*! \overload
3404 3410
3405 This version does not set matchedLength(), capturedTexts() and friends. 3411 This version does not set matchedLength(), capturedTexts() and friends.
3406*/ 3412*/
3407bool QRegExp3::exactMatch( const QString& str ) const 3413bool QRegExp3::exactMatch( const QString& str ) const
3408{ 3414{
3409 return eng->match(str, 0, priv->min, TRUE)[0] == 0 && 3415 return eng->match(str, 0, priv->min, TRUE)[0] == 0 &&
3410 eng->matchedLength() == (int) str.length(); 3416 eng->matchedLength() == (int) str.length();
3411} 3417}
3412 3418
3413/*! \obsolete 3419/*! \obsolete
3414 3420
3415 Attempts to match in \a str, starting from position \a index. Returns the 3421 Attempts to match in \a str, starting from position \a index. Returns the
3416 position of the match, or -1 if there was no match. 3422 position of the match, or -1 if there was no match.
3417 3423
3418 The length of the match is stored in \a *len, unless \a len is a null pointer. 3424 The length of the match is stored in \a *len, unless \a len is a null pointer.
3419 3425
3420 If \a indexIsStart is TRUE (the default), the position \a index in the string 3426 If \a indexIsStart is TRUE (the default), the position \a index in the string
3421 will match the start of string anchor, <b>^</b>, in the regexp, if present. 3427 will match the start of string anchor, <b>^</b>, in the regexp, if present.
3422 Otherwise, position 0 in \a str will match. 3428 Otherwise, position 0 in \a str will match.
3423 3429
3424 Use search() and matchedLength() instead of this function. 3430 Use search() and matchedLength() instead of this function.
3425 3431
3426 If you really need the \a indexIsStart functionality, try this: 3432 If you really need the \a indexIsStart functionality, try this:
3427 3433
3428 \code 3434 \code
3429 QRegExp3 rx( "some pattern" ); 3435 QRegExp3 rx( "some pattern" );
3430 int pos = rx.search( str.mid( index ) ); 3436 int pos = rx.search( str.mid( index ) );
3431 if ( pos != -1 ) 3437 if ( pos != -1 )
3432 pos += index; 3438 pos += index;
3433 int len = rx.matchedLength(); 3439 int len = rx.matchedLength();
3434 \endcode 3440 \endcode
3435*/ 3441*/
3436#ifndef QT_NO_COMPAT 3442#ifndef QT_NO_COMPAT
3437int QRegExp3::match( const QString& str, int index, int *len, 3443int QRegExp3::match( const QString& str, int index, int *len,
3438 bool indexIsStart ) 3444 bool indexIsStart )
3439{ 3445{
3440 int pos; 3446 int pos;
3441 if ( indexIsStart ) { 3447 if ( indexIsStart ) {
3442 pos = search( str.mid(index) ); 3448 pos = search( str.mid(index) );
3443 if ( pos >= 0 ) { 3449 if ( pos >= 0 ) {
3444 pos += index; 3450 pos += index;
3445 if ( len != 0 ) 3451 if ( len != 0 )
3446 *len = matchedLength(); 3452 *len = matchedLength();
3447 } else { 3453 } else {
3448 if ( len != 0 ) 3454 if ( len != 0 )
3449 *len = 0; 3455 *len = 0;
3450 } 3456 }
3451 } else { 3457 } else {
3452 pos = search( str, index ); 3458 pos = search( str, index );
3453 if ( len != 0 ) 3459 if ( len != 0 )
3454 *len = matchedLength(); 3460 *len = matchedLength();
3455 } 3461 }
3456 return pos; 3462 return pos;
3457} 3463}
3458#endif 3464#endif
3459 3465
3460/*! 3466/*!
3461 Attempts to find a match in \a str from position \a start (0 by default). If 3467 Attempts to find a match in \a str from position \a start (0 by default). If
3462 \a start is -1, the search starts at the last character; if -2, at the next to 3468 \a start is -1, the search starts at the last character; if -2, at the next to
3463 last character; etc. 3469 last character; etc.
3464 3470
3465 Returns the position of the first match, or -1 if there was no match. 3471 Returns the position of the first match, or -1 if there was no match.
3466 3472
3467 You might prefer to use QString::find(), QString::contains() or even 3473 You might prefer to use QString::find(), QString::contains() or even
3468 QStringList::grep(). To replace matches use QString::replace(). 3474 QStringList::grep(). To replace matches use QString::replace().
3469 3475
3470 Example: 3476 Example:
3471 \code 3477 \code
3472 QString str = "offsets: 1.23 .50 71.00 6.00"; 3478 QString str = "offsets: 1.23 .50 71.00 6.00";
3473 QRegExp3 rx( "\\d*\\.\\d+" ); // very simple floating point matching 3479 QRegExp3 rx( "\\d*\\.\\d+" ); // very simple floating point matching
3474 int count = 0; 3480 int count = 0;
3475 int pos = 0; 3481 int pos = 0;
3476 while ( pos >= 0 ) { 3482 while ( pos >= 0 ) {
3477 pos = rx.search( str, pos ); 3483 pos = rx.search( str, pos );
3478 count++; 3484 count++;
3479 } 3485 }
3480 // pos will be 9, 14, 18 and finally 24; count will end up as 4. 3486 // pos will be 9, 14, 18 and finally 24; count will end up as 4.
3481 \endcode 3487 \endcode
3482 3488
3483 \sa searchRev() match() matchedLength() capturedTexts() 3489 \sa searchRev() match() matchedLength() capturedTexts()
3484*/ 3490*/
3485// QChar versions 3491// QChar versions
3486 3492
3487#ifdef QCHAR_SUPPORT 3493#ifdef QCHAR_SUPPORT
3488const QString makeString(const QChar *str) 3494const QString makeString(const QChar *str)
3489{ 3495{
3490// A sentinel value checked in case the QChar *ptr is never null terminated 3496// A sentinel value checked in case the QChar *ptr is never null terminated
3491 const uint MAXLENGTH=65535; 3497 const uint MAXLENGTH=65535;
3492 3498
3493 const QChar *s=str; 3499 const QChar *s=str;
3494 uint i=0; 3500 uint i=0;
3495 while(i < MAXLENGTH && *s != QChar::null) { i++;s++ ;} 3501 while(i < MAXLENGTH && *s != QChar::null) { i++;s++ ;}
3496 return QString(str,i); 3502 return QString(str,i);
3497 3503
3498} 3504}
3499int QRegExp3::search(const QChar *str,int start) 3505int QRegExp3::search(const QChar *str,int start)
3500{ 3506{
3501 return search(makeString(str),start); 3507 return search(makeString(str),start);
3502} 3508}
3503int QRegExp3::search(const QChar *str,int start) const 3509int QRegExp3::search(const QChar *str,int start) const
3504{ 3510{
3505 return search(makeString(str),start); 3511 return search(makeString(str),start);
3506} 3512}
3507int QRegExp3::searchRev(const QChar *str,int start) 3513int QRegExp3::searchRev(const QChar *str,int start)
3508{ 3514{
3509 return searchRev(makeString(str),start); 3515 return searchRev(makeString(str),start);
3510} 3516}
3511int QRegExp3::searchRev(const QChar *str,int start) const 3517int QRegExp3::searchRev(const QChar *str,int start) const
3512{ 3518{
3513 return searchRev(makeString(str),start); 3519 return searchRev(makeString(str),start);
3514} 3520}
3515bool QRegExp3::exactMatch(const QChar *str) 3521bool QRegExp3::exactMatch(const QChar *str)
3516{ 3522{
3517 return exactMatch(makeString(str)); 3523 return exactMatch(makeString(str));
3518} 3524}
3519bool QRegExp3::exactMatch(const QChar *str) const 3525bool QRegExp3::exactMatch(const QChar *str) const
3520{ 3526{
3521 return exactMatch(makeString(str)); 3527 return exactMatch(makeString(str));
3522} 3528}
3523#endif // QCHAR_SUPPORT 3529#endif // QCHAR_SUPPORT
3524 3530
3525int QRegExp3::search( const QString& str, int start ) 3531int QRegExp3::search( const QString& str, int start )
3526{ 3532{
3527 if ( start < 0 ) 3533 if ( start < 0 )
3528 start += str.length(); 3534 start += str.length();
3529#ifndef QT_NO_REGEXP_CAPTURE 3535#ifndef QT_NO_REGEXP_CAPTURE
3530 priv->t = str; 3536 priv->t = str;
3531 priv->capturedCache.clear(); 3537 priv->capturedCache.clear();
3532#endif 3538#endif
3533 priv->captured = eng->match( str, start, priv->min, FALSE ); 3539 priv->captured = eng->match( str, start, priv->min, FALSE );
3534 return priv->captured[0]; 3540 return priv->captured[0];
3535} 3541}
3536 3542
3537/*! \overload 3543/*! \overload
3538 3544
3539 This version does not set matchedLength(), capturedTexts() and friends. 3545 This version does not set matchedLength(), capturedTexts() and friends.
3540*/ 3546*/
3541int QRegExp3::search( const QString& str, int start ) const 3547int QRegExp3::search( const QString& str, int start ) const
3542{ 3548{
3543 if ( start < 0 ) 3549 if ( start < 0 )
3544 start += str.length(); 3550 start += str.length();
3545 return eng->match( str, start, priv->min, FALSE )[0]; 3551 return eng->match( str, start, priv->min, FALSE )[0];
3546} 3552}
3547 3553
3548/*! 3554/*!
3549 Attempts to find a match backwards in \a str from position \a start. If 3555 Attempts to find a match backwards in \a str from position \a start. If
3550 \a start is -1 (the default), the search starts at the last character; if -2, 3556 \a start is -1 (the default), the search starts at the last character; if -2,
3551 at the next to last character; etc. 3557 at the next to last character; etc.
3552 3558
3553 Returns the position of the first match, or -1 if there was no match. 3559 Returns the position of the first match, or -1 if there was no match.
3554 3560
3555 You might prefer to use QString::findRev(). 3561 You might prefer to use QString::findRev().
3556 3562
3557 \sa search() matchedLength() capturedTexts() 3563 \sa search() matchedLength() capturedTexts()
3558*/ 3564*/
3559int QRegExp3::searchRev( const QString& str, int start ) 3565int QRegExp3::searchRev( const QString& str, int start )
3560{ 3566{
3561 if ( start < 0 ) 3567 if ( start < 0 )
3562 start += str.length(); 3568 start += str.length();
3563#ifndef QT_NO_REGEXP_CAPTURE 3569#ifndef QT_NO_REGEXP_CAPTURE
3564 priv->t = str; 3570 priv->t = str;
3565 priv->capturedCache.clear(); 3571 priv->capturedCache.clear();
3566#endif 3572#endif
3567 if ( start < 0 || start > (int) str.length() ) { 3573 if ( start < 0 || start > (int) str.length() ) {
3568 priv->captured.detach(); 3574 priv->captured.detach();
3569 priv->captured.fill( -1 ); 3575 priv->captured.fill( -1 );
3570 return -1; 3576 return -1;
3571 } 3577 }
3572 3578
3573 while ( start >= 0 ) { 3579 while ( start >= 0 ) {
3574 priv->captured = eng->match( str, start, priv->min, TRUE ); 3580 priv->captured = eng->match( str, start, priv->min, TRUE );
3575 if ( priv->captured[0] == start ) 3581 if ( priv->captured[0] == start )
3576 return start; 3582 return start;
3577 start--; 3583 start--;
3578 } 3584 }
3579 return -1; 3585 return -1;
3580} 3586}
3581 3587
3582/*! \overload 3588/*! \overload
3583 3589
3584 This version does not set matchedLength(), capturedText() and friends. 3590 This version does not set matchedLength(), capturedText() and friends.
3585*/ 3591*/
3586int QRegExp3::searchRev( const QString& str, int start ) const 3592int QRegExp3::searchRev( const QString& str, int start ) const
3587{ 3593{
3588 if ( start < 0 ) 3594 if ( start < 0 )
3589 start += str.length(); 3595 start += str.length();
3590 if ( start < 0 || start > (int) str.length() ) 3596 if ( start < 0 || start > (int) str.length() )
3591 return -1; 3597 return -1;
3592 3598
3593 while ( start >= 0 ) { 3599 while ( start >= 0 ) {
3594 if ( eng->match(str, start, priv->min, TRUE)[0] == start ) 3600 if ( eng->match(str, start, priv->min, TRUE)[0] == start )
3595 return start; 3601 return start;
3596 start--; 3602 start--;
3597 } 3603 }
3598 return -1; 3604 return -1;
3599} 3605}
3600 3606
3601/*! 3607/*!
3602 Returns the length of the last matched string, or -1 if there was no match. 3608 Returns the length of the last matched string, or -1 if there was no match.
3603 3609
3604 \sa match() search() 3610 \sa match() search()
3605*/ 3611*/
3606int QRegExp3::matchedLength() 3612int QRegExp3::matchedLength()
3607{ 3613{
3608 return priv->captured[1]; 3614 return priv->captured[1];
3609} 3615}
3610 3616
3611#ifndef QT_NO_REGEXP_CAPTURE 3617#ifndef QT_NO_REGEXP_CAPTURE
3612/*! 3618/*!
3613 Returns a list of the captured text strings. 3619 Returns a list of the captured text strings.
3614 3620
3615 The first string in the list is the entire matched string. Each 3621 The first string in the list is the entire matched string. Each
3616 subsequent list element contains a string that matched a 3622 subsequent list element contains a string that matched a
3617 (capturing) subexpression of the regexp. 3623 (capturing) subexpression of the regexp.
3618 3624
3619 For example: 3625 For example:
3620 \code 3626 \code
3621 QRegExp3 rx( "(\\d+)(\\s*)(cm|inch(es)?)" ); 3627 QRegExp3 rx( "(\\d+)(\\s*)(cm|inch(es)?)" );
3622 int pos = rx.search( "Length: 36 inches" ); 3628 int pos = rx.search( "Length: 36 inches" );
3623 QStringList list = rx.capturedTexts(); 3629 QStringList list = rx.capturedTexts();
3624 // list is now ( "36 inches", "36", " ", "inches", "es" ). 3630 // list is now ( "36 inches", "36", " ", "inches", "es" ).
3625 \endcode 3631 \endcode
3626 3632
3627 The above example also captures elements 3633 The above example also captures elements
3628 that may be present but which we have no interest in. This problem 3634 that may be present but which we have no interest in. This problem
3629 can be solved by using non-capturing parenthesis: 3635 can be solved by using non-capturing parenthesis:
3630 3636
3631 \code 3637 \code
3632 QRegExp3 rx( "(\\d+)(?:\\s*)(cm|inch(?:es)?)" ); 3638 QRegExp3 rx( "(\\d+)(?:\\s*)(cm|inch(?:es)?)" );
3633 int pos = rx.search( "Length: 36 inches" ); 3639 int pos = rx.search( "Length: 36 inches" );
3634 QStringList list = rx.capturedTexts(); 3640 QStringList list = rx.capturedTexts();
3635 // list is now ( "36 inches", "36", "inches" ). 3641 // list is now ( "36 inches", "36", "inches" ).
3636 \endcode 3642 \endcode
3637 3643
3638 Some regexps can match an indeterminate number of times. For example 3644 Some regexps can match an indeterminate number of times. For example
3639 if the input string is "Offsets: 12 14 99 231 7" and the regexp, 3645 if the input string is "Offsets: 12 14 99 231 7" and the regexp,
3640 <tt>rx</tt>, is <b>(</b><b>\\</b><b>d+)+</b>, we would hope to get a 3646 <tt>rx</tt>, is <b>(</b><b>\\</b><b>d+)+</b>, we would hope to get a
3641 list of all the numbers matched. However, after calling 3647 list of all the numbers matched. However, after calling
3642 <tt>rx.search(str)</tt>, capturedTexts() will return the list ( "12", 3648 <tt>rx.search(str)</tt>, capturedTexts() will return the list ( "12",
3643 "12" ), i.e. the entire match was "12" and the first subexpression 3649 "12" ), i.e. the entire match was "12" and the first subexpression
3644 matched was "12". The correct approach is to use cap() in a 3650 matched was "12". The correct approach is to use cap() in a
3645 <a href="#cap_in_a_loop">loop</a>. 3651 <a href="#cap_in_a_loop">loop</a>.
3646 3652
3647 The order of elements in the string list is as follows. The first 3653 The order of elements in the string list is as follows. The first
3648 element is the entire matching string. Each subsequent element 3654 element is the entire matching string. Each subsequent element
3649 corresponds to the next capturing open left parenthesis. Thus 3655 corresponds to the next capturing open left parenthesis. Thus
3650 capturedTexts()[1] is the text of the first capturing parenthesis, 3656 capturedTexts()[1] is the text of the first capturing parenthesis,
3651 capturedTexts()[2] is the text of the second and so on (corresponding 3657 capturedTexts()[2] is the text of the second and so on (corresponding
3652 to $1, $2 etc. in some other regexp languages). 3658 to $1, $2 etc. in some other regexp languages).
3653 3659
3654 \sa cap() pos() 3660 \sa cap() pos()
3655*/ 3661*/
3656QStringList QRegExp3::capturedTexts() 3662QStringList QRegExp3::capturedTexts()
3657{ 3663{
3658 if ( priv->capturedCache.isEmpty() ) { 3664 if ( priv->capturedCache.isEmpty() ) {
3659 for ( int i = 0; i < (int) priv->captured.size(); i += 2 ) { 3665 for ( int i = 0; i < (int) priv->captured.size(); i += 2 ) {
3660 QString m; 3666 QString m;
3661 if ( priv->captured[i + 1] == 0 ) 3667 if ( priv->captured[i + 1] == 0 )
3662 m = QString::fromLatin1( "" ); 3668 m = QString::fromLatin1( "" );
3663 else if ( priv->captured[i] >= 0 ) 3669 else if ( priv->captured[i] >= 0 )
3664 m = priv->t.mid( priv->captured[i], 3670 m = priv->t.mid( priv->captured[i],
3665 priv->captured[i + 1] ); 3671 priv->captured[i + 1] );
3666 priv->capturedCache.append( m ); 3672 priv->capturedCache.append( m );
3667 } 3673 }
3668 priv->t = QString::null; 3674 priv->t = QString::null;
3669 } 3675 }
3670 return priv->capturedCache; 3676 return priv->capturedCache;
3671} 3677}
3672 3678
3673/*! Returns the text captured by the \a nth subexpression. The entire match 3679/*! Returns the text captured by the \a nth subexpression. The entire match
3674 has index 0 and the parenthesised subexpressions have indices starting 3680 has index 0 and the parenthesised subexpressions have indices starting
3675 from 1 (excluding non-capturing parenthesis). 3681 from 1 (excluding non-capturing parenthesis).
3676 3682
3677 \code 3683 \code
3678 QRegExp3 rxlen( "(\\d+)(?:\\s*)(cm|inch)" ); 3684 QRegExp3 rxlen( "(\\d+)(?:\\s*)(cm|inch)" );
3679 int pos = rxlen.search( "Length: 189cm" ); 3685 int pos = rxlen.search( "Length: 189cm" );
3680 if ( pos > -1 ) { 3686 if ( pos > -1 ) {
3681 QString value = rxlen.cap( 1 );// "189" 3687 QString value = rxlen.cap( 1 ); // "189"
3682 QString unit = rxlen.cap( 2 ); // "cm" 3688 QString unit = rxlen.cap( 2 ); // "cm"
3683 // ... 3689 // ...
3684 } 3690 }
3685 \endcode 3691 \endcode
3686 3692
3687 <a name="cap_in_a_loop"> 3693 <a name="cap_in_a_loop">
3688 Some patterns may lead to a number of matches which cannot be 3694 Some patterns may lead to a number of matches which cannot be
3689 determined in advance, for example:</a> 3695 determined in advance, for example:</a>
3690 3696
3691 \code 3697 \code
3692 QRegExp3 rx( "(\\d+)" ); 3698 QRegExp3 rx( "(\\d+)" );
3693 str = "Offsets: 12 14 99 231 7"; 3699 str = "Offsets: 12 14 99 231 7";
3694 QStringList list; 3700 QStringList list;
3695 pos = 0; 3701 pos = 0;
3696 while ( pos >= 0 ) { 3702 while ( pos >= 0 ) {
3697 pos = rx.search( str, pos ); 3703 pos = rx.search( str, pos );
3698 if ( pos > -1 ) { 3704 if ( pos > -1 ) {
3699 list += rx.cap( 1 ); 3705 list += rx.cap( 1 );
3700 pos += rx.matchedLength(); 3706 pos += rx.matchedLength();
3701 } 3707 }
3702 } 3708 }
3703 // list contains: ( "12", "14", "99", "231", "7" ). 3709 // list contains: ( "12", "14", "99", "231", "7" ).
3704 \endcode 3710 \endcode
3705 3711
3706 The order of elements matched by cap() is as follows. The first 3712 The order of elements matched by cap() is as follows. The first
3707 element, cap( 0 ), is the entire matching string. Each subsequent 3713 element, cap( 0 ), is the entire matching string. Each subsequent
3708 element corresponds to the next capturing open left parenthesis. Thus 3714 element corresponds to the next capturing open left parenthesis. Thus
3709 cap( 1 ) is the text of the first capturing parenthesis, cap( 2 ) is 3715 cap( 1 ) is the text of the first capturing parenthesis, cap( 2 ) is
3710 the text of the second and so on. 3716 the text of the second and so on.
3711 3717
3712 \sa search() pos() capturedTexts() 3718 \sa search() pos() capturedTexts()
3713*/ 3719*/
3714QString QRegExp3::cap( int nth ) 3720QString QRegExp3::cap( int nth )
3715{ 3721{
3716 if ( nth < 0 || nth >= (int) priv->captured.size() / 2 ) 3722 if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
3717 return QString::null; 3723 return QString::null;
3718 else 3724 else
3719 return capturedTexts()[nth]; 3725 return capturedTexts()[nth];
3720} 3726}
3721 3727
3722/*! Returns the position of the \a nth captured text in the 3728/*! Returns the position of the \a nth captured text in the
3723 searched string. If \a nth is 0 (the default), pos() returns the 3729 searched string. If \a nth is 0 (the default), pos() returns the
3724 position of the whole match. 3730 position of the whole match.
3725 3731
3726 Example: 3732 Example:
3727 \code 3733 \code
3728 QRegExp3 rx( "/([a-z]+)/([a-z]+)" ); 3734 QRegExp3 rx( "/([a-z]+)/([a-z]+)" );
3729 rx.search( "Output /dev/null" );// Returns 7 (position of /dev/null) 3735 rx.search( "Output /dev/null" ); // Returns 7 (position of /dev/null)
3730 rx.pos( 0 ); // Returns 7 (position of /dev/null) 3736 rx.pos( 0 ); // Returns 7 (position of /dev/null)
3731 rx.pos( 1 ); // Returns 8 (position of dev) 3737 rx.pos( 1 ); // Returns 8 (position of dev)
3732 rx.pos( 2 ); // Returns 12 (position of null) 3738 rx.pos( 2 ); // Returns 12 (position of null)
3733 \endcode 3739 \endcode
3734 3740
3735 Note that pos() returns -1 for zero-length matches. (For example, if 3741 Note that pos() returns -1 for zero-length matches. (For example, if
3736 cap(4) would return an empty string, pos(4) returns -1.) This is due 3742 cap(4) would return an empty string, pos(4) returns -1.) This is due
3737 to an implementation tradeoff. 3743 to an implementation tradeoff.
3738 3744
3739 \sa capturedTexts() cap() 3745 \sa capturedTexts() cap()
3740*/ 3746*/
3741int QRegExp3::pos( int nth ) 3747int QRegExp3::pos( int nth )
3742{ 3748{
3743 if ( nth < 0 || nth >= (int) priv->captured.size() / 2 ) 3749 if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
3744 return -1; 3750 return -1;
3745 else 3751 else
3746 return priv->captured[2 * nth]; 3752 return priv->captured[2 * nth];
3747} 3753}
3748#endif 3754#endif
3749 3755
3750void QRegExp3::compile( bool caseSensitive ) 3756void QRegExp3::compile( bool caseSensitive )
3751{ 3757{
3752 derefEngine( eng, priv->rxpattern ); 3758 derefEngine( eng, priv->rxpattern );
3753#ifndef QT_NO_REGEXP_WILDCARD 3759#ifndef QT_NO_REGEXP_WILDCARD
3754 if ( priv->wc ) 3760 if ( priv->wc )
3755 priv->rxpattern = wc2rx( priv->pattern ); 3761 priv->rxpattern = wc2rx( priv->pattern );
3756 else 3762 else
3757#endif 3763#endif
3758 priv->rxpattern = priv->pattern.isNull() ? QString::fromLatin1( "" ) 3764 priv->rxpattern = priv->pattern.isNull() ? QString::fromLatin1( "" )
3759 : priv->pattern; 3765 : priv->pattern;
3760 eng = newEngine( priv->rxpattern, caseSensitive ); 3766 eng = newEngine( priv->rxpattern, caseSensitive );
3761#ifndef QT_NO_REGEXP_CAPTURE 3767#ifndef QT_NO_REGEXP_CAPTURE
3762 priv->t = QString::null; 3768 priv->t = QString::null;
3763 priv->capturedCache.clear(); 3769 priv->capturedCache.clear();
3764#endif 3770#endif
3765 priv->captured.detach(); 3771 priv->captured.detach();
3766 priv->captured.fill( -1, 2 + 2 * eng->numCaptures() ); 3772 priv->captured.fill( -1, 2 + 2 * eng->numCaptures() );
3767} 3773}