summaryrefslogtreecommitdiff
path: root/qmake/tools
authorkergoth <kergoth>2002-11-01 00:10:42 (UTC)
committer kergoth <kergoth>2002-11-01 00:10:42 (UTC)
commit5042e3cf0d3514552769e441f5aad590c8eaf967 (patch) (unidiff)
tree4a5ea45f3519d981a172ab5275bf38c6fa778dec /qmake/tools
parent108c1c753e74e989cc13923086996791428c9af4 (diff)
downloadopie-5042e3cf0d3514552769e441f5aad590c8eaf967.zip
opie-5042e3cf0d3514552769e441f5aad590c8eaf967.tar.gz
opie-5042e3cf0d3514552769e441f5aad590c8eaf967.tar.bz2
Adding qmake in preperation for new build system
Diffstat (limited to 'qmake/tools') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qbitarray.cpp661
-rw-r--r--qmake/tools/qbuffer.cpp495
-rw-r--r--qmake/tools/qcomlibrary.cpp538
-rw-r--r--qmake/tools/qcomponentfactory.cpp352
-rw-r--r--qmake/tools/qconfig.cpp17
-rw-r--r--qmake/tools/qcriticalsection_p.cpp75
-rw-r--r--qmake/tools/qcstring.cpp2474
-rw-r--r--qmake/tools/qdatastream.cpp1024
-rw-r--r--qmake/tools/qdatetime.cpp2490
-rw-r--r--qmake/tools/qdeepcopy.cpp165
-rw-r--r--qmake/tools/qdir.cpp1294
-rw-r--r--qmake/tools/qdir_unix.cpp291
-rw-r--r--qmake/tools/qfile.cpp614
-rw-r--r--qmake/tools/qfile_unix.cpp687
-rw-r--r--qmake/tools/qfileinfo.cpp659
-rw-r--r--qmake/tools/qfileinfo_unix.cpp331
-rw-r--r--qmake/tools/qgarray.cpp754
-rw-r--r--qmake/tools/qgcache.cpp863
-rw-r--r--qmake/tools/qgdict.cpp1146
-rw-r--r--qmake/tools/qglist.cpp1255
-rw-r--r--qmake/tools/qglobal.cpp835
-rw-r--r--qmake/tools/qgpluginmanager.cpp544
-rw-r--r--qmake/tools/qgvector.cpp584
-rw-r--r--qmake/tools/qiodevice.cpp755
-rw-r--r--qmake/tools/qlibrary.cpp343
-rw-r--r--qmake/tools/qlibrary_unix.cpp163
-rw-r--r--qmake/tools/qmap.cpp254
-rw-r--r--qmake/tools/qmutex_unix.cpp687
-rw-r--r--qmake/tools/qmutexpool.cpp130
-rw-r--r--qmake/tools/qptrcollection.cpp180
-rw-r--r--qmake/tools/qregexp.cpp3935
-rw-r--r--qmake/tools/qsemaphore_unix.cpp292
-rw-r--r--qmake/tools/qsettings.cpp1955
-rw-r--r--qmake/tools/qstring.cpp17867
-rw-r--r--qmake/tools/qstringlist.cpp376
-rw-r--r--qmake/tools/qtextstream.cpp2593
-rw-r--r--qmake/tools/qucom.cpp668
-rw-r--r--qmake/tools/quuid.cpp230
-rw-r--r--qmake/tools/qwaitcondition_unix.cpp310
39 files changed, 48886 insertions, 0 deletions
diff --git a/qmake/tools/qbitarray.cpp b/qmake/tools/qbitarray.cpp
new file mode 100644
index 0000000..4f4e14b
--- a/dev/null
+++ b/qmake/tools/qbitarray.cpp
@@ -0,0 +1,661 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QBitArray class
5**
6** Created : 940118
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qbitarray.h"
39#include "qdatastream.h"
40
41 #define SHBLOCK ((bitarr_data*)(sharedBlock()))
42
43
44/*!
45 \class QBitVal qbitarray.h
46 \reentrant
47 \brief The QBitVal class is an internal class, used with QBitArray.
48
49 \ingroup collection
50
51 The QBitVal is required by the indexing [] operator on bit arrays.
52 It is not for use in any other context.
53*/
54
55/*!
56 \fn QBitVal::QBitVal (QBitArray* a, uint i)
57
58 Constructs a reference to element \a i in the QBitArray \a a.
59 This is what QBitArray::operator[] constructs its return value
60 with.
61*/
62
63/*!
64 \fn QBitVal::operator int()
65
66 Returns the value referenced by the QBitVal.
67*/
68
69/*!
70 \fn QBitVal& QBitVal::operator= (const QBitVal& v)
71
72 Sets the value referenced by the QBitVal to that referenced by
73 QBitVal \a v.
74*/
75
76/*!
77 \overload QBitVal& QBitVal::operator= (bool v)
78
79 Sets the value referenced by the QBitVal to \a v.
80*/
81
82
83/*!
84 \class QBitArray qbitarray.h
85 \reentrant
86 \brief The QBitArray class provides an array of bits.
87
88 \ingroup collection
89 \ingroup tools
90 \ingroup shared
91
92 Because QBitArray is a QMemArray, it uses explicit \link
93 shclass.html sharing\endlink with a reference count.
94
95 A QBitArray is a special byte array that can access individual
96 bits and perform bit-operations (AND, OR, XOR and NOT) on entire
97 arrays or bits.
98
99 Bits can be manipulated by the setBit() and clearBit() functions,
100 but it is also possible to use the indexing [] operator to test
101 and set individual bits. The [] operator is a little slower than
102 setBit() and clearBit() because some tricks are required to
103 implement single-bit assignments.
104
105 Example:
106 \code
107 QBitArray a(3);
108 a.setBit( 0 );
109 a.clearBit( 1 );
110 a.setBit( 2 ); // a = [1 0 1]
111
112 QBitArray b(3);
113 b[0] = 1;
114 b[1] = 1;
115 b[2] = 0; // b = [1 1 0]
116
117 QBitArray c;
118 c = ~a & b; // c = [0 1 0]
119 \endcode
120
121 When a QBitArray is constructed the bits are uninitialized. Use
122 fill() to set all the bits to 0 or 1. The array can be resized
123 with resize() and copied with copy(). Bits can be set with
124 setBit() and cleared with clearBit(). Bits can be toggled with
125 toggleBit(). A bit's value can be obtained with testBit() and with
126 at().
127
128 QBitArray supports the \& (AND), | (OR), ^ (XOR) and ~ (NOT)
129 operators.
130*/
131
132/*! \class QBitArray::bitarr_data
133 \brief The QBitArray::bitarr_data class is internal.
134 \internal
135*/
136
137
138/*!
139 Constructs an empty bit array.
140*/
141
142QBitArray::QBitArray() : QByteArray( 0, 0 )
143{
144 bitarr_data *x = new bitarr_data;
145 Q_CHECK_PTR( x );
146 x->nbits = 0;
147 setSharedBlock( x );
148}
149
150/*!
151 Constructs a bit array of \a size bits. The bits are uninitialized.
152
153 \sa fill()
154*/
155
156QBitArray::QBitArray( uint size ) : QByteArray( 0, 0 )
157{
158 bitarr_data *x = new bitarr_data;
159 Q_CHECK_PTR( x );
160 x->nbits = 0;
161 setSharedBlock( x );
162 resize( size );
163}
164
165/*!
166 \fn QBitArray::QBitArray( const QBitArray &a )
167
168 Constructs a shallow copy of \a a.
169*/
170
171/*!
172 \fn QBitArray &QBitArray::operator=( const QBitArray &a )
173
174 Assigns a shallow copy of \a a to this bit array and returns a
175 reference to this array.
176*/
177
178
179/*!
180 Pad last byte with 0-bits.
181*/
182void QBitArray::pad0()
183{
184 uint sz = size();
185 if ( sz && sz%8 )
186 *(data()+sz/8) &= (1 << (sz%8)) - 1;
187}
188
189
190/*!
191 \fn uint QBitArray::size() const
192
193 Returns the bit array's size (number of bits).
194
195 \sa resize()
196*/
197
198/*!
199 Resizes the bit array to \a size bits and returns TRUE if the bit
200 array could be resized; otherwise returns FALSE.
201
202 If the array is expanded, the new bits are set to 0.
203
204 \sa size()
205*/
206
207bool QBitArray::resize( uint size )
208{
209 uint s = this->size();
210 if ( !QByteArray::resize( (size+7)/8 ) )
211 return FALSE; // cannot resize
212 SHBLOCK->nbits = size;
213 if ( size != 0 ) { // not null array
214 int ds = (int)(size+7)/8 - (int)(s+7)/8;// number of bytes difference
215 if ( ds > 0 ) // expanding array
216 memset( data() + (s+7)/8, 0, ds );// reset new data
217 }
218 return TRUE;
219}
220
221
222/*!
223 Fills the bit array with \a v (1's if \a v is TRUE, or 0's if \a v
224 is FALSE).
225
226 fill() resizes the bit array to \a size bits if \a size is
227 nonnegative.
228
229 Returns FALSE if a nonnegative \e size was specified and the bit
230 array could not be resized; otherwise returns TRUE.
231
232 \sa resize()
233*/
234
235bool QBitArray::fill( bool v, int size )
236{
237 if ( size >= 0 ) { // resize first
238 if ( !resize( size ) )
239 return FALSE; // cannot resize
240 } else {
241 size = this->size();
242 }
243 if ( size > 0 )
244 memset( data(), v ? 0xff : 0, (size + 7) / 8 );
245 if ( v )
246 pad0();
247 return TRUE;
248}
249
250
251/*!
252 Detaches from shared bit array data and makes sure that this bit
253 array is the only one referring to the data.
254
255 If multiple bit arrays share common data, this bit array
256 dereferences the data and gets a copy of the data. Nothing happens
257 if there is only a single reference.
258
259 \sa copy()
260*/
261
262void QBitArray::detach()
263{
264 int nbits = SHBLOCK->nbits;
265 this->duplicate( *this );
266 SHBLOCK->nbits = nbits;
267}
268
269/*!
270 Returns a deep copy of the bit array.
271
272 \sa detach()
273*/
274
275QBitArray QBitArray::copy() const
276{
277 QBitArray tmp;
278 tmp.duplicate( *this );
279 ((bitarr_data*)(tmp.sharedBlock()))->nbits = SHBLOCK->nbits;
280 return tmp;
281}
282
283
284/*!
285 Returns TRUE if the bit at position \a index is set, i.e. is 1;
286 otherwise returns FALSE.
287
288 \sa setBit(), clearBit()
289*/
290
291bool QBitArray::testBit( uint index ) const
292{
293#if defined(QT_CHECK_RANGE)
294 if ( index >= size() ) {
295 qWarning( "QBitArray::testBit: Index %d out of range", index );
296 return FALSE;
297 }
298#endif
299 return (*(data()+(index>>3)) & (1 << (index & 7))) != 0;
300}
301
302/*!
303 \overload
304
305 Sets the bit at position \a index to 1.
306
307 \sa clearBit() toggleBit()
308*/
309
310void QBitArray::setBit( uint index )
311{
312#if defined(QT_CHECK_RANGE)
313 if ( index >= size() ) {
314 qWarning( "QBitArray::setBit: Index %d out of range", index );
315 return;
316 }
317#endif
318 *(data()+(index>>3)) |= (1 << (index & 7));
319}
320
321/*!
322 \fn void QBitArray::setBit( uint index, bool value )
323
324 Sets the bit at position \a index to \a value.
325
326 Equivalent to:
327 \code
328 if ( value )
329 setBit( index );
330 else
331 clearBit( index );
332 \endcode
333
334 \sa clearBit() toggleBit()
335*/
336
337/*!
338 Clears the bit at position \a index, i.e. sets it to 0.
339
340 \sa setBit(), toggleBit()
341*/
342
343void QBitArray::clearBit( uint index )
344{
345#if defined(QT_CHECK_RANGE)
346 if ( index >= size() ) {
347 qWarning( "QBitArray::clearBit: Index %d out of range", index );
348 return;
349 }
350#endif
351 *(data()+(index>>3)) &= ~(1 << (index & 7));
352}
353
354/*!
355 Toggles the bit at position \a index.
356
357 If the previous value was 0, the new value will be 1. If the
358 previous value was 1, the new value will be 0.
359
360 \sa setBit(), clearBit()
361*/
362
363bool QBitArray::toggleBit( uint index )
364{
365#if defined(QT_CHECK_RANGE)
366 if ( index >= size() ) {
367 qWarning( "QBitArray::toggleBit: Index %d out of range", index );
368 return FALSE;
369 }
370#endif
371 register uchar *p = (uchar *)data() + (index>>3);
372 uchar b = (1 << (index & 7)); // bit position
373 uchar c = *p & b; // read bit
374 *p ^= b; // toggle bit
375 return c;
376}
377
378
379/*!
380 \fn bool QBitArray::at( uint index ) const
381
382 Returns the value (0 or 1) of the bit at position \a index.
383
384 \sa operator[]()
385*/
386
387/*!
388 \fn QBitVal QBitArray::operator[]( int index )
389
390 Implements the [] operator for bit arrays.
391
392 The returned QBitVal is a context object. It makes it possible to
393 get and set a single bit value by its \a index position.
394
395 Example:
396 \code
397 QBitArray a( 3 );
398 a[0] = 0;
399 a[1] = 1;
400 a[2] = a[0] ^ a[1];
401 \endcode
402
403 The functions testBit(), setBit() and clearBit() are faster.
404
405 \sa at()
406*/
407
408/*!
409 \overload bool QBitArray::operator[]( int index ) const
410
411 Implements the [] operator for constant bit arrays.
412*/
413
414
415/*!
416 Performs the AND operation between all bits in this bit array and
417 \a a. Returns a reference to this bit array.
418
419 The result has the length of the longest of the two bit arrays,
420 with any missing bits (i.e. if one array is shorter than the
421 other), taken to be 0.
422 \code
423 QBitArray a( 3 ), b( 2 );
424 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
425 b[0] = 1; b[1] = 0; // b = [1 0]
426 a &= b; // a = [1 0 0]
427 \endcode
428
429 \sa operator|=(), operator^=(), operator~()
430*/
431
432QBitArray &QBitArray::operator&=( const QBitArray &a )
433{
434 resize( QMAX(size(), a.size()) );
435 register uchar *a1 = (uchar *)data();
436 register uchar *a2 = (uchar *)a.data();
437 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
438 int p = QMAX( QByteArray::size(), a.QByteArray::size() ) - n;
439 while ( n-- > 0 )
440 *a1++ &= *a2++;
441 while ( p-- > 0 )
442 *a1++ = 0;
443 return *this;
444}
445
446/*!
447 Performs the OR operation between all bits in this bit array and
448 \a a. Returns a reference to this bit array.
449
450 The result has the length of the longest of the two bit arrays,
451 with any missing bits (i.e. if one array is shorter than the
452 other), taken to be 0.
453 \code
454 QBitArray a( 3 ), b( 2 );
455 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
456 b[0] = 1; b[1] = 0; // b = [1 0]
457 a |= b; // a = [1 0 1]
458 \endcode
459
460 \sa operator&=(), operator^=(), operator~()
461*/
462
463QBitArray &QBitArray::operator|=( const QBitArray &a )
464{
465 resize( QMAX(size(), a.size()) );
466 register uchar *a1 = (uchar *)data();
467 register uchar *a2 = (uchar *)a.data();
468 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
469 while ( n-- > 0 )
470 *a1++ |= *a2++;
471 return *this;
472}
473
474/*!
475 Performs the XOR operation between all bits in this bit array and
476 \a a. Returns a reference to this bit array.
477
478 The result has the length of the longest of the two bit arrays,
479 with any missing bits (i.e. if one array is shorter than the
480 other), taken to be 0.
481 \code
482 QBitArray a( 3 ), b( 2 );
483 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
484 b[0] = 1; b[1] = 0; // b = [1 0]
485 a ^= b; // a = [0 0 1]
486 \endcode
487
488 \sa operator&=(), operator|=(), operator~()
489*/
490
491QBitArray &QBitArray::operator^=( const QBitArray &a )
492{
493 resize( QMAX(size(), a.size()) );
494 register uchar *a1 = (uchar *)data();
495 register uchar *a2 = (uchar *)a.data();
496 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
497 while ( n-- > 0 )
498 *a1++ ^= *a2++;
499 return *this;
500}
501
502/*!
503 Returns a bit array that contains the inverted bits of this bit array.
504
505 Example:
506 \code
507 QBitArray a( 3 ), b;
508 a[0] = 1; a[1] = 0; a[2] = 1;// a = [1 0 1]
509 b = ~a; // b = [0 1 0]
510 \endcode
511*/
512
513QBitArray QBitArray::operator~() const
514{
515 QBitArray a( size() );
516 register uchar *a1 = (uchar *)data();
517 register uchar *a2 = (uchar *)a.data();
518 int n = QByteArray::size();
519 while ( n-- )
520 *a2++ = ~*a1++;
521 a.pad0();
522 return a;
523}
524
525
526/*!
527 \relates QBitArray
528
529 Returns the AND result between the bit arrays \a a1 and \a a2.
530
531 The result has the length of the longest of the two bit arrays,
532 with any missing bits (i.e. if one array is shorter than the
533 other), taken to be 0.
534
535 \sa QBitArray::operator&=()
536*/
537
538QBitArray operator&( const QBitArray &a1, const QBitArray &a2 )
539{
540 QBitArray tmp = a1.copy();
541 tmp &= a2;
542 return tmp;
543}
544
545/*!
546 \relates QBitArray
547
548 Returns the OR result between the bit arrays \a a1 and \a a2.
549
550 The result has the length of the longest of the two bit arrays,
551 with any missing bits (i.e. if one array is shorter than the
552 other), taken to be 0.
553
554 \sa QBitArray::operator|=()
555*/
556
557QBitArray operator|( const QBitArray &a1, const QBitArray &a2 )
558{
559 QBitArray tmp = a1.copy();
560 tmp |= a2;
561 return tmp;
562}
563
564/*!
565 \relates QBitArray
566
567 Returns the XOR result between the bit arrays \a a1 and \a a2.
568
569 The result has the length of the longest of the two bit arrays,
570 with any missing bits (i.e. if one array is shorter than the
571 other), taken to be 0.
572
573 \sa QBitArray::operator^()
574*/
575
576QBitArray operator^( const QBitArray &a1, const QBitArray &a2 )
577{
578 QBitArray tmp = a1.copy();
579 tmp ^= a2;
580 return tmp;
581}
582
583
584/* \enum QGArray::array_data
585
586 \warning This will be renamed in the next major release of Qt. Until
587 then it is undocumented and we recommend against its use.
588
589 \internal
590
591 ### 3.0 rename ###
592 ### 3.0 move it to QGArray? ###
593*/
594
595
596/*!
597 \fn QBitArray::array_data * QBitArray::newData()
598
599 \internal
600
601 Returns data specific to QBitArray that extends what QGArray provides.
602 QPtrCollection mechanism for allowing extra/different data.
603*/
604
605
606/*!
607 \fn void QBitArray::deleteData ( array_data * d )
608
609 \internal
610
611 Deletes data specific to QBitArray that extended what QGArray provided.
612
613 QPtrCollection mechanism for allowing extra/different data.
614*/
615
616
617/*****************************************************************************
618 QBitArray stream functions
619 *****************************************************************************/
620
621/*!
622 \relates QBitArray
623
624 Writes bit array \a a to stream \a s.
625
626 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
627*/
628#ifndef QT_NO_DATASTREAM
629QDataStream &operator<<( QDataStream &s, const QBitArray &a )
630{
631 Q_UINT32 len = a.size();
632 s << len; // write size of array
633 if ( len > 0 ) // write data
634 s.writeRawBytes( a.data(), a.QByteArray::size() );
635 return s;
636}
637
638/*!
639 \relates QBitArray
640
641 Reads a bit array into \a a from stream \a s.
642
643 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
644*/
645
646QDataStream &operator>>( QDataStream &s, QBitArray &a )
647{
648 Q_UINT32 len;
649 s >> len; // read size of array
650 if ( !a.resize( (uint)len ) ) { // resize array
651#if defined(QT_CHECK_NULL)
652 qWarning( "QDataStream: Not enough memory to read QBitArray" );
653#endif
654 len = 0;
655 }
656 if ( len > 0 ) // read data
657 s.readRawBytes( a.data(), a.QByteArray::size() );
658 return s;
659}
660
661#endif // QT_NO_DATASTREAM
diff --git a/qmake/tools/qbuffer.cpp b/qmake/tools/qbuffer.cpp
new file mode 100644
index 0000000..b213dd9
--- a/dev/null
+++ b/qmake/tools/qbuffer.cpp
@@ -0,0 +1,495 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QBuffer class
5**
6** Created : 930812
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qbuffer.h"
39#include <stdlib.h>
40
41/*!
42 \class QBuffer qbuffer.h
43 \reentrant
44 \brief The QBuffer class is an I/O device that operates on a QByteArray.
45
46 \ingroup io
47 \ingroup collection
48
49 QBuffer is used to read and write to a memory buffer. It is
50 normally used with a QTextStream or a QDataStream. QBuffer has an
51 associated QByteArray which holds the buffer data. The size() of
52 the buffer is automatically adjusted as data is written.
53
54 The constructor \c QBuffer(QByteArray) creates a QBuffer using an
55 existing byte array. The byte array can also be set with
56 setBuffer(). Writing to the QBuffer will modify the original byte
57 array because QByteArray is \link shclass.html explicitly
58 shared.\endlink
59
60 Use open() to open the buffer before use and to set the mode
61 (read-only, write-only, etc.). close() closes the buffer. The
62 buffer must be closed before reopening or calling setBuffer().
63
64 A common way to use QBuffer is through \l QDataStream or \l
65 QTextStream, which have constructors that take a QBuffer
66 parameter. For convenience, there are also QDataStream and
67 QTextStream constructors that take a QByteArray parameter. These
68 constructors create and open an internal QBuffer.
69
70 Note that QTextStream can also operate on a QString (a Unicode
71 string); a QBuffer cannot.
72
73 You can also use QBuffer directly through the standard QIODevice
74 functions readBlock(), writeBlock() readLine(), at(), getch(),
75 putch() and ungetch().
76
77 \sa QFile, QDataStream, QTextStream, QByteArray, \link shclass.html Shared Classes\endlink
78*/
79
80
81/*!
82 Constructs an empty buffer.
83*/
84
85QBuffer::QBuffer()
86{
87 setFlags( IO_Direct );
88 a_inc = 16; // initial increment
89 a_len = 0;
90 ioIndex = 0;
91}
92
93
94/*!
95 Constructs a buffer that operates on \a buf.
96
97 If you open the buffer in write mode (\c IO_WriteOnly or
98 \c IO_ReadWrite) and write something into the buffer, \a buf
99 will be modified.
100
101 Example:
102 \code
103 QCString str = "abc";
104 QBuffer b( str );
105 b.open( IO_WriteOnly );
106 b.at( 3 ); // position at the 4th character (the terminating \0)
107 b.writeBlock( "def", 4 ); // write "def" including the terminating \0
108 b.close();
109 // Now, str == "abcdef" with a terminating \0
110 \endcode
111
112 \sa setBuffer()
113*/
114
115QBuffer::QBuffer( QByteArray buf ) : a(buf)
116{
117 setFlags( IO_Direct );
118 a_len = a.size();
119 a_inc = (a_len > 512) ? 512 : a_len; // initial increment
120 if ( a_inc < 16 )
121 a_inc = 16;
122 ioIndex = 0;
123}
124
125/*!
126 Destroys the buffer.
127*/
128
129QBuffer::~QBuffer()
130{
131}
132
133
134/*!
135 Replaces the buffer's contents with \a buf and returns TRUE.
136
137 Does nothing (and returns FALSE) if isOpen() is TRUE.
138
139 Note that if you open the buffer in write mode (\c IO_WriteOnly or
140 IO_ReadWrite) and write something into the buffer, \a buf is also
141 modified because QByteArray is an explicitly shared class.
142
143 \sa buffer(), open(), close()
144*/
145
146bool QBuffer::setBuffer( QByteArray buf )
147{
148 if ( isOpen() ) {
149#if defined(QT_CHECK_STATE)
150 qWarning( "QBuffer::setBuffer: Buffer is open" );
151#endif
152 return FALSE;
153 }
154 a = buf;
155 a_len = a.size();
156 a_inc = (a_len > 512) ? 512 : a_len; // initial increment
157 if ( a_inc < 16 )
158 a_inc = 16;
159 ioIndex = 0;
160 return TRUE;
161}
162
163/*!
164 \fn QByteArray QBuffer::buffer() const
165
166 Returns this buffer's byte array.
167
168 \sa setBuffer()
169*/
170
171/*!
172 \reimp
173
174 Opens the buffer in mode \a m. Returns TRUE if successful;
175 otherwise returns FALSE. The buffer must be opened before use.
176
177 The mode parameter \a m must be a combination of the following flags.
178 \list
179 \i \c IO_ReadOnly opens the buffer in read-only mode.
180 \i \c IO_WriteOnly opens the buffer in write-only mode.
181 \i \c IO_ReadWrite opens the buffer in read/write mode.
182 \i \c IO_Append sets the buffer index to the end of the buffer.
183 \i \c IO_Truncate truncates the buffer.
184 \endlist
185
186 \sa close(), isOpen()
187*/
188
189bool QBuffer::open( int m )
190{
191 if ( isOpen() ) { // buffer already open
192#if defined(QT_CHECK_STATE)
193 qWarning( "QBuffer::open: Buffer already open" );
194#endif
195 return FALSE;
196 }
197 setMode( m );
198 if ( m & IO_Truncate ) { // truncate buffer
199 a.resize( 0 );
200 a_len = 0;
201 }
202 if ( m & IO_Append ) { // append to end of buffer
203 ioIndex = a.size();
204 } else {
205 ioIndex = 0;
206 }
207 a_inc = 16;
208 setState( IO_Open );
209 setStatus( 0 );
210 return TRUE;
211}
212
213/*!
214 \reimp
215
216 Closes an open buffer.
217
218 \sa open()
219*/
220
221void QBuffer::close()
222{
223 if ( isOpen() ) {
224 setFlags( IO_Direct );
225 ioIndex = 0;
226 a_inc = 16;
227 }
228}
229
230/*!
231 \reimp
232
233 The flush function does nothing for a QBuffer.
234*/
235
236void QBuffer::flush()
237{
238 return;
239}
240
241
242/*!
243 \fn QIODevice::Offset QBuffer::at() const
244
245 \reimp
246*/
247
248/*!
249 \fn QIODevice::Offset QBuffer::size() const
250
251 \reimp
252*/
253
254/*!
255 \reimp
256*/
257
258bool QBuffer::at( Offset pos )
259{
260#if defined(QT_CHECK_STATE)
261 if ( !isOpen() ) {
262 qWarning( "QBuffer::at: Buffer is not open" );
263 return FALSE;
264 }
265#endif
266 if ( pos > a_len ) {
267#if defined(QT_CHECK_RANGE)
268#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
269 qWarning( "QBuffer::at: Index %llu out of range", pos );
270#else
271 qWarning( "QBuffer::at: Index %lu out of range", pos );
272#endif
273#endif
274 return FALSE;
275 }
276 ioIndex = pos;
277 return TRUE;
278}
279
280
281/*!
282 \reimp
283*/
284
285Q_LONG QBuffer::readBlock( char *p, Q_ULONG len )
286{
287#if defined(QT_CHECK_STATE)
288 if ( !p ) {
289 qWarning( "QBuffer::readBlock: Null pointer error" );
290 return -1;
291 }
292 if ( !isOpen() ) { // buffer not open
293 qWarning( "QBuffer::readBlock: Buffer not open" );
294 return -1;
295 }
296 if ( !isReadable() ) { // reading not permitted
297 qWarning( "QBuffer::readBlock: Read operation not permitted" );
298 return -1;
299 }
300#endif
301 if ( ioIndex + len > a.size() ) { // overflow
302 if ( ioIndex >= a.size() ) {
303 return 0;
304 } else {
305 len = a.size() - ioIndex;
306 }
307 }
308 memcpy( p, a.data()+ioIndex, len );
309 ioIndex += len;
310 return len;
311}
312
313/*!
314 \overload Q_LONG QBuffer::writeBlock( const QByteArray& data )
315
316 This convenience function is the same as calling
317 \c{writeBlock( data.data(), data.size() )} with \a data.
318*/
319
320/*!
321 Writes \a len bytes from \a p into the buffer at the current
322 index position, overwriting any characters there and extending the
323 buffer if necessary. Returns the number of bytes actually written.
324
325 Returns -1 if an error occurred.
326
327 \sa readBlock()
328*/
329
330Q_LONG QBuffer::writeBlock( const char *p, Q_ULONG len )
331{
332 if ( len == 0 )
333 return 0;
334
335#if defined(QT_CHECK_NULL)
336 if ( p == 0 ) {
337 qWarning( "QBuffer::writeBlock: Null pointer error" );
338 return -1;
339 }
340#endif
341#if defined(QT_CHECK_STATE)
342 if ( !isOpen() ) { // buffer not open
343 qWarning( "QBuffer::writeBlock: Buffer not open" );
344 return -1;
345 }
346 if ( !isWritable() ) { // writing not permitted
347 qWarning( "QBuffer::writeBlock: Write operation not permitted" );
348 return -1;
349 }
350#endif
351 if ( ioIndex + len >= a_len ) { // overflow
352 Q_ULONG new_len = a_len + a_inc*((ioIndex+len-a_len)/a_inc+1);
353 if ( !a.resize( new_len ) ) { // could not resize
354#if defined(QT_CHECK_NULL)
355 qWarning( "QBuffer::writeBlock: Memory allocation error" );
356#endif
357 setStatus( IO_ResourceError );
358 return -1;
359 }
360 a_inc *= 2; // double increment
361 a_len = new_len;
362 a.shd->len = ioIndex + len;
363 }
364 memcpy( a.data()+ioIndex, p, len );
365 ioIndex += len;
366 if ( a.shd->len < ioIndex )
367 a.shd->len = ioIndex; // fake (not alloc'd) length
368 return len;
369}
370
371
372/*!
373 \reimp
374*/
375
376Q_LONG QBuffer::readLine( char *p, Q_ULONG maxlen )
377{
378#if defined(QT_CHECK_NULL)
379 if ( p == 0 ) {
380 qWarning( "QBuffer::readLine: Null pointer error" );
381 return -1;
382 }
383#endif
384#if defined(QT_CHECK_STATE)
385 if ( !isOpen() ) { // buffer not open
386 qWarning( "QBuffer::readLine: Buffer not open" );
387 return -1;
388 }
389 if ( !isReadable() ) { // reading not permitted
390 qWarning( "QBuffer::readLine: Read operation not permitted" );
391 return -1;
392 }
393#endif
394 if ( maxlen == 0 )
395 return 0;
396 Q_ULONG start = ioIndex;
397 char *d = a.data() + ioIndex;
398 maxlen--; // make room for 0-terminator
399 if ( a.size() - ioIndex < maxlen )
400 maxlen = a.size() - ioIndex;
401 while ( maxlen-- ) {
402 if ( (*p++ = *d++) == '\n' )
403 break;
404 }
405 *p = '\0';
406 ioIndex = d - a.data();
407 return ioIndex - start;
408}
409
410
411/*!
412 \reimp
413*/
414
415int QBuffer::getch()
416{
417#if defined(QT_CHECK_STATE)
418 if ( !isOpen() ) { // buffer not open
419 qWarning( "QBuffer::getch: Buffer not open" );
420 return -1;
421 }
422 if ( !isReadable() ) { // reading not permitted
423 qWarning( "QBuffer::getch: Read operation not permitted" );
424 return -1;
425 }
426#endif
427 if ( ioIndex+1 > a.size() ) { // overflow
428 setStatus( IO_ReadError );
429 return -1;
430 }
431 return uchar(*(a.data()+ioIndex++));
432}
433
434/*!
435 \reimp
436
437 Writes the character \a ch into the buffer at the current index
438 position, overwriting any existing character and extending the
439 buffer if necessary.
440
441 Returns \a ch, or -1 if an error occurred.
442
443 \sa getch(), ungetch()
444*/
445
446int QBuffer::putch( int ch )
447{
448#if defined(QT_CHECK_STATE)
449 if ( !isOpen() ) { // buffer not open
450 qWarning( "QBuffer::putch: Buffer not open" );
451 return -1;
452 }
453 if ( !isWritable() ) { // writing not permitted
454 qWarning( "QBuffer::putch: Write operation not permitted" );
455 return -1;
456 }
457#endif
458 if ( ioIndex + 1 >= a_len ) { // overflow
459 char buf[1];
460 buf[0] = (char)ch;
461 if ( writeBlock(buf,1) != 1 )
462 return -1; // write error
463 } else {
464 *(a.data() + ioIndex++) = (char)ch;
465 if ( a.shd->len < ioIndex )
466 a.shd->len = ioIndex;
467 }
468 return ch;
469}
470
471/*!
472 \reimp
473*/
474
475int QBuffer::ungetch( int ch )
476{
477#if defined(QT_CHECK_STATE)
478 if ( !isOpen() ) { // buffer not open
479 qWarning( "QBuffer::ungetch: Buffer not open" );
480 return -1;
481 }
482 if ( !isReadable() ) { // reading not permitted
483 qWarning( "QBuffer::ungetch: Read operation not permitted" );
484 return -1;
485 }
486#endif
487 if ( ch != -1 ) {
488 if ( ioIndex )
489 ioIndex--;
490 else
491 ch = -1;
492 }
493 return ch;
494}
495
diff --git a/qmake/tools/qcomlibrary.cpp b/qmake/tools/qcomlibrary.cpp
new file mode 100644
index 0000000..a7162fc
--- a/dev/null
+++ b/qmake/tools/qcomlibrary.cpp
@@ -0,0 +1,538 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QComLibrary class
5**
6** Copyright (C) 2001-2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the tools module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "qcomlibrary_p.h"
37
38#ifndef QT_NO_COMPONENT
39#include <qapplication.h>
40#include <qsettings.h>
41#include <qfileinfo.h>
42#include <qdatetime.h>
43#include <qcleanuphandler.h>
44#include <errno.h>
45
46#ifdef QT_THREAD_SUPPORT
47# include "qmutexpool_p.h"
48#endif // QT_THREAD_SUPPORT
49
50#ifndef QT_DEBUG_COMPONENT
51# if defined(QT_DEBUG)
52# define QT_DEBUG_COMPONENT 1
53# endif
54#endif
55
56
57QComLibrary::QComLibrary( const QString &filename )
58 : QLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 )
59{
60}
61
62QComLibrary::~QComLibrary()
63{
64 if ( autoUnload() )
65 unload();
66}
67
68bool QComLibrary::unload()
69{
70 if ( libiface ) {
71 libiface->cleanup();
72 if ( !libiface->canUnload() )
73 return FALSE;
74 libiface->release();
75 libiface = 0;
76 }
77 int refs = entry ? entry->release() : 0;
78 if ( refs )
79 return FALSE;
80
81 entry = 0;
82
83 return QLibrary::unload();
84}
85
86static bool qt_verify( const QString& library, uint version, uint flags,
87 const QCString &key, bool warn )
88{
89 uint our_flags = 1;
90#if defined(QT_THREAD_SUPPORT)
91 our_flags |= 2;
92#endif
93
94 if ( (flags & 1) == 0 ) {
95 if ( warn )
96 qWarning( "Conflict in %s:\n"
97 " Plugin cannot be queried successfully!",
98 (const char*) QFile::encodeName(library) );
99 } else if ( ( version > QT_VERSION ) ||
100 ( ( QT_VERSION & 0xff0000 ) > ( version & 0xff0000 ) ) ) {
101 if ( warn )
102 qWarning( "Conflict in %s:\n"
103 " Plugin uses incompatible Qt library (%d.%d.%d)!",
104 (const char*) QFile::encodeName(library),
105 (version&0xff0000) >> 16, (version&0xff00) >> 8, version&0xff );
106 } else if ( (flags & 2) != (our_flags & 2) ) {
107 if ( warn )
108 qWarning( "Conflict in %s:\n"
109 " Plugin uses %s Qt library!",
110 (const char*) QFile::encodeName(library),
111 (flags & 2) ? "multi threaded" : "single threaded" );
112 } else if ( key != QT_BUILD_KEY ) {
113 if ( warn )
114 qWarning( "Conflict in %s:\n"
115 " Plugin uses incompatible Qt library!\n"
116 " expected build key \"%s\", got \"%s\".",
117 (const char*) QFile::encodeName(library),
118 QT_BUILD_KEY,
119 key.isEmpty() ? "<null>" : (const char *) key );
120 } else {
121 return TRUE;
122 }
123 return FALSE;
124}
125
126struct qt_token_info
127{
128 qt_token_info( const char *f, const ulong fc )
129 : fields( f ), field_count( fc ), results( fc ), lengths( fc )
130 {
131 results.fill( 0 );
132 lengths.fill( 0 );
133 }
134
135 const char *fields;
136 const ulong field_count;
137
138 QMemArray<const char *> results;
139 QMemArray<ulong> lengths;
140};
141
142/*
143 return values:
144 1 parse ok
145 0 eos
146 -1 parse error
147*/
148static int qt_tokenize( const char *s, ulong s_len, ulong *advance,
149 const qt_token_info &token_info )
150{
151 ulong pos = 0, field = 0, fieldlen = 0;
152 char current;
153 int ret = -1;
154 *advance = 0;
155 for (;;) {
156 current = s[ pos ];
157
158 // next char
159 ++pos;
160 ++fieldlen;
161 ++*advance;
162
163 if ( ! current || pos == s_len + 1 ) {
164 // save result
165 token_info.results[ (int)field ] = s;
166 token_info.lengths[ (int)field ] = fieldlen - 1;
167
168 // end of string
169 ret = 0;
170 break;
171 }
172
173 if ( current == token_info.fields[ field ] ) {
174 // save result
175 token_info.results[ (int)field ] = s;
176 token_info.lengths[ (int)field ] = fieldlen - 1;
177
178 // end of field
179 fieldlen = 0;
180 ++field;
181 if ( field == token_info.field_count - 1 ) {
182 // parse ok
183 ret = 1;
184 }
185 if ( field == token_info.field_count ) {
186 // done parsing
187 break;
188 }
189
190 // reset string and its length
191 s = s + pos;
192 s_len -= pos;
193 pos = 0;
194 }
195 }
196
197 return ret;
198}
199
200/*
201 returns TRUE if the string s was correctly parsed, FALSE otherwise.
202*/
203static bool qt_parse_pattern( const char *s, uint *version, uint *flags,
204 QCString *key )
205{
206 bool ret = TRUE;
207
208 qt_token_info pinfo("=\n", 2);
209 int parse;
210 ulong at = 0, advance, parselen = qstrlen( s );
211 do {
212 parse = qt_tokenize( s + at, parselen, &advance, pinfo );
213 if ( parse == -1 ) {
214 ret = FALSE;
215 break;
216 }
217
218 at += advance;
219 parselen -= advance;
220
221 if ( qstrncmp( "version", pinfo.results[ 0 ], pinfo.lengths[ 0 ] ) == 0 ) {
222 // parse version string
223 qt_token_info pinfo2("..-", 3);
224 if ( qt_tokenize( pinfo.results[ 1 ], pinfo.lengths[ 1 ],
225 &advance, pinfo2 ) != -1 ) {
226 QCString m( pinfo2.results[ 0 ], pinfo2.lengths[ 0 ] + 1 );
227 QCString n( pinfo2.results[ 1 ], pinfo2.lengths[ 1 ] + 1 );
228 QCString p( pinfo2.results[ 2 ], pinfo2.lengths[ 2 ] + 1 );
229 *version = (m.toUInt() << 16) | (n.toUInt() << 8) | p.toUInt();
230 } else {
231 ret = FALSE;
232 break;
233 }
234 } else if ( qstrncmp( "flags", pinfo.results[ 0 ], pinfo.lengths[ 0 ] ) == 0 ) {
235 // parse flags string
236 char ch;
237 *flags = 0;
238 ulong p = 0, c = 0, bit = 0;
239 while ( p < pinfo.lengths[ 1 ] ) {
240 ch = pinfo.results[ 1 ][ p ];
241 bit = pinfo.lengths[ 1 ] - p - 1;
242 c = 1 << bit;
243 if ( ch == '1' ) {
244 *flags |= c;
245 } else if ( ch != '0' ) {
246 ret = FALSE;
247 break;
248 }
249 ++p;
250 }
251 } else if ( qstrncmp( "buildkey", pinfo.results[ 0 ],
252 pinfo.lengths[ 0 ] ) == 0 ){
253 // save buildkey
254 *key = QCString( pinfo.results[ 1 ], pinfo.lengths[ 1 ] + 1 );
255 }
256 } while ( parse == 1 && parselen > 0 );
257
258 return ret;
259}
260
261#if defined(Q_OS_UNIX)
262
263#if defined(Q_OS_FREEBSD) || defined(Q_OS_LINUX)
264# define USE_MMAP
265# include <sys/types.h>
266# include <sys/mman.h>
267#endif // Q_OS_FREEBSD || Q_OS_LINUX
268
269static long qt_find_pattern( const char *s, ulong s_len,
270 const char *pattern, ulong p_len )
271{
272 /*
273 this uses the same algorithm as QString::findRev...
274
275 we search from the end of the file because on the supported
276 systems, the read-only data/text segments are placed at the end
277 of the file. HOWEVER, when building with debugging enabled, all
278 the debug symbols are placed AFTER the data/text segments.
279
280 what does this mean? when building in release mode, the search
281 is fast because the data we are looking for is at the end of the
282 file... when building in debug mode, the search is slower
283 because we have to skip over all the debugging symbols first
284 */
285
286 if ( ! s || ! pattern || p_len > s_len ) return -1;
287 ulong i, hs = 0, hp = 0, delta = s_len - p_len;
288
289 for (i = 0; i < p_len; ++i ) {
290 hs += s[delta + i];
291 hp += pattern[i];
292 }
293 i = delta;
294 for (;;) {
295 if ( hs == hp && qstrncmp( s + i, pattern, p_len ) == 0 )
296 return i;
297 if ( i == 0 )
298 break;
299 --i;
300 hs -= s[i + p_len];
301 hs += s[i];
302 }
303
304 return -1;
305}
306
307/*
308 This opens the specified library, mmaps it into memory, and searches
309 for the QT_UCM_VERIFICATION_DATA. The advantage of this approach is that
310 we can get the verification data without have to actually load the library.
311 This lets us detect mismatches more safely.
312
313 Returns FALSE if version/flags/key information is not present, or if the
314 information could not be read.
315 Returns TRUE if version/flags/key information is present and succesfully read.
316*/
317static bool qt_unix_query( const QString &library, uint *version, uint *flags,
318 QCString *key )
319{
320 QFile file( library );
321 if (! file.open( IO_ReadOnly ) ) {
322 qWarning( "%s: %s", (const char*) QFile::encodeName(library),
323 strerror( errno ) );
324 return FALSE;
325 }
326
327 QByteArray data;
328 char *filedata = 0;
329 ulong fdlen = 0;
330
331#ifdef USE_MMAP
332 char *mapaddr = 0;
333 size_t maplen = file.size();
334 mapaddr = (char *) mmap( mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0 );
335 if ( mapaddr != MAP_FAILED ) {
336 // mmap succeeded
337 filedata = mapaddr;
338 fdlen = maplen;
339 } else {
340 // mmap failed
341 qWarning( "mmap: %s", strerror( errno ) );
342#endif // USE_MMAP
343 // try reading the data into memory instead
344 data = file.readAll();
345 filedata = data.data();
346 fdlen = data.size();
347#ifdef USE_MMAP
348 }
349#endif // USE_MMAP
350
351 // verify that the pattern is present in the plugin
352 const char *pattern = "pattern=QT_UCM_VERIFICATION_DATA";
353 const ulong plen = qstrlen( pattern );
354 long pos = qt_find_pattern( filedata, fdlen, pattern, plen );
355
356 bool ret = FALSE;
357 if ( pos >= 0 ) {
358 ret = qt_parse_pattern( filedata + pos, version, flags, key );
359 }
360
361#ifdef USE_MMAP
362 if ( mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0 ) {
363 qWarning( "munmap: %s", strerror( errno ) );
364 }
365#endif // USE_MMAP
366
367 file.close();
368 return ret;
369}
370
371#endif // Q_OS_UNIX
372
373
374static QSettings *cache = 0;
375static QSingleCleanupHandler<QSettings> cleanup_cache;
376
377void QComLibrary::createInstanceInternal()
378{
379 if ( library().isEmpty() )
380 return;
381
382 QFileInfo fileinfo( library() );
383 QString lastModified = fileinfo.lastModified().toString();
384 QString regkey = QString("/Qt Plugins %1.%2/%3")
385 .arg( ( QT_VERSION & 0xff0000 ) >> 16 )
386 .arg( ( QT_VERSION & 0xff00 ) >> 8 )
387 .arg( library() );
388 QStringList reg;
389 uint flags = 0;
390 QCString key;
391 bool query_done = FALSE;
392 bool warn_mismatch = TRUE;
393
394 if ( ! query_done ) {
395
396#ifdef QT_THREAD_SUPPORT
397 QMutexLocker locker( qt_global_mutexpool->get( &cache ) );
398#endif // QT_THREAD_SUPPORT
399
400 if ( ! cache ) {
401 cache = new QSettings;
402 cache->insertSearchPath( QSettings::Windows, "/Trolltech" );
403 cleanup_cache.set( &cache );
404 }
405
406 reg = cache->readListEntry( regkey );
407 if ( reg.count() == 4 ) {
408 // check timestamp
409 if ( lastModified == reg[3] ) {
410 qt_version = reg[0].toUInt(0, 16);
411 flags = reg[1].toUInt(0, 16);
412 key = reg[2].latin1();
413
414 query_done = TRUE;
415 warn_mismatch = FALSE;
416 }
417 }
418 }
419
420#if defined(Q_OS_UNIX)
421 if ( ! query_done ) {
422 // get the query information directly from the plugin without loading
423 if ( qt_unix_query( library(), &qt_version, &flags, &key ) ) {
424 // info read succesfully from library
425 query_done = TRUE;
426 }
427 }
428#else // !Q_OS_UNIX
429 if ( ! query_done ) {
430 // get the query information by loading the plugin
431 if ( !isLoaded() ) {
432 Q_ASSERT( entry == 0 );
433 if ( !load() )
434 return;
435 }
436
437# ifdef Q_CC_BOR
438 typedef const char * __stdcall (*UCMQueryVerificationDataProc)();
439# else
440 typedef const char * (*UCMQueryVerificationDataProc)();
441# endif
442 UCMQueryVerificationDataProc ucmQueryVerificationdataProc;
443 ucmQueryVerificationdataProc =
444 (UCMQueryVerificationDataProc) resolve( "qt_ucm_query_verification_data" );
445
446 if ( !ucmQueryVerificationdataProc ||
447 !qt_parse_pattern( ucmQueryVerificationdataProc(),
448 &qt_version, &flags, &key ) ) {
449 qt_version = flags = 0;
450 key = "unknown";
451 } else {
452 query_done = TRUE;
453 }
454 }
455#endif // Q_OS_UNIX
456
457 QStringList queried;
458 queried << QString::number( qt_version,16 )
459 << QString::number( flags, 16 )
460 << key
461 << lastModified;
462
463 if ( queried != reg ) {
464
465#ifdef QT_THREAD_SUPPORT
466 QMutexLocker locker( qt_global_mutexpool->get( &cache ) );
467#endif // QT_THREAD_SUPPORT
468
469 cache->writeEntry( regkey, queried );
470 // delete the cache, which forces the settings to be written
471 delete cache;
472 cache = 0;
473 }
474
475 if ( ! query_done ) {
476 if ( warn_mismatch ) {
477 qWarning( "Conflict in %s:\n Plugin cannot be queried successfully!",
478 (const char*) QFile::encodeName( library() ) );
479 }
480 unload();
481 return;
482 }
483
484 if ( ! qt_verify( library(), qt_version, flags, key, warn_mismatch ) ) {
485 unload();
486 return;
487 } else if ( !isLoaded() ) {
488 Q_ASSERT( entry == 0 );
489 if ( !load() )
490 return;
491 }
492
493#ifdef Q_CC_BOR
494 typedef QUnknownInterface* __stdcall (*UCMInstanceProc)();
495#else
496 typedef QUnknownInterface* (*UCMInstanceProc)();
497#endif
498 UCMInstanceProc ucmInstanceProc;
499 ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" );
500#if defined(QT_DEBUG_COMPONENT)
501 if ( !ucmInstanceProc )
502 qWarning( "%s: Not a UCOM library.", (const char*) QFile::encodeName(library()) );
503#endif
504 entry = ucmInstanceProc ? ucmInstanceProc() : 0;
505
506 if ( entry ) {
507 if ( entry->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) == QS_OK ) {
508 if ( libiface && !libiface->init() ) {
509 libiface->release();
510 libiface = 0;
511 unload();
512 return;
513 }
514 }
515 } else {
516#if defined(QT_DEBUG_COMPONENT)
517 qWarning( "%s: No exported component provided.", (const char*) QFile::encodeName(library()) );
518#endif
519 unload();
520 }
521}
522
523QRESULT QComLibrary::queryInterface( const QUuid& request, QUnknownInterface** iface )
524{
525 if ( !entry )
526 createInstanceInternal();
527 return entry ? entry->queryInterface( request, iface ) : QE_NOCOMPONENT;
528}
529
530uint QComLibrary::qtVersion()
531{
532 if ( !entry )
533 createInstanceInternal();
534 return entry ? qt_version : 0;
535}
536
537
538#endif // QT_NO_COMPONENT
diff --git a/qmake/tools/qcomponentfactory.cpp b/qmake/tools/qcomponentfactory.cpp
new file mode 100644
index 0000000..8ea81a8
--- a/dev/null
+++ b/qmake/tools/qcomponentfactory.cpp
@@ -0,0 +1,352 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of the QComponentFactory class
5**
6** Created : 990101
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qcomponentfactory_p.h"
39
40#ifndef QT_NO_COMPONENT
41#include "qsettings.h"
42#include <private/qcomlibrary_p.h>
43#include "qdir.h"
44#include "qapplication.h"
45
46/*!
47 \class QComponentFactory qcomponentfactory.h
48 \brief The QComponentFactory class provides static functions to create and register components.
49
50 \internal
51
52 The static convenience functions can be used both by applications to instantiate components,
53 and by component servers to register components.
54
55 The createInstance() function provides a pointer to an interface implemented in a specific
56 component if the component requested has been installed properly and implements the interface.
57
58 Use registerServer() to load a component server and register its components, and unregisterServer()
59 to unregister the components. The component exported by the component server has to implement the
60 QComponentRegistrationInterface.
61
62 The static functions registerComponent() and unregisterComponent() register and unregister a single
63 component in the system component registry, and should be used when implementing the
64 \link QComponentRegistrationInterface::registerComponents() registerCompontents() \endlink and
65 \link QComponentRegistrationInterface::unregisterComponents() unregisterCompontents() \endlink functions
66 in the QComponentRegistrationInterface.
67
68 A component is registered using a UUID, but can additionally be registered with a name, version and
69 description. A component registered with a name and a version can be instantiated by client applications
70 using the name and specific version number, or the highest available version number for that component by
71 just using the name. A component that is registered calling
72
73 \code
74 QComponentFactory::registerComponent( QUuid(...), filename, "MyProgram.Component", 1 );
75 \endcode
76
77 can be instantiated calling either:
78
79 \code
80 QComponentFactory::createInstance( QUuid(...), IID_XYZ, (QUnknownInterface**)&iface );
81 \endcode
82 or
83 \code
84 QComponentFactory::createInstance( "MyProgram.Component", IID_XYZ, (QUnknownInterface**)&iface );
85 \endcode
86 or
87 \code
88 QComponentFactory::createInstance( "MyProgram.Component.1", IID_XYZ, (QUnknownInterface**)&iface );
89 \endcode
90
91 The first and the last way will always instantiate exactly the component registered above, while
92 the second call might also return a later version of the same component. This allows smoother upgrading
93 of components, and is easier to use in application source code, but should only be used when new versions
94 of the component are guaranteed to work with the application.
95
96 The component name can be anything, but should be unique on the system the component is being
97 installed on. A common naming convention for components is \e application.component.
98
99 \sa QComponentRegistrationInterface QComponentFactoryInterface
100*/
101
102
103static QPtrList<QComLibrary> *libraries = 0;
104
105static void cleanup()
106{
107 delete libraries;
108 libraries = 0;
109}
110
111static QPtrList<QComLibrary> *liblist()
112{
113 if ( !libraries ) {
114 libraries = new QPtrList<QComLibrary>();
115 libraries->setAutoDelete( TRUE );
116 qAddPostRoutine( cleanup );
117 }
118 return libraries;
119}
120
121/*!
122 Searches for the component identifier \a cid in the system component registry,
123 loads the corresponding component server and queries for the interface \a iid.
124 \a iface is set to the resulting interface pointer. \a cid can either be the
125 UUID or the name of the component.
126
127 The parameter \a outer is a pointer to the outer interface used
128 for containment and aggregation and is propagated to the \link
129 QComponentFactoryInterface::createInstance() createInstance() \endlink
130 implementation of the QComponentFactoryInterface in the component server if
131 provided.
132
133 The function returns QS_OK if the interface was successfully instantiated, QE_NOINTERFACE if
134 the component does not provide an interface \a iid, or QE_NOCOMPONENT if there was
135 an error loading the component.
136
137 Example:
138 \code
139 QInterfacePtr<MyInterface> iface;
140 if ( QComponentFactory::createInstance( IID_MyInterface, CID_MyComponent, (QUnknownInterface**)&iface ) == QS_OK )
141 iface->doSomething();
142 ...
143 }
144 \endcode
145*/
146QRESULT QComponentFactory::createInstance( const QString &cid, const QUuid &iid, QUnknownInterface** iface, QUnknownInterface *outer )
147{
148 QSettings settings;
149 settings.insertSearchPath( QSettings::Windows, "/Classes" );
150 bool ok = FALSE;
151 QString cidStr = cid;
152 QRESULT res = QE_NOCOMPONENT;
153
154 QUuid uuid( cidStr ); // try to parse, and resolve CLSID if necessary
155 if ( uuid.isNull() ) {
156 uuid = settings.readEntry( "/" + cid + "/CLSID/Default", QString::null, &ok );
157 cidStr = uuid.toString().upper();
158 }
159
160 if ( cidStr.isEmpty() )
161 return res;
162
163 QString file = settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", QString::null, &ok );
164 if ( !ok )
165 return res;
166
167 QComLibrary *library = new QComLibrary( file );
168 library->setAutoUnload( FALSE );
169
170 QComponentFactoryInterface *cfIface =0;
171 library->queryInterface( IID_QComponentFactory, (QUnknownInterface**)&cfIface );
172
173 if ( cfIface ) {
174 res = cfIface->createInstance( uuid, iid, iface, outer );
175 cfIface->release();
176 } else {
177 res = library->queryInterface( iid, iface );
178 }
179 QLibraryInterface *libiface = 0;
180 if ( library->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) != QS_OK || !qApp ) {
181 delete library; // only deletes the object, thanks to QLibrary::Manual
182 } else {
183 libiface->release();
184 library->setAutoUnload( TRUE );
185 liblist()->prepend( library );
186 }
187 return res;
188}
189
190/*!
191 Loads the shared library \a filename and queries for a
192 QComponentRegistrationInterface. If the library implements this interface,
193 the \link QComponentRegistrationInterface::registerComponents()
194 registerComponents() \endlink function is called.
195
196 Returns TRUE if the interface is found and successfully called,
197 otherwise returns FALSE.
198*/
199QRESULT QComponentFactory::registerServer( const QString &filename )
200{
201 QComLibrary lib( filename );
202 lib.load();
203 QComponentRegistrationInterface *iface = 0;
204 QRESULT res = lib.queryInterface( IID_QComponentRegistration, (QUnknownInterface**)&iface );
205 if ( res != QS_OK )
206 return res;
207 QDir dir( filename );
208 bool ok = iface->registerComponents( dir.absPath() );
209 iface->release();
210 return ok ? QS_OK : QS_FALSE;
211}
212
213/*!
214 Loads the shared library \a filename and queries for a
215 QComponentRegistrationInterface. If the library implements this interface,
216 the \link QComponentRegistrationInterface::unregisterComponents()
217 unregisterComponents() \endlink function is called.
218
219 Returns TRUE if the interface is found and successfully unregistered,
220 otherwise returns FALSE.
221*/
222QRESULT QComponentFactory::unregisterServer( const QString &filename )
223{
224 QComLibrary lib( filename );
225 lib.load();
226 QComponentRegistrationInterface *iface = 0;
227 QRESULT res = lib.queryInterface( IID_QComponentRegistration, (QUnknownInterface**)&iface );
228 if ( res != QS_OK )
229 return res;
230 bool ok = iface->unregisterComponents();
231 iface->release();
232 return ok ? QS_OK : QS_FALSE;
233}
234
235/*!
236 Registers the component with id \a cid in the system component registry and
237 returns TRUE if the component was registerd successfully, otherwise returns
238 FALSE. The component is provided by the component server at \a filepath and
239 registered with an optional \a name, \a version and \a description.
240
241 This function does nothing and returns FALSE if a component with an identical
242 \a cid does already exist on the system.
243
244 A component that has been registered with a \a name can be created using both the
245 \a cid and the \a name value using createInstance().
246
247 Call this function for each component in an implementation of
248 \link QComponentRegistrationInterface::registerComponents() registerComponents() \endlink.
249
250 \sa unregisterComponent(), registerServer(), createInstance()
251*/
252bool QComponentFactory::registerComponent( const QUuid &cid, const QString &filepath, const QString &name, int version, const QString &description )
253{
254 bool ok = FALSE;
255 QSettings settings;
256 settings.insertSearchPath( QSettings::Windows, "/Classes" );
257
258 QString cidStr = cid.toString().upper();
259 settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", QString::null, &ok );
260 if ( ok ) // don't overwrite existing component
261 return FALSE;
262
263 ok = settings.writeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", filepath );
264 if ( ok && !!description )
265 settings.writeEntry( "/CLSID/" + cidStr + "/Default", description );
266
267 // register the human readable part
268 if ( ok && !!name ) {
269 QString vName = version ? name + "." + QString::number( version ) : name;
270 settings.writeEntry( "/CLSID/" + cidStr + "/ProgID/Default", vName );
271 ok = settings.writeEntry( "/" + vName + "/CLSID/Default", cidStr );
272 if ( ok && !!description )
273 settings.writeEntry( "/" + vName + "/Default", description );
274
275 if ( ok && version ) {
276 settings.writeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", name );
277 QString curVer = settings.readEntry( "/" + name + "/CurVer/Default" );
278 if ( !curVer || curVer < vName ) { // no previous, or a lesser version installed
279 settings.writeEntry( "/" + name + "/CurVer/Default", vName );
280 ok = settings.writeEntry( "/" + name + "/CLSID/Default", cidStr );
281 if ( ok && !!description )
282 settings.writeEntry( "/" + name + "/Default", description );
283 }
284 }
285 }
286
287 return ok;
288}
289
290/*!
291 Unregisters the component with id \a cid from the system component registry and returns
292 TRUE if the component was unregistered successfully, otherwise returns FALSE.
293
294 Call this function for each component in an implementation of
295 \link QComponentRegistrationInterface::unregisterComponents() unregisterComponents() \endlink.
296
297 \sa registerComponent(), unregisterServer()
298*/
299bool QComponentFactory::unregisterComponent( const QUuid &cid )
300{
301 QSettings settings;
302 bool ok = FALSE;
303 settings.insertSearchPath( QSettings::Windows, "/Classes" );
304
305 QString cidStr = cid.toString().upper();
306 if ( cidStr.isEmpty() )
307 return FALSE;
308
309 // unregister the human readable part
310 QString vName = settings.readEntry( "/CLSID/" + cidStr + "/ProgID/Default", QString::null, &ok );
311 if ( ok ) {
312 QString name = settings.readEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", QString::null );
313 if ( !!name && settings.readEntry( "/" + name + "/CurVer/Default" ) == vName ) {
314 // unregistering the current version -> change CurVer to previous version
315 QString version = vName.right( vName.length() - name.length() - 1 );
316 QString newVerName;
317 QString newCidStr;
318 if ( version.find( '.' ) == -1 ) {
319 int ver = version.toInt();
320 // see if a lesser version is installed, and make that the CurVer
321 while ( ver-- ) {
322 newVerName = name + "." + QString::number( ver );
323 newCidStr = settings.readEntry( "/" + newVerName + "/CLSID/Default" );
324 if ( !!newCidStr )
325 break;
326 }
327 } else {
328 // oh well...
329 }
330 if ( !!newCidStr ) {
331 settings.writeEntry( "/" + name + "/CurVer/Default", newVerName );
332 settings.writeEntry( "/" + name + "/CLSID/Default", newCidStr );
333 } else {
334 settings.removeEntry( "/" + name + "/CurVer/Default" );
335 settings.removeEntry( "/" + name + "/CLSID/Default" );
336 settings.removeEntry( "/" + name + "/Default" );
337 }
338 }
339
340 settings.removeEntry( "/" + vName + "/CLSID/Default" );
341 settings.removeEntry( "/" + vName + "/Default" );
342 }
343
344 settings.removeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default" );
345 settings.removeEntry( "/CLSID/" + cidStr + "/ProgID/Default" );
346 settings.removeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default" );
347 ok = settings.removeEntry( "/CLSID/" + cidStr + "/Default" );
348
349 return ok;
350}
351
352#endif // QT_NO_COMPONENT
diff --git a/qmake/tools/qconfig.cpp b/qmake/tools/qconfig.cpp
new file mode 100644
index 0000000..433827c
--- a/dev/null
+++ b/qmake/tools/qconfig.cpp
@@ -0,0 +1,17 @@
1/* Install paths from configure */
2
3static const char QT_INSTALL_PREFIX [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2";
4static const char QT_INSTALL_BINS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/bin";
5static const char QT_INSTALL_DOCS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/doc";
6static const char QT_INSTALL_HEADERS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/include";
7static const char QT_INSTALL_LIBS [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/lib";
8static const char QT_INSTALL_PLUGINS[256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2/plugins";
9static const char QT_INSTALL_DATA [256] = "/usr/src/coding/projects/userspace/qt-embedded-free-3.1.0-b2";
10
11const char *qInstallPath() { return QT_INSTALL_PREFIX; }
12const char *qInstallPathDocs() { return QT_INSTALL_DOCS; }
13const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS; }
14const char *qInstallPathLibs() { return QT_INSTALL_LIBS; }
15const char *qInstallPathBins() { return QT_INSTALL_BINS; }
16const char *qInstallPathPlugins() { return QT_INSTALL_PLUGINS; }
17const char *qInstallPathData() { return QT_INSTALL_DATA; }
diff --git a/qmake/tools/qcriticalsection_p.cpp b/qmake/tools/qcriticalsection_p.cpp
new file mode 100644
index 0000000..60fc8bd
--- a/dev/null
+++ b/qmake/tools/qcriticalsection_p.cpp
@@ -0,0 +1,75 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QCriticalSection class
5**
6** Created :
7**
8** Copyright (C) 2001 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#if defined(QT_THREAD_SUPPORT)
39
40#include "qt_windows.h"
41
42#include <private/qcriticalsection_p.h>
43
44class QCriticalSectionPrivate
45{
46public:
47 QCriticalSectionPrivate() {}
48
49 CRITICAL_SECTION section;
50};
51
52
53QCriticalSection::QCriticalSection()
54{
55 d = new QCriticalSectionPrivate;
56 InitializeCriticalSection( &d->section );
57}
58
59QCriticalSection::~QCriticalSection()
60{
61 DeleteCriticalSection( &d->section );
62 delete d;
63}
64
65void QCriticalSection::enter()
66{
67 EnterCriticalSection( &d->section );
68}
69
70void QCriticalSection::leave()
71{
72 LeaveCriticalSection( &d->section );
73}
74
75#endif
diff --git a/qmake/tools/qcstring.cpp b/qmake/tools/qcstring.cpp
new file mode 100644
index 0000000..cf1b853
--- a/dev/null
+++ b/qmake/tools/qcstring.cpp
@@ -0,0 +1,2474 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of extended char array operations, and QByteArray and
5** QCString classes
6**
7** Created : 920722
8**
9** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
10**
11** This file is part of the tools module of the Qt GUI Toolkit.
12**
13** This file may be distributed under the terms of the Q Public License
14** as defined by Trolltech AS of Norway and appearing in the file
15** LICENSE.QPL included in the packaging of this file.
16**
17** This file may be distributed and/or modified under the terms of the
18** GNU General Public License version 2 as published by the Free Software
19** Foundation and appearing in the file LICENSE.GPL included in the
20** packaging of this file.
21**
22** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
23** licenses may use this file in accordance with the Qt Commercial License
24** Agreement provided with the Software.
25**
26** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
27** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28**
29** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
30** information about Qt Commercial License Agreements.
31** See http://www.trolltech.com/qpl/ for QPL licensing information.
32** See http://www.trolltech.com/gpl/ for GPL licensing information.
33**
34** Contact info@trolltech.com if any conditions of this licensing are
35** not clear to you.
36**
37**********************************************************************/
38
39#include "qstring.h"
40#include "qregexp.h"
41#include "qdatastream.h"
42
43#ifdef QT_THREAD_SUPPORT
44# include <private/qmutexpool_p.h>
45#endif // QT_THREAD_SUPPORT
46
47#include <stdio.h>
48#include <stdarg.h>
49#include <stdlib.h>
50#include <ctype.h>
51#include <limits.h>
52#ifndef QT_NO_COMPRESS
53#include "../3rdparty/zlib/zlib.h"
54#endif
55
56/*****************************************************************************
57 Safe and portable C string functions; extensions to standard string.h
58 *****************************************************************************/
59
60/*!
61 \relates QCString
62
63 This function is normally part of the C library. Qt implements
64 memmove() for platforms that do not provide it.
65
66 memmove() copies \a len bytes from \a src into \a dst. The data
67 is copied correctly even if \a src and \a dst overlap.
68*/
69
70void *qmemmove( void *dst, const void *src, uint len )
71{
72 register char *d;
73 register char *s;
74 if ( dst > src ) {
75 d = (char *)dst + len - 1;
76 s = (char *)src + len - 1;
77 while ( len-- )
78 *d-- = *s--;
79 } else if ( dst < src ) {
80 d = (char *)dst;
81 s = (char *)src;
82 while ( len-- )
83 *d++ = *s++;
84 }
85 return dst;
86}
87
88
89/*!
90 \relates QCString
91
92 Returns a duplicate string.
93
94 Allocates space for a copy of \a src, copies it, and returns a
95 pointer to the copy. If \a src is 0, it immediately returns 0.
96
97 The returned string must be deleted using \c delete[].
98*/
99
100char *qstrdup( const char *src )
101{
102 if ( !src )
103 return 0;
104 char *dst = new char[strlen(src)+1];
105 Q_CHECK_PTR( dst );
106 return strcpy( dst, src );
107}
108
109/*!
110 \fn char *qstrcpy( char *dst, const char *src )
111
112 \relates QCString
113
114 A safe strcpy() function.
115
116 Copies all characters up to and including the '\0' from \a src
117 into \a dst and returns a pointer to \a dst.
118*/
119
120/*!
121 \relates QCString
122
123 A safe strncpy() function.
124
125 Copies at most \a len bytes from \a src (stopping at \a len or the
126 terminating '\0' whichever comes first) into \a dst and returns a
127 pointer to \a dst. Guarantees that \a dst is '\0'-terminated. If
128 \a src or \a dst is 0, returns 0 immediately.
129
130 \sa qstrcpy()
131*/
132
133char *qstrncpy( char *dst, const char *src, uint len )
134{
135 if ( !src || !dst )
136 return 0;
137 strncpy( dst, src, len );
138 if ( len > 0 )
139 dst[len-1] = '\0';
140 return dst;
141}
142
143/*!
144 \fn int qstrcmp( const char *str1, const char *str2 );
145
146 \relates QCString
147
148 A safe strcmp() function.
149
150 Compares \a str1 and \a str2. Returns a negative value if \a str1
151 is less than \a str2, 0 if \a str1 is equal to \a str2 or a
152 positive value if \a str1 is greater than \a str2.
153
154 Special case I: Returns 0 if \a str1 and \a str2 are both 0.
155
156 Special case II: Returns a random nonzero value if \a str1 is 0
157 or \a str2 is 0 (but not both).
158
159 \sa qstrncmp() qstricmp() qstrnicmp()
160 \link #asciinotion Note on character comparisons \endlink
161*/
162
163/*!
164 \fn int qstrncmp( const char *str1, const char *str2, uint len );
165
166 \relates QCString
167
168 A safe strncmp() function.
169
170 Compares at most \a len bytes of \a str1 and \a str2.
171
172 Returns a negative value if \a str1 is less than \a str2, 0 if \a
173 str1 is equal to \a str2 or a positive value if \a str1 is greater
174 than \a str2.
175
176 Special case I: Returns 0 if \a str1 and \a str2 are both 0.
177
178 Special case II: Returns a random nonzero value if \a str1 is 0
179 or \a str2 is 0 (but not both).
180
181 \sa qstrcmp(), qstricmp(), qstrnicmp()
182 \link #asciinotion Note on character comparisons \endlink
183*/
184
185/*!
186 \relates QCString
187
188 A safe stricmp() function.
189
190 Compares \a str1 and \a str2 ignoring the case.
191
192 Returns a negative value if \a str1 is less than \a str2, 0 if \a
193 str1 is equal to \a str2 or a positive value if \a str1 is greater
194 than \a str2.
195
196 Special case I: Returns 0 if \a str1 and \a str2 are both 0.
197
198 Special case II: Returns a random nonzero value if \a str1 is 0
199 or \a str2 is 0 (but not both).
200
201 \sa qstrcmp(), qstrncmp(), qstrnicmp()
202 \link #asciinotion Note on character comparisons \endlink
203*/
204
205int qstricmp( const char *str1, const char *str2 )
206{
207 register const uchar *s1 = (const uchar *)str1;
208 register const uchar *s2 = (const uchar *)str2;
209 int res;
210 uchar c;
211 if ( !s1 || !s2 )
212 return s1 ? 1 : ( s2 ? -1 : 0 );
213 for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
214 if ( !c ) // strings are equal
215 break;
216 return res;
217}
218
219/*!
220 \relates QCString
221
222 A safe strnicmp() function.
223
224 Compares at most \a len bytes of \a str1 and \a str2 ignoring the case.
225
226 Returns a negative value if \a str1 is less than \a str2, 0 if \a str1
227 is equal to \a str2 or a positive value if \a str1 is greater than \a
228 str2.
229
230 Special case I: Returns 0 if \a str1 and \a str2 are both 0.
231
232 Special case II: Returns a random nonzero value if \a str1 is 0
233 or \a str2 is 0 (but not both).
234
235 \sa qstrcmp(), qstrncmp() qstricmp()
236 \link #asciinotion Note on character comparisons \endlink
237*/
238
239int qstrnicmp( const char *str1, const char *str2, uint len )
240{
241 register const uchar *s1 = (const uchar *)str1;
242 register const uchar *s2 = (const uchar *)str2;
243 int res;
244 uchar c;
245 if ( !s1 || !s2 )
246 return s1 ? 1 : ( s2 ? -1 : 0 );
247 for ( ; len--; s1++, s2++ ) {
248 if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
249 return res;
250 if ( !c ) // strings are equal
251 break;
252 }
253 return 0;
254}
255
256
257static Q_UINT16 crc_tbl[16];
258static bool crc_tbl_init = FALSE;
259
260 static void createCRC16Table() // build CRC16 lookup table
261{
262 register uint i;
263 register uint j;
264 uint v0, v1, v2, v3;
265 for ( i = 0; i < 16; i++ ) {
266 v0 = i & 1;
267 v1 = ( i >> 1 ) & 1;
268 v2 = ( i >> 2 ) & 1;
269 v3 = ( i >> 3 ) & 1;
270 j = 0;
271#undef SET_BIT
272#define SET_BIT(x, b, v) (x) |= (v) << (b)
273 SET_BIT( j, 0, v0 );
274 SET_BIT( j, 7, v0 );
275 SET_BIT( j, 12, v0 );
276 SET_BIT( j, 1, v1 );
277 SET_BIT( j, 8, v1 );
278 SET_BIT( j, 13, v1 );
279 SET_BIT( j, 2, v2 );
280 SET_BIT( j, 9, v2 );
281 SET_BIT( j, 14, v2 );
282 SET_BIT( j, 3, v3 );
283 SET_BIT( j, 10, v3 );
284 SET_BIT( j, 15, v3 );
285 crc_tbl[i] = j;
286 }
287}
288
289/*!
290 \relates QMemArray
291
292 Returns the CRC-16 checksum of \a len bytes starting at \a data.
293
294 The checksum is independent of the byte order (endianness).
295*/
296
297Q_UINT16 qChecksum( const char *data, uint len )
298{
299 if ( !crc_tbl_init ) { // create lookup table
300
301#ifdef QT_THREAD_SUPPORT
302 QMutexLocker locker( qt_global_mutexpool->get( &crc_tbl_init ) );
303#endif // QT_THREAD_SUPPORT
304
305 if ( !crc_tbl_init ) {
306 createCRC16Table();
307 crc_tbl_init = TRUE;
308 }
309 }
310 register Q_UINT16 crc = 0xffff;
311 uchar c;
312 uchar *p = (uchar *)data;
313 while ( len-- ) {
314 c = *p++;
315 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
316 c >>= 4;
317 crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
318 }
319 return ~crc & 0xffff;
320}
321
322/*! \fn QByteArray qCompress( const QByteArray& data)
323 \relates QByteArray
324 \overload
325*/
326
327/*!
328 \relates QByteArray
329
330 Compresses the array \a data which is \a nbytes long and returns the
331 compressed byte array.
332
333 \sa qUncompress()
334*/
335
336#ifndef QT_NO_COMPRESS
337QByteArray qCompress( const uchar* data, int nbytes )
338{
339 if ( nbytes == 0 ) {
340 QByteArray tmp( 4 );
341 tmp.fill( 0 );
342 return tmp;
343 }
344 if ( !data ) {
345#if defined(QT_CHECK_RANGE)
346 qWarning( "qCompress: data is NULL." );
347#endif
348 return QByteArray();
349 }
350
351 ulong len = nbytes * 2;
352 QByteArray bazip;
353 int res;
354 do {
355 bazip.resize( len + 4 );
356 res = ::compress( (uchar*)bazip.data()+4, &len, (uchar*)data, nbytes );
357
358 switch ( res ) {
359 case Z_OK:
360 bazip.resize( len + 4 );
361 bazip[0] = ( nbytes & 0xff000000 ) >> 24;
362 bazip[1] = ( nbytes & 0x00ff0000 ) >> 16;
363 bazip[2] = ( nbytes & 0x0000ff00 ) >> 8;
364 bazip[3] = ( nbytes & 0x000000ff );
365 break;
366 case Z_MEM_ERROR:
367#if defined(QT_CHECK_RANGE)
368 qWarning( "qCompress: Z_MEM_ERROR: Not enough memory." );
369#endif
370 bazip.resize( 0 );
371 break;
372 case Z_BUF_ERROR:
373 len *= 2;
374 break;
375 }
376 } while ( res == Z_BUF_ERROR );
377
378 return bazip;
379}
380#endif
381
382/*! \fn QByteArray qUncompress( const QByteArray& data )
383 \relates QByteArray
384 \overload
385*/
386
387/*!
388 \relates QByteArray
389
390 Uncompresses the array \a data which is \a nbytes long and returns
391 the uncompressed byte array.
392
393 Returns an empty QByteArray if the input data was corrupt.
394
395 \sa qCompress()
396*/
397
398#ifndef QT_NO_COMPRESS
399QByteArray qUncompress( const uchar* data, int nbytes )
400{
401 if ( !data ) {
402#if defined(QT_CHECK_RANGE)
403 qWarning( "qUncompress: data is NULL." );
404#endif
405 return QByteArray();
406 }
407 if ( nbytes <= 4 ) {
408#if defined(QT_CHECK_RANGE)
409 if ( nbytes < 4 || ( data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0 ) )
410 qWarning( "qUncompress: Input data is corrupted." );
411#endif
412 return QByteArray();
413 }
414 ulong expectedSize = ( data[0] << 24 ) | ( data[1] << 16 ) | ( data[2] << 8 ) | data[3];
415 ulong len = QMAX( expectedSize, 1 );
416 QByteArray baunzip;
417 int res;
418 do {
419 baunzip.resize( len );
420 res = ::uncompress( (uchar*)baunzip.data(), &len,
421 (uchar*)data+4, nbytes-4 );
422
423 switch ( res ) {
424 case Z_OK:
425 if ( len != baunzip.size() )
426 baunzip.resize( len );
427 break;
428 case Z_MEM_ERROR:
429#if defined(QT_CHECK_RANGE)
430 qWarning( "qUncompress: Z_MEM_ERROR: Not enough memory." );
431#endif
432 break;
433 case Z_BUF_ERROR:
434 len *= 2;
435 break;
436 case Z_DATA_ERROR:
437#if defined(QT_CHECK_RANGE)
438 qWarning( "qUncompress: Z_DATA_ERROR: Input data is corrupted." );
439#endif
440 break;
441 }
442 } while ( res == Z_BUF_ERROR );
443
444 if ( res != Z_OK )
445 baunzip = QByteArray();
446
447 return baunzip;
448}
449#endif
450
451/*****************************************************************************
452 QByteArray documentation
453 *****************************************************************************/
454
455/*!
456 \class QByteArray
457 \reentrant
458 \brief The QByteArray class provides an array of bytes.
459
460 \ingroup collection
461 \ingroup tools
462
463 The QByteArray class provides an explicitly shared array of bytes.
464 It is useful for manipulating memory areas with custom data.
465 QByteArray is implemented as a QMemArray\<char\>. See the \l
466 QMemArray documentation for further information.
467*/
468
469/*!
470 \fn QByteArray::QByteArray()
471
472 Constructs an empty QByteArray.
473*/
474
475/*!
476 \fn QByteArray::QByteArray( int size )
477
478 Constructs a QByteArray of size \a size.
479*/
480
481/*****************************************************************************
482 QByteArray stream functions
483 *****************************************************************************/
484
485/*!
486 \relates QMemArray
487
488 Writes byte array \a a to the stream \a s and returns a reference
489 to the stream.
490
491 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
492*/
493#ifndef QT_NO_DATASTREAM
494
495QDataStream &operator<<( QDataStream &s, const QByteArray &a )
496{
497 return s.writeBytes( a.data(), a.size() );
498}
499
500/*!
501 \relates QMemArray
502
503 Reads a byte array into \a a from the stream \a s and returns a
504 reference to the stream.
505
506 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
507*/
508
509QDataStream &operator>>( QDataStream &s, QByteArray &a )
510{
511 Q_UINT32 len;
512 s >> len; // read size of array
513 if ( len == 0 || s.eof() ) { // end of file reached
514 a.resize( 0 );
515 return s;
516 }
517 if ( !a.resize( (uint)len ) ) { // resize array
518#if defined(QT_CHECK_NULL)
519 qWarning( "QDataStream: Not enough memory to read QByteArray" );
520#endif
521 len = 0;
522 }
523 if ( len > 0 ) // not null array
524 s.readRawBytes( a.data(), (uint)len );
525 return s;
526}
527
528#endif //QT_NO_DATASTREAM
529
530/*****************************************************************************
531 QCString member functions
532 *****************************************************************************/
533
534/*!
535 \class QCString qcstring.h
536 \reentrant
537 \brief The QCString class provides an abstraction of the classic C
538 zero-terminated char array (char *).
539
540 \ingroup text
541 \ingroup collection
542 \ingroup tools
543 \ingroup shared
544
545 QCString inherits QByteArray, which is defined as
546 QMemArray\<char\>. Since QCString is a QMemArray, it uses \link
547 shclass.html explicit sharing\endlink with a reference count.
548
549 QCString tries to behave like a more convenient \c{const char *}.
550 The price of doing this is that some algorithms will perform
551 badly. For example, append() is O(length()) since it scans for a
552 null terminator. Although you might use QCString for text that is
553 never exposed to the user, for most purposes, and especially for
554 user-visible text, you should use QString. QString provides
555 implicit sharing, Unicode and other internationalization support,
556 and is well optimized.
557
558 Note that for the QCString methods that take a \c{const char *}
559 parameter the \c{const char *} must either be 0 (null) or not-null
560 and '\0' (NUL byte) terminated; otherwise the results are
561 undefined.
562
563 A QCString that has not been assigned to anything is \e null, i.e.
564 both the length and the data pointer is 0. A QCString that
565 references the empty string ("", a single '\0' char) is \e empty.
566 Both null and empty QCStrings are legal parameters to the methods.
567 Assigning \c{const char *} 0 to QCString produces a null QCString.
568
569 The length() function returns the length of the string; resize()
570 resizes the string and truncate() truncates the string. A string
571 can be filled with a character using fill(). Strings can be left
572 or right padded with characters using leftJustify() and
573 rightJustify(). Characters, strings and regular expressions can be
574 searched for using find() and findRev(), and counted using
575 contains().
576
577 Strings and characters can be inserted with insert() and appended
578 with append(). A string can be prepended with prepend().
579 Characters can be removed from the string with remove() and
580 replaced with replace().
581
582 Portions of a string can be extracted using left(), right() and
583 mid(). Whitespace can be removed using stripWhiteSpace() and
584 simplifyWhiteSpace(). Strings can be converted to uppercase or
585 lowercase with upper() and lower() respectively.
586
587 Strings that contain numbers can be converted to numbers with
588 toShort(), toInt(), toLong(), toULong(), toFloat() and toDouble().
589 Numbers can be converted to strings with setNum().
590
591 Many operators are overloaded to work with QCStrings. QCString
592 also supports some more obscure functions, e.g. sprintf(),
593 setStr() and setExpand().
594
595 \target asciinotion
596 \sidebar Note on Character Comparisons
597
598 In QCString the notion of uppercase and lowercase and of which
599 character is greater than or less than another character is locale
600 dependent. This affects functions which support a case insensitive
601 option or which compare or lowercase or uppercase their arguments.
602 Case insensitive operations and comparisons will be accurate if
603 both strings contain only ASCII characters. (If \c $LC_CTYPE is
604 set, most Unix systems do "the right thing".) Functions that this
605 affects include contains(), find(), findRev(), \l operator<(), \l
606 operator<=(), \l operator>(), \l operator>=(), lower() and
607 upper().
608
609 This issue does not apply to \l{QString}s since they represent
610 characters using Unicode.
611 \endsidebar
612
613 Performance note: The QCString methods for QRegExp searching are
614 implemented by converting the QCString to a QString and performing
615 the search on that. This implies a deep copy of the QCString data.
616 If you are going to perform many QRegExp searches on a large
617 QCString, you will get better performance by converting the
618 QCString to a QString yourself, and then searching in the QString.
619*/
620
621/*!
622 \fn QCString::QCString()
623
624 Constructs a null string.
625
626 \sa isNull()
627*/
628
629/*!
630 \fn QCString::QCString( const QCString &s )
631
632 Constructs a shallow copy \a s.
633
634 \sa assign()
635*/
636
637/*!
638 Constructs a string with room for \a size characters, including
639 the '\0'-terminator. Makes a null string if \a size == 0.
640
641 If \a size \> 0, then the first and last characters in the string
642 are initialized to '\0'. All other characters are uninitialized.
643
644 \sa resize(), isNull()
645*/
646
647QCString::QCString( int size )
648 : QByteArray( size )
649{
650 if ( size > 0 ) {
651 *data() = '\0'; // set terminator
652 *(data()+(size-1)) = '\0';
653 }
654}
655
656/*!
657 Constructs a string that is a deep copy of \a str.
658
659 If \a str is 0 a null string is created.
660
661 \sa isNull()
662*/
663
664QCString::QCString( const char *str )
665{
666 duplicate( str, qstrlen(str) + 1 );
667}
668
669
670/*!
671 Constructs a string that is a deep copy of \a str. The copy will
672 be at most \a maxsize bytes long including the '\0'-terminator.
673
674 Example:
675 \code
676 QCString str( "helloworld", 6 ); // assigns "hello" to str
677 \endcode
678
679 If \a str contains a 0 byte within the first \a maxsize bytes, the
680 resulting QCString will be terminated by this 0. If \a str is 0 a
681 null string is created.
682
683 \sa isNull()
684*/
685
686QCString::QCString( const char *str, uint maxsize )
687{
688 if ( str == 0 )
689 return;
690 uint len; // index of first '\0'
691 for ( len = 0; len < maxsize - 1; len++ ) {
692 if ( str[len] == '\0' )
693 break;
694 }
695 QByteArray::resize( len + 1 );
696 memcpy( data(), str, len );
697 data()[len] = 0;
698}
699
700/*!
701 \reimp
702*/
703
704QCString::~QCString()
705{
706}
707
708/*!
709 \fn QCString &QCString::operator=( const QCString &s )
710
711 Assigns a shallow copy of \a s to this string and returns a
712 reference to this string.
713*/
714
715/*!
716 \overload QCString &QCString::operator=( const char *str )
717
718 Assigns a deep copy of \a str to this string and returns a
719 reference to this string.
720
721 If \a str is 0 a null string is created.
722
723 \sa isNull()
724*/
725
726/*!
727 \fn bool QCString::isNull() const
728
729 Returns TRUE if the string is null, i.e. if data() == 0; otherwise
730 returns FALSE. A null string is also an empty string.
731
732 Example:
733 \code
734 QCString a; // a.data() == 0, a.size() == 0, a.length() == 0
735 QCString b == "";// b.data() == "", b.size() == 1, b.length() == 0
736 a.isNull(); // TRUE because a.data() == 0
737 a.isEmpty();// TRUE because a.length() == 0
738 b.isNull(); // FALSE because b.data() == ""
739 b.isEmpty();// TRUE because b.length() == 0
740 \endcode
741
742 \sa isEmpty(), length(), size()
743*/
744
745/*!
746 \fn bool QCString::isEmpty() const
747
748 Returns TRUE if the string is empty, i.e. if length() == 0;
749 otherwise returns FALSE. An empty string is not always a null
750 string.
751
752 See example in isNull().
753
754 \sa isNull(), length(), size()
755*/
756
757/*!
758 \fn uint QCString::length() const
759
760 Returns the length of the string, excluding the '\0'-terminator.
761 Equivalent to calling \c strlen(data()).
762
763 Null strings and empty strings have zero length.
764
765 \sa size(), isNull(), isEmpty()
766*/
767
768/*!
769 \fn bool QCString::truncate( uint pos )
770
771 Truncates the string at position \a pos.
772
773 Equivalent to calling \c resize(pos+1).
774
775 Example:
776 \code
777 QCString s = "truncate this string";
778 s.truncate( 5 ); // s == "trunc"
779 \endcode
780
781 \sa resize()
782*/
783
784/*!
785 Extends or shrinks the string to \a len bytes, including the
786 '\0'-terminator.
787
788 A '\0'-terminator is set at position \c{len - 1} unless
789 \c{len == 0}.
790
791 Example:
792 \code
793 QCString s = "resize this string";
794 s.resize( 7 ); // s == "resize"
795 \endcode
796
797 \sa truncate()
798*/
799
800bool QCString::resize( uint len )
801{
802 detach();
803 uint wasNull = isNull();
804 if ( !QByteArray::resize(len) )
805 return FALSE;
806 if ( len )
807 data()[len - 1] = '\0';
808 if ( len > 0 && wasNull )
809 data()[0] = '\0';
810 return TRUE;
811}
812
813
814/*!
815 Implemented as a call to the native vsprintf() (see the manual for
816 your C library).
817
818 If the string is shorter than 256 characters, this sprintf() calls
819 resize(256) to decrease the chance of memory corruption. The
820 string is resized back to its actual length before sprintf()
821 returns.
822
823 Example:
824 \code
825 QCString s;
826 s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars
827
828 QCString big( 25000 ); // very long string
829 big.sprintf( "%d - %s", 2, longString );// result < 25000 chars
830 \endcode
831
832 \warning All vsprintf() implementations will write past the end of
833 the target string (*this) if the \a format specification and
834 arguments happen to be longer than the target string, and some
835 will also fail if the target string is longer than some arbitrary
836 implementation limit.
837
838 Giving user-supplied arguments to sprintf() is risky: Sooner or
839 later someone will paste a huge line into your application.
840*/
841
842QCString &QCString::sprintf( const char *format, ... )
843{
844 detach();
845 va_list ap;
846 va_start( ap, format );
847 if ( size() < 256 )
848 QByteArray::resize( 256 ); // make string big enough
849 vsprintf( data(), format, ap );
850 resize( qstrlen(data()) + 1 ); // truncate
851 va_end( ap );
852 return *this;
853}
854
855
856/*!
857 Fills the string with \a len bytes of character \a c, followed by
858 a '\0'-terminator.
859
860 If \a len is negative, then the current string length is used.
861
862 Returns FALSE is \a len is nonnegative and there is not enough
863 memory to resize the string; otherwise returns TRUE.
864*/
865
866bool QCString::fill( char c, int len )
867{
868 detach();
869 if ( len < 0 )
870 len = length();
871 if ( !QByteArray::fill(c,len+1) )
872 return FALSE;
873 *(data()+len) = '\0';
874 return TRUE;
875}
876
877
878/*!
879 \fn QCString QCString::copy() const
880
881 Returns a deep copy of this string.
882
883 \sa detach()
884*/
885
886
887/*!
888 Finds the first occurrence of the character \a c, starting at
889 position \a index.
890
891 The search is case sensitive if \a cs is TRUE, or case insensitive
892 if \a cs is FALSE.
893
894 Returns the position of \a c, or -1 if \a c could not be found.
895
896 \sa \link #asciinotion Note on character comparisons \endlink
897*/
898
899int QCString::find( char c, int index, bool cs ) const
900{
901 if ( (uint)index >= size() ) // index outside string
902 return -1;
903 register const char *d;
904 if ( cs ) { // case sensitive
905 d = strchr( data()+index, c );
906 } else {
907 d = data()+index;
908 c = tolower( (uchar) c );
909 while ( *d && tolower((uchar) *d) != c )
910 d++;
911 if ( !*d && c ) // not found
912 d = 0;
913 }
914 return d ? (int)(d - data()) : -1;
915}
916
917#define REHASH( a ) \
918 if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
919 hashHaystack -= (a) << sl_minus_1; \
920 hashHaystack <<= 1
921
922/*!
923 \overload
924
925 Finds the first occurrence of the string \a str, starting at
926 position \a index.
927
928 The search is case sensitive if \a cs is TRUE, or case insensitive
929 if \a cs is FALSE.
930
931 Returns the position of \a str, or -1 if \a str could not be
932 found.
933
934 \sa \link #asciinotion Note on character comparisons \endlink
935*/
936
937int QCString::find( const char *str, int index, bool cs ) const
938{
939 if ( (uint)index >= size() )
940 return -1;
941 if ( !str )
942 return -1;
943 if ( !*str )
944 return index;
945 const uint l = length();
946 const uint sl = qstrlen( str );
947 if ( sl + index > l )
948 return -1;
949
950 if ( sl == 1 )
951 return find( *str, index, cs );
952
953 /*
954 See QString::find() for details.
955 */
956 const char* needle = str;
957 const char* haystack = data() + index;
958 const char* end = data() + (l-sl);
959 const uint sl_minus_1 = sl-1;
960 uint hashNeedle = 0, hashHaystack = 0,i;
961
962 if ( cs ) {
963 for ( i = 0; i < sl; ++i ) {
964 hashNeedle = ((hashNeedle<<1) + needle[i] );
965 hashHaystack = ((hashHaystack<<1) + haystack[i] );
966 }
967 hashHaystack -= *(haystack+sl_minus_1);
968
969 while ( haystack <= end ) {
970 hashHaystack += *(haystack+sl_minus_1);
971 if ( hashHaystack == hashNeedle && *needle == *haystack
972 && qstrncmp( needle, haystack, sl ) == 0 )
973 return haystack - data();
974
975 REHASH( *haystack );
976 ++haystack;
977 }
978 } else {
979 for ( i = 0; i < sl; ++i ) {
980 hashNeedle = ((hashNeedle<<1) +
981 tolower( needle[i] ) );
982 hashHaystack = ((hashHaystack<<1) +
983 tolower( haystack[i] ) );
984 }
985 hashHaystack -= tolower(*(haystack+sl_minus_1));
986
987 while ( haystack <= end ) {
988 hashHaystack += tolower(*(haystack+sl_minus_1));
989 if ( hashHaystack == hashNeedle
990 && qstrnicmp( needle, haystack, sl ) == 0 )
991 return haystack - data();
992
993 REHASH( tolower(*haystack) );
994 ++haystack;
995 }
996 }
997 return -1;
998}
999
1000
1001/*!
1002 Finds the first occurrence of the character \a c, starting at
1003 position \a index and searching backwards.
1004
1005 The search is case sensitive if \a cs is TRUE, or case insensitive
1006 if \a cs is FALSE.
1007
1008 Returns the position of \a c, or -1 if \a c could not be found.
1009
1010 \sa \link #asciinotion Note on character comparisons \endlink
1011*/
1012
1013int QCString::findRev( char c, int index, bool cs ) const
1014{
1015 register const char *b = data();
1016 register const char *d;
1017 if ( index < 0 )
1018 index = length();
1019 if ( (uint)index >= size() )
1020 return -1;
1021 d = b + index;
1022 if ( cs ) {
1023 while ( d >= b && *d != c )
1024 d--;
1025 } else {
1026 c = tolower( (uchar) c );
1027 while ( d >= b && tolower((uchar) *d) != c )
1028 d--;
1029 }
1030 return d >= b ? (int)(d - b) : -1;
1031}
1032
1033/*!
1034 \overload
1035
1036 Finds the first occurrence of the string \a str, starting at
1037 position \a index and searching backwards.
1038
1039 The search is case sensitive if \a cs is TRUE, or case insensitive
1040 if \a cs is FALSE.
1041
1042 Returns the position of \a str, or -1 if \a str could not be
1043 found.
1044
1045 \sa \link #asciinotion Note on character comparisons \endlink
1046*/
1047
1048int QCString::findRev( const char *str, int index, bool cs ) const
1049{
1050 /*
1051 See QString::find() for explanations.
1052 */
1053 const uint sl = qstrlen( str );
1054 const uint l = length();
1055 int delta = l-sl;
1056 if ( index < 0 )
1057 index = delta;
1058 if ( index < 0 || index > (int)l )
1059 return -1;
1060 if ( index > delta )
1061 index = delta;
1062
1063 if ( sl == 1 )
1064 return findRev( *str, index, cs );
1065
1066 const char* needle = str;
1067 const char* haystack = data() + index;
1068 const char* end = data();
1069 const uint sl_minus_1 = sl-1;
1070 const char* n = needle+sl_minus_1;
1071 const char* h = haystack+sl_minus_1;
1072 uint hashNeedle = 0, hashHaystack = 0, i;
1073
1074 if ( cs ) {
1075 for ( i = 0; i < sl; ++i ) {
1076 hashNeedle = ((hashNeedle<<1) + *(n-i) );
1077 hashHaystack = ((hashHaystack<<1) + *(h-i) );
1078 }
1079 hashHaystack -= *haystack;
1080 while ( haystack >= end ) {
1081 hashHaystack += *haystack;
1082 if ( hashHaystack == hashNeedle && qstrncmp( needle, haystack, sl ) == 0 )
1083 return haystack-data();
1084 --haystack;
1085 REHASH( *(haystack+sl) );
1086 }
1087 } else {
1088 for ( i = 0; i < sl; ++i ) {
1089 hashNeedle = ((hashNeedle<<1) + tolower( *(n-i) ) );
1090 hashHaystack = ((hashHaystack<<1) + tolower( *(h-i) ) );
1091 }
1092 hashHaystack -= tolower(*haystack);
1093 while ( haystack >= end ) {
1094 hashHaystack += tolower(*haystack);
1095 if ( hashHaystack == hashNeedle && qstrnicmp( needle, haystack, sl ) == 0 )
1096 return haystack-data();
1097 --haystack;
1098 REHASH( tolower(*(haystack+sl)) );
1099 }
1100 }
1101 return -1;
1102}
1103
1104
1105/*!
1106 Returns the number of times the character \a c occurs in the
1107 string.
1108
1109 The match is case sensitive if \a cs is TRUE, or case insensitive
1110 if \a cs if FALSE.
1111
1112 \sa \link #asciinotion Note on character comparisons \endlink
1113*/
1114
1115int QCString::contains( char c, bool cs ) const
1116{
1117 int count = 0;
1118 char *d = data();
1119 if ( !d )
1120 return 0;
1121 if ( cs ) { // case sensitive
1122 while ( *d )
1123 if ( *d++ == c )
1124 count++;
1125 } else { // case insensitive
1126 c = tolower( (uchar) c );
1127 while ( *d ) {
1128 if ( tolower((uchar) *d) == c )
1129 count++;
1130 d++;
1131 }
1132 }
1133 return count;
1134}
1135
1136/*!
1137 \overload
1138
1139 Returns the number of times \a str occurs in the string.
1140
1141 The match is case sensitive if \a cs is TRUE, or case insensitive
1142 if \a cs if FALSE.
1143
1144 This function counts overlapping substrings, for example, "banana"
1145 contains two occurrences of "ana".
1146
1147 \sa findRev()
1148 \link #asciinotion Note on character comparisons \endlink
1149*/
1150
1151int QCString::contains( const char *str, bool cs ) const
1152{
1153 int count = 0;
1154 int i = -1;
1155 // use find for the faster hashing algorithm
1156 while ( ( i = find ( str, i+1, cs ) ) != -1 )
1157 count++;
1158 return count;
1159}
1160
1161/*!
1162 Returns a substring that contains the \a len leftmost characters
1163 of the string.
1164
1165 The whole string is returned if \a len exceeds the length of the
1166 string.
1167
1168 Example:
1169 \code
1170 QCString s = "Pineapple";
1171 QCString t = s.left( 4 ); // t == "Pine"
1172 \endcode
1173
1174 \sa right(), mid()
1175*/
1176
1177QCString QCString::left( uint len ) const
1178{
1179 if ( isEmpty() ) {
1180 QCString empty;
1181 return empty;
1182 } else if ( len >= size() ) {
1183 QCString same( data() );
1184 return same;
1185 } else {
1186 QCString s( len+1 );
1187 strncpy( s.data(), data(), len );
1188 *(s.data()+len) = '\0';
1189 return s;
1190 }
1191}
1192
1193/*!
1194 Returns a substring that contains the \a len rightmost characters
1195 of the string.
1196
1197 The whole string is returned if \a len exceeds the length of the
1198 string.
1199
1200 Example:
1201 \code
1202 QCString s = "Pineapple";
1203 QCString t = s.right( 5 ); // t == "apple"
1204 \endcode
1205
1206 \sa left(), mid()
1207*/
1208
1209QCString QCString::right( uint len ) const
1210{
1211 if ( isEmpty() ) {
1212 QCString empty;
1213 return empty;
1214 } else {
1215 uint l = length();
1216 if ( len > l )
1217 len = l;
1218 char *p = data() + (l - len);
1219 return QCString( p );
1220 }
1221}
1222
1223/*!
1224 Returns a substring that contains at most \a len characters from
1225 this string, starting at position \a index.
1226
1227 Returns a null string if the string is empty or if \a index is out
1228 of range. Returns the whole string from \a index if \a index+len
1229 exceeds the length of the string.
1230
1231 Example:
1232 \code
1233 QCString s = "Two pineapples";
1234 QCString t = s.mid( 4, 3 ); // t == "pin"
1235 \endcode
1236
1237 \sa left(), right()
1238*/
1239
1240QCString QCString::mid( uint index, uint len ) const
1241{
1242 uint slen = qstrlen( data() );
1243 if ( isEmpty() || index >= slen ) {
1244 QCString empty;
1245 return empty;
1246 } else {
1247 if ( len > slen-index )
1248 len = slen - index;
1249 register char *p = data()+index;
1250 QCString s( len+1 );
1251 strncpy( s.data(), p, len );
1252 *(s.data()+len) = '\0';
1253 return s;
1254 }
1255}
1256
1257/*!
1258 Returns a string of length \a width (plus one for the terminating
1259 '\0') that contains this string padded with the \a fill character.
1260
1261 If the length of the string exceeds \a width and \a truncate is
1262 FALSE (the default), then the returned string is a copy of the
1263 string. If the length of the string exceeds \a width and \a
1264 truncate is TRUE, then the returned string is a left(\a width).
1265
1266 Example:
1267 \code
1268 QCString s("apple");
1269 QCString t = s.leftJustify(8, '.'); // t == "apple..."
1270 \endcode
1271
1272 \sa rightJustify()
1273*/
1274
1275QCString QCString::leftJustify( uint width, char fill, bool truncate ) const
1276{
1277 QCString result;
1278 int len = qstrlen(data());
1279 int padlen = width - len;
1280 if ( padlen > 0 ) {
1281 result.QByteArray::resize( len+padlen+1 );
1282 memcpy( result.data(), data(), len );
1283 memset( result.data()+len, fill, padlen );
1284 result[len+padlen] = '\0';
1285 } else {
1286 if ( truncate )
1287 result = left( width );
1288 else
1289 result = copy();
1290 }
1291 return result;
1292}
1293
1294/*!
1295 Returns a string of length \a width (plus one for the terminating
1296 '\0') that contains zero or more of the \a fill character followed
1297 by this string.
1298
1299 If the length of the string exceeds \a width and \a truncate is
1300 FALSE (the default), then the returned string is a copy of the
1301 string. If the length of the string exceeds \a width and \a
1302 truncate is TRUE, then the returned string is a left(\a width).
1303
1304 Example:
1305 \code
1306 QCString s("pie");
1307 QCString t = s.rightJustify(8, '.'); // t == ".....pie"
1308 \endcode
1309
1310 \sa leftJustify()
1311*/
1312
1313QCString QCString::rightJustify( uint width, char fill, bool truncate ) const
1314{
1315 QCString result;
1316 int len = qstrlen(data());
1317 int padlen = width - len;
1318 if ( padlen > 0 ) {
1319 result.QByteArray::resize( len+padlen+1 );
1320 memset( result.data(), fill, padlen );
1321 memcpy( result.data()+padlen, data(), len );
1322 result[len+padlen] = '\0';
1323 } else {
1324 if ( truncate )
1325 result = left( width );
1326 else
1327 result = copy();
1328 }
1329 return result;
1330}
1331
1332/*!
1333 Returns a new string that is a copy of this string converted to lower
1334 case.
1335
1336 Example:
1337 \code
1338 QCString s("Credit");
1339 QCString t = s.lower(); // t == "credit"
1340 \endcode
1341
1342 \sa upper()
1343 \link #asciinotion Note on character comparisons \endlink
1344*/
1345
1346QCString QCString::lower() const
1347{
1348 QCString s( data() );
1349 register char *p = s.data();
1350 if ( p ) {
1351 while ( *p ) {
1352 *p = tolower( (uchar) *p );
1353 p++;
1354 }
1355 }
1356 return s;
1357}
1358
1359/*!
1360 Returns a new string that is a copy of this string converted to upper case.
1361
1362 Example:
1363 \code
1364 QCString s( "Debit" );
1365 QCString t = s.upper(); // t == "DEBIT"
1366 \endcode
1367
1368 \sa lower()
1369 \link #asciinotion Note on character comparisons \endlink
1370*/
1371
1372QCString QCString::upper() const
1373{
1374 QCString s( data() );
1375 register char *p = s.data();
1376 if ( p ) {
1377 while ( *p ) {
1378 *p = toupper(*p);
1379 p++;
1380 }
1381 }
1382 return s;
1383}
1384
1385
1386/*!
1387 Returns a new string that has white space removed from the start
1388 and the end.
1389
1390 White space means the decimal ASCII codes 9, 10, 11, 12, 13 and
1391 32.
1392
1393 Example:
1394 \code
1395 QCString s = " space ";
1396 QCString t = s.stripWhiteSpace(); // t == "space"
1397 \endcode
1398
1399 \sa simplifyWhiteSpace()
1400*/
1401
1402QCString QCString::stripWhiteSpace() const
1403{
1404 if ( isEmpty() ) // nothing to do
1405 return copy();
1406
1407 register char *s = data();
1408 QCString result = s;
1409 int reslen = result.length();
1410 if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
1411 return result; // returns a copy
1412
1413 s = result.data();
1414 int start = 0;
1415 int end = reslen - 1;
1416 while ( isspace((uchar) s[start]) ) // skip white space from start
1417 start++;
1418 if ( s[start] == '\0' ) { // only white space
1419 result.resize( 1 );
1420 return result;
1421 }
1422 while ( end && isspace((uchar) s[end]) )// skip white space from end
1423 end--;
1424 end -= start - 1;
1425 memmove( result.data(), &s[start], end );
1426 result.resize( end + 1 );
1427 return result;
1428}
1429
1430
1431/*!
1432 Returns a new string that has white space removed from the start
1433 and the end, plus any sequence of internal white space replaced
1434 with a single space (ASCII 32).
1435
1436 White space means the decimal ASCII codes 9, 10, 11, 12, 13 and
1437 32.
1438
1439 \code
1440 QCString s = " lots\t of\nwhite space ";
1441 QCString t = s.simplifyWhiteSpace(); // t == "lots of white space"
1442 \endcode
1443
1444 \sa stripWhiteSpace()
1445*/
1446
1447QCString QCString::simplifyWhiteSpace() const
1448{
1449 if ( isEmpty() ) // nothing to do
1450 return copy();
1451 QCString result( size() );
1452 char *from= data();
1453 char *to= result.data();
1454 char *first = to;
1455 for ( ;; ) {
1456 while ( isspace((uchar) *from) )
1457 from++;
1458 while ( *from && !isspace((uchar) *from) )
1459 *to++ = *from++;
1460 if ( *from )
1461 *to++ = 0x20; // ' '
1462 else
1463 break;
1464 }
1465 if ( to > first && *(to-1) == 0x20 )
1466 to--;
1467 *to = '\0';
1468 result.resize( (int)(to - result.data()) + 1 );
1469 return result;
1470}
1471
1472
1473/*!
1474 \overload
1475
1476 Inserts string \a s into the string at position \a index.
1477
1478 If \a index is beyond the end of the string, the string is
1479 padded with spaces (ASCII 32) to length \a index and then \a s
1480 is appended.
1481
1482 \code
1483 QCString s = "I like fish";
1484 s.insert( 2, "don't "); // s == "I don't like fish"
1485
1486 s = "x"; // index 01234
1487 s.insert( 3, "yz" ); // s == "x yz"
1488 \endcode
1489*/
1490
1491QCString &QCString::insert( uint index, const char *s )
1492{
1493 int len = qstrlen(s);
1494 if ( len == 0 )
1495 return *this;
1496 uint olen = length();
1497 int nlen = olen + len;
1498 if ( index >= olen ) { // insert after end of string
1499 detach();
1500 if ( QByteArray::resize(nlen+index-olen+1) ) {
1501 memset( data()+olen, ' ', index-olen );
1502 memcpy( data()+index, s, len+1 );
1503 }
1504 } else if ( QByteArray::resize(nlen+1) ) {// normal insert
1505 detach();
1506 memmove( data()+index+len, data()+index, olen-index+1 );
1507 memcpy( data()+index, s, len );
1508 }
1509 return *this;
1510}
1511
1512/*!
1513 Inserts character \a c into the string at position \a index and
1514 returns a reference to the string.
1515
1516 If \a index is beyond the end of the string, the string is
1517 padded with spaces (ASCII 32) to length \a index and then \a c
1518 is appended.
1519
1520 Example:
1521 \code
1522 QCString s = "Yes";
1523 s.insert( 3, '!'); // s == "Yes!"
1524 \endcode
1525
1526 \sa remove(), replace()
1527*/
1528
1529 QCString &QCString::insert( uint index, char c )// insert char
1530{
1531 char buf[2];
1532 buf[0] = c;
1533 buf[1] = '\0';
1534 return insert( index, buf );
1535}
1536
1537/*!
1538 \fn QCString &QCString::prepend( const char *s )
1539
1540 Prepend \a s to the string. Equivalent to insert(0, s).
1541
1542 \sa insert()
1543*/
1544
1545/*!
1546 Removes \a len characters from the string, starting at position \a
1547 index, and returns a reference to the string.
1548
1549 If \a index is out of range, nothing happens. If \a index is
1550 valid, but \a index + \a len is larger than the length of the
1551 string, the string is truncated at position \a index.
1552
1553 \code
1554 QCString s = "Montreal";
1555 s.remove( 1, 4 ); // s == "Meal"
1556 \endcode
1557
1558 \sa insert(), replace()
1559*/
1560
1561QCString &QCString::remove( uint index, uint len )
1562{
1563 uint olen = length();
1564 if ( index + len >= olen ) { // range problems
1565 if ( index < olen ) { // index ok
1566 detach();
1567 resize( index+1 );
1568 }
1569 } else if ( len != 0 ) {
1570 detach();
1571 memmove( data()+index, data()+index+len, olen-index-len+1 );
1572 QByteArray::resize(olen-len+1);
1573 }
1574 return *this;
1575}
1576
1577/*!
1578 Replaces \a len characters from the string, starting at position
1579 \a index, with \a str, and returns a reference to the string.
1580
1581 If \a index is out of range, nothing is removed and \a str is
1582 appended at the end of the string. If \a index is valid, but \a
1583 index + \a len is larger than the length of the string, \a str
1584 replaces the rest of the string from position \a index.
1585
1586 \code
1587 QCString s = "Say yes!";
1588 s.replace( 4, 3, "NO" ); // s == "Say NO!"
1589 \endcode
1590
1591 \sa insert(), remove()
1592*/
1593
1594QCString &QCString::replace( uint index, uint len, const char *str )
1595{
1596 remove( index, len );
1597 insert( index, str );
1598 return *this;
1599}
1600
1601
1602/*! \overload
1603
1604 Replaces every occurrence of the character \a c in the string
1605 with \a after. Returns a reference to the string.
1606
1607 Example:
1608 \code
1609 QCString s = "a,b,c";
1610 s.replace( ',', " or " );
1611 // s == "a or b or c"
1612 \endcode
1613*/
1614QCString &QCString::replace( char c, const char *after )
1615{
1616 char str[2];
1617 str[0] = c;
1618 str[1] = '\0';
1619 return replace( str, after );
1620}
1621
1622/*! \overload
1623
1624 Replaces every occurrence of the string \a before in the string
1625 with the string \a after. Returns a reference to the string.
1626
1627 Example:
1628 \code
1629 QCString s = "Greek is Greek";
1630 s.replace( "Greek", "English" );
1631 // s == "English is English"
1632 \endcode
1633*/
1634QCString &QCString::replace( const char *before, const char *after )
1635{
1636 if ( before == after || isNull() )
1637 return *this;
1638
1639 detach();
1640
1641 int index = 0;
1642 const int bl = before ? strlen( before ) : 0;
1643 const int al = after ? strlen( after ) : 0;
1644 char *d = data();
1645 uint len = length();
1646
1647 if ( bl == al ) {
1648 if ( bl ) {
1649 while( (index = find( before, index ) ) != -1 ) {
1650 memcpy( d+index, after, al );
1651 index += bl;
1652 }
1653 }
1654 } else if ( al < bl ) {
1655 uint to = 0;
1656 uint movestart = 0;
1657 uint num = 0;
1658 while( (index = find( before, index ) ) != -1 ) {
1659 if ( num ) {
1660 int msize = index - movestart;
1661 if ( msize > 0 ) {
1662 memmove( d + to, d + movestart, msize );
1663 to += msize;
1664 }
1665 } else {
1666 to = index;
1667 }
1668 if ( al ) {
1669 memcpy( d + to, after, al );
1670 to += al;
1671 }
1672 index += bl;
1673 movestart = index;
1674 num++;
1675 }
1676 if ( num ) {
1677 int msize = len - movestart;
1678 if ( msize > 0 )
1679 memmove( d + to, d + movestart, msize );
1680 resize( len - num*(bl-al) + 1 );
1681 }
1682 } else {
1683 // the most complex case. We don't want to loose performance by doing repeated
1684 // copies and reallocs of the string.
1685 while( index != -1 ) {
1686 uint indices[4096];
1687 uint pos = 0;
1688 while( pos < 4095 ) {
1689 index = find(before, index);
1690 if ( index == -1 )
1691 break;
1692 indices[pos++] = index;
1693 index += bl;
1694 // avoid infinite loop
1695 if ( !bl )
1696 index++;
1697 }
1698 if ( !pos )
1699 break;
1700
1701 // we have a table of replacement positions, use them for fast replacing
1702 int adjust = pos*(al-bl);
1703 // index has to be adjusted in case we get back into the loop above.
1704 if ( index != -1 )
1705 index += adjust;
1706 uint newlen = len + adjust;
1707 int moveend = len;
1708 if ( newlen > len ) {
1709 resize( newlen + 1 );
1710 len = newlen;
1711 }
1712 d = data();
1713
1714 while( pos ) {
1715 pos--;
1716 int movestart = indices[pos] + bl;
1717 int insertstart = indices[pos] + pos*(al-bl);
1718 int moveto = insertstart + al;
1719 memmove( d + moveto, d + movestart, (moveend - movestart) );
1720 if ( after )
1721 memcpy( d + insertstart, after, al );
1722 moveend = movestart - bl;
1723 }
1724 }
1725 }
1726 return *this;
1727}
1728
1729/*! \overload
1730
1731 Replaces every occurrence of \a c1 with the char \a c2.
1732 Returns a reference to the string.
1733*/
1734QCString &QCString::replace( char c1, char c2 )
1735{
1736 detach();
1737 uint i = 0;
1738 char *d = data();
1739 uint len = length();
1740 while ( i < len ) {
1741 if ( d[i] == c1 )
1742 d[i] = c2;
1743 i++;
1744 }
1745 return *this;
1746}
1747
1748
1749#ifndef QT_NO_REGEXP_CAPTURE
1750/*!
1751 \overload
1752
1753 Finds the first occurrence of the regular expression \a rx,
1754 starting at position \a index.
1755
1756 Returns the position of the next match, or -1 if \a rx was not
1757 found.
1758
1759 \warning If you want to apply this function repeatedly to the same
1760 string it is more efficient to convert the string to a QString and
1761 apply the function to that.
1762*/
1763
1764int QCString::find( const QRegExp& rx, int index ) const
1765{
1766 QString d = QString::fromLatin1( data() );
1767 return d.find( rx, index );
1768}
1769
1770/*!
1771 \overload
1772
1773 Finds the first occurrence of the regular expression \a rx,
1774 starting at position \a index and searching backwards.
1775
1776 Returns the position of the next match (backwards), or -1 if \a rx
1777 was not found.
1778
1779 \warning If you want to apply this function repeatedly to the same
1780 string it is more efficient to convert the string to a QString and
1781 apply the function to that.
1782*/
1783
1784int QCString::findRev( const QRegExp& rx, int index ) const
1785{
1786 QString d = QString::fromLatin1( data() );
1787 return d.findRev( rx, index );
1788}
1789
1790/*!
1791 \overload
1792
1793 Counts the number of overlapping occurrences of \a rx in the string.
1794
1795 Example:
1796 \code
1797 QString s = "banana and panama";
1798 QRegExp r = QRegExp( "a[nm]a", TRUE, FALSE );
1799 s.contains( r ); // 4 matches
1800 \endcode
1801
1802 \sa find(), findRev()
1803
1804 \warning If you want to apply this function repeatedly to the same
1805 string it is more efficient to convert the string to a QString and
1806 apply the function to that.
1807*/
1808
1809int QCString::contains( const QRegExp &rx ) const
1810{
1811 QString d = QString::fromLatin1( data() );
1812 return d.contains( rx );
1813}
1814
1815
1816/*!
1817 \overload
1818
1819 Replaces every occurrence of \a rx in the string with \a str.
1820 Returns a reference to the string.
1821
1822 Example:
1823 \code
1824 QString s = "banana";
1825 s.replace( QRegExp("a.*a"), "" ); // becomes "b"
1826
1827 s = "banana";
1828 s.replace( QRegExp("^[bn]a"), "X" ); // becomes "Xnana"
1829
1830 s = "banana";
1831 s.replace( QRegExp("^[bn]a"), "" ); // becomes "nana"
1832 \endcode
1833
1834 \warning If you want to apply this function repeatedly to the same
1835 string it is more efficient to convert the string to a QString and
1836 apply the function to that.
1837*/
1838
1839QCString &QCString::replace( const QRegExp &rx, const char *str )
1840{
1841 QString d = QString::fromLatin1( data() );
1842 QString r = QString::fromLatin1( str );
1843 d.replace( rx, r );
1844 setStr( d.ascii() );
1845 return *this;
1846}
1847#endif //QT_NO_REGEXP
1848
1849/*!
1850 Returns the string converted to a \c long value.
1851
1852 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1853 number, or if it has trailing garbage; otherwise \a *ok is set to
1854 TRUE.
1855*/
1856
1857long QCString::toLong( bool *ok ) const
1858{
1859 char *p = data();
1860 long val=0;
1861 const long max_mult = 214748364;
1862 bool is_ok = FALSE;
1863 int neg = 0;
1864 if ( !p )
1865 goto bye;
1866 while ( isspace((uchar) *p) ) // skip leading space
1867 p++;
1868 if ( *p == '-' ) {
1869 p++;
1870 neg = 1;
1871 } else if ( *p == '+' ) {
1872 p++;
1873 }
1874 if ( !isdigit((uchar) *p) )
1875 goto bye;
1876 while ( isdigit((uchar) *p) ) {
1877 if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) )
1878 goto bye;
1879 val = 10*val + (*p++ - '0');
1880 }
1881 if ( neg )
1882 val = -val;
1883 while ( isspace((uchar) *p) ) // skip trailing space
1884 p++;
1885 if ( *p == '\0' )
1886 is_ok = TRUE;
1887bye:
1888 if ( ok )
1889 *ok = is_ok;
1890 return is_ok ? val : 0;
1891}
1892
1893/*!
1894 Returns the string converted to an \c{unsigned long} value.
1895
1896 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1897 number, or if it has trailing garbage; otherwise \a *ok is set to
1898 TRUE.
1899*/
1900
1901ulong QCString::toULong( bool *ok ) const
1902{
1903 char *p = data();
1904 ulong val=0;
1905 const ulong max_mult = 429496729;
1906 bool is_ok = FALSE;
1907 if ( !p )
1908 goto bye;
1909 while ( isspace((uchar) *p) ) // skip leading space
1910 p++;
1911 if ( *p == '+' )
1912 p++;
1913 if ( !isdigit((uchar) *p) )
1914 goto bye;
1915 while ( isdigit((uchar) *p) ) {
1916 if ( val > max_mult || (val == max_mult && (*p-'0') > 5) )
1917 goto bye;
1918 val = 10*val + (*p++ - '0');
1919 }
1920 while ( isspace((uchar) *p) ) // skip trailing space
1921 p++;
1922 if ( *p == '\0' )
1923 is_ok = TRUE;
1924bye:
1925 if ( ok )
1926 *ok = is_ok;
1927 return is_ok ? val : 0;
1928}
1929
1930/*!
1931 Returns the string converted to a \c{short} value.
1932
1933 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1934 number, is out of range, or if it has trailing garbage; otherwise
1935 \a *ok is set to TRUE.
1936*/
1937
1938short QCString::toShort( bool *ok ) const
1939{
1940 long v = toLong( ok );
1941 if ( ok && *ok && (v < -32768 || v > 32767) )
1942 *ok = FALSE;
1943 return (short)v;
1944}
1945
1946/*!
1947 Returns the string converted to an \c{unsigned short} value.
1948
1949 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1950 number, is out of range, or if it has trailing garbage; otherwise
1951 \a *ok is set to TRUE.
1952*/
1953
1954ushort QCString::toUShort( bool *ok ) const
1955{
1956 ulong v = toULong( ok );
1957 if ( ok && *ok && (v > 65535) )
1958 *ok = FALSE;
1959 return (ushort)v;
1960}
1961
1962
1963/*!
1964 Returns the string converted to a \c{int} value.
1965
1966 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1967 number, or if it has trailing garbage; otherwise \a *ok is set to
1968 TRUE.
1969*/
1970
1971int QCString::toInt( bool *ok ) const
1972{
1973 return (int)toLong( ok );
1974}
1975
1976/*!
1977 Returns the string converted to an \c{unsigned int} value.
1978
1979 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1980 number, or if it has trailing garbage; otherwise \a *ok is set to
1981 TRUE.
1982*/
1983
1984uint QCString::toUInt( bool *ok ) const
1985{
1986 return (uint)toULong( ok );
1987}
1988
1989/*!
1990 Returns the string converted to a \c{double} value.
1991
1992 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
1993 number, or if it has trailing garbage; otherwise \a *ok is set to
1994 TRUE.
1995*/
1996
1997double QCString::toDouble( bool *ok ) const
1998{
1999 char *end;
2000 double val = strtod( data() ? data() : "", &end );
2001 if ( ok )
2002 *ok = ( data() && *data() && ( end == 0 || *end == '\0' ) );
2003 return val;
2004}
2005
2006/*!
2007 Returns the string converted to a \c{float} value.
2008
2009 If \a ok is not 0: \a *ok is set to FALSE if the string is not a
2010 number, or if it has trailing garbage; otherwise \a *ok is set to
2011 TRUE.
2012*/
2013
2014float QCString::toFloat( bool *ok ) const
2015{
2016 return (float)toDouble( ok );
2017}
2018
2019
2020/*!
2021 Makes a deep copy of \a str. Returns a reference to the string.
2022*/
2023
2024QCString &QCString::setStr( const char *str )
2025{
2026 detach();
2027 if ( str ) // valid string
2028 store( str, qstrlen(str)+1 );
2029 else // empty
2030 resize( 0 );
2031 return *this;
2032}
2033
2034/*!
2035 \overload
2036
2037 Sets the string to the string representation of the number \a n
2038 and returns a reference to the string.
2039*/
2040
2041QCString &QCString::setNum( long n )
2042{
2043 detach();
2044 char buf[20];
2045 register char *p = &buf[19];
2046 bool neg;
2047 if ( n < 0 ) {
2048 neg = TRUE;
2049 n = -n;
2050 } else {
2051 neg = FALSE;
2052 }
2053 *p = '\0';
2054 do {
2055 *--p = ((int)(n%10)) + '0';
2056 n /= 10;
2057 } while ( n );
2058 if ( neg )
2059 *--p = '-';
2060 store( p, qstrlen(p)+1 );
2061 return *this;
2062}
2063
2064/*!
2065 \overload
2066
2067 Sets the string to the string representation of the number \a n
2068 and returns a reference to the string.
2069*/
2070
2071QCString &QCString::setNum( ulong n )
2072{
2073 detach();
2074 char buf[20];
2075 register char *p = &buf[19];
2076 *p = '\0';
2077 do {
2078 *--p = ((int)(n%10)) + '0';
2079 n /= 10;
2080 } while ( n );
2081 store( p, qstrlen(p)+1 );
2082 return *this;
2083}
2084
2085/*!
2086 \overload QCString &QCString::setNum( int n )
2087
2088 Sets the string to the string representation of the number \a n
2089 and returns a reference to the string.
2090*/
2091
2092/*!
2093 \overload QCString &QCString::setNum( uint n )
2094
2095 Sets the string to the string representation of the number \a n
2096 and returns a reference to the string.
2097*/
2098
2099/*!
2100 \overload QCString &QCString::setNum( short n )
2101
2102 Sets the string to the string representation of the number \a n
2103 and returns a reference to the string.
2104*/
2105
2106/*!
2107 \overload QCString &QCString::setNum( ushort n )
2108
2109 Sets the string to the string representation of the number \a n
2110 and returns a reference to the string.
2111*/
2112
2113/*!
2114 Sets the string to the string representation of the number \a n
2115 and returns a reference to the string.
2116
2117 The format of the string representation is specified by the format
2118 character \a f, and the precision (number of digits after the
2119 decimal point) is specified with \a prec.
2120
2121 The valid formats for \a f are 'e', 'E', 'f', 'g' and 'G'. The
2122 formats are the same as for sprintf(); they are explained in \l
2123 QString::arg().
2124*/
2125
2126QCString &QCString::setNum( double n, char f, int prec )
2127{
2128#if defined(QT_CHECK_RANGE)
2129 if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') )
2130 qWarning( "QCString::setNum: Invalid format char '%c'", f );
2131#endif
2132 char format[20];
2133 register char *fs = format; // generate format string
2134 *fs++ = '%'; // "%.<prec>l<f>"
2135 if ( prec > 99 )
2136 prec = 99;
2137 *fs++ = '.';
2138 if ( prec >= 10 ) {
2139 *fs++ = prec / 10 + '0';
2140 *fs++ = prec % 10 + '0';
2141 } else {
2142 *fs++ = prec + '0';
2143 }
2144 *fs++ = 'l';
2145 *fs++ = f;
2146 *fs = '\0';
2147 return sprintf( format, n );
2148}
2149
2150/*! \overload QCString &QCString::setNum( float n, char f, int prec ) */
2151
2152
2153/*!
2154 Sets the character at position \a index to \a c and expands the
2155 string if necessary, padding with spaces.
2156
2157 Returns FALSE if \a index was out of range and the string could
2158 not be expanded; otherwise returns TRUE.
2159*/
2160
2161bool QCString::setExpand( uint index, char c )
2162{
2163 detach();
2164 uint oldlen = length();
2165 if ( index >= oldlen ) {
2166 if ( !QByteArray::resize( index+2 ) )// no memory
2167 return FALSE;
2168 if ( index > oldlen )
2169 memset( data() + oldlen, ' ', index - oldlen );
2170 *(data() + index+1) = '\0'; // terminate padded string
2171 }
2172 *(data() + index) = c;
2173 return TRUE;
2174}
2175
2176
2177/*!
2178 \fn QCString::operator const char *() const
2179
2180 Returns the string data.
2181*/
2182
2183
2184/*!
2185 \fn QCString& QCString::append( const char *str )
2186
2187 Appends string \a str to the string and returns a reference to the
2188 string. Equivalent to operator+=().
2189*/
2190
2191/*!
2192 Appends string \a str to the string and returns a reference to the string.
2193*/
2194
2195QCString& QCString::operator+=( const char *str )
2196{
2197 if ( !str )
2198 return *this; // nothing to append
2199 detach();
2200 uint len1 = length();
2201 uint len2 = qstrlen(str);
2202 if ( !QByteArray::resize( len1 + len2 + 1 ) )
2203 return *this; // no memory
2204 memcpy( data() + len1, str, len2 + 1 );
2205 return *this;
2206}
2207
2208/*!
2209 \overload
2210
2211 Appends character \a c to the string and returns a reference to the string.
2212*/
2213
2214QCString &QCString::operator+=( char c )
2215{
2216 detach();
2217 uint len = length();
2218 if ( !QByteArray::resize( len + 2 ) )
2219 return *this; // no memory
2220 *(data() + len) = c;
2221 *(data() + len+1) = '\0';
2222 return *this;
2223}
2224
2225
2226/*****************************************************************************
2227 QCString stream functions
2228 *****************************************************************************/
2229#ifndef QT_NO_DATASTREAM
2230/*!
2231 \relates QCString
2232
2233 Writes string \a str to the stream \a s.
2234
2235 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2236*/
2237QDataStream &operator<<( QDataStream &s, const QCString &str )
2238{
2239 return s.writeBytes( str.data(), str.size() );
2240}
2241
2242/*!
2243 \relates QCString
2244
2245 Reads a string into \a str from the stream \a s.
2246
2247 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2248*/
2249
2250QDataStream &operator>>( QDataStream &s, QCString &str )
2251{
2252 str.detach();
2253 Q_UINT32 len;
2254 s >> len; // read size of string
2255 if ( len == 0 || s.eof() ) { // end of file reached
2256 str.resize( 0 );
2257 return s;
2258 }
2259 if ( !str.QByteArray::resize( (uint)len )) {// resize string
2260#if defined(QT_CHECK_NULL)
2261 qWarning( "QDataStream: Not enough memory to read QCString" );
2262#endif
2263 len = 0;
2264 }
2265 if ( len > 0 ) // not null array
2266 s.readRawBytes( str.data(), (uint)len );
2267 return s;
2268}
2269#endif //QT_NO_DATASTREAM
2270
2271/*****************************************************************************
2272 Documentation for related functions
2273 *****************************************************************************/
2274
2275/*!
2276 \fn bool operator==( const QCString &s1, const QCString &s2 )
2277
2278 \relates QCString
2279
2280 Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
2281
2282 Equivalent to qstrcmp(\a s1, \a s2) == 0.
2283*/
2284
2285/*!
2286 \overload bool operator==( const QCString &s1, const char *s2 )
2287
2288 \relates QCString
2289
2290 Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
2291
2292 Equivalent to qstrcmp(\a s1, \a s2) == 0.
2293*/
2294
2295/*!
2296 \overload bool operator==( const char *s1, const QCString &s2 )
2297
2298 \relates QCString
2299
2300 Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
2301
2302 Equivalent to qstrcmp(\a s1, \a s2) == 0.
2303*/
2304
2305/*!
2306 \fn bool operator!=( const QCString &s1, const QCString &s2 )
2307
2308 \relates QCString
2309
2310 Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
2311
2312 Equivalent to qstrcmp(\a s1, \a s2) != 0.
2313*/
2314
2315/*!
2316 \overload bool operator!=( const QCString &s1, const char *s2 )
2317
2318 \relates QCString
2319
2320 Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
2321
2322 Equivalent to qstrcmp(\a s1, \a s2) != 0.
2323*/
2324
2325/*!
2326 \overload bool operator!=( const char *s1, const QCString &s2 )
2327
2328 \relates QCString
2329
2330 Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
2331
2332 Equivalent to qstrcmp(\a s1, \a s2) != 0.
2333*/
2334
2335/*!
2336 \fn bool operator<( const QCString &s1, const char *s2 )
2337
2338 \relates QCString
2339
2340 Returns TRUE if \a s1 is less than \a s2; otherwise returns FALSE.
2341
2342 Equivalent to qstrcmp(\a s1, \a s2) \< 0.
2343
2344 \sa \link #asciinotion Note on character comparisons \endlink
2345*/
2346
2347/*!
2348 \overload bool operator<( const char *s1, const QCString &s2 )
2349
2350 \relates QCString
2351
2352 Returns TRUE if \a s1 is less than \a s2; otherwise returns FALSE.
2353
2354 Equivalent to qstrcmp(\a s1, \a s2) \< 0.
2355
2356 \sa \link #asciinotion Note on character comparisons \endlink
2357*/
2358
2359/*!
2360 \fn bool operator<=( const QCString &s1, const char *s2 )
2361
2362 \relates QCString
2363
2364 Returns TRUE if \a s1 is less than or equal to \a s2; otherwise
2365 returns FALSE.
2366
2367 Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
2368
2369 \sa \link #asciinotion Note on character comparisons \endlink
2370*/
2371
2372/*!
2373 \overload bool operator<=( const char *s1, const QCString &s2 )
2374
2375 \relates QCString
2376
2377 Returns TRUE if \a s1 is less than or equal to \a s2; otherwise
2378 returns FALSE.
2379
2380 Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
2381
2382 \sa \link #asciinotion Note on character comparisons \endlink
2383*/
2384
2385/*!
2386 \fn bool operator>( const QCString &s1, const char *s2 )
2387
2388 \relates QCString
2389
2390 Returns TRUE if \a s1 is greater than \a s2; otherwise returns FALSE.
2391
2392 Equivalent to qstrcmp(\a s1, \a s2) \> 0.
2393
2394 \sa \link #asciinotion Note on character comparisons \endlink
2395*/
2396
2397/*!
2398 \overload bool operator>( const char *s1, const QCString &s2 )
2399
2400 \relates QCString
2401
2402 Returns TRUE if \a s1 is greater than \a s2; otherwise returns FALSE.
2403
2404 Equivalent to qstrcmp(\a s1, \a s2) \> 0.
2405
2406 \sa \link #asciinotion Note on character comparisons \endlink
2407*/
2408
2409/*!
2410 \fn bool operator>=( const QCString &s1, const char *s2 )
2411
2412 \relates QCString
2413
2414 Returns TRUE if \a s1 is greater than or equal to \a s2; otherwise
2415 returns FALSE.
2416
2417 Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
2418
2419 \sa \link #asciinotion Note on character comparisons \endlink
2420*/
2421
2422/*!
2423 \overload bool operator>=( const char *s1, const QCString &s2 )
2424
2425 \relates QCString
2426
2427 Returns TRUE if \a s1 is greater than or equal to \a s2; otherwise
2428 returns FALSE.
2429
2430 Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
2431
2432 \sa \link #asciinotion Note on character comparisons \endlink
2433*/
2434
2435/*!
2436 \fn const QCString operator+( const QCString &s1, const QCString &s2 )
2437
2438 \relates QCString
2439
2440 Returns a string which consists of the concatenation of \a s1 and
2441 \a s2.
2442*/
2443
2444/*!
2445 \overload const QCString operator+( const QCString &s1, const char *s2 )
2446
2447 \relates QCString
2448
2449 Returns a string which consists of the concatenation of \a s1 and \a s2.
2450*/
2451
2452/*!
2453 \overload const QCString operator+( const char *s1, const QCString &s2 )
2454
2455 \relates QCString
2456
2457 Returns a string which consists of the concatenation of \a s1 and \a s2.
2458*/
2459
2460/*!
2461 \overload const QCString operator+( const QCString &s, char c )
2462
2463 \relates QCString
2464
2465 Returns a string which consists of the concatenation of \a s and \a c.
2466*/
2467
2468/*!
2469 \overload const QCString operator+( char c, const QCString &s )
2470
2471 \relates QCString
2472
2473 Returns a string which consists of the concatenation of \a c and \a s.
2474*/
diff --git a/qmake/tools/qdatastream.cpp b/qmake/tools/qdatastream.cpp
new file mode 100644
index 0000000..9c573c7
--- a/dev/null
+++ b/qmake/tools/qdatastream.cpp
@@ -0,0 +1,1024 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QDataStream class
5**
6** Created : 930831
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qdatastream.h"
39
40#ifndef QT_NO_DATASTREAM
41#include "qbuffer.h"
42#include <stdio.h>
43#include <ctype.h>
44#include <stdlib.h>
45
46/*!
47 \class QDataStream qdatastream.h
48 \reentrant
49 \brief The QDataStream class provides serialization of binary data
50 to a QIODevice.
51
52 \ingroup io
53
54 A data stream is a binary stream of encoded information which is
55 100% independent of the host computer's operating system, CPU or
56 byte order. For example, a data stream that is written by a PC
57 under Windows can be read by a Sun SPARC running Solaris.
58
59 You can also use a data stream to read/write \link #raw raw
60 unencoded binary data\endlink. If you want a "parsing" input
61 stream, see QTextStream.
62
63 The QDataStream class implements serialization of primitive types,
64 like \c char, \c short, \c int, \c char* etc. Serialization of
65 more complex data is accomplished by breaking up the data into
66 primitive units.
67
68 A data stream cooperates closely with a QIODevice. A QIODevice
69 represents an input/output medium one can read data from and write
70 data to. The QFile class is an example of an IO device.
71
72 Example (write binary data to a stream):
73 \code
74 QFile file( "file.dat" );
75 file.open( IO_WriteOnly );
76 QDataStream stream( &file ); // we will serialize the data into the file
77 stream << "the answer is"; // serialize a string
78 stream << (Q_INT32)42; // serialize an integer
79 \endcode
80
81 Example (read binary data from a stream):
82 \code
83 QFile file( "file.dat" );
84 file.open( IO_ReadOnly );
85 QDataStream stream( &file ); // read the data serialized from the file
86 QString str;
87 Q_INT32 a;
88 stream >> str >> a; // extract "the answer is" and 42
89 \endcode
90
91 Each item written to the stream is written in a predefined binary
92 format that varies depending on the item's type. Supported Qt
93 types include QBrush, QColor, QDateTime, QFont, QPixmap, QString,
94 QVariant and many others. For the complete list of all Qt types
95 supporting data streaming see the \link datastreamformat.html
96 Format of the QDataStream operators \endlink.
97
98 To take one example, a \c char* string is written as a 32-bit
99 integer equal to the length of the string including the NUL byte
100 ('\0'), followed by all the characters of the string including the
101 NUL byte. When reading a \c char* string, 4 bytes are read to
102 create the 32-bit length value, then that many characters for the
103 \c char* string including the NUL are read.
104
105 The initial IODevice is usually set in the constructor, but can be
106 changed with setDevice(). If you've reached the end of the data
107 (or if there is no IODevice set) atEnd() will return TRUE.
108
109 If you want the data to be compatible with an earlier version of
110 Qt use setVersion().
111
112 If you want the data to be human-readable, e.g. for debugging, you
113 can set the data stream into printable data mode with
114 setPrintableData(). The data is then written slower, in a bloated
115 but human readable format.
116
117 If you are producing a new binary data format, such as a file
118 format for documents created by your application, you could use a
119 QDataStream to write the data in a portable format. Typically, you
120 would write a brief header containing a magic string and a version
121 number to give yourself room for future expansion. For example:
122
123 \code
124 QFile file( "file.xxx" );
125 file.open( IO_WriteOnly );
126 QDataStream stream( &file );
127
128 // Write a header with a "magic number" and a version
129 stream << (Q_UINT32)0xA0B0C0D0;
130 stream << (Q_INT32)123;
131
132 // Write the data
133 stream << [lots of interesting data]
134 \endcode
135
136 Then read it in with:
137
138 \code
139 QFile file( "file.xxx" );
140 file.open( IO_ReadOnly );
141 QDataStream stream( &file );
142
143 // Read and check the header
144 Q_UINT32 magic;
145 stream >> magic;
146 if ( magic != 0xA0B0C0D0 )
147 return XXX_BAD_FILE_FORMAT;
148
149 // Read the version
150 Q_INT32 version;
151 stream >> version;
152 if ( version < 100 )
153 return XXX_BAD_FILE_TOO_OLD;
154 if ( version > 123 )
155 return XXX_BAD_FILE_TOO_NEW;
156 if ( version <= 110 )
157 stream.setVersion(1);
158
159 // Read the data
160 stream >> [lots of interesting data];
161 if ( version > 120 )
162 stream >> [data new in XXX version 1.2];
163 stream >> [other interesting data];
164 \endcode
165
166 You can select which byte order to use when serializing data. The
167 default setting is big endian (MSB first). Changing it to little
168 endian breaks the portability (unless the reader also changes to
169 little endian). We recommend keeping this setting unless you have
170 special requirements.
171
172 \target raw
173 \section1 Reading and writing raw binary data
174
175 You may wish to read/write your own raw binary data to/from the
176 data stream directly. Data may be read from the stream into a
177 preallocated char* using readRawBytes(). Similarly data can be
178 written to the stream using writeRawBytes(). Notice that any
179 encoding/decoding of the data must be done by you.
180
181 A similar pair of functions is readBytes() and writeBytes(). These
182 differ from their \e raw counterparts as follows: readBytes()
183 reads a Q_UINT32 which is taken to be the length of the data to be
184 read, then that number of bytes is read into the preallocated
185 char*; writeBytes() writes a Q_UINT32 containing the length of the
186 data, followed by the data. Notice that any encoding/decoding of
187 the data (apart from the length Q_UINT32) must be done by you.
188
189 \sa QTextStream QVariant
190*/
191
192/*!
193 \enum QDataStream::ByteOrder
194
195 The byte order used for reading/writing the data.
196
197 \value BigEndian the default
198 \value LittleEndian
199*/
200
201
202/*****************************************************************************
203 QDataStream member functions
204 *****************************************************************************/
205
206#if defined(QT_CHECK_STATE)
207#undef CHECK_STREAM_PRECOND
208 #define CHECK_STREAM_PRECOND if ( !dev ) { \
209 qWarning( "QDataStream: No device" );\
210 return *this; }
211#else
212#define CHECK_STREAM_PRECOND
213#endif
214
215static int systemWordSize = 0;
216static bool systemBigEndian;
217
218static const int DefaultStreamVersion = 5;
219// 5 is default in Qt 3.1
220// 4 is default in Qt 3.0
221// 3 is default in Qt 2.1
222// 2 is the Qt 2.0.x format
223// 1 is the Qt 1.x format
224
225/*!
226 Constructs a data stream that has no IO device.
227
228 \sa setDevice()
229*/
230
231QDataStream::QDataStream()
232{
233 if ( systemWordSize == 0 ) // get system features
234 qSysInfo( &systemWordSize, &systemBigEndian );
235 dev = 0; // no device set
236 owndev = FALSE;
237 byteorder = BigEndian; // default byte order
238 printable = FALSE;
239 ver = DefaultStreamVersion;
240 noswap = systemBigEndian;
241}
242
243/*!
244 Constructs a data stream that uses the IO device \a d.
245
246 \warning If you use QSocket or QSocketDevice as the IO device \a d
247 for reading data, you must make sure that enough data is available
248 on the socket for the operation to successfully proceed;
249 QDataStream does not have any means to handle or recover from
250 short-reads.
251
252 \sa setDevice(), device()
253*/
254
255QDataStream::QDataStream( QIODevice *d )
256{
257 if ( systemWordSize == 0 ) // get system features
258 qSysInfo( &systemWordSize, &systemBigEndian );
259 dev = d; // set device
260 owndev = FALSE;
261 byteorder = BigEndian; // default byte order
262 printable = FALSE;
263 ver = DefaultStreamVersion;
264 noswap = systemBigEndian;
265}
266
267/*!
268 Constructs a data stream that operates on a byte array, \a a,
269 through an internal QBuffer device. The \a mode is a
270 QIODevice::mode(), usually either \c IO_ReadOnly or \c
271 IO_WriteOnly.
272
273 Example:
274 \code
275 static char bindata[] = { 231, 1, 44, ... };
276 QByteArray a;
277 a.setRawData( bindata, sizeof(bindata) );// a points to bindata
278 QDataStream stream( a, IO_ReadOnly );// open on a's data
279 stream >> [something]; // read raw bindata
280 a.resetRawData( bindata, sizeof(bindata) ); // finished
281 \endcode
282
283 The QByteArray::setRawData() function is not for the inexperienced.
284*/
285
286QDataStream::QDataStream( QByteArray a, int mode )
287{
288 if ( systemWordSize == 0 ) // get system features
289 qSysInfo( &systemWordSize, &systemBigEndian );
290 dev = new QBuffer( a ); // create device
291 ((QBuffer *)dev)->open( mode ); // open device
292 owndev = TRUE;
293 byteorder = BigEndian; // default byte order
294 printable = FALSE;
295 ver = DefaultStreamVersion;
296 noswap = systemBigEndian;
297}
298
299/*!
300 Destroys the data stream.
301
302 The destructor will not affect the current IO device, unless it is
303 an internal IO device processing a QByteArray passed in the \e
304 constructor, in which case the internal IO device is destroyed.
305*/
306
307QDataStream::~QDataStream()
308{
309 if ( owndev )
310 delete dev;
311}
312
313
314/*!
315 \fn QIODevice *QDataStream::device() const
316
317 Returns the IO device currently set.
318
319 \sa setDevice(), unsetDevice()
320*/
321
322/*!
323 void QDataStream::setDevice(QIODevice *d )
324
325 Sets the IO device to \a d.
326
327 \sa device(), unsetDevice()
328*/
329
330void QDataStream::setDevice(QIODevice *d )
331{
332 if ( owndev ) {
333 delete dev;
334 owndev = FALSE;
335 }
336 dev = d;
337}
338
339/*!
340 Unsets the IO device. This is the same as calling setDevice( 0 ).
341
342 \sa device(), setDevice()
343*/
344
345void QDataStream::unsetDevice()
346{
347 setDevice( 0 );
348}
349
350
351/*!
352 \fn bool QDataStream::atEnd() const
353
354 Returns TRUE if the IO device has reached the end position (end of
355 the stream or file) or if there is no IO device set; otherwise
356 returns FALSE, i.e. if the current position of the IO device is
357 before the end position.
358
359 \sa QIODevice::atEnd()
360*/
361
362/*!\fn bool QDataStream::eof() const
363
364 \obsolete
365
366 Returns TRUE if the IO device has reached the end position (end of
367 stream or file) or if there is no IO device set.
368
369 Returns FALSE if the current position of the read/write head of the IO
370 device is somewhere before the end position.
371
372 \sa QIODevice::atEnd()
373*/
374
375/*!
376 \fn int QDataStream::byteOrder() const
377
378 Returns the current byte order setting -- either \c BigEndian or
379 \c LittleEndian.
380
381 \sa setByteOrder()
382*/
383
384/*!
385 Sets the serialization byte order to \a bo.
386
387 The \a bo parameter can be \c QDataStream::BigEndian or \c
388 QDataStream::LittleEndian.
389
390 The default setting is big endian. We recommend leaving this
391 setting unless you have special requirements.
392
393 \sa byteOrder()
394*/
395
396void QDataStream::setByteOrder( int bo )
397{
398 byteorder = bo;
399 if ( systemBigEndian )
400 noswap = byteorder == BigEndian;
401 else
402 noswap = byteorder == LittleEndian;
403}
404
405
406/*!
407 \fn bool QDataStream::isPrintableData() const
408
409 Returns TRUE if the printable data flag has been set; otherwise
410 returns FALSE.
411
412 \sa setPrintableData()
413*/
414
415/*!
416 \fn void QDataStream::setPrintableData( bool enable )
417
418 If \a enable is TRUE, data will be output in a human readable
419 format. If \a enable is FALSE, data will be output in a binary
420 format.
421
422 If \a enable is TRUE, the write functions will generate output
423 that consists of printable characters (7 bit ASCII). This output
424 will typically be a lot larger than the default binary output, and
425 consequently slower to write.
426
427 We recommend only enabling printable data for debugging purposes.
428*/
429
430
431/*!
432 \fn int QDataStream::version() const
433
434 Returns the version number of the data serialization format. In Qt
435 3.1, this number is 5.
436
437 \sa setVersion()
438*/
439
440/*!
441 \fn void QDataStream::setVersion( int v )
442
443 Sets the version number of the data serialization format to \a v.
444
445 You don't need to set a version if you are using the current
446 version of Qt.
447
448 In order to accommodate new functionality, the datastream
449 serialization format of some Qt classes has changed in some
450 versions of Qt. If you want to read data that was created by an
451 earlier version of Qt, or write data that can be read by a program
452 that was compiled with an earlier version of Qt, use this function
453 to modify the serialization format of QDataStream.
454
455 \table
456 \header \i Qt Version \i QDataStream Version
457 \row \i Qt 3.1 \i11 5
458 \row \i Qt 3.0 \i11 4
459 \row \i Qt 2.1.x and Qt 2.2.x \i11 3
460 \row \i Qt 2.0.x \i11 2
461 \row \i Qt 1.x \i11 1
462 \endtable
463
464 \sa version()
465*/
466
467/*****************************************************************************
468 QDataStream read functions
469 *****************************************************************************/
470
471
472static Q_INT32 read_int_ascii( QDataStream *s )
473{
474 register int n = 0;
475 char buf[40];
476 for ( ;; ) {
477 buf[n] = s->device()->getch();
478 if ( buf[n] == '\n' || n > 38 ) // $-terminator
479 break;
480 n++;
481 }
482 buf[n] = '\0';
483 return atol( buf );
484}
485
486
487/*!
488 \overload QDataStream &QDataStream::operator>>( Q_UINT8 &i )
489
490 Reads an unsigned byte from the stream into \a i, and returns a
491 reference to the stream.
492*/
493
494/*!
495 Reads a signed byte from the stream into \a i, and returns a
496 reference to the stream.
497*/
498
499QDataStream &QDataStream::operator>>( Q_INT8 &i )
500{
501 CHECK_STREAM_PRECOND
502 if ( printable ) { // printable data
503 i = (Q_INT8)dev->getch();
504 if ( i == '\\' ) { // read octal code
505 char buf[4];
506 dev->readBlock( buf, 3 );
507 i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
508 }
509 } else { // data or text
510 i = (Q_INT8)dev->getch();
511 }
512 return *this;
513}
514
515
516/*!
517 \overload QDataStream &QDataStream::operator>>( Q_UINT16 &i )
518
519 Reads an unsigned 16-bit integer from the stream into \a i, and
520 returns a reference to the stream.
521*/
522
523/*!
524 \overload
525
526 Reads a signed 16-bit integer from the stream into \a i, and
527 returns a reference to the stream.
528*/
529
530QDataStream &QDataStream::operator>>( Q_INT16 &i )
531{
532 CHECK_STREAM_PRECOND
533 if ( printable ) { // printable data
534 i = (Q_INT16)read_int_ascii( this );
535 } else if ( noswap ) { // no conversion needed
536 dev->readBlock( (char *)&i, sizeof(Q_INT16) );
537 } else { // swap bytes
538 register uchar *p = (uchar *)(&i);
539 char b[2];
540 dev->readBlock( b, 2 );
541 *p++ = b[1];
542 *p = b[0];
543 }
544 return *this;
545}
546
547
548/*!
549 \overload QDataStream &QDataStream::operator>>( Q_UINT32 &i )
550
551 Reads an unsigned 32-bit integer from the stream into \a i, and
552 returns a reference to the stream.
553*/
554
555/*!
556 \overload
557
558 Reads a signed 32-bit integer from the stream into \a i, and
559 returns a reference to the stream.
560*/
561
562QDataStream &QDataStream::operator>>( Q_INT32 &i )
563{
564 CHECK_STREAM_PRECOND
565 if ( printable ) { // printable data
566 i = read_int_ascii( this );
567 } else if ( noswap ) { // no conversion needed
568 dev->readBlock( (char *)&i, sizeof(Q_INT32) );
569 } else { // swap bytes
570 uchar *p = (uchar *)(&i);
571 char b[4];
572 dev->readBlock( b, 4 );
573 *p++ = b[3];
574 *p++ = b[2];
575 *p++ = b[1];
576 *p = b[0];
577 }
578 return *this;
579}
580
581/*!
582 \overload QDataStream &QDataStream::operator>>( Q_ULONG &i )
583
584 Reads an unsigned integer of the system's word length from the
585 stream, into \a i, and returns a reference to the stream.
586*/
587
588/*!
589 \overload
590
591 Reads a signed integer of the system's word length from the stream
592 into \a i, and returns a reference to the stream.
593*/
594
595QDataStream &QDataStream::operator>>( Q_LONG &i )
596{
597 CHECK_STREAM_PRECOND
598 if ( printable ) { // printable data
599 i = read_int_ascii( this );
600 } else if ( noswap ) { // no conversion needed
601 dev->readBlock( (char *)&i, sizeof(Q_LONG) );
602 } else { // swap bytes
603 register uchar *p = (uchar *)(&i);
604 char b[sizeof(Q_LONG)];
605 dev->readBlock( b, sizeof(Q_LONG) );
606 for ( int j = sizeof(Q_LONG); j; )
607 *p++ = b[--j];
608 }
609 return *this;
610}
611
612static double read_double_ascii( QDataStream *s )
613{
614 register int n = 0;
615 char buf[80];
616 for ( ;; ) {
617 buf[n] = s->device()->getch();
618 if ( buf[n] == '\n' || n > 78 ) // $-terminator
619 break;
620 n++;
621 }
622 buf[n] = '\0';
623 return atof( buf );
624}
625
626
627/*!
628 \overload
629
630 Reads a 32-bit floating point number from the stream into \a f,
631 using the standard IEEE754 format. Returns a reference to the
632 stream.
633*/
634
635QDataStream &QDataStream::operator>>( float &f )
636{
637 CHECK_STREAM_PRECOND
638 if ( printable ) { // printable data
639 f = (float)read_double_ascii( this );
640 } else if ( noswap ) { // no conversion needed
641 dev->readBlock( (char *)&f, sizeof(float) );
642 } else { // swap bytes
643 uchar *p = (uchar *)(&f);
644 char b[4];
645 dev->readBlock( b, 4 );
646 *p++ = b[3];
647 *p++ = b[2];
648 *p++ = b[1];
649 *p = b[0];
650 }
651 return *this;
652}
653
654
655/*!
656 \overload
657
658 Reads a 64-bit floating point number from the stream into \a f,
659 using the standard IEEE754 format. Returns a reference to the
660 stream.
661*/
662
663QDataStream &QDataStream::operator>>( double &f )
664{
665 CHECK_STREAM_PRECOND
666 if ( printable ) { // printable data
667 f = read_double_ascii( this );
668 } else if ( noswap ) { // no conversion needed
669 dev->readBlock( (char *)&f, sizeof(double) );
670 } else { // swap bytes
671 register uchar *p = (uchar *)(&f);
672 char b[8];
673 dev->readBlock( b, 8 );
674 *p++ = b[7];
675 *p++ = b[6];
676 *p++ = b[5];
677 *p++ = b[4];
678 *p++ = b[3];
679 *p++ = b[2];
680 *p++ = b[1];
681 *p = b[0];
682 }
683 return *this;
684}
685
686
687/*!
688 \overload
689
690 Reads the '\0'-terminated string \a s from the stream and returns
691 a reference to the stream.
692
693 Space for the string is allocated using \c new -- the caller must
694 destroy it with delete[].
695*/
696
697QDataStream &QDataStream::operator>>( char *&s )
698{
699 uint len = 0;
700 return readBytes( s, len );
701}
702
703
704/*!
705 Reads the buffer \a s from the stream and returns a reference to
706 the stream.
707
708 The buffer \a s is allocated using \c new. Destroy it with the \c
709 delete[] operator. If the length is zero or \a s cannot be
710 allocated, \a s is set to 0.
711
712 The \a l parameter will be set to the length of the buffer.
713
714 The serialization format is a Q_UINT32 length specifier first,
715 then \a l bytes of data. Note that the data is \e not encoded.
716
717 \sa readRawBytes(), writeBytes()
718*/
719
720QDataStream &QDataStream::readBytes( char *&s, uint &l )
721{
722 CHECK_STREAM_PRECOND
723 Q_UINT32 len;
724 *this >> len; // first read length spec
725 l = (uint)len;
726 if ( len == 0 || eof() ) {
727 s = 0;
728 return *this;
729 } else {
730 s = new char[len]; // create char array
731 Q_CHECK_PTR( s );
732 if ( !s ) // no memory
733 return *this;
734 return readRawBytes( s, (uint)len );
735 }
736}
737
738
739/*!
740 Reads \a len bytes from the stream into \a s and returns a
741 reference to the stream.
742
743 The buffer \a s must be preallocated. The data is \e not encoded.
744
745 \sa readBytes(), QIODevice::readBlock(), writeRawBytes()
746*/
747
748QDataStream &QDataStream::readRawBytes( char *s, uint len )
749{
750 CHECK_STREAM_PRECOND
751 if ( printable ) { // printable data
752 register Q_INT8 *p = (Q_INT8*)s;
753 while ( len-- )
754 *this >> *p++;
755 } else { // read data char array
756 dev->readBlock( s, len );
757 }
758 return *this;
759}
760
761
762/*****************************************************************************
763 QDataStream write functions
764 *****************************************************************************/
765
766
767/*!
768 \overload QDataStream &QDataStream::operator<<( Q_UINT8 i )
769
770 Writes an unsigned byte, \a i, to the stream and returns a
771 reference to the stream.
772*/
773
774/*!
775 Writes a signed byte, \a i, to the stream and returns a reference
776 to the stream.
777*/
778
779QDataStream &QDataStream::operator<<( Q_INT8 i )
780{
781 CHECK_STREAM_PRECOND
782 if ( printable && (i == '\\' || !isprint((uchar) i)) ) {
783 char buf[6]; // write octal code
784 buf[0] = '\\';
785 buf[1] = '0' + ((i >> 6) & 0x07);
786 buf[2] = '0' + ((i >> 3) & 0x07);
787 buf[3] = '0' + (i & 0x07);
788 buf[4] = '\0';
789 dev->writeBlock( buf, 4 );
790 } else {
791 dev->putch( i );
792 }
793 return *this;
794}
795
796
797/*!
798 \overload QDataStream &QDataStream::operator<<( Q_UINT16 i )
799
800 Writes an unsigned 16-bit integer, \a i, to the stream and returns
801 a reference to the stream.
802*/
803
804/*!
805 \overload
806
807 Writes a signed 16-bit integer, \a i, to the stream and returns a
808 reference to the stream.
809*/
810
811QDataStream &QDataStream::operator<<( Q_INT16 i )
812{
813 CHECK_STREAM_PRECOND
814 if ( printable ) { // printable data
815 char buf[16];
816 sprintf( buf, "%d\n", i );
817 dev->writeBlock( buf, strlen(buf) );
818 } else if ( noswap ) { // no conversion needed
819 dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
820 } else { // swap bytes
821 register uchar *p = (uchar *)(&i);
822 char b[2];
823 b[1] = *p++;
824 b[0] = *p;
825 dev->writeBlock( b, 2 );
826 }
827 return *this;
828}
829
830/*!
831 \overload
832
833 Writes a signed 32-bit integer, \a i, to the stream and returns a
834 reference to the stream.
835*/
836
837QDataStream &QDataStream::operator<<( Q_INT32 i )
838{
839 CHECK_STREAM_PRECOND
840 if ( printable ) { // printable data
841 char buf[16];
842 sprintf( buf, "%d\n", i );
843 dev->writeBlock( buf, strlen(buf) );
844 } else if ( noswap ) { // no conversion needed
845 dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
846 } else { // swap bytes
847 register uchar *p = (uchar *)(&i);
848 char b[4];
849 b[3] = *p++;
850 b[2] = *p++;
851 b[1] = *p++;
852 b[0] = *p;
853 dev->writeBlock( b, 4 );
854 }
855 return *this;
856}
857
858/*!
859 \overload QDataStream &QDataStream::operator<<( Q_ULONG i )
860
861 Writes an unsigned integer \a i, of the system's word length, to
862 the stream and returns a reference to the stream.
863*/
864
865/*!
866 \overload
867
868 Writes a signed integer \a i, of the system's word length, to the
869 stream and returns a reference to the stream.
870*/
871
872QDataStream &QDataStream::operator<<( Q_LONG i )
873{
874 CHECK_STREAM_PRECOND
875 if ( printable ) { // printable data
876 char buf[20];
877 sprintf( buf, "%ld\n", i );
878 dev->writeBlock( buf, strlen(buf) );
879 } else if ( noswap ) { // no conversion needed
880 dev->writeBlock( (char *)&i, sizeof(Q_LONG) );
881 } else { // swap bytes
882 register uchar *p = (uchar *)(&i);
883 char b[sizeof(Q_LONG)];
884 for ( int j = sizeof(Q_LONG); j; )
885 b[--j] = *p++;
886 dev->writeBlock( b, sizeof(Q_LONG) );
887 }
888 return *this;
889}
890
891/*!
892 \overload QDataStream &QDataStream::operator<<( Q_UINT32 i )
893
894 Writes an unsigned integer, \a i, to the stream as a 32-bit
895 unsigned integer (Q_UINT32). Returns a reference to the stream.
896*/
897
898/*!
899 \overload
900
901 Writes a 32-bit floating point number, \a f, to the stream using
902 the standard IEEE754 format. Returns a reference to the stream.
903*/
904
905QDataStream &QDataStream::operator<<( float f )
906{
907 CHECK_STREAM_PRECOND
908 if ( printable ) { // printable data
909 char buf[32];
910 sprintf( buf, "%g\n", (double)f );
911 dev->writeBlock( buf, strlen(buf) );
912 } else {
913 float g = f; // fixes float-on-stack problem
914 if ( noswap ) { // no conversion needed
915 dev->writeBlock( (char *)&g, sizeof(float) );
916 } else { // swap bytes
917 register uchar *p = (uchar *)(&g);
918 char b[4];
919 b[3] = *p++;
920 b[2] = *p++;
921 b[1] = *p++;
922 b[0] = *p;
923 dev->writeBlock( b, 4 );
924 }
925 }
926 return *this;
927}
928
929
930/*!
931 \overload
932
933 Writes a 64-bit floating point number, \a f, to the stream using
934 the standard IEEE754 format. Returns a reference to the stream.
935*/
936
937QDataStream &QDataStream::operator<<( double f )
938{
939 CHECK_STREAM_PRECOND
940 if ( printable ) { // printable data
941 char buf[32];
942 sprintf( buf, "%g\n", f );
943 dev->writeBlock( buf, strlen(buf) );
944 } else if ( noswap ) { // no conversion needed
945 dev->writeBlock( (char *)&f, sizeof(double) );
946 } else { // swap bytes
947 register uchar *p = (uchar *)(&f);
948 char b[8];
949 b[7] = *p++;
950 b[6] = *p++;
951 b[5] = *p++;
952 b[4] = *p++;
953 b[3] = *p++;
954 b[2] = *p++;
955 b[1] = *p++;
956 b[0] = *p;
957 dev->writeBlock( b, 8 );
958 }
959 return *this;
960}
961
962
963/*!
964 \overload
965
966 Writes the '\0'-terminated string \a s to the stream and returns a
967 reference to the stream.
968
969 The string is serialized using writeBytes().
970*/
971
972QDataStream &QDataStream::operator<<( const char *s )
973{
974 if ( !s ) {
975 *this << (Q_UINT32)0;
976 return *this;
977 }
978 uint len = qstrlen( s ) + 1; // also write null terminator
979 *this << (Q_UINT32)len; // write length specifier
980 return writeRawBytes( s, len );
981}
982
983
984/*!
985 Writes the length specifier \a len and the buffer \a s to the
986 stream and returns a reference to the stream.
987
988 The \a len is serialized as a Q_UINT32, followed by \a len bytes
989 from \a s. Note that the data is \e not encoded.
990
991 \sa writeRawBytes(), readBytes()
992*/
993
994QDataStream &QDataStream::writeBytes(const char *s, uint len)
995{
996 CHECK_STREAM_PRECOND
997 *this << (Q_UINT32)len; // write length specifier
998 if ( len )
999 writeRawBytes( s, len );
1000 return *this;
1001}
1002
1003
1004/*!
1005 Writes \a len bytes from \a s to the stream and returns a
1006 reference to the stream. The data is \e not encoded.
1007
1008 \sa writeBytes(), QIODevice::writeBlock(), readRawBytes()
1009*/
1010
1011QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
1012{
1013 CHECK_STREAM_PRECOND
1014 if ( printable ) { // write printable
1015 register Q_INT8 *p = (Q_INT8*)s;
1016 while ( len-- )
1017 *this << *p++;
1018 } else { // write data char array
1019 dev->writeBlock( s, len );
1020 }
1021 return *this;
1022}
1023
1024#endif // QT_NO_DATASTREAM
diff --git a/qmake/tools/qdatetime.cpp b/qmake/tools/qdatetime.cpp
new file mode 100644
index 0000000..93e40a8
--- a/dev/null
+++ b/qmake/tools/qdatetime.cpp
@@ -0,0 +1,2490 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of date and time classes
5**
6** Created : 940124
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38// Get the system specific includes and defines
39#include "qplatformdefs.h"
40
41#include "qdatetime.h"
42#include "qdatastream.h"
43#include "qregexp.h"
44
45#include <stdio.h>
46#ifndef Q_OS_TEMP
47#include <time.h>
48#endif
49
50#if defined(Q_OS_WIN32)
51#include <windows.h>
52#endif
53
54 static const uint FIRST_DAY = 2361222;// Julian day for 1752-09-14
55 static const int FIRST_YEAR = 1752; // ### wrong for many countries
56 static const uint SECS_PER_DAY= 86400;
57static const uint MSECS_PER_DAY = 86400000;
58static const uint SECS_PER_HOUR = 3600;
59static const uint MSECS_PER_HOUR= 3600000;
60 static const uint SECS_PER_MIN= 60;
61static const uint MSECS_PER_MIN = 60000;
62
63static const short monthDays[] = {
64 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
65
66static const char * const qt_shortMonthNames[] = {
67 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
68 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
69
70#ifndef QT_NO_DATESTRING
71/*****************************************************************************
72 Some static function used by QDate, QTime and QDateTime
73 *****************************************************************************/
74
75// Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
76static QString getFmtString( const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = FALSE )
77{
78 if ( f.isEmpty() )
79 return QString::null;
80
81 QString buf = f;
82
83 if ( dt ) {
84 if ( f == "h" ) {
85 if ( ( am_pm ) && ( dt->hour() > 12 ) )
86 buf = QString::number( dt->hour() - 12 );
87 else if ( ( am_pm ) && ( dt->hour() == 0 ) )
88 buf = "12";
89 else
90 buf = QString::number( dt->hour() );
91 } else if ( f == "hh" ) {
92 if ( ( am_pm ) && ( dt->hour() > 12 ) )
93 buf = QString::number( dt->hour() - 12 ).rightJustify( 2, '0', TRUE );
94 else if ( ( am_pm ) && ( dt->hour() == 0 ) )
95 buf = "12";
96 else
97 buf = QString::number( dt->hour() ).rightJustify( 2, '0', TRUE );
98 } else if ( f == "m" ) {
99 buf = QString::number( dt->minute() );
100 } else if ( f == "mm" ) {
101 buf = QString::number( dt->minute() ).rightJustify( 2, '0', TRUE );
102 } else if ( f == "s" ) {
103 buf = QString::number( dt->second() );
104 } else if ( f == "ss" ) {
105 buf = QString::number( dt->second() ).rightJustify( 2, '0', TRUE );
106 } else if ( f == "z" ) {
107 buf = QString::number( dt->msec() );
108 } else if ( f == "zzz" ) {
109 buf = QString::number( dt->msec() ).rightJustify( 3, '0', TRUE );
110 } else if ( f == "ap" ) {
111 buf = dt->hour() < 12 ? "am" : "pm";
112 } else if ( f == "AP" ) {
113 buf = dt->hour() < 12 ? "AM" : "PM";
114 }
115 }
116
117 if ( dd ) {
118 if ( f == "d" ) {
119 buf = QString::number( dd->day() );
120 } else if ( f == "dd" ) {
121 buf = QString::number( dd->day() ).rightJustify( 2, '0', TRUE );
122 } else if ( f == "M" ) {
123 buf = QString::number( dd->month() );
124 } else if ( f == "MM" ) {
125 buf = QString::number( dd->month() ).rightJustify( 2, '0', TRUE );
126#ifndef QT_NO_TEXTDATE
127 } else if ( f == "ddd" ) {
128 buf = dd->shortDayName( dd->dayOfWeek() );
129 } else if ( f == "dddd" ) {
130 buf = dd->longDayName( dd->dayOfWeek() );
131 } else if ( f == "MMM" ) {
132 buf = dd->shortMonthName( dd->month() );
133 } else if ( f == "MMMM" ) {
134 buf = dd->longMonthName( dd->month() );
135#endif
136 } else if ( f == "yy" ) {
137 buf = QString::number( dd->year() ).right( 2 );
138 } else if ( f == "yyyy" ) {
139 buf = QString::number( dd->year() );
140 }
141 }
142
143 return buf;
144}
145
146// Parses the format string and uses getFmtString to get the values for the tokens. Ret
147static QString fmtDateTime( const QString& f, const QTime* dt = 0, const QDate* dd = 0 )
148{
149 if ( f.isEmpty() ) {
150 return QString::null;
151 }
152
153 bool ap = ( f.contains( "AP" ) || f.contains( "ap" ) );
154
155 QString buf;
156 QString frm;
157 QChar status = '0';
158
159 for ( int i = 0; i < (int)f.length(); ++i ) {
160
161 if ( f[ i ] == status ) {
162 if ( ( ap ) && ( ( f[ i ] == 'P' ) || ( f[ i ] == 'p' ) ) )
163 status = '0';
164 frm += f[ i ];
165 } else {
166 buf += getFmtString( frm, dt, dd, ap );
167 frm = QString::null;
168 if ( ( f[ i ] == 'h' ) || ( f[ i ] == 'm' ) || ( f[ i ] == 's' ) || ( f[ i ] == 'z' ) ) {
169 status = f[ i ];
170 frm += f[ i ];
171 } else if ( ( f[ i ] == 'd' ) || ( f[ i ] == 'M' ) || ( f[ i ] == 'y' ) ) {
172 status = f[ i ];
173 frm += f[ i ];
174 } else if ( ( ap ) && ( f[ i ] == 'A' ) ) {
175 status = 'P';
176 frm += f[ i ];
177 } else if( ( ap ) && ( f[ i ] == 'a' ) ) {
178 status = 'p';
179 frm += f[ i ];
180 } else {
181 buf += f[ i ];
182 status = '0';
183 }
184 }
185 }
186
187 buf += getFmtString( frm, dt, dd, ap );
188
189 return buf;
190}
191#endif // QT_NO_DATESTRING
192
193/*****************************************************************************
194 QDate member functions
195 *****************************************************************************/
196
197/*!
198 \class QDate qdatetime.h
199 \reentrant
200 \brief The QDate class provides date functions.
201
202 \ingroup time
203 \mainclass
204
205 A QDate object contains a calendar date, i.e. year, month, and day
206 numbers, in the modern Western (Gregorian) calendar. It can read
207 the current date from the system clock. It provides functions for
208 comparing dates and for manipulating dates, e.g. by adding a
209 number of days or months or years.
210
211 A QDate object is typically created either by giving the year,
212 month and day numbers explicitly, or by using the static function
213 currentDate(), which creates a QDate object containing the system
214 clock's date. An explicit date can also be set using setYMD(). The
215 fromString() function returns a QDate given a string and a date
216 format which is used to interpret the date within the string.
217
218 The year(), month(), and day() functions provide access to the
219 year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
220 functions are provided. The same information is provided in
221 textual format by the toString(), shortDayName(), longDayName(),
222 shortMonthName() and longMonthName() functions.
223
224 QDate provides a full set of operators to compare two QDate
225 objects where smaller means earlier and larger means later.
226
227 You can increment (or decrement) a date by a given number of days
228 using addDays(). Similarly you can use addMonths() and addYears().
229 The daysTo() function returns the number of days between two
230 dates.
231
232 The daysInMonth() and daysInYear() functions return how many days
233 there are in this date's month and year, respectively. The
234 leapYear() function indicates whether this date is in a leap year.
235
236 Note that QDate should not be used for date calculations for dates
237 prior to the introduction of the Gregorian calendar. This calendar
238 was adopted by England from the 14<sup><small>th</small></sup>
239 September 1752 (hence this is the earliest valid QDate), and
240 subsequently by most other Western countries, until 1923.
241
242 The end of time is reached around the year 8000, by which time we
243 expect Qt to be obsolete.
244
245 \sa QTime QDateTime QDateEdit QDateTimeEdit
246*/
247
248/*!
249 \enum Qt::DateFormat
250
251 \value TextDate (default) Qt format
252 \value ISODate ISO 8601 extended format (YYYY-MM-DD, or with time,
253 YYYY-MM-DDTHH:MM:SS)
254 \value LocalDate locale dependent format
255*/
256
257
258/*!
259 \enum Qt::TimeSpec
260
261 \value LocalTime Locale dependent time (Timezones and Daylight Savings Time)
262 \value UTC Coordinated Universal Time, replaces Greenwich Time
263*/
264
265/*!
266 \fn QDate::QDate()
267
268 Constructs a null date. Null dates are invalid.
269
270 \sa isNull(), isValid()
271*/
272
273
274/*!
275 Constructs a date with year \a y, month \a m and day \a d.
276
277 \a y must be in the range 1752..8000, \a m must be in the range
278 1..12, and \a d must be in the range 1..31.
279
280 \warning If \a y is in the range 0..99, it is interpreted as
281 1900..1999.
282
283 \sa isValid()
284*/
285
286QDate::QDate( int y, int m, int d )
287{
288 jd = 0;
289 setYMD( y, m, d );
290}
291
292
293/*!
294 \fn bool QDate::isNull() const
295
296 Returns TRUE if the date is null; otherwise returns FALSE. A null
297 date is invalid.
298
299 \sa isValid()
300*/
301
302
303/*!
304 Returns TRUE if this date is valid; otherwise returns FALSE.
305
306 \sa isNull()
307*/
308
309bool QDate::isValid() const
310{
311 return jd >= FIRST_DAY;
312}
313
314
315/*!
316 Returns the year (1752..8000) of this date.
317
318 \sa month(), day()
319*/
320
321int QDate::year() const
322{
323 int y, m, d;
324 julianToGregorian( jd, y, m, d );
325 return y;
326}
327
328/*!
329 Returns the month (January=1..December=12) of this date.
330
331 \sa year(), day()
332*/
333
334int QDate::month() const
335{
336 int y, m, d;
337 julianToGregorian( jd, y, m, d );
338 return m;
339}
340
341/*!
342 Returns the day of the month (1..31) of this date.
343
344 \sa year(), month(), dayOfWeek()
345*/
346
347int QDate::day() const
348{
349 int y, m, d;
350 julianToGregorian( jd, y, m, d );
351 return d;
352}
353
354/*!
355 Returns the weekday (Monday=1..Sunday=7) for this date.
356
357 \sa day(), dayOfYear()
358*/
359
360int QDate::dayOfWeek() const
361{
362 return ( jd % 7 ) + 1;
363}
364
365/*!
366 Returns the day of the year (1..365) for this date.
367
368 \sa day(), dayOfWeek()
369*/
370
371int QDate::dayOfYear() const
372{
373 return jd - gregorianToJulian(year(), 1, 1) + 1;
374}
375
376/*!
377 Returns the number of days in the month (28..31) for this date.
378
379 \sa day(), daysInYear()
380*/
381
382int QDate::daysInMonth() const
383{
384 int y, m, d;
385 julianToGregorian( jd, y, m, d );
386 if ( m == 2 && leapYear(y) )
387 return 29;
388 else
389 return monthDays[m];
390}
391
392/*!
393 Returns the number of days in the year (365 or 366) for this date.
394
395 \sa day(), daysInMonth()
396*/
397
398int QDate::daysInYear() const
399{
400 int y, m, d;
401 julianToGregorian( jd, y, m, d );
402 return leapYear( y ) ? 366 : 365;
403}
404
405/*!
406 Returns the week number (1 to 53), and stores the year in \a
407 *yearNumber unless \a yearNumber is null (the default).
408
409 Returns 0 if the date is invalid.
410
411 In accordance with ISO 8601, weeks start on Monday and the first
412 Thursday of a year is always in week 1 of that year. Most years
413 have 52 weeks, but some have 53.
414
415 \a *yearNumber is not always the same as year(). For example, 1
416 January 2000 has week number 52 in the year 1999, and 31 December
417 2002 has week number 1 in the year 2003.
418
419 \sa isValid()
420*/
421
422int QDate::weekNumber( int *yearNumber ) const
423{
424 if ( !isValid() )
425 return 0;
426
427 int dow = dayOfWeek();
428 int doy = dayOfYear();
429 int currYear = year();
430 int jan1WeekDay = QDate( currYear, 1, 1 ).dayOfWeek();
431 int yearNum;
432 int weekNum;
433
434 if ( doy <= (8 - jan1WeekDay) && jan1WeekDay > 4 ) {
435 yearNum = currYear - 1;
436 weekNum = 52;
437 if ( jan1WeekDay == 5 ||
438 (jan1WeekDay == 6 && QDate::leapYear(yearNum)) )
439 weekNum++;
440 } else {
441 int totalDays = 365;
442 if ( QDate::leapYear(currYear) )
443 totalDays++;
444
445 if ( (totalDays - doy < 4 - dow)
446 || (jan1WeekDay == 7 && totalDays - doy < 3) ) {
447 yearNum = currYear + 1;
448 weekNum = 1;
449 } else {
450 int j = doy + ( 7 - dow ) + ( jan1WeekDay - 1 );
451 yearNum = currYear;
452 weekNum = j / 7;
453 if ( jan1WeekDay > 4 )
454 weekNum--;
455 }
456 }
457 if ( yearNumber )
458 *yearNumber = yearNum;
459 return weekNum;
460}
461
462/*!
463 \fn QString QDate::monthName( int month )
464 \obsolete
465
466 Use shortMonthName() instead.
467*/
468#ifndef QT_NO_TEXTDATE
469/*!
470 Returns the name of the \a month.
471
472 1 = "Jan", 2 = "Feb", ... 12 = "Dec"
473
474 The month names will be localized according to the system's locale
475 settings.
476
477 \sa toString(), longMonthName(), shortDayName(), longDayName()
478*/
479
480QString QDate::shortMonthName( int month )
481{
482#if defined(QT_CHECK_RANGE)
483 if ( month < 1 || month > 12 ) {
484 qWarning( "QDate::shortMonthName: Parameter out ouf range." );
485 month = 1;
486 }
487#endif
488#ifndef Q_WS_WIN
489 char buffer[255];
490 tm tt;
491 memset( &tt, 0, sizeof( tm ) );
492 tt.tm_mon = month - 1;
493 if ( strftime( buffer, sizeof( buffer ), "%b", &tt ) )
494 return QString::fromLocal8Bit( buffer );
495#else
496 SYSTEMTIME st;
497 memset( &st, 0, sizeof(SYSTEMTIME) );
498 st.wYear = 2000;
499 st.wMonth = month;
500 st.wDay = 1;
501 const wchar_t mmm_t[] = L"MMM"; // workaround for Borland
502 QT_WA( {
503 TCHAR buf[255];
504 if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, mmm_t, buf, 255 ) )
505 return QString::fromUcs2( (ushort*)buf );
506 } , {
507 char buf[255];
508 if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "MMM", (char*)&buf, 255 ) )
509 return QString::fromLocal8Bit( buf );
510 } );
511#endif
512 return QString::null;
513}
514
515/*!
516 Returns the long name of the \a month.
517
518 1 = "January", 2 = "February", ... 12 = "December"
519
520 The month names will be localized according to the system's locale
521 settings.
522
523 \sa toString(), shortMonthName(), shortDayName(), longDayName()
524*/
525
526QString QDate::longMonthName( int month )
527{
528#if defined(QT_CHECK_RANGE)
529 if ( month < 1 || month > 12 ) {
530 qWarning( "QDate::longMonthName: Parameter out ouf range." );
531 month = 1;
532 }
533#endif
534#ifndef Q_WS_WIN
535 char buffer[255];
536 tm tt;
537 memset( &tt, 0, sizeof( tm ) );
538 tt.tm_mon = month - 1;
539 if ( strftime( buffer, sizeof( buffer ), "%B", &tt ) )
540 return QString::fromLocal8Bit( buffer );
541#else
542 SYSTEMTIME st;
543 memset( &st, 0, sizeof(SYSTEMTIME) );
544 st.wYear = 2000;
545 st.wMonth = month;
546 st.wDay = 1 ;
547 const wchar_t mmmm_t[] = L"MMMM"; // workaround for Borland
548 QT_WA( {
549 TCHAR buf[255];
550 if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, mmmm_t, buf, 255 ) )
551 return QString::fromUcs2( (ushort*)buf );
552 } , {
553 char buf[255];
554 if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "MMMM", (char*)&buf, 255 ) )
555 return QString::fromLocal8Bit( buf );
556 } )
557#endif
558
559 return QString::null;
560}
561
562/*!
563 \fn QString QDate::dayName( int weekday )
564 \obsolete
565
566 Use shortDayName() instead.
567*/
568
569/*!
570 Returns the name of the \a weekday.
571
572 1 = "Mon", 2 = "Tue", ... 7 = "Sun"
573
574 The day names will be localized according to the system's locale
575 settings.
576
577 \sa toString(), shortMonthName(), longMonthName(), longDayName()
578*/
579
580QString QDate::shortDayName( int weekday )
581{
582#if defined(QT_CHECK_RANGE)
583 if ( weekday < 1 || weekday > 7 ) {
584 qWarning( "QDate::shortDayName: Parameter out of range." );
585 weekday = 1;
586 }
587#endif
588#ifndef Q_WS_WIN
589 char buffer[255];
590 tm tt;
591 memset( &tt, 0, sizeof( tm ) );
592 tt.tm_wday = ( weekday == 7 ) ? 0 : weekday;
593 if ( strftime( buffer, sizeof( buffer ), "%a", &tt ) )
594 return QString::fromLocal8Bit( buffer );
595#else
596 SYSTEMTIME st;
597 memset( &st, 0, sizeof(SYSTEMTIME) );
598 st.wYear = 2001;
599 st.wMonth = 10;
600 st.wDayOfWeek = ( weekday == 7 ) ? 0 : weekday;
601 st.wDay = 21 + st.wDayOfWeek;
602 const wchar_t ddd_t[] = L"ddd"; // workaround for Borland
603 QT_WA( {
604 TCHAR buf[255];
605 if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, ddd_t, buf, 255 ) )
606 return QString::fromUcs2( (ushort*)buf );
607 } , {
608 char buf[255];
609 if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "ddd", (char*)&buf, 255 ) )
610 return QString::fromLocal8Bit( buf );
611 } );
612#endif
613
614 return QString::null;
615}
616
617/*!
618 Returns the long name of the \a weekday.
619
620 1 = "Monday", 2 = "Tuesday", ... 7 = "Sunday"
621
622 The day names will be localized according to the system's locale
623 settings.
624
625 \sa toString(), shortDayName(), shortMonthName(), longMonthName()
626*/
627
628QString QDate::longDayName( int weekday )
629{
630#if defined(QT_CHECK_RANGE)
631 if ( weekday < 1 || weekday > 7 ) {
632 qWarning( "QDate::longDayName: Parameter out of range." );
633 weekday = 1;
634 }
635#endif
636#ifndef Q_WS_WIN
637 char buffer[255];
638 tm tt;
639 memset( &tt, 0, sizeof( tm ) );
640 tt.tm_wday = ( weekday == 7 ) ? 0 : weekday;
641 if ( strftime( buffer, sizeof( buffer ), "%A", &tt ) )
642 return QString::fromLocal8Bit( buffer );
643#else
644 SYSTEMTIME st;
645 memset( &st, 0, sizeof(SYSTEMTIME) );
646 st.wYear = 2001;
647 st.wMonth = 10;
648 st.wDayOfWeek = ( weekday == 7 ) ? 0 : weekday;
649 st.wDay = 21 + st.wDayOfWeek;
650 const wchar_t dddd_t[] = L"dddd"; // workaround for Borland
651 QT_WA( {
652 TCHAR buf[255];
653 if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, dddd_t, buf, 255 ) )
654 return QString::fromUcs2( (ushort*)buf );
655 } , {
656 char buf[255];
657 if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "dddd", (char*)&buf, 255 ) )
658 return QString::fromLocal8Bit( buf );
659 } );
660#endif
661
662 return QString::null;
663}
664#endif //QT_NO_TEXTDATE
665
666#ifndef QT_NO_DATESTRING
667
668#if !defined(QT_NO_SPRINTF)
669/*!
670 \overload
671
672 Returns the date as a string. The \a f parameter determines the
673 format of the string.
674
675 If \a f is \c Qt::TextDate, the string format is "Sat May 20 1995"
676 (using the shortDayName() and shortMonthName() functions to
677 generate the string, so the day and month names are locale
678 specific).
679
680 If \a f is \c Qt::ISODate, the string format corresponds to the
681 ISO 8601 specification for representations of dates, which is
682 YYYY-MM-DD where YYYY is the year, MM is the month of the year
683 (between 01 and 12), and DD is the day of the month between 01 and
684 31.
685
686 If \a f is \c Qt::LocalDate, the string format depends on the
687 locale settings of the system.
688
689 \sa shortDayName(), shortMonthName()
690*/
691QString QDate::toString( Qt::DateFormat f ) const
692{
693 int y, m, d;
694 julianToGregorian( jd, y, m, d );
695 switch ( f ) {
696 case Qt::LocalDate:
697 {
698#ifndef Q_WS_WIN
699 tm tt;
700 memset( &tt, 0, sizeof( tm ) );
701 char buf[255];
702 tt.tm_mday = day();
703 tt.tm_mon = month() - 1;
704 tt.tm_year = year() - 1900;
705
706 static const char * avoidEgcsWarning = "%x";
707 if ( strftime( buf, sizeof(buf), avoidEgcsWarning, &tt ) )
708 return QString::fromLocal8Bit( buf );
709#else
710 SYSTEMTIME st;
711 memset( &st, 0, sizeof(SYSTEMTIME) );
712 st.wYear = year();
713 st.wMonth = month();
714 st.wDay = day();
715 QT_WA( {
716 TCHAR buf[255];
717 if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, 0, buf, 255 ) )
718 return QString::fromUcs2( (ushort*)buf );
719 } , {
720 char buf[255];
721 if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, 0, (char*)&buf, 255 ) )
722 return QString::fromLocal8Bit( buf );
723 } );
724#endif
725 return QString::null;
726 }
727 default:
728#ifndef QT_NO_TEXTDATE
729 case Qt::TextDate:
730 {
731 QString buf = shortDayName( dayOfWeek() );
732 buf += ' ';
733 buf += shortMonthName( m );
734 QString t;
735 t.sprintf( " %d %d", d, y );
736 buf += t;
737 return buf;
738 }
739#endif
740 case Qt::ISODate:
741 {
742 QString month( QString::number( m ).rightJustify( 2, '0' ) );
743 QString day( QString::number( d ).rightJustify( 2, '0' ) );
744 return QString::number( y ) + "-" + month + "-" + day;
745 }
746 }
747}
748#endif //QT_NO_SPRINTF
749
750/*!
751 Returns the date as a string. The \a format parameter determines
752 the format of the result string.
753
754 These expressions may be used:
755
756 \table
757 \header \i Expression \i Output
758 \row \i d \i the day as number without a leading zero (1-31)
759 \row \i dd \i the day as number with a leading zero (01-31)
760 \row \i ddd
761 \i the abbreviated localized day name (e.g. 'Mon'..'Sun').
762 Uses QDate::shortDayName().
763 \row \i dddd
764 \i the long localized day name (e.g. 'Monday'..'Sunday').
765 Uses QDate::longDayName().
766 \row \i M \i the month as number without a leading zero (1-12)
767 \row \i MM \i the month as number with a leading zero (01-12)
768 \row \i MMM
769 \i the abbreviated localized month name (e.g. 'Jan'..'Dec').
770 Uses QDate::shortMonthName().
771 \row \i MMMM
772 \i the long localized month name (e.g. 'January'..'December').
773 Uses QDate::longMonthName().
774 \row \i yy \i the year as two digit number (00-99)
775 \row \i yyyy \i the year as four digit number (1752-8000)
776 \endtable
777
778 All other input characters will be ignored.
779
780 Example format strings (assuming that the QDate is the
781 20<sup><small>th</small></sup> July 1969):
782 \table
783 \header \i Format \i Result
784 \row \i dd.MM.yyyy \i11 20.07.1969
785 \row \i ddd MMMM d yy \i11 Sun July 20 69
786 \endtable
787
788 \sa QDate::toString() QTime::toString()
789
790*/
791QString QDate::toString( const QString& format ) const
792{
793 return fmtDateTime( format, 0, this );
794}
795#endif //QT_NO_DATESTRING
796
797/*!
798 Sets the date's year \a y, month \a m and day \a d.
799
800 \a y must be in the range 1752..8000, \a m must be in the range
801 1..12, and \a d must be in the range 1..31.
802
803 \warning If \a y is in the range 0..99, it is interpreted as
804 1900..1999.
805
806 Returns TRUE if the date is valid; otherwise returns FALSE.
807*/
808
809bool QDate::setYMD( int y, int m, int d )
810{
811 if ( year() == y && month() == m && day() == d )
812 return isValid();
813 if ( !isValid(y,m,d) ) {
814#if defined(QT_CHECK_RANGE)
815 qWarning( "QDate::setYMD: Invalid date %04d-%02d-%02d", y, m, d );
816#endif
817 return FALSE;
818 }
819 jd = gregorianToJulian( y, m, d );
820 return TRUE;
821}
822
823/*!
824 Returns a QDate object containing a date \a ndays later than the
825 date of this object (or earlier if \a ndays is negative).
826
827 \sa addMonths() addYears() daysTo()
828*/
829
830QDate QDate::addDays( int ndays ) const
831{
832 QDate d;
833 d.jd = jd + ndays;
834 return d;
835}
836
837/*!
838 Returns a QDate object containing a date \a nmonths later than the
839 date of this object (or earlier if \a nmonths is negative).
840
841 \sa addDays() addYears()
842*/
843
844QDate QDate::addMonths( int nmonths ) const
845{
846 int y, m, d;
847 julianToGregorian( jd, y, m, d );
848
849 while ( nmonths != 0 ) {
850 if ( nmonths < 0 && nmonths + 12 <= 0 ) {
851 y--;
852 nmonths+=12;
853 } else if ( nmonths < 0 ) {
854 m+= nmonths;
855 nmonths = 0;
856 if ( m <= 0 ) {
857 --y;
858 m+=12;
859 }
860 } else if ( nmonths - 12 >= 0 ) {
861 y++;
862 nmonths-=12;
863 } else if ( m == 12 ) {
864 y++;
865 m = 0;
866 } else {
867 m+= nmonths;
868 nmonths = 0;
869 if ( m > 12 ) {
870 ++y;
871 m -= 12;
872 }
873 }
874 }
875
876 QDate tmp(y,m,1);
877
878 if( d > tmp.daysInMonth() )
879 d = tmp.daysInMonth();
880
881 QDate date(y, m, d);
882 return date;
883
884}
885
886/*!
887 Returns a QDate object containing a date \a nyears later than the
888 date of this object (or earlier if \a nyears is negative).
889
890 \sa addDays(), addMonths()
891*/
892
893QDate QDate::addYears( int nyears ) const
894{
895 int y, m, d;
896 julianToGregorian( jd, y, m, d );
897 y += nyears;
898 QDate date(y, m, d);
899 return date;
900}
901
902
903
904/*!
905 Returns the number of days from this date to \a d (which is
906 negative if \a d is earlier than this date).
907
908 Example:
909 \code
910 QDate d1( 1995, 5, 17 ); // May 17th 1995
911 QDate d2( 1995, 5, 20 ); // May 20th 1995
912 d1.daysTo( d2 ); // returns 3
913 d2.daysTo( d1 ); // returns -3
914 \endcode
915
916 \sa addDays()
917*/
918
919int QDate::daysTo( const QDate &d ) const
920{
921 return d.jd - jd;
922}
923
924
925/*!
926 \fn bool QDate::operator==( const QDate &d ) const
927
928 Returns TRUE if this date is equal to \a d; otherwise returns FALSE.
929*/
930
931/*!
932 \fn bool QDate::operator!=( const QDate &d ) const
933
934 Returns TRUE if this date is different from \a d; otherwise returns FALSE.
935*/
936
937/*!
938 \fn bool QDate::operator<( const QDate &d ) const
939
940 Returns TRUE if this date is earlier than \a d, otherwise returns FALSE.
941*/
942
943/*!
944 \fn bool QDate::operator<=( const QDate &d ) const
945
946 Returns TRUE if this date is earlier than or equal to \a d,
947 otherwise returns FALSE.
948*/
949
950/*!
951 \fn bool QDate::operator>( const QDate &d ) const
952
953 Returns TRUE if this date is later than \a d, otherwise returns FALSE.
954*/
955
956/*!
957 \fn bool QDate::operator>=( const QDate &d ) const
958
959 Returns TRUE if this date is later than or equal to \a d,
960 otherwise returns FALSE.
961*/
962
963/*!
964 \overload
965 Returns the current date, as reported by the system clock.
966
967 \sa QTime::currentTime(), QDateTime::currentDateTime()
968*/
969
970QDate QDate::currentDate()
971{
972 return currentDate( Qt::LocalTime );
973}
974
975/*!
976 Returns the current date, as reported by the system clock, for the
977 TimeSpec \a ts. The default TimeSpec is LocalTime.
978
979 \sa QTime::currentTime(), QDateTime::currentDateTime(), Qt::TimeSpec
980*/
981QDate QDate::currentDate( Qt::TimeSpec ts )
982{
983 QDate d;
984#if defined(Q_OS_WIN32)
985 SYSTEMTIME t;
986 memset( &t, 0, sizeof(SYSTEMTIME) );
987 if ( ts == Qt::LocalTime )
988 GetLocalTime( &t );
989 else
990 GetSystemTime( &t );
991 d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay );
992#else
993 time_t ltime;
994 time( &ltime );
995 tm *t;
996 if ( ts == Qt::LocalTime )
997 t = localtime( &ltime );
998 else
999 t = gmtime( &ltime );
1000 d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday );
1001#endif
1002 return d;
1003}
1004
1005#ifndef QT_NO_DATESTRING
1006/*!
1007 Returns the QDate represented by the string \a s, using the format
1008 \a f, or an invalid date if the string cannot be parsed.
1009
1010 Note for \c Qt::TextDate: It is recommended that you use the
1011 English short month names (e.g. "Jan"). Although localized month
1012 names can also be used, they depend on the user's locale settings.
1013
1014 \warning \c Qt::LocalDate cannot be used here.
1015*/
1016QDate QDate::fromString( const QString& s, Qt::DateFormat f )
1017{
1018 if ( ( s.isEmpty() ) || ( f == Qt::LocalDate ) ) {
1019#if defined(QT_CHECK_RANGE)
1020 qWarning( "QDate::fromString: Parameter out of range." );
1021#endif
1022 return QDate();
1023 }
1024 switch ( f ) {
1025 case Qt::ISODate:
1026 {
1027 int year( s.mid( 0, 4 ).toInt() );
1028 int month( s.mid( 5, 2 ).toInt() );
1029 int day( s.mid( 8, 2 ).toInt() );
1030 if ( year && month && day )
1031 return QDate( year, month, day );
1032 }
1033 break;
1034 default:
1035#ifndef QT_NO_TEXTDATE
1036 case Qt::TextDate:
1037 {
1038 /*
1039 This will fail gracefully if the input string doesn't
1040 contain any space.
1041 */
1042 int monthPos = s.find( ' ' ) + 1;
1043 int dayPos = s.find( ' ', monthPos ) + 1;
1044
1045 QString monthName( s.mid(monthPos, dayPos - monthPos - 1) );
1046 int month = -1;
1047
1048 // try English names first
1049 for ( int i = 0; i < 12; i++ ) {
1050 if ( monthName == qt_shortMonthNames[i] ) {
1051 month = i + 1;
1052 break;
1053 }
1054 }
1055
1056 // try the localized names
1057 if ( month == -1 ) {
1058 for ( int i = 0; i < 12; i++ ) {
1059 if ( monthName == shortMonthName( i + 1 ) ) {
1060 month = i + 1;
1061 break;
1062 }
1063 }
1064 }
1065#if defined(QT_CHECK_RANGE)
1066 if ( month < 1 || month > 12 ) {
1067 qWarning( "QDate::fromString: Parameter out of range." );
1068 month = 1;
1069 }
1070#endif
1071 int day = s.mid( dayPos, 2 ).stripWhiteSpace().toInt();
1072 int year = s.right( 4 ).toInt();
1073 return QDate( year, month, day );
1074 }
1075#else
1076 break;
1077#endif
1078 }
1079 return QDate();
1080}
1081#endif //QT_NO_DATESTRING
1082
1083/*!
1084 \overload
1085
1086 Returns TRUE if the specified date (year \a y, month \a m and day
1087 \a d) is valid; otherwise returns FALSE.
1088
1089 Example:
1090 \code
1091 QDate::isValid( 2002, 5, 17 ); // TRUE May 17th 2002 is valid
1092 QDate::isValid( 2002, 2, 30 ); // FALSE Feb 30th does not exist
1093 QDate::isValid( 2004, 2, 29 ); // TRUE 2004 is a leap year
1094 QDate::isValid( 1202, 6, 6 ); // FALSE 1202 is pre-Gregorian
1095 \endcode
1096
1097 \warning A \a y value in the range 00..99 is interpreted as
1098 1900..1999.
1099
1100 \sa isNull(), setYMD()
1101*/
1102
1103bool QDate::isValid( int y, int m, int d )
1104{
1105 if ( y >= 0 && y <= 99 )
1106 y += 1900;
1107 else if ( y < FIRST_YEAR || (y == FIRST_YEAR && (m < 9 ||
1108 (m == 9 && d < 14))) )
1109 return FALSE;
1110 return (d > 0 && m > 0 && m <= 12) &&
1111 (d <= monthDays[m] || (d == 29 && m == 2 && leapYear(y)));
1112}
1113
1114/*!
1115 Returns TRUE if the specified year \a y is a leap year; otherwise
1116 returns FALSE.
1117*/
1118
1119bool QDate::leapYear( int y )
1120{
1121 return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
1122}
1123
1124/*!
1125 \internal
1126 Converts a Gregorian date to a Julian day.
1127 This algorithm is taken from Communications of the ACM, Vol 6, No 8.
1128 \sa julianToGregorian()
1129*/
1130
1131uint QDate::gregorianToJulian( int y, int m, int d )
1132{
1133 uint c, ya;
1134 if ( y <= 99 )
1135 y += 1900;
1136 if ( m > 2 ) {
1137 m -= 3;
1138 } else {
1139 m += 9;
1140 y--;
1141 }
1142 c = y; // NOTE: Sym C++ 6.0 bug
1143 c /= 100;
1144 ya = y - 100*c;
1145 return 1721119 + d + (146097*c)/4 + (1461*ya)/4 + (153*m+2)/5;
1146}
1147
1148/*!
1149 \internal
1150 Converts a Julian day to a Gregorian date.
1151 This algorithm is taken from Communications of the ACM, Vol 6, No 8.
1152 \sa gregorianToJulian()
1153*/
1154
1155void QDate::julianToGregorian( uint jd, int &y, int &m, int &d )
1156{
1157 uint x;
1158 uint j = jd - 1721119;
1159 y = (j*4 - 1)/146097;
1160 j = j*4 - 146097*y - 1;
1161 x = j/4;
1162 j = (x*4 + 3) / 1461;
1163 y = 100*y + j;
1164 x = (x*4) + 3 - 1461*j;
1165 x = (x + 4)/4;
1166 m = (5*x - 3)/153;
1167 x = 5*x - 3 - 153*m;
1168 d = (x + 5)/5;
1169 if ( m < 10 ) {
1170 m += 3;
1171 } else {
1172 m -= 9;
1173 y++;
1174 }
1175}
1176
1177
1178/*****************************************************************************
1179 QTime member functions
1180 *****************************************************************************/
1181
1182/*!
1183 \class QTime qdatetime.h
1184 \reentrant
1185
1186 \brief The QTime class provides clock time functions.
1187
1188 \ingroup time
1189 \mainclass
1190
1191 A QTime object contains a clock time, i.e. the number of hours,
1192 minutes, seconds, and milliseconds since midnight. It can read the
1193 current time from the system clock and measure a span of elapsed
1194 time. It provides functions for comparing times and for
1195 manipulating a time by adding a number of (milli)seconds.
1196
1197 QTime uses the 24-hour clock format; it has no concept of AM/PM.
1198 It operates in local time; it knows nothing about time zones or
1199 daylight savings time.
1200
1201 A QTime object is typically created either by giving the number of
1202 hours, minutes, seconds, and milliseconds explicitly, or by using
1203 the static function currentTime(), which creates a QTime object
1204 that contains the system's clock time. Note that the accuracy
1205 depends on the accuracy of the underlying operating system; not
1206 all systems provide 1-millisecond accuracy.
1207
1208 The hour(), minute(), second(), and msec() functions provide
1209 access to the number of hours, minutes, seconds, and milliseconds
1210 of the time. The same information is provided in textual format by
1211 the toString() function.
1212
1213 QTime provides a full set of operators to compare two QTime
1214 objects. One time is considered smaller than another if it is
1215 earlier than the other.
1216
1217 The time a given number of seconds or milliseconds later than a
1218 given time can be found using the addSecs() or addMSecs()
1219 functions. Correspondingly, the number of (milli)seconds between
1220 two times can be found using the secsTo() or msecsTo() functions.
1221
1222 QTime can be used to measure a span of elapsed time using the
1223 start(), restart(), and elapsed() functions.
1224
1225 \sa QDate, QDateTime
1226*/
1227
1228/*!
1229 \fn QTime::QTime()
1230
1231 Constructs the time 0 hours, minutes, seconds and milliseconds,
1232 i.e. 00:00:00.000 (midnight). This is a valid time.
1233
1234 \sa isValid()
1235*/
1236
1237/*!
1238 Constructs a time with hour \a h, minute \a m, seconds \a s and
1239 milliseconds \a ms.
1240
1241 \a h must be in the range 0..23, \a m and \a s must be in the
1242 range 0..59, and \a ms must be in the range 0..999.
1243
1244 \sa isValid()
1245*/
1246
1247QTime::QTime( int h, int m, int s, int ms )
1248{
1249 setHMS( h, m, s, ms );
1250}
1251
1252
1253/*!
1254 \fn bool QTime::isNull() const
1255
1256 Returns TRUE if the time is equal to 00:00:00.000; otherwise
1257 returns FALSE. A null time is valid.
1258
1259 \sa isValid()
1260*/
1261
1262/*!
1263 Returns TRUE if the time is valid; otherwise returns FALSE. The
1264 time 23:30:55.746 is valid, whereas 24:12:30 is invalid.
1265
1266 \sa isNull()
1267*/
1268
1269bool QTime::isValid() const
1270{
1271 return ds < MSECS_PER_DAY;
1272}
1273
1274
1275/*!
1276 Returns the hour part (0..23) of the time.
1277*/
1278
1279int QTime::hour() const
1280{
1281 return ds / MSECS_PER_HOUR;
1282}
1283
1284/*!
1285 Returns the minute part (0..59) of the time.
1286*/
1287
1288int QTime::minute() const
1289{
1290 return (ds % MSECS_PER_HOUR)/MSECS_PER_MIN;
1291}
1292
1293/*!
1294 Returns the second part (0..59) of the time.
1295*/
1296
1297int QTime::second() const
1298{
1299 return (ds / 1000)%SECS_PER_MIN;
1300}
1301
1302/*!
1303 Returns the millisecond part (0..999) of the time.
1304*/
1305
1306int QTime::msec() const
1307{
1308 return ds % 1000;
1309}
1310
1311#ifndef QT_NO_DATESTRING
1312#ifndef QT_NO_SPRINTF
1313/*!
1314 \overload
1315
1316 Returns the time as a string. Milliseconds are not included. The
1317 \a f parameter determines the format of the string.
1318
1319 If \a f is \c Qt::TextDate, the string format is HH:MM:SS; e.g. 1
1320 second before midnight would be "23:59:59".
1321
1322 If \a f is \c Qt::ISODate, the string format corresponds to the
1323 ISO 8601 extended specification for representations of dates,
1324 which is also HH:MM:SS.
1325
1326 If \a f is Qt::LocalDate, the string format depends on the locale
1327 settings of the system.
1328*/
1329
1330QString QTime::toString( Qt::DateFormat f ) const
1331{
1332 switch ( f ) {
1333 case Qt::LocalDate:
1334 {
1335#ifndef Q_WS_WIN
1336 tm tt;
1337 memset( &tt, 0, sizeof( tm ) );
1338 char buf[255];
1339 tt.tm_sec = second();
1340 tt.tm_min = minute();
1341 tt.tm_hour = hour();
1342 if ( strftime( buf, sizeof(buf), "%X", &tt ) )
1343 return QString::fromLocal8Bit( buf );
1344#else
1345 SYSTEMTIME st;
1346 memset( &st, 0, sizeof(SYSTEMTIME) );
1347 st.wHour = hour();
1348 st.wMinute = minute();
1349 st.wSecond = second();
1350 st.wMilliseconds = 0;
1351 QT_WA( {
1352 TCHAR buf[255];
1353 if ( GetTimeFormat( LOCALE_USER_DEFAULT, 0, &st, 0, buf, 255 ) )
1354 return QString::fromUcs2( (ushort*)buf );
1355 } , {
1356 char buf[255];
1357 if ( GetTimeFormatA( LOCALE_USER_DEFAULT, 0, &st, 0, (char*)&buf, 255 ) )
1358 return QString::fromLocal8Bit( buf );
1359 } );
1360#endif
1361 return QString::null;
1362 }
1363 default:
1364 case Qt::ISODate:
1365 case Qt::TextDate:
1366 QString buf;
1367 buf.sprintf( "%.2d:%.2d:%.2d", hour(), minute(), second() );
1368 return buf;
1369 }
1370}
1371#endif
1372
1373/*!
1374 Returns the time as a string. The \a format parameter determines
1375 the format of the result string.
1376
1377 These expressions may be used:
1378
1379 \table
1380 \header \i Expression \i Output
1381 \row \i h
1382 \i the hour without a leading zero (0..23 or 1..12 if AM/PM display)
1383 \row \i hh
1384 \i the hour with a leading zero (00..23 or 01..12 if AM/PM display)
1385 \row \i m \i the minute without a leading zero (0..59)
1386 \row \i mm \i the minute with a leading zero (00..59)
1387 \row \i s \i the second whithout a leading zero (0..59)
1388 \row \i ss \i the second whith a leading zero (00..59)
1389 \row \i z \i the milliseconds without leading zeroes (0..999)
1390 \row \i zzz \i the milliseconds with leading zeroes (000..999)
1391 \row \i AP
1392 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1393 \row \i ap
1394 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1395 \endtable
1396
1397 All other input characters will be ignored.
1398
1399 Example format strings (assuming that the QTime is 14:13:09.042)
1400
1401 \table
1402 \header \i Format \i Result
1403 \row \i hh:mm:ss.zzz \i11 14:13:09.042
1404 \row \i h:m:s ap \i11 2:13:9 pm
1405 \endtable
1406
1407 \sa QDate::toString() QTime::toString()
1408*/
1409QString QTime::toString( const QString& format ) const
1410{
1411 return fmtDateTime( format, this, 0 );
1412}
1413#endif //QT_NO_DATESTRING
1414/*!
1415 Sets the time to hour \a h, minute \a m, seconds \a s and
1416 milliseconds \a ms.
1417
1418 \a h must be in the range 0..23, \a m and \a s must be in the
1419 range 0..59, and \a ms must be in the range 0..999. Returns TRUE
1420 if the set time is valid; otherwise returns FALSE.
1421
1422 \sa isValid()
1423*/
1424
1425bool QTime::setHMS( int h, int m, int s, int ms )
1426{
1427 if ( !isValid(h,m,s,ms) ) {
1428#if defined(QT_CHECK_RANGE)
1429 qWarning( "QTime::setHMS Invalid time %02d:%02d:%02d.%03d", h, m, s,
1430 ms );
1431#endif
1432 ds = MSECS_PER_DAY; // make this invalid
1433 return FALSE;
1434 }
1435 ds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
1436 return TRUE;
1437}
1438
1439/*!
1440 Returns a QTime object containing a time \a nsecs seconds later
1441 than the time of this object (or earlier if \a nsecs is negative).
1442
1443 Note that the time will wrap if it passes midnight.
1444
1445 Example:
1446 \code
1447 QTime n( 14, 0, 0 ); // n == 14:00:00
1448 QTime t;
1449 t = n.addSecs( 70 ); // t == 14:01:10
1450 t = n.addSecs( -70 ); // t == 13:58:50
1451 t = n.addSecs( 10*60*60 + 5 ); // t == 00:00:05
1452 t = n.addSecs( -15*60*60 ); // t == 23:00:00
1453 \endcode
1454
1455 \sa addMSecs(), secsTo(), QDateTime::addSecs()
1456*/
1457
1458QTime QTime::addSecs( int nsecs ) const
1459{
1460 return addMSecs( nsecs * 1000 );
1461}
1462
1463/*!
1464 Returns the number of seconds from this time to \a t (which is
1465 negative if \a t is earlier than this time).
1466
1467 Because QTime measures time within a day and there are 86400
1468 seconds in a day, the result is always between -86400 and 86400.
1469
1470 \sa addSecs() QDateTime::secsTo()
1471*/
1472
1473int QTime::secsTo( const QTime &t ) const
1474{
1475 return ((int)t.ds - (int)ds)/1000;
1476}
1477
1478/*!
1479 Returns a QTime object containing a time \a ms milliseconds later
1480 than the time of this object (or earlier if \a ms is negative).
1481
1482 Note that the time will wrap if it passes midnight. See addSecs()
1483 for an example.
1484
1485 \sa addSecs(), msecsTo()
1486*/
1487
1488QTime QTime::addMSecs( int ms ) const
1489{
1490 QTime t;
1491 if ( ms < 0 ) {
1492 // % not well-defined for -ve, but / is.
1493 int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
1494 t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
1495 % MSECS_PER_DAY;
1496 } else {
1497 t.ds = ((int)ds + ms) % MSECS_PER_DAY;
1498 }
1499 return t;
1500}
1501
1502/*!
1503 Returns the number of milliseconds from this time to \a t (which
1504 is negative if \a t is earlier than this time).
1505
1506 Because QTime measures time within a day and there are 86400
1507 seconds in a day, the result is always between -86400 and 86400s.
1508
1509 \sa secsTo()
1510*/
1511
1512int QTime::msecsTo( const QTime &t ) const
1513{
1514 return (int)t.ds - (int)ds;
1515}
1516
1517
1518/*!
1519 \fn bool QTime::operator==( const QTime &t ) const
1520
1521 Returns TRUE if this time is equal to \a t; otherwise returns FALSE.
1522*/
1523
1524/*!
1525 \fn bool QTime::operator!=( const QTime &t ) const
1526
1527 Returns TRUE if this time is different from \a t; otherwise returns FALSE.
1528*/
1529
1530/*!
1531 \fn bool QTime::operator<( const QTime &t ) const
1532
1533 Returns TRUE if this time is earlier than \a t; otherwise returns FALSE.
1534*/
1535
1536/*!
1537 \fn bool QTime::operator<=( const QTime &t ) const
1538
1539 Returns TRUE if this time is earlier than or equal to \a t;
1540 otherwise returns FALSE.
1541*/
1542
1543/*!
1544 \fn bool QTime::operator>( const QTime &t ) const
1545
1546 Returns TRUE if this time is later than \a t; otherwise returns FALSE.
1547*/
1548
1549/*!
1550 \fn bool QTime::operator>=( const QTime &t ) const
1551
1552 Returns TRUE if this time is later than or equal to \a t;
1553 otherwise returns FALSE.
1554*/
1555
1556
1557
1558/*!
1559 \overload
1560
1561 Returns the current time as reported by the system clock.
1562
1563 Note that the accuracy depends on the accuracy of the underlying
1564 operating system; not all systems provide 1-millisecond accuracy.
1565*/
1566
1567QTime QTime::currentTime()
1568{
1569 return currentTime( Qt::LocalTime );
1570}
1571
1572/*!
1573 Returns the current time as reported by the system clock, for the
1574 TimeSpec \a ts. The default TimeSpec is LocalTime.
1575
1576 Note that the accuracy depends on the accuracy of the underlying
1577 operating system; not all systems provide 1-millisecond accuracy.
1578
1579 \sa Qt::TimeSpec
1580*/
1581QTime QTime::currentTime( Qt::TimeSpec ts )
1582{
1583 QTime t;
1584 currentTime( &t, ts );
1585 return t;
1586}
1587
1588#ifndef QT_NO_DATESTRING
1589/*!
1590 Returns the representation \a s as a QTime using the format \a f,
1591 or an invalid time if this is not possible.
1592
1593 \warning Note that \c Qt::LocalDate cannot be used here.
1594*/
1595QTime QTime::fromString( const QString& s, Qt::DateFormat f )
1596{
1597 if ( ( s.isEmpty() ) || ( f == Qt::LocalDate ) ) {
1598#if defined(QT_CHECK_RANGE)
1599 qWarning( "QTime::fromString: Parameter out of range." );
1600#endif
1601 return QTime();
1602 }
1603
1604 int hour( s.mid( 0, 2 ).toInt() );
1605 int minute( s.mid( 3, 2 ).toInt() );
1606 int second( s.mid( 6, 2 ).toInt() );
1607 int msec( s.mid( 9, 3 ).toInt() );
1608 return QTime( hour, minute, second, msec );
1609}
1610#endif
1611
1612/*!
1613 \internal
1614 \obsolete
1615
1616 Fetches the current time and returns TRUE if the time is within one
1617 minute after midnight, otherwise FALSE. The return value is used by
1618 QDateTime::currentDateTime() to ensure that the date there is correct.
1619*/
1620
1621bool QTime::currentTime( QTime *ct )
1622{
1623 return currentTime( ct, Qt::LocalTime );
1624}
1625
1626
1627/*!
1628 \internal
1629
1630 Fetches the current time, for the TimeSpec \a ts, and returns TRUE
1631 if the time is within one minute after midnight, otherwise FALSE. The
1632 return value is used by QDateTime::currentDateTime() to ensure that
1633 the date there is correct. The default TimeSpec is LocalTime.
1634
1635 \sa Qt::TimeSpec
1636*/
1637bool QTime::currentTime( QTime *ct, Qt::TimeSpec ts )
1638{
1639 if ( !ct ) {
1640#if defined(QT_CHECK_NULL)
1641 qWarning( "QTime::currentTime(QTime *): Null pointer not allowed" );
1642#endif
1643 return FALSE;
1644 }
1645
1646#if defined(Q_OS_WIN32)
1647 SYSTEMTIME t;
1648 if ( ts == Qt::LocalTime ) {
1649 GetLocalTime( &t );
1650 } else {
1651 GetSystemTime( &t );
1652 }
1653 ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute +
1654 1000*t.wSecond + t.wMilliseconds );
1655#elif defined(Q_OS_UNIX)
1656 struct timeval tv;
1657 gettimeofday( &tv, 0 );
1658 time_t ltime = tv.tv_sec;
1659 tm *t;
1660 if ( ts == Qt::LocalTime ) {
1661 t = localtime( &ltime );
1662 } else {
1663 t = gmtime( &ltime );
1664 }
1665 ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
1666 1000 * t->tm_sec + tv.tv_usec / 1000 );
1667#else
1668 time_t ltime; // no millisecond resolution
1669 ::time( &ltime );
1670 tm *t;
1671 if ( ts == Qt::LocalTime )
1672 localtime( &ltime );
1673 else
1674 gmtime( &ltime );
1675 ct->ds = (uint) ( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
1676 1000 * t->tm_sec );
1677#endif
1678 // 00:00.00 to 00:00.59.999 is considered as "midnight or right after"
1679 return ct->ds < (uint) MSECS_PER_MIN;
1680}
1681
1682/*!
1683 \overload
1684
1685 Returns TRUE if the specified time is valid; otherwise returns
1686 FALSE.
1687
1688 The time is valid if \a h is in the range 0..23, \a m and \a s are
1689 in the range 0..59, and \a ms is in the range 0..999.
1690
1691 Example:
1692 \code
1693 QTime::isValid(21, 10, 30); // returns TRUE
1694 QTime::isValid(22, 5, 62); // returns FALSE
1695 \endcode
1696*/
1697
1698bool QTime::isValid( int h, int m, int s, int ms )
1699{
1700 return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
1701}
1702
1703
1704/*!
1705 Sets this time to the current time. This is practical for timing:
1706
1707 \code
1708 QTime t;
1709 t.start(); // start clock
1710 ... // some lengthy task
1711 qDebug( "%d\n", t.elapsed() ); // prints the number of msecs elapsed
1712 \endcode
1713
1714 \sa restart(), elapsed(), currentTime()
1715*/
1716
1717void QTime::start()
1718{
1719 *this = currentTime();
1720}
1721
1722/*!
1723 Sets this time to the current time and returns the number of
1724 milliseconds that have elapsed since the last time start() or
1725 restart() was called.
1726
1727 This function is guaranteed to be atomic and is thus very handy
1728 for repeated measurements. Call start() to start the first
1729 measurement and then restart() for each later measurement.
1730
1731 Note that the counter wraps to zero 24 hours after the last call
1732 to start() or restart().
1733
1734 \warning If the system's clock setting has been changed since the
1735 last time start() or restart() was called, the result is
1736 undefined. This can happen when daylight savings time is turned on
1737 or off.
1738
1739 \sa start(), elapsed(), currentTime()
1740*/
1741
1742int QTime::restart()
1743{
1744 QTime t = currentTime();
1745 int n = msecsTo( t );
1746 if ( n < 0 ) // passed midnight
1747 n += 86400*1000;
1748 *this = t;
1749 return n;
1750}
1751
1752/*!
1753 Returns the number of milliseconds that have elapsed since the
1754 last time start() or restart() was called.
1755
1756 Note that the counter wraps to zero 24 hours after the last call
1757 to start() or restart.
1758
1759 Note that the accuracy depends on the accuracy of the underlying
1760 operating system; not all systems provide 1-millisecond accuracy.
1761
1762 \warning If the system's clock setting has been changed since the
1763 last time start() or restart() was called, the result is
1764 undefined. This can happen when daylight savings time is turned on
1765 or off.
1766
1767 \sa start(), restart()
1768*/
1769
1770int QTime::elapsed() const
1771{
1772 int n = msecsTo( currentTime() );
1773 if ( n < 0 ) // passed midnight
1774 n += 86400*1000;
1775 return n;
1776}
1777
1778
1779/*****************************************************************************
1780 QDateTime member functions
1781 *****************************************************************************/
1782
1783/*!
1784 \class QDateTime qdatetime.h
1785 \reentrant
1786 \brief The QDateTime class provides date and time functions.
1787
1788 \ingroup time
1789 \mainclass
1790
1791 A QDateTime object contains a calendar date and a clock time (a
1792 "datetime"). It is a combination of the QDate and QTime classes.
1793 It can read the current datetime from the system clock. It
1794 provides functions for comparing datetimes and for manipulating a
1795 datetime by adding a number of seconds, days, months or years.
1796
1797 A QDateTime object is typically created either by giving a date
1798 and time explicitly in the constructor, or by using the static
1799 function currentDateTime(), which returns a QDateTime object set
1800 to the system clock's time. The date and time can be changed with
1801 setDate() and setTime(). A datetime can also be set using the
1802 setTime_t() function, which takes a POSIX-standard "number of
1803 seconds since 00:00:00 on January 1, 1970" value. The fromString()
1804 function returns a QDateTime given a string and a date format
1805 which is used to interpret the date within the string.
1806
1807 The date() and time() functions provide access to the date and
1808 time parts of the datetime. The same information is provided in
1809 textual format by the toString() function.
1810
1811 QDateTime provides a full set of operators to compare two
1812 QDateTime objects where smaller means earlier and larger means
1813 later.
1814
1815 You can increment (or decrement) a datetime by a given number of
1816 seconds using addSecs() or days using addDays(). Similarly you can
1817 use addMonths() and addYears(). The daysTo() function returns the
1818 number of days between two datetimes, and secsTo() returns the
1819 number of seconds between two datetimes.
1820
1821 The range of a datetime object is constrained to the ranges of the
1822 QDate and QTime objects which it embodies.
1823
1824 \sa QDate QTime QDateTimeEdit
1825*/
1826
1827
1828/*!
1829 \fn QDateTime::QDateTime()
1830
1831 Constructs a null datetime (i.e. null date and null time). A null
1832 datetime is invalid, since the date is invalid.
1833
1834 \sa isValid()
1835*/
1836
1837
1838/*!
1839 Constructs a datetime with date \a date and null (but valid) time
1840 (00:00:00.000).
1841*/
1842
1843QDateTime::QDateTime( const QDate &date )
1844 : d(date)
1845{
1846}
1847
1848/*!
1849 Constructs a datetime with date \a date and time \a time.
1850*/
1851
1852QDateTime::QDateTime( const QDate &date, const QTime &time )
1853 : d(date), t(time)
1854{
1855}
1856
1857
1858/*!
1859 \fn bool QDateTime::isNull() const
1860
1861 Returns TRUE if both the date and the time are null; otherwise
1862 returns FALSE. A null datetime is invalid.
1863
1864 \sa QDate::isNull(), QTime::isNull()
1865*/
1866
1867/*!
1868 \fn bool QDateTime::isValid() const
1869
1870 Returns TRUE if both the date and the time are valid; otherwise
1871 returns FALSE.
1872
1873 \sa QDate::isValid(), QTime::isValid()
1874*/
1875
1876/*!
1877 \fn QDate QDateTime::date() const
1878
1879 Returns the date part of the datetime.
1880
1881 \sa setDate(), time()
1882*/
1883
1884/*!
1885 \fn QTime QDateTime::time() const
1886
1887 Returns the time part of the datetime.
1888
1889 \sa setTime(), date()
1890*/
1891
1892/*!
1893 \fn void QDateTime::setDate( const QDate &date )
1894
1895 Sets the date part of this datetime to \a date.
1896
1897 \sa date(), setTime()
1898*/
1899
1900/*!
1901 \fn void QDateTime::setTime( const QTime &time )
1902
1903 Sets the time part of this datetime to \a time.
1904
1905 \sa time(), setDate()
1906*/
1907
1908
1909/*!
1910 Returns the datetime as the number of seconds that have passed
1911 since 1970-01-01T00:00:00, Coordinated Universal Time (UTC).
1912
1913 On systems that do not support timezones, this function will
1914 behave as if local time were UTC.
1915
1916 \sa setTime_t()
1917*/
1918
1919uint QDateTime::toTime_t() const
1920{
1921 tm brokenDown;
1922 brokenDown.tm_sec = t.second();
1923 brokenDown.tm_min = t.minute();
1924 brokenDown.tm_hour = t.hour();
1925 brokenDown.tm_mday = d.day();
1926 brokenDown.tm_mon = d.month() - 1;
1927 brokenDown.tm_year = d.year() - 1900;
1928 brokenDown.tm_isdst = -1;
1929 int secsSince1Jan1970UTC = (int) mktime( &brokenDown );
1930 if ( secsSince1Jan1970UTC < -1 )
1931 secsSince1Jan1970UTC = -1;
1932 return (uint) secsSince1Jan1970UTC;
1933}
1934
1935/*!
1936 \overload
1937
1938 Convenience function that sets the date and time to local time
1939 based on the given UTC time.
1940*/
1941
1942void QDateTime::setTime_t( uint secsSince1Jan1970UTC )
1943{
1944 setTime_t( secsSince1Jan1970UTC, Qt::LocalTime );
1945}
1946
1947/*!
1948 Sets the date and time to \a ts time (\c Qt::LocalTime or \c
1949 Qt::UTC) given the number of seconds that have passed since
1950 1970-01-01T00:00:00, Coordinated Universal Time (UTC). On systems
1951 that do not support timezones this function will behave as if
1952 local time were UTC.
1953
1954 On Windows, only a subset of \a secsSince1Jan1970UTC values are
1955 supported, as Windows starts counting from 1980.
1956
1957 \sa toTime_t()
1958*/
1959void QDateTime::setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec ts )
1960{
1961 time_t tmp = (time_t) secsSince1Jan1970UTC;
1962 tm *brokenDown = 0;
1963 if ( ts == Qt::LocalTime )
1964 brokenDown = localtime( &tmp );
1965 if ( !brokenDown ) {
1966 brokenDown = gmtime( &tmp );
1967 if ( !brokenDown ) {
1968 d.jd = QDate::gregorianToJulian( 1970, 1, 1 );
1969 t.ds = 0;
1970 return;
1971 }
1972 }
1973 d.jd = QDate::gregorianToJulian( brokenDown->tm_year + 1900,
1974 brokenDown->tm_mon + 1,
1975 brokenDown->tm_mday );
1976 t.ds = MSECS_PER_HOUR * brokenDown->tm_hour +
1977 MSECS_PER_MIN * brokenDown->tm_min +
1978 1000 * brokenDown->tm_sec;
1979}
1980#ifndef QT_NO_DATESTRING
1981#ifndef QT_NO_SPRINTF
1982/*!
1983 \overload
1984
1985 Returns the datetime as a string. The \a f parameter determines
1986 the format of the string.
1987
1988 If \a f is \c Qt::TextDate, the string format is "Wed May 20
1989 03:40:13 1998" (using QDate::shortDayName(), QDate::shortMonthName(),
1990 and QTime::toString() to generate the string, so the day and month
1991 names will have localized names).
1992
1993 If \a f is \c Qt::ISODate, the string format corresponds to the
1994 ISO 8601 extended specification for representations of dates and
1995 times, which is YYYY-MM-DDTHH:MM:SS.
1996
1997 If \a f is \c Qt::LocalDate, the string format depends on the
1998 locale settings of the system.
1999
2000 If the format \a f is invalid, toString() returns a null string.
2001
2002 \sa QDate::toString() QTime::toString()
2003*/
2004
2005QString QDateTime::toString( Qt::DateFormat f ) const
2006{
2007 if ( f == Qt::ISODate ) {
2008 return d.toString( Qt::ISODate ) + "T" + t.toString( Qt::ISODate );
2009 }
2010#ifndef QT_NO_TEXTDATE
2011 else if ( f == Qt::TextDate ) {
2012#ifndef Q_WS_WIN
2013 QString buf = d.shortDayName( d.dayOfWeek() );
2014 buf += ' ';
2015 buf += d.shortMonthName( d.month() );
2016 buf += ' ';
2017 buf += QString().setNum( d.day() );
2018 buf += ' ';
2019#else
2020 QString buf;
2021 QString winstr;
2022 QT_WA( {
2023 TCHAR out[255];
2024 GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255 );
2025 winstr = QString::fromUcs2( (ushort*)out );
2026 } , {
2027 char out[255];
2028 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_ILDATE, (char*)&out, 255 );
2029 winstr = QString::fromLocal8Bit( out );
2030 } );
2031 switch ( winstr.toInt() ) {
2032 case 1:
2033 buf = d.shortDayName( d.dayOfWeek() ) + " " + QString().setNum( d.day() ) + ". " + d.shortMonthName( d.month() ) + " ";
2034 break;
2035 default:
2036 buf = d.shortDayName( d.dayOfWeek() ) + " " + d.shortMonthName( d.month() ) + " " + QString().setNum( d.day() ) + " ";
2037 break;
2038 }
2039#endif
2040 buf += t.toString();
2041 buf += ' ';
2042 buf += QString().setNum( d.year() );
2043 return buf;
2044 }
2045#endif
2046 else if ( f == Qt::LocalDate ) {
2047 return d.toString( Qt::LocalDate ) + " " + t.toString( Qt::LocalDate );
2048 }
2049 return QString::null;
2050}
2051#endif
2052
2053/*!
2054 Returns the datetime as a string. The \a format parameter
2055 determines the format of the result string.
2056
2057 These expressions may be used for the date:
2058
2059 \table
2060 \header \i Expression \i Output
2061 \row \i d \i the day as number without a leading zero (1-31)
2062 \row \i dd \i the day as number with a leading zero (01-31)
2063 \row \i ddd
2064 \i the abbreviated localized day name (e.g. 'Mon'..'Sun').
2065 Uses QDate::shortDayName().
2066 \row \i dddd
2067 \i the long localized day name (e.g. 'Monday'..'Sunday').
2068 Uses QDate::longDayName().
2069 \row \i M \i the month as number without a leading zero (1-12)
2070 \row \i MM \i the month as number with a leading zero (01-12)
2071 \row \i MMM
2072 \i the abbreviated localized month name (e.g. 'Jan'..'Dec').
2073 Uses QDate::shortMonthName().
2074 \row \i MMMM
2075 \i the long localized month name (e.g. 'January'..'December').
2076 Uses QDate::longMonthName().
2077 \row \i yy \i the year as two digit number (00-99)
2078 \row \i yyyy \i the year as four digit number (1752-8000)
2079 \endtable
2080
2081 These expressions may be used for the time:
2082
2083 \table
2084 \header \i Expression \i Output
2085 \row \i h
2086 \i the hour without a leading zero (0..23 or 1..12 if AM/PM display)
2087 \row \i hh
2088 \i the hour with a leading zero (00..23 or 01..12 if AM/PM display)
2089 \row \i m \i the minute without a leading zero (0..59)
2090 \row \i mm \i the minute with a leading zero (00..59)
2091 \row \i s \i the second whithout a leading zero (0..59)
2092 \row \i ss \i the second whith a leading zero (00..59)
2093 \row \i z \i the milliseconds without leading zeroes (0..999)
2094 \row \i zzz \i the milliseconds with leading zeroes (000..999)
2095 \row \i AP
2096 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
2097 \row \i ap
2098 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
2099 \endtable
2100
2101 All other input characters will be ignored.
2102
2103 Example format strings (assumed that the QDateTime is
2104 21<small><sup>st</sup></small> May 2001 14:13:09)
2105
2106 \table
2107 \header \i Format \i Result
2108 \row \i dd.MM.yyyy \i11 21.05.2001
2109 \row \i ddd MMMM d yy \i11 Tue May 21 01
2110 \row \i hh:mm:ss.zzz \i11 14:13:09.042
2111 \row \i h:m:s ap \i11 2:13:9 pm
2112 \endtable
2113
2114 \sa QDate::toString() QTime::toString()
2115*/
2116QString QDateTime::toString( const QString& format ) const
2117{
2118 return fmtDateTime( format, &t, &d );
2119}
2120#endif //QT_NO_DATESTRING
2121
2122/*!
2123 Returns a QDateTime object containing a datetime \a ndays days
2124 later than the datetime of this object (or earlier if \a ndays is
2125 negative).
2126
2127 \sa daysTo(), addMonths(), addYears(), addSecs()
2128*/
2129
2130QDateTime QDateTime::addDays( int ndays ) const
2131{
2132 return QDateTime( d.addDays(ndays), t );
2133}
2134
2135/*!
2136 Returns a QDateTime object containing a datetime \a nmonths months
2137 later than the datetime of this object (or earlier if \a nmonths
2138 is negative).
2139
2140 \sa daysTo(), addDays(), addYears(), addSecs()
2141*/
2142
2143QDateTime QDateTime::addMonths( int nmonths ) const
2144{
2145 return QDateTime( d.addMonths(nmonths), t );
2146}
2147
2148/*!
2149 Returns a QDateTime object containing a datetime \a nyears years
2150 later than the datetime of this object (or earlier if \a nyears is
2151 negative).
2152
2153 \sa daysTo(), addDays(), addMonths(), addSecs()
2154*/
2155
2156QDateTime QDateTime::addYears( int nyears ) const
2157{
2158 return QDateTime( d.addYears(nyears), t );
2159}
2160
2161/*!
2162 Returns a QDateTime object containing a datetime \a nsecs seconds
2163 later than the datetime of this object (or earlier if \a nsecs is
2164 negative).
2165
2166 \sa secsTo(), addDays(), addMonths(), addYears()
2167*/
2168
2169QDateTime QDateTime::addSecs( int nsecs ) const
2170{
2171 uint dd = d.jd;
2172 int tt = t.ds;
2173 int sign = 1;
2174 if ( nsecs < 0 ) {
2175 nsecs = -nsecs;
2176 sign = -1;
2177 }
2178 if ( nsecs >= (int)SECS_PER_DAY ) {
2179 dd += sign*(nsecs/SECS_PER_DAY);
2180 nsecs %= SECS_PER_DAY;
2181 }
2182 tt += sign*nsecs*1000;
2183 if ( tt < 0 ) {
2184 tt = MSECS_PER_DAY - tt - 1;
2185 dd -= tt / MSECS_PER_DAY;
2186 tt = tt % MSECS_PER_DAY;
2187 tt = MSECS_PER_DAY - tt - 1;
2188 } else if ( tt >= (int)MSECS_PER_DAY ) {
2189 dd += ( tt / MSECS_PER_DAY );
2190 tt = tt % MSECS_PER_DAY;
2191 }
2192 QDateTime ret;
2193 ret.t.ds = tt;
2194 ret.d.jd = dd;
2195 return ret;
2196}
2197
2198/*!
2199 Returns the number of days from this datetime to \a dt (which is
2200 negative if \a dt is earlier than this datetime).
2201
2202 \sa addDays(), secsTo()
2203*/
2204
2205int QDateTime::daysTo( const QDateTime &dt ) const
2206{
2207 return d.daysTo( dt.d );
2208}
2209
2210/*!
2211 Returns the number of seconds from this datetime to \a dt (which
2212 is negative if \a dt is earlier than this datetime).
2213
2214 Example:
2215 \code
2216 QDateTime dt = QDateTime::currentDateTime();
2217 QDateTime xmas( QDate(dt.year(),12,24), QTime(17,00) );
2218 qDebug( "There are %d seconds to Christmas", dt.secsTo(xmas) );
2219 \endcode
2220
2221 \sa addSecs(), daysTo(), QTime::secsTo()
2222*/
2223
2224int QDateTime::secsTo( const QDateTime &dt ) const
2225{
2226 return t.secsTo(dt.t) + d.daysTo(dt.d)*SECS_PER_DAY;
2227}
2228
2229
2230/*!
2231 Returns TRUE if this datetime is equal to \a dt; otherwise returns FALSE.
2232
2233 \sa operator!=()
2234*/
2235
2236bool QDateTime::operator==( const QDateTime &dt ) const
2237{
2238 return t == dt.t && d == dt.d;
2239}
2240
2241/*!
2242 Returns TRUE if this datetime is different from \a dt; otherwise
2243 returns FALSE.
2244
2245 \sa operator==()
2246*/
2247
2248bool QDateTime::operator!=( const QDateTime &dt ) const
2249{
2250 return t != dt.t || d != dt.d;
2251}
2252
2253/*!
2254 Returns TRUE if this datetime is earlier than \a dt; otherwise
2255 returns FALSE.
2256*/
2257
2258bool QDateTime::operator<( const QDateTime &dt ) const
2259{
2260 if ( d < dt.d )
2261 return TRUE;
2262 return d == dt.d ? t < dt.t : FALSE;
2263}
2264
2265/*!
2266 Returns TRUE if this datetime is earlier than or equal to \a dt;
2267 otherwise returns FALSE.
2268*/
2269
2270bool QDateTime::operator<=( const QDateTime &dt ) const
2271{
2272 if ( d < dt.d )
2273 return TRUE;
2274 return d == dt.d ? t <= dt.t : FALSE;
2275}
2276
2277/*!
2278 Returns TRUE if this datetime is later than \a dt; otherwise
2279 returns FALSE.
2280*/
2281
2282bool QDateTime::operator>( const QDateTime &dt ) const
2283{
2284 if ( d > dt.d )
2285 return TRUE;
2286 return d == dt.d ? t > dt.t : FALSE;
2287}
2288
2289/*!
2290 Returns TRUE if this datetime is later than or equal to \a dt;
2291 otherwise returns FALSE.
2292*/
2293
2294bool QDateTime::operator>=( const QDateTime &dt ) const
2295{
2296 if ( d > dt.d )
2297 return TRUE;
2298 return d == dt.d ? t >= dt.t : FALSE;
2299}
2300
2301/*!
2302 \overload
2303
2304 Returns the current datetime, as reported by the system clock.
2305
2306 \sa QDate::currentDate(), QTime::currentTime()
2307*/
2308
2309QDateTime QDateTime::currentDateTime()
2310{
2311 return currentDateTime( Qt::LocalTime );
2312}
2313
2314/*!
2315 Returns the current datetime, as reported by the system clock, for the
2316 TimeSpec \a ts. The default TimeSpec is LocalTime.
2317
2318 \sa QDate::currentDate(), QTime::currentTime(), Qt::TimeSpec
2319*/
2320
2321QDateTime QDateTime::currentDateTime( Qt::TimeSpec ts )
2322{
2323 QDateTime dt;
2324 QTime t;
2325 dt.setDate( QDate::currentDate(ts) );
2326 if ( QTime::currentTime(&t, ts) ) // midnight or right after?
2327 dt.setDate( QDate::currentDate(ts) ); // fetch date again
2328 dt.setTime( t );
2329 return dt;
2330}
2331
2332#ifndef QT_NO_DATESTRING
2333/*!
2334 Returns the QDateTime represented by the string \a s, using the
2335 format \a f, or an invalid datetime if this is not possible.
2336
2337 Note for \c Qt::TextDate: It is recommended that you use the
2338 English short month names (e.g. "Jan"). Although localized month
2339 names can also be used, they depend on the user's locale settings.
2340
2341 \warning Note that \c Qt::LocalDate cannot be used here.
2342*/
2343QDateTime QDateTime::fromString( const QString& s, Qt::DateFormat f )
2344{
2345 if ( ( s.isEmpty() ) || ( f == Qt::LocalDate ) ) {
2346#if defined(QT_CHECK_RANGE)
2347 qWarning( "QDateTime::fromString: Parameter out of range" );
2348#endif
2349 return QDateTime();
2350 }
2351 if ( f == Qt::ISODate ) {
2352 return QDateTime( QDate::fromString( s.mid(0,10), Qt::ISODate ),
2353 QTime::fromString( s.mid(11), Qt::ISODate ) );
2354 }
2355#if !defined(QT_NO_REGEXP) && !defined(QT_NO_TEXTDATE)
2356 else if ( f == Qt::TextDate ) {
2357 QString monthName( s.mid( 4, 3 ) );
2358 int month = -1;
2359 // Assume that English monthnames are the default
2360 for ( int i = 0; i < 12; ++i ) {
2361 if ( monthName == qt_shortMonthNames[i] ) {
2362 month = i + 1;
2363 break;
2364 }
2365 }
2366 // If English names can't be found, search the localized ones
2367 if ( month == -1 ) {
2368 for ( int i = 1; i <= 12; ++i ) {
2369 if ( monthName == QDate::shortMonthName( i ) ) {
2370 month = i;
2371 break;
2372 }
2373 }
2374 }
2375#if defined(QT_CHECK_RANGE)
2376 if ( month < 1 || month > 12 ) {
2377 qWarning( "QDateTime::fromString: Parameter out of range." );
2378 month = 1;
2379 }
2380#endif
2381 int day = s.mid( 8, 2 ).simplifyWhiteSpace().toInt();
2382 int year = s.right( 4 ).toInt();
2383 QDate date( year, month, day );
2384 QTime time;
2385 int hour, minute, second;
2386 int pivot = s.find( QRegExp("[0-9][0-9]:[0-9][0-9]:[0-9][0-9]") );
2387 if ( pivot != -1 ) {
2388 hour = s.mid( pivot, 2 ).toInt();
2389 minute = s.mid( pivot+3, 2 ).toInt();
2390 second = s.mid( pivot+6, 2 ).toInt();
2391 time.setHMS( hour, minute, second );
2392 }
2393 return QDateTime( date, time );
2394 }
2395#endif //QT_NO_REGEXP
2396 return QDateTime();
2397}
2398#endif //QT_NO_DATESTRING
2399
2400
2401/*****************************************************************************
2402 Date/time stream functions
2403 *****************************************************************************/
2404
2405#ifndef QT_NO_DATASTREAM
2406/*!
2407 \relates QDate
2408
2409 Writes the date, \a d, to the data stream, \a s.
2410
2411 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2412*/
2413
2414QDataStream &operator<<( QDataStream &s, const QDate &d )
2415{
2416 return s << (Q_UINT32)(d.jd);
2417}
2418
2419/*!
2420 \relates QDate
2421
2422 Reads a date from the stream \a s into \a d.
2423
2424 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2425*/
2426
2427QDataStream &operator>>( QDataStream &s, QDate &d )
2428{
2429 Q_UINT32 jd;
2430 s >> jd;
2431 d.jd = jd;
2432 return s;
2433}
2434
2435/*!
2436 \relates QTime
2437
2438 Writes time \a t to the stream \a s.
2439
2440 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2441*/
2442
2443QDataStream &operator<<( QDataStream &s, const QTime &t )
2444{
2445 return s << (Q_UINT32)(t.ds);
2446}
2447
2448/*!
2449 \relates QTime
2450
2451 Reads a time from the stream \a s into \a t.
2452
2453 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2454*/
2455
2456QDataStream &operator>>( QDataStream &s, QTime &t )
2457{
2458 Q_UINT32 ds;
2459 s >> ds;
2460 t.ds = ds;
2461 return s;
2462}
2463
2464/*!
2465 \relates QDateTime
2466
2467 Writes the datetime \a dt to the stream \a s.
2468
2469 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2470*/
2471
2472QDataStream &operator<<( QDataStream &s, const QDateTime &dt )
2473{
2474 return s << dt.d << dt.t;
2475}
2476
2477/*!
2478 \relates QDateTime
2479
2480 Reads a datetime from the stream \a s into \a dt.
2481
2482 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
2483*/
2484
2485QDataStream &operator>>( QDataStream &s, QDateTime &dt )
2486{
2487 s >> dt.d >> dt.t;
2488 return s;
2489}
2490#endif //QT_NO_DATASTREAM
diff --git a/qmake/tools/qdeepcopy.cpp b/qmake/tools/qdeepcopy.cpp
new file mode 100644
index 0000000..5008e36
--- a/dev/null
+++ b/qmake/tools/qdeepcopy.cpp
@@ -0,0 +1,165 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QDeepCopy class
5**
6** Created : 20020613
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qdeepcopy.h"
39
40/*!
41 \class QDeepCopy qdeepcopy.h
42 \brief The QDeepCopy class is a template class which ensures that
43 implicitly shared and explicitly shared classes reference unique
44 data.
45
46 \reentrant
47
48 \ingroup tools
49 \ingroup shared
50
51 Normally, shared copies reference the same data to optimize memory
52 use and for maximum speed. In the example below, \c s1, \c s2, \c
53 s3, \c s4 and \c s5 share data.
54
55 \code
56 // all 5 strings share the same data
57 QString s1 = "abcd";
58 QString s2 = s1;
59 QString s3 = s2;
60 QString s4 = s3;
61 QString s5 = s2;
62 \endcode
63
64 QDeepCopy can be used several ways to ensure that an object
65 references unique, unshared data. In the example below, \c s1, \c
66 s2 and \c s5 share data, while neither \c s3 nor \c s4 share data.
67 \code
68 // s1, s2 and s5 share the same data, neither s3 nor s4 are shared
69 QString s1 = "abcd";
70 QString s2 = s1;
71 QDeepCopy<QString> s3 = s2; // s3 is a deep copy of s2
72 QString s4 = s3; // s4 is a deep copy of s3
73 QString s5 = s2;
74 \endcode
75
76 In the example below, \c s1, \c s2 and \c s5 share data, and \c s3
77 and \c s4 share data.
78 \code
79 // s1, s2 and s5 share the same data, s3 and s4 share the same data
80 QString s1 = "abcd";
81 QString s2 = s1;
82 QString s3 = QDeepCopy<QString>( s2 ); // s3 is a deep copy of s2
83 QString s4 = s3; // s4 is a shallow copy of s3
84 QString s5 = s2;
85 \endcode
86
87 QDeepCopy can also provide safety in multithreaded applications
88 that use shared classes. In the example below, the variable \c
89 global_string is used safely since the data contained in \c
90 global_string is always a deep copy. This ensures that all threads
91 get a unique copy of the data, and that any assignments to \c
92 global_string will result in a deep copy.
93
94 \code
95 QDeepCopy<QString> global_string; // global string data
96 QMutex global_mutex; // mutex to protext global_string
97
98 ...
99
100 void setGlobalString( const QString &str )
101 {
102 global_mutex.lock();
103 global_string = str; // global_string is a deep copy of str
104 global_mutex.unlock();
105 }
106
107 ...
108
109 void MyThread::run()
110 {
111 global_mutex.lock();
112 QString str = global_string; // str is a deep copy of global_string
113 global_mutex.unlock();
114
115 // process the string data
116 ...
117
118 // update global_string
119 setGlobalString( str );
120 }
121 \endcode
122
123 \warning It is the application developer's responsibility to
124 protect the object shared across multiple threads.
125
126 The examples above use QString, which is an implicitly shared
127 class. The behavior of QDeepCopy is the same when using explicitly
128 shared classes like QByteArray.
129
130 Currently, QDeepCopy works with the following classes:
131 \list
132 \i QMemArray (including subclasses like QByteArray and QCString)
133 \i QMap
134 \i QString
135 \i QValueList (including subclasses like QStringList and QValueStack)
136 \i QValueVector
137 \endlist
138
139 \sa \link threads.html Thread Support in Qt \endlink
140*/
141
142/*!
143 \fn QDeepCopy::QDeepCopy()
144
145 Constructs an empty instance of type \e T.
146*/
147
148/*!
149 \fn QDeepCopy::QDeepCopy( const T &t )
150
151 Constructs a deep copy of \a t.
152*/
153
154/*!
155 \fn QDeepCopy<T>& QDeepCopy::operator=( const T &t )
156
157 Assigns a deep copy of \a t.
158*/
159
160/*!
161 \fn QDeepCopy::operator T ()
162
163 Returns a deep copy of the encapsulated data.
164*/
165
diff --git a/qmake/tools/qdir.cpp b/qmake/tools/qdir.cpp
new file mode 100644
index 0000000..418ea49
--- a/dev/null
+++ b/qmake/tools/qdir.cpp
@@ -0,0 +1,1294 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QDir class
5**
6** Created : 950427
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include "qdir.h"
40
41#ifndef QT_NO_DIR
42#include <private/qdir_p.h>
43#include "qfileinfo.h"
44#include "qregexp.h"
45#include "qstringlist.h"
46#include <stdlib.h>
47#include <ctype.h>
48
49
50
51/*!
52 \class QDir
53 \brief The QDir class provides access to directory structures and their contents in a platform-independent way.
54
55 \ingroup io
56 \mainclass
57
58 A QDir is used to manipulate path names, access information
59 regarding paths and files, and manipulate the underlying file
60 system.
61
62 A QDir can point to a file using either a relative or an absolute
63 path. Absolute paths begin with the directory separator "/"
64 (optionally preceded by a drive specification under Windows). If
65 you always use "/" as a directory separator, Qt will translate
66 your paths to conform to the underlying operating system. Relative
67 file names begin with a directory name or a file name and specify
68 a path relative to the current directory.
69
70 The "current" path refers to the application's working directory.
71 A QDir's own path is set and retrieved with setPath() and path().
72
73 An example of an absolute path is the string "/tmp/quartz", a
74 relative path might look like "src/fatlib". You can use the
75 function isRelative() to check if a QDir is using a relative or an
76 absolute file path. Call convertToAbs() to convert a relative QDir
77 to an absolute one. For a simplified path use cleanDirPath(). To
78 obtain a path which has no symbolic links or redundant ".."
79 elements use canonicalPath(). The path can be set with setPath(),
80 and changed with cd() and cdUp().
81
82 QDir provides several static functions, for example, setCurrent()
83 to set the application's working directory and currentDirPath() to
84 retrieve the application's working directory. Access to some
85 common paths is provided with the static functions, current(),
86 home() and root() which return QDir objects or currentDirPath(),
87 homeDirPath() and rootDirPath() which return the path as a string.
88
89 The number of entries in a directory is returned by count().
90 Obtain a string list of the names of all the files and directories
91 in a directory with entryList(). If you prefer a list of QFileInfo
92 pointers use entryInfoList(). Both these functions can apply a
93 name filter, an attributes filter (e.g. read-only, files not
94 directories, etc.), and a sort order. The filters and sort may be
95 set with calls to setNameFilter(), setFilter() and setSorting().
96 They may also be specified in the entryList() and
97 entryInfoList()'s arguments.
98
99 Create a new directory with mkdir(), rename a directory with
100 rename() and remove an existing directory with rmdir(). Remove a
101 file with remove(). You can interrogate a directory with exists(),
102 isReadable() and isRoot().
103
104 To get a path with a filename use filePath(), and to get a
105 directory name use dirName(); neither of these functions checks
106 for the existence of the file or directory.
107
108 The list of root directories is provided by drives(); on Unix
109 systems this returns a list containing one root directory, "/"; on
110 Windows the list will usually contain "C:/", and possibly "D:/",
111 etc.
112
113 If you need the path in a form suitable for the underlying
114 operating system use convertSeparators().
115
116 Examples:
117
118 See if a directory exists.
119 \code
120 QDir d( "example" ); // "./example"
121 if ( !d.exists() )
122 qWarning( "Cannot find the example directory" );
123 \endcode
124
125 Traversing directories and reading a file.
126 \code
127 QDir d = QDir::root(); // "/"
128 if ( !d.cd("tmp") ) { // "/tmp"
129 qWarning( "Cannot find the \"/tmp\" directory" );
130 } else {
131 QFile f( d.filePath("ex1.txt") );// "/tmp/ex1.txt"
132 if ( !f.open(IO_ReadWrite) )
133 qWarning( "Cannot create the file %s", f.name() );
134 }
135 \endcode
136
137 A program that lists all the files in the current directory
138 (excluding symbolic links), sorted by size, smallest first:
139 \code
140 #include <stdio.h>
141 #include <qdir.h>
142
143 int main( int argc, char **argv )
144 {
145 QDir d;
146 d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
147 d.setSorting( QDir::Size | QDir::Reversed );
148
149 const QFileInfoList *list = d.entryInfoList();
150 QFileInfoListIterator it( *list );
151 QFileInfo *fi;
152
153 printf( " Bytes Filename\n" );
154 while ( (fi = it.current()) != 0 ) {
155 printf( "%10li %s\n", fi->size(), fi->fileName().latin1() );
156 ++it;
157 }
158 return 0;
159 }
160 \endcode
161*/
162
163/*!
164 Constructs a QDir pointing to the current directory.
165
166 \sa currentDirPath()
167*/
168
169QDir::QDir()
170{
171 dPath = QString::fromLatin1(".");
172 init();
173}
174
175/*!
176 Constructs a QDir with path \a path, that filters its entries by
177 name using \a nameFilter and by attributes using \a filterSpec. It
178 also sorts the names using \a sortSpec.
179
180 The default \a nameFilter is an empty string, which excludes
181 nothing; the default \a filterSpec is \c All, which also means
182 exclude nothing. The default \a sortSpec is \c Name|IgnoreCase,
183 i.e. sort by name case-insensitively.
184
185 Example that lists all the files in "/tmp":
186 \code
187 QDir d( "/tmp" );
188 for ( int i = 0; i < d.count(); i++ )
189 printf( "%s\n", d[i] );
190 \endcode
191
192 If \a path is "" or QString::null, QDir uses "." (the current
193 directory). If \a nameFilter is "" or QString::null, QDir uses the
194 name filter "*" (all files).
195
196 Note that \a path need not exist.
197
198 \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
199*/
200
201QDir::QDir( const QString &path, const QString &nameFilter,
202 int sortSpec, int filterSpec )
203{
204 init();
205 dPath = cleanDirPath( path );
206 if ( dPath.isEmpty() )
207 dPath = QString::fromLatin1(".");
208 nameFilt = nameFilter;
209 if ( nameFilt.isEmpty() )
210 nameFilt = QString::fromLatin1("*");
211 filtS = (FilterSpec)filterSpec;
212 sortS = (SortSpec)sortSpec;
213}
214
215/*!
216 Constructs a QDir that is a copy of the directory \a d.
217
218 \sa operator=()
219*/
220
221QDir::QDir( const QDir &d )
222{
223 dPath = d.dPath;
224 fList = 0;
225 fiList = 0;
226 nameFilt = d.nameFilt;
227 dirty = TRUE;
228 allDirs = d.allDirs;
229 filtS = d.filtS;
230 sortS = d.sortS;
231}
232
233
234void QDir::init()
235{
236 fList = 0;
237 fiList = 0;
238 nameFilt = QString::fromLatin1("*");
239 dirty = TRUE;
240 allDirs = FALSE;
241 filtS = All;
242 sortS = SortSpec(Name | IgnoreCase);
243}
244
245/*!
246 Destroys the QDir frees up its resources.
247*/
248
249QDir::~QDir()
250{
251 delete fList;
252 delete fiList;
253}
254
255
256/*!
257 Sets the path of the directory to \a path. The path is cleaned of
258 redundant ".", ".." and of multiple separators. No check is made
259 to ensure that a directory with this path exists.
260
261 The path can be either absolute or relative. Absolute paths begin
262 with the directory separator "/" (optionally preceded by a drive
263 specification under Windows). Relative file names begin with a
264 directory name or a file name and specify a path relative to the
265 current directory. An example of an absolute path is the string
266 "/tmp/quartz", a relative path might look like "src/fatlib".
267
268 \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
269 absFilePath(), isRelative(), convertToAbs()
270*/
271
272void QDir::setPath( const QString &path )
273{
274 dPath = cleanDirPath( path );
275 if ( dPath.isEmpty() )
276 dPath = QString::fromLatin1(".");
277 dirty = TRUE;
278}
279
280/*!
281 \fn QString QDir::path() const
282
283 Returns the path, this may contain symbolic links, but never
284 contains redundant ".", ".." or multiple separators.
285
286 The returned path can be either absolute or relative (see
287 setPath()).
288
289 \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
290 absFilePath(), convertSeparators()
291*/
292
293/*!
294 Returns the absolute path (a path that starts with "/" or with a
295 drive specification), which may contain symbolic links, but never
296 contains redundant ".", ".." or multiple separators.
297
298 \sa setPath(), canonicalPath(), exists(), cleanDirPath(),
299 dirName(), absFilePath()
300*/
301
302QString QDir::absPath() const
303{
304 if ( QDir::isRelativePath(dPath) ) {
305 QString tmp = currentDirPath();
306 if ( tmp.right(1) != QString::fromLatin1("/") )
307 tmp += '/';
308 tmp += dPath;
309 return cleanDirPath( tmp );
310 } else {
311 return cleanDirPath( dPath );
312 }
313}
314
315/*!
316 Returns the name of the directory; this is \e not the same as the
317 path, e.g. a directory with the name "mail", might have the path
318 "/var/spool/mail". If the directory has no name (e.g. it is the
319 root directory) QString::null is returned.
320
321 No check is made to ensure that a directory with this name
322 actually exists.
323
324 \sa path(), absPath(), absFilePath(), exists(), QString::isNull()
325*/
326
327QString QDir::dirName() const
328{
329 int pos = dPath.findRev( '/' );
330 if ( pos == -1 )
331 return dPath;
332 return dPath.right( dPath.length() - pos - 1 );
333}
334
335/*!
336 Returns the path name of a file in the directory. Does \e not
337 check if the file actually exists in the directory. If the QDir is
338 relative the returned path name will also be relative. Redundant
339 multiple separators or "." and ".." directories in \a fileName
340 will not be removed (see cleanDirPath()).
341
342 If \a acceptAbsPath is TRUE a \a fileName starting with a
343 separator "/" will be returned without change. If \a acceptAbsPath
344 is FALSE an absolute path will be prepended to the fileName and
345 the resultant string returned.
346
347 \sa absFilePath(), isRelative(), canonicalPath()
348*/
349
350QString QDir::filePath( const QString &fileName,
351 bool acceptAbsPath ) const
352{
353 if ( acceptAbsPath && !isRelativePath(fileName) )
354 return QString(fileName);
355
356 QString tmp = dPath;
357 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
358 fileName[0] != '/') )
359 tmp += '/';
360 tmp += fileName;
361 return tmp;
362}
363
364/*!
365 Returns the absolute path name of a file in the directory. Does \e
366 not check if the file actually exists in the directory. Redundant
367 multiple separators or "." and ".." directories in \a fileName
368 will not be removed (see cleanDirPath()).
369
370 If \a acceptAbsPath is TRUE a \a fileName starting with a
371 separator "/" will be returned without change. If \a acceptAbsPath
372 is FALSE an absolute path will be prepended to the fileName and
373 the resultant string returned.
374
375 \sa filePath()
376*/
377
378QString QDir::absFilePath( const QString &fileName,
379 bool acceptAbsPath ) const
380{
381 if ( acceptAbsPath && !isRelativePath( fileName ) )
382 return fileName;
383
384 QString tmp = absPath();
385 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
386 fileName[0] != '/') )
387 tmp += '/';
388 tmp += fileName;
389 return tmp;
390}
391
392
393/*!
394 Returns \a pathName with the '/' separators converted to
395 separators that are appropriate for the underlying operating
396 system.
397
398 On Windows, convertSeparators("c:/winnt/system32") returns
399 "c:\winnt\system32".
400
401 The returned string may be the same as the argument on some
402 operating systems, for example on Unix.
403*/
404
405QString QDir::convertSeparators( const QString &pathName )
406{
407 QString n( pathName );
408#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
409 for ( int i=0; i<(int)n.length(); i++ ) {
410 if ( n[i] == '/' )
411 n[i] = '\\';
412 }
413#elif defined(Q_OS_MAC9)
414 while(n.length() && n[0] == '/' ) n = n.right(n.length()-1);
415 for ( int i=0; i<(int)n.length(); i++ ) {
416 if ( n[i] == '/' )
417 n[i] = ':';
418 }
419 if(n.contains(':') && n.left(1) != ':')
420 n.prepend(':');
421#endif
422 return n;
423}
424
425
426/*!
427 Changes the QDir's directory to \a dirName.
428
429 If \a acceptAbsPath is TRUE a path starting with separator "/"
430 will cause the function to change to the absolute directory. If \a
431 acceptAbsPath is FALSE any number of separators at the beginning
432 of \a dirName will be removed and the function will descend into
433 \a dirName.
434
435 Returns TRUE if the new directory exists and is readable;
436 otherwise returns FALSE. Note that the logical cd() operation is
437 not performed if the new directory does not exist.
438
439 Calling cd( ".." ) is equivalent to calling cdUp().
440
441 \sa cdUp(), isReadable(), exists(), path()
442*/
443
444bool QDir::cd( const QString &dirName, bool acceptAbsPath )
445{
446 if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
447 return TRUE;
448 QString old = dPath;
449 if ( acceptAbsPath && !isRelativePath(dirName) ) {
450 dPath = cleanDirPath( dirName );
451 } else {
452 if ( !isRoot() ) {
453 dPath += '/';
454 } else if ( dirName == ".." ) {
455 dPath = old;
456 return FALSE;
457 }
458 dPath += dirName;
459 if ( dirName.find('/') >= 0
460 || old == QString::fromLatin1(".")
461 || dirName == QString::fromLatin1("..") )
462 dPath = cleanDirPath( dPath );
463 }
464 if ( !exists() ) {
465 dPath = old; // regret
466 return FALSE;
467 }
468 dirty = TRUE;
469 return TRUE;
470}
471
472/*!
473 Changes directory by moving one directory up from the QDir's
474 current directory.
475
476 Returns TRUE if the new directory exists and is readable;
477 otherwise returns FALSE. Note that the logical cdUp() operation is
478 not performed if the new directory does not exist.
479
480 \sa cd(), isReadable(), exists(), path()
481*/
482
483bool QDir::cdUp()
484{
485 return cd( QString::fromLatin1("..") );
486}
487
488/*!
489 \fn QString QDir::nameFilter() const
490
491 Returns the string set by setNameFilter()
492*/
493
494/*!
495 Sets the name filter used by entryList() and entryInfoList() to \a
496 nameFilter.
497
498 The \a nameFilter is a wildcard (globbing) filter that understands
499 "*" and "?" wildcards. (See \link qregexp.html#wildcard-matching
500 QRegExp wildcard matching\endlink.) You may specify several filter
501 entries all separated by a single space " " or by a semi-colon
502 ";".
503
504 For example, if you want entryList() and entryInfoList() to list
505 all files ending with either ".cpp" or ".h", you would use either
506 dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h").
507
508 \sa nameFilter(), setFilter()
509*/
510
511void QDir::setNameFilter( const QString &nameFilter )
512{
513 nameFilt = nameFilter;
514 if ( nameFilt.isEmpty() )
515 nameFilt = QString::fromLatin1("*");
516 dirty = TRUE;
517}
518
519/*!
520 \fn QDir::FilterSpec QDir::filter() const
521
522 Returns the value set by setFilter()
523*/
524
525/*!
526 \enum QDir::FilterSpec
527
528 This enum describes the filtering options available to QDir, e.g.
529 for entryList() and entryInfoList(). The filter value is specified
530 by OR-ing together values from the following list:
531
532 \value Dirs List directories only.
533 \value Files List files only.
534 \value Drives List disk drives (ignored under Unix).
535 \value NoSymLinks Do not list symbolic links (ignored by operating
536 systems that don't support symbolic links).
537 \value All List directories, files, drives and symlinks (this does not list
538 broken symlinks unless you specify System).
539 \value TypeMask A mask for the the Dirs, Files, Drives and
540 NoSymLinks flags.
541 \value Readable List files for which the application has read access.
542 \value Writable List files for which the application has write access.
543 \value Executable List files for which the application has execute
544 access. Executables needs to be combined with Dirs or Files.
545 \value RWEMask A mask for the Readable, Writable and Executable flags.
546 \value Modified Only list files that have been modified (ignored
547 under Unix).
548 \value Hidden List hidden files (on Unix, files starting with a .).
549 \value System List system files (on Unix, FIFOs, sockets and
550 device files)
551 \value AccessMask A mask for the Readable, Writable, Executable
552 Modified, Hidden and System flags
553 \value DefaultFilter Internal flag.
554
555 If you do not set any of \c Readable, \c Writable or \c
556 Executable, QDir will set all three of them. This makes the
557 default easy to write and at the same time useful.
558
559 Examples: \c Readable|Writable means list all files for which the
560 application has read access, write access or both. \c Dirs|Drives
561 means list drives, directories, all files that the application can
562 read, write or execute, and also symlinks to such
563 files/directories.
564*/
565
566
567/*!
568 Sets the filter used by entryList() and entryInfoList() to \a
569 filterSpec. The filter is used to specify the kind of files that
570 should be returned by entryList() and entryInfoList(). See
571 \l{QDir::FilterSpec}.
572
573 \sa filter(), setNameFilter()
574*/
575
576void QDir::setFilter( int filterSpec )
577{
578 if ( filtS == (FilterSpec) filterSpec )
579 return;
580 filtS = (FilterSpec) filterSpec;
581 dirty = TRUE;
582}
583
584/*!
585 \fn QDir::SortSpec QDir::sorting() const
586
587 Returns the value set by setSorting()
588
589 \sa setSorting() SortSpec
590*/
591
592/*!
593 \enum QDir::SortSpec
594
595 This enum describes the sort options available to QDir, e.g. for
596 entryList() and entryInfoList(). The sort value is specified by
597 OR-ing together values from the following list:
598
599 \value Name Sort by name.
600 \value Time Sort by time (modification time).
601 \value Size Sort by file size.
602 \value Unsorted Do not sort.
603 \value SortByMask A mask for Name, Time and Size.
604
605 \value DirsFirst Put the directories first, then the files.
606 \value Reversed Reverse the sort order.
607 \value IgnoreCase Sort case-insensitively.
608 \value DefaultSort Internal flag.
609
610 You can only specify one of the first four.
611
612 If you specify both \c DirsFirst and \c Reversed, directories are
613 still put first, but in reverse order; the files will be listed
614 after the directories, again in reverse order.
615*/
616
617// ### Unsorted+DirsFirst ? Unsorted+Reversed?
618
619/*!
620 Sets the sort order used by entryList() and entryInfoList().
621
622 The \a sortSpec is specified by OR-ing values from the enum
623 \l{QDir::SortSpec}.
624
625 \sa sorting() SortSpec
626*/
627
628void QDir::setSorting( int sortSpec )
629{
630 if ( sortS == (SortSpec) sortSpec )
631 return;
632 sortS = (SortSpec) sortSpec;
633 dirty = TRUE;
634}
635
636/*!
637 \fn bool QDir::matchAllDirs() const
638
639 Returns the value set by setMatchAllDirs()
640
641 \sa setMatchAllDirs()
642*/
643
644/*!
645 If \a enable is TRUE then all directories are included (e.g. in
646 entryList()), and the nameFilter() is only applied to the files.
647 If \a enable is FALSE then the nameFilter() is applied to both
648 directories and files.
649
650 \sa matchAllDirs()
651*/
652
653void QDir::setMatchAllDirs( bool enable )
654{
655 if ( (bool)allDirs == enable )
656 return;
657 allDirs = enable;
658 dirty = TRUE;
659}
660
661
662/*!
663 Returns the total number of directories and files that were found.
664
665 Equivalent to entryList().count().
666
667 \sa operator[](), entryList()
668*/
669
670uint QDir::count() const
671{
672 return (uint)entryList().count();
673}
674
675/*!
676 Returns the file name at position \a index in the list of file
677 names. Equivalent to entryList().at(index).
678
679 Returns a QString::null if the \a index is out of range or if the
680 entryList() function failed.
681
682 \sa count(), entryList()
683*/
684
685QString QDir::operator[]( int index ) const
686{
687 entryList();
688 return fList && index >= 0 && index < (int)fList->count() ?
689 (*fList)[index] : QString::null;
690}
691
692
693/*!
694 \obsolete
695 This function is included to easy porting from Qt 1.x to Qt 2.0,
696 it is the same as entryList(), but encodes the filenames as 8-bit
697 strings using QFile::encodedName().
698
699 It is more efficient to use entryList().
700*/
701QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
702{
703 QStrList r;
704 QStringList l = entryList(filterSpec,sortSpec);
705 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
706 r.append( QFile::encodeName(*it) );
707 }
708 return r;
709}
710
711/*!
712 \obsolete
713 \overload
714 This function is included to easy porting from Qt 1.x to Qt 2.0,
715 it is the same as entryList(), but encodes the filenames as 8-bit
716 strings using QFile::encodedName().
717
718 It is more efficient to use entryList().
719*/
720QStrList QDir::encodedEntryList( const QString &nameFilter,
721 int filterSpec,
722 int sortSpec ) const
723{
724 QStrList r;
725 QStringList l = entryList(nameFilter,filterSpec,sortSpec);
726 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
727 r.append( QFile::encodeName(*it) );
728 }
729 return r;
730}
731
732
733
734/*!
735 \overload
736
737 Returns a list of the names of all the files and directories in
738 the directory, ordered in accordance with setSorting() and
739 filtered in accordance with setFilter() and setNameFilter().
740
741 The filter and sorting specifications can be overridden using the
742 \a filterSpec and \a sortSpec arguments.
743
744 Returns an empty list if the directory is unreadable or does not
745 exist.
746
747 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter()
748*/
749
750QStringList QDir::entryList( int filterSpec, int sortSpec ) const
751{
752 if ( !dirty && filterSpec == (int)DefaultFilter &&
753 sortSpec == (int)DefaultSort )
754 return *fList;
755 return entryList( nameFilt, filterSpec, sortSpec );
756}
757
758/*!
759 Returns a list of the names of all the files and directories in
760 the directory, ordered in accordance with setSorting() and
761 filtered in accordance with setFilter() and setNameFilter().
762
763 The filter and sorting specifications can be overridden using the
764 \a nameFilter, \a filterSpec and \a sortSpec arguments.
765
766 Returns an empty list if the directory is unreadable or does not
767 exist.
768
769 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter()
770*/
771
772QStringList QDir::entryList( const QString &nameFilter,
773 int filterSpec, int sortSpec ) const
774{
775 if ( filterSpec == (int)DefaultFilter )
776 filterSpec = filtS;
777 if ( sortSpec == (int)DefaultSort )
778 sortSpec = sortS;
779 QDir *that = (QDir*)this; // mutable function
780 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) ) {
781 if ( that->fList )
782 return *that->fList;
783 }
784 return QStringList();
785}
786
787/*!
788 \overload
789
790 Returns a list of QFileInfo objects for all the files and
791 directories in the directory, ordered in accordance with
792 setSorting() and filtered in accordance with setFilter() and
793 setNameFilter().
794
795 The filter and sorting specifications can be overridden using the
796 \a filterSpec and \a sortSpec arguments.
797
798 Returns 0 if the directory is unreadable or does not exist.
799
800 The returned pointer is a const pointer to a QFileInfoList. The
801 list is owned by the QDir object and will be reused on the next
802 call to entryInfoList() for the same QDir instance. If you want to
803 keep the entries of the list after a subsequent call to this
804 function you must copy them.
805
806 \sa entryList(), setNameFilter(), setSorting(), setFilter()
807*/
808
809const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
810{
811 if ( !dirty && filterSpec == (int)DefaultFilter &&
812 sortSpec == (int)DefaultSort )
813 return fiList;
814 return entryInfoList( nameFilt, filterSpec, sortSpec );
815}
816
817/*!
818 Returns a list of QFileInfo objects for all the files and
819 directories in the directory, ordered in accordance with
820 setSorting() and filtered in accordance with setFilter() and
821 setNameFilter().
822
823 The filter and sorting specifications can be overridden using the
824 \a nameFilter, \a filterSpec and \a sortSpec arguments.
825
826 Returns 0 if the directory is unreadable or does not exist.
827
828 The returned pointer is a const pointer to a QFileInfoList. The
829 list is owned by the QDir object and will be reused on the next
830 call to entryInfoList() for the same QDir instance. If you want to
831 keep the entries of the list after a subsequent call to this
832 function you must copy them.
833
834 \sa entryList(), setNameFilter(), setSorting(), setFilter()
835*/
836
837const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
838 int filterSpec, int sortSpec ) const
839{
840 if ( filterSpec == (int)DefaultFilter )
841 filterSpec = filtS;
842 if ( sortSpec == (int)DefaultSort )
843 sortSpec = sortS;
844 QDir *that = (QDir*)this; // mutable function
845 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
846 return that->fiList;
847 else
848 return 0;
849}
850
851/*!
852 \overload
853
854 Returns TRUE if the \e directory exists; otherwise returns FALSE.
855 (If a file with the same name is found this function will return
856 FALSE).
857
858 \sa QFileInfo::exists(), QFile::exists()
859*/
860
861bool QDir::exists() const
862{
863 QFileInfo fi( dPath );
864 return fi.exists() && fi.isDir();
865}
866
867/*!
868 Returns TRUE if the directory path is relative to the current
869 directory and returns FALSE if the path is absolute (e.g. under
870 UNIX a path is relative if it does not start with a "/").
871
872 \sa convertToAbs()
873*/
874
875bool QDir::isRelative() const
876{
877 return isRelativePath( dPath );
878}
879
880/*!
881 Converts the directory path to an absolute path. If it is already
882 absolute nothing is done.
883
884 \sa isRelative()
885*/
886
887void QDir::convertToAbs()
888{
889 dPath = absPath();
890}
891
892/*!
893 Makes a copy of QDir \a d and assigns it to this QDir.
894*/
895
896QDir &QDir::operator=( const QDir &d )
897{
898 dPath = d.dPath;
899 delete fList;
900 fList = 0;
901 delete fiList;
902 fiList = 0;
903 nameFilt = d.nameFilt;
904 dirty = TRUE;
905 allDirs = d.allDirs;
906 filtS = d.filtS;
907 sortS = d.sortS;
908 return *this;
909}
910
911/*!
912 \overload
913
914 Sets the directory path to be the given \a path.
915*/
916
917QDir &QDir::operator=( const QString &path )
918{
919 dPath = cleanDirPath( path );
920 dirty = TRUE;
921 return *this;
922}
923
924
925/*!
926 \fn bool QDir::operator!=( const QDir &d ) const
927
928 Returns TRUE if directory \a d and this directory have different
929 paths or different sort or filter settings; otherwise returns
930 FALSE.
931
932 Example:
933 \code
934 // The current directory is "/usr/local"
935 QDir d1( "/usr/local/bin" );
936 QDir d2( "bin" );
937 if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed
938 \endcode
939*/
940
941/*!
942 Returns TRUE if directory \a d and this directory have the same
943 path and their sort and filter settings are the same; otherwise
944 returns FALSE.
945
946 Example:
947 \code
948 // The current directory is "/usr/local"
949 QDir d1( "/usr/local/bin" );
950 QDir d2( "bin" );
951 d2.convertToAbs();
952 if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed
953 \endcode
954*/
955
956bool QDir::operator==( const QDir &d ) const
957{
958 return dPath == d.dPath &&
959 nameFilt == d.nameFilt &&
960 allDirs == d.allDirs &&
961 filtS == d.filtS &&
962 sortS == d.sortS;
963}
964
965
966/*!
967 Removes the file, \a fileName.
968
969 If \a acceptAbsPath is TRUE a path starting with separator "/"
970 will remove the file with the absolute path. If \a acceptAbsPath
971 is FALSE any number of separators at the beginning of \a fileName
972 will be removed and the resultant file name will be removed.
973
974 Returns TRUE if the file is removed successfully; otherwise
975 returns FALSE.
976*/
977
978bool QDir::remove( const QString &fileName, bool acceptAbsPath )
979{
980 if ( fileName.isEmpty() ) {
981#if defined(QT_CHECK_NULL)
982 qWarning( "QDir::remove: Empty or null file name" );
983#endif
984 return FALSE;
985 }
986 QString p = filePath( fileName, acceptAbsPath );
987 return QFile::remove( p );
988}
989
990/*!
991 Checks for the existence of the file \a name.
992
993 If \a acceptAbsPath is TRUE a path starting with separator "/"
994 will check the file with the absolute path. If \a acceptAbsPath is
995 FALSE any number of separators at the beginning of \a name will be
996 removed and the resultant file name will be checked.
997
998 Returns TRUE if the file exists; otherwise returns FALSE.
999
1000 \sa QFileInfo::exists(), QFile::exists()
1001*/
1002
1003bool QDir::exists( const QString &name, bool acceptAbsPath ) //### const in 4.0
1004{
1005 if ( name.isEmpty() ) {
1006#if defined(QT_CHECK_NULL)
1007 qWarning( "QDir::exists: Empty or null file name" );
1008#endif
1009 return FALSE;
1010 }
1011 QString tmp = filePath( name, acceptAbsPath );
1012 return QFile::exists( tmp );
1013}
1014
1015/*!
1016 Returns the native directory separator; "/" under UNIX (including
1017 Mac OS X) and "\" under Windows.
1018
1019 You do not need to use this function to build file paths. If you
1020 always use "/", Qt will translate your paths to conform to the
1021 underlying operating system.
1022*/
1023
1024char QDir::separator()
1025{
1026#if defined(Q_OS_UNIX)
1027 return '/';
1028#elif defined (Q_FS_FAT) || defined(Q_WS_WIN)
1029 return '\\';
1030#elif defined (Q_OS_MAC)
1031 return ':';
1032#else
1033 return '/';
1034#endif
1035}
1036
1037/*!
1038 Returns the application's current directory.
1039
1040 Use path() to access a QDir object's path.
1041
1042 \sa currentDirPath(), QDir::QDir()
1043*/
1044
1045QDir QDir::current()
1046{
1047 return QDir( currentDirPath() );
1048}
1049
1050/*!
1051 Returns the home directory.
1052
1053 Under Windows the \c HOME environment variable is used. If this
1054 does not exist the \c USERPROFILE environment variable is used. If
1055 that does not exist the path is formed by concatenating the \c
1056 HOMEDRIVE and \c HOMEPATH environment variables. If they don't
1057 exist the rootDirPath() is used (this uses the \c SystemDrive
1058 environment variable). If none of these exist "C:\" is used.
1059
1060 Under non-Windows operating systems the \c HOME environment
1061 variable is used if it exists, otherwise rootDirPath() is used.
1062
1063 \sa homeDirPath()
1064*/
1065
1066QDir QDir::home()
1067{
1068 return QDir( homeDirPath() );
1069}
1070
1071/*!
1072 Returns the root directory.
1073
1074 \sa rootDirPath() drives()
1075*/
1076
1077QDir QDir::root()
1078{
1079 return QDir( rootDirPath() );
1080}
1081
1082/*!
1083 \fn QString QDir::homeDirPath()
1084
1085 Returns the absolute path of the user's home directory.
1086
1087 \sa home()
1088*/
1089
1090QStringList qt_makeFilterList( const QString &filter )
1091{
1092 if ( filter.isEmpty() )
1093 return QStringList();
1094
1095 QChar sep( ';' );
1096 int i = filter.find( sep, 0 );
1097 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
1098 sep = QChar( ' ' );
1099
1100 QStringList list = QStringList::split( sep, filter );
1101 QStringList::Iterator it = list.begin();
1102 QStringList list2;
1103
1104 for ( ; it != list.end(); ++it ) {
1105 QString s = *it;
1106 list2 << s.stripWhiteSpace();
1107 }
1108 return list2;
1109}
1110
1111/*!
1112 \overload
1113
1114 Returns TRUE if the \a fileName matches any of the wildcard (glob)
1115 patterns in the list of \a filters; otherwise returns FALSE.
1116
1117 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1118 matching.\endlink)
1119 \sa QRegExp::match()
1120*/
1121
1122bool QDir::match( const QStringList &filters, const QString &fileName )
1123{
1124 QStringList::ConstIterator sit = filters.begin();
1125 while ( sit != filters.end() ) {
1126#if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
1127 QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive..
1128#else
1129 QRegExp rx( *sit, TRUE, TRUE ); // ..while others are.
1130#endif
1131 if ( rx.exactMatch(fileName) )
1132 return TRUE;
1133 ++sit;
1134 }
1135 return FALSE;
1136}
1137
1138/*!
1139 Returns TRUE if the \a fileName matches the wildcard (glob)
1140 pattern \a filter; otherwise returns FALSE. The \a filter may
1141 contain multiple patterns separated by spaces or semicolons.
1142
1143 (See \link qregexp.html#wildcard-matching QRegExp wildcard
1144 matching.\endlink)
1145 \sa QRegExp::match()
1146*/
1147
1148bool QDir::match( const QString &filter, const QString &fileName )
1149{
1150 QStringList lst = qt_makeFilterList( filter );
1151 return match( lst, fileName );
1152}
1153
1154
1155/*!
1156 Removes all multiple directory separators "/" and resolves any
1157 "."s or ".."s found in the path, \a filePath.
1158
1159 Symbolic links are kept. This function does not return the
1160 canonical path, but rather the simplest version of the input.
1161 For example, "./local" becomes "local", "local/../bin" becomes
1162 "bin" and "/local/usr/../bin" becomes "/local/bin".
1163
1164 \sa absPath() canonicalPath()
1165*/
1166
1167QString QDir::cleanDirPath( const QString &filePath )
1168{
1169 QString name = filePath;
1170 QString newPath;
1171
1172 if ( name.isEmpty() )
1173 return name;
1174
1175 slashify( name );
1176
1177 bool addedSeparator;
1178 if ( isRelativePath(name) ) {
1179 addedSeparator = TRUE;
1180 name.insert( 0, '/' );
1181 } else {
1182 addedSeparator = FALSE;
1183 }
1184
1185 int ePos, pos, upLevel;
1186
1187 pos = ePos = name.length();
1188 upLevel = 0;
1189 int len;
1190
1191 while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
1192 len = ePos - pos - 1;
1193 if ( len == 2 && name.at(pos + 1) == '.'
1194 && name.at(pos + 2) == '.' ) {
1195 upLevel++;
1196 } else {
1197 if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
1198 if ( !upLevel )
1199 newPath = QString::fromLatin1("/")
1200 + name.mid(pos + 1, len) + newPath;
1201 else
1202 upLevel--;
1203 }
1204 }
1205 ePos = pos;
1206 }
1207 if ( addedSeparator ) {
1208 while ( upLevel-- )
1209 newPath.insert( 0, QString::fromLatin1("/..") );
1210 if ( !newPath.isEmpty() )
1211 newPath.remove( 0, 1 );
1212 else
1213 newPath = QString::fromLatin1(".");
1214 } else {
1215 if ( newPath.isEmpty() )
1216 newPath = QString::fromLatin1("/");
1217#if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
1218 if ( name[0] == '/' ) {
1219 if ( name[1] == '/' ) // "\\machine\x\ ..."
1220 newPath.insert( 0, '/' );
1221 } else {
1222 newPath = name.left(2) + newPath;
1223 }
1224#endif
1225 }
1226 return newPath;
1227}
1228
1229int qt_cmp_si_sortSpec;
1230
1231#if defined(Q_C_CALLBACKS)
1232extern "C" {
1233#endif
1234
1235#ifdef Q_OS_TEMP
1236int __cdecl qt_cmp_si( const void *n1, const void *n2 )
1237#else
1238int qt_cmp_si( const void *n1, const void *n2 )
1239#endif
1240{
1241 if ( !n1 || !n2 )
1242 return 0;
1243
1244 QDirSortItem* f1 = (QDirSortItem*)n1;
1245 QDirSortItem* f2 = (QDirSortItem*)n2;
1246
1247 if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
1248 if ( f1->item->isDir() != f2->item->isDir() )
1249 return f1->item->isDir() ? -1 : 1;
1250
1251 int r = 0;
1252 int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
1253
1254 switch ( sortBy ) {
1255 case QDir::Time:
1256 r = f1->item->lastModified().secsTo(f2->item->lastModified());
1257 break;
1258 case QDir::Size:
1259 r = f2->item->size() - f1->item->size();
1260 break;
1261 default:
1262 ;
1263 }
1264
1265 if ( r == 0 && sortBy != QDir::Unsorted ) {
1266 // Still not sorted - sort by name
1267 bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
1268
1269 if ( f1->filename_cache.isNull() )
1270 f1->filename_cache = ic ? f1->item->fileName().lower()
1271 : f1->item->fileName();
1272 if ( f2->filename_cache.isNull() )
1273 f2->filename_cache = ic ? f2->item->fileName().lower()
1274 : f2->item->fileName();
1275
1276 r = f1->filename_cache.compare(f2->filename_cache);
1277 }
1278
1279 if ( r == 0 ) {
1280 // Enforce an order - the order the items appear in the array
1281 r = (char*)n1 - (char*)n2;
1282 }
1283
1284 if ( qt_cmp_si_sortSpec & QDir::Reversed )
1285 return -r;
1286 else
1287 return r;
1288}
1289
1290#if defined(Q_C_CALLBACKS)
1291}
1292#endif
1293
1294#endif // QT_NO_DIR
diff --git a/qmake/tools/qdir_unix.cpp b/qmake/tools/qdir_unix.cpp
new file mode 100644
index 0000000..57fe3c5
--- a/dev/null
+++ b/qmake/tools/qdir_unix.cpp
@@ -0,0 +1,291 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QDir class
5**
6** Created : 950628
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
23** with the Qt Commercial License Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include "qdir.h"
40
41#ifndef QT_NO_DIR
42
43#include "qdir_p.h"
44#include "qfileinfo.h"
45#include "qregexp.h"
46#include "qstringlist.h"
47
48#ifdef QT_THREAD_SUPPORT
49# include <private/qmutexpool_p.h>
50#endif // QT_THREAD_SUPPORT
51
52#include <stdlib.h>
53#include <limits.h>
54
55
56void QDir::slashify( QString& )
57{
58}
59
60QString QDir::homeDirPath()
61{
62 QString d;
63 d = QFile::decodeName(getenv("HOME"));
64 slashify( d );
65 if ( d.isNull() )
66 d = rootDirPath();
67 return d;
68}
69
70QString QDir::canonicalPath() const
71{
72 QString r;
73
74 char cur[PATH_MAX+1];
75 if ( ::getcwd( cur, PATH_MAX ) )
76 if ( ::chdir(QFile::encodeName(dPath)) >= 0 ) {
77 char tmp[PATH_MAX+1];
78 if ( ::getcwd( tmp, PATH_MAX ) )
79 r = QFile::decodeName(tmp);
80 ::chdir( cur );
81 }
82
83 slashify( r );
84 return r;
85}
86
87bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
88{
89#if defined(Q_OS_MACX) // Mac X doesn't support trailing /'s
90 QString name = dirName;
91 if (dirName[dirName.length() - 1] == "/")
92 name = dirName.left( dirName.length() - 1 );
93 return ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 )
94 == 0;
95#else
96 return ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 )
97 == 0;
98#endif
99}
100
101bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
102{
103 return ::rmdir( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
104}
105
106bool QDir::isReadable() const
107{
108 return ::access( QFile::encodeName(dPath), R_OK | X_OK ) == 0;
109}
110
111bool QDir::isRoot() const
112{
113 return dPath == QString::fromLatin1("/");
114}
115
116bool QDir::rename( const QString &name, const QString &newName,
117 bool acceptAbsPaths)
118{
119 if ( name.isEmpty() || newName.isEmpty() ) {
120#if defined(QT_CHECK_NULL)
121 qWarning( "QDir::rename: Empty or null file name(s)" );
122#endif
123 return FALSE;
124 }
125 QString fn1 = filePath( name, acceptAbsPaths );
126 QString fn2 = filePath( newName, acceptAbsPaths );
127 return ::rename( QFile::encodeName(fn1),
128 QFile::encodeName(fn2) ) == 0;
129}
130
131bool QDir::setCurrent( const QString &path )
132{
133 int r;
134 r = ::chdir( QFile::encodeName(path) );
135 return r >= 0;
136}
137
138QString QDir::currentDirPath()
139{
140 QString result;
141
142 struct stat st;
143 if ( ::stat( ".", &st ) == 0 ) {
144 char currentName[PATH_MAX+1];
145 if ( ::getcwd( currentName, PATH_MAX ) )
146 result = QFile::decodeName(currentName);
147#if defined(QT_DEBUG)
148 if ( result.isNull() )
149 qWarning( "QDir::currentDirPath: getcwd() failed" );
150#endif
151 } else {
152#if defined(QT_DEBUG)
153 qWarning( "QDir::currentDirPath: stat(\".\") failed" );
154#endif
155 }
156 slashify( result );
157 return result;
158}
159
160QString QDir::rootDirPath()
161{
162 QString d = QString::fromLatin1( "/" );
163 return d;
164}
165
166bool QDir::isRelativePath( const QString &path )
167{
168 int len = path.length();
169 if ( len == 0 )
170 return TRUE;
171 return path[0] != '/';
172}
173
174bool QDir::readDirEntries( const QString &nameFilter,
175 int filterSpec, int sortSpec )
176{
177 int i;
178 if ( !fList ) {
179 fList = new QStringList;
180 Q_CHECK_PTR( fList );
181 fiList = new QFileInfoList;
182 Q_CHECK_PTR( fiList );
183 fiList->setAutoDelete( TRUE );
184 } else {
185 fList->clear();
186 fiList->clear();
187 }
188
189 QStringList filters = qt_makeFilterList( nameFilter );
190
191 bool doDirs = (filterSpec & Dirs)!= 0;
192 bool doFiles = (filterSpec & Files)!= 0;
193 bool noSymLinks = (filterSpec & NoSymLinks) != 0;
194 bool doReadable = (filterSpec & Readable)!= 0;
195 bool doWritable = (filterSpec & Writable)!= 0;
196 bool doExecable = (filterSpec & Executable) != 0;
197 bool doHidden = (filterSpec & Hidden)!= 0;
198 bool doSystem = (filterSpec & System) != 0;
199
200#if defined(Q_OS_OS2EMX)
201 //QRegExp wc( nameFilter, FALSE, TRUE );// wild card, case insensitive
202#else
203 //QRegExp wc( nameFilter, TRUE, TRUE );// wild card, case sensitive
204#endif
205 QFileInfo fi;
206 DIR *dir;
207 dirent *file;
208
209 dir = opendir( QFile::encodeName(dPath) );
210 if ( !dir )
211 return FALSE; // cannot read the directory
212
213 while ( (file = readdir(dir)) ) {
214 QString fn = QFile::decodeName(file->d_name);
215 fi.setFile( *this, fn );
216 if ( !match( filters, fn ) && !(allDirs && fi.isDir()) )
217 continue;
218 if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ||
219 (doSystem && (!fi.isFile() && !fi.isDir())) ) {
220 if ( noSymLinks && fi.isSymLink() )
221 continue;
222 if ( (filterSpec & RWEMask) != 0 )
223 if ( (doReadable && !fi.isReadable()) ||
224 (doWritable && !fi.isWritable()) ||
225 (doExecable && !fi.isExecutable()) )
226 continue;
227 if ( !doHidden && fn[0] == '.' &&
228 fn != QString::fromLatin1(".")
229 && fn != QString::fromLatin1("..") )
230 continue;
231 fiList->append( new QFileInfo( fi ) );
232 }
233 }
234 if ( closedir(dir) != 0 ) {
235#if defined(QT_CHECK_NULL)
236 qWarning( "QDir::readDirEntries: Cannot close the directory: %s",
237 dPath.local8Bit().data() );
238#endif
239 }
240
241 // Sort...
242 if(fiList->count()) {
243 QDirSortItem* si= new QDirSortItem[fiList->count()];
244 QFileInfo* itm;
245 i=0;
246 for (itm = fiList->first(); itm; itm = fiList->next())
247 si[i++].item = itm;
248 qt_cmp_si_sortSpec = sortSpec;
249 qsort( si, i, sizeof(si[0]), qt_cmp_si );
250 // put them back in the list
251 fiList->setAutoDelete( FALSE );
252 fiList->clear();
253 int j;
254 for ( j=0; j<i; j++ ) {
255 fiList->append( si[j].item );
256 fList->append( si[j].item->fileName() );
257 }
258 delete [] si;
259 fiList->setAutoDelete( TRUE );
260 }
261
262 if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
263 nameFilter == nameFilt )
264 dirty = FALSE;
265 else
266 dirty = TRUE;
267 return TRUE;
268}
269
270const QFileInfoList * QDir::drives()
271{
272 // at most one instance of QFileInfoList is leaked, and this variable
273 // points to that list
274 static QFileInfoList * knownMemoryLeak = 0;
275
276 if ( !knownMemoryLeak ) {
277
278#ifdef QT_THREAD_SUPPORT
279 QMutexLocker locker( qt_global_mutexpool->get( &knownMemoryLeak ) );
280#endif // QT_THREAD_SUPPORT
281
282 if ( !knownMemoryLeak ) {
283 knownMemoryLeak = new QFileInfoList;
284 // non-win32 versions both use just one root directory
285 knownMemoryLeak->append( new QFileInfo( rootDirPath() ) );
286 }
287 }
288
289 return knownMemoryLeak;
290}
291#endif //QT_NO_DIR
diff --git a/qmake/tools/qfile.cpp b/qmake/tools/qfile.cpp
new file mode 100644
index 0000000..a578b49
--- a/dev/null
+++ b/qmake/tools/qfile.cpp
@@ -0,0 +1,614 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QFile class
5**
6** Created : 930812
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40// POSIX Large File Support redefines open -> open64
41#if defined(open)
42# undef open
43#endif
44
45// POSIX Large File Support redefines truncate -> truncate64
46#if defined(truncate)
47# undef truncate
48#endif
49
50#include "qfile.h"
51
52
53extern bool qt_file_access( const QString& fn, int t );
54
55/*!
56 \class QFile qfile.h
57 \reentrant
58 \brief The QFile class is an I/O device that operates on files.
59
60 \ingroup io
61 \mainclass
62
63 QFile is an I/O device for reading and writing binary and text
64 files. A QFile may be used by itself or more conveniently with a
65 QDataStream or QTextStream.
66
67 The file name is usually passed in the constructor but can be
68 changed with setName(). You can check for a file's existence with
69 exists() and remove a file with remove().
70
71 The file is opened with open(), closed with close() and flushed
72 with flush(). Data is usually read and written using QDataStream
73 or QTextStream, but you can read with readBlock() and readLine()
74 and write with writeBlock(). QFile also supports getch(),
75 ungetch() and putch().
76
77 The size of the file is returned by size(). You can get the
78 current file position or move to a new file position using the
79 at() functions. If you've reached the end of the file, atEnd()
80 returns TRUE. The file handle is returned by handle().
81
82 Here is a code fragment that uses QTextStream to read a text file
83 line by line. It prints each line with a line number.
84 \code
85 QStringList lines;
86 QFile file( "file.txt" );
87 if ( file.open( IO_ReadOnly ) ) {
88 QTextStream stream( &file );
89 QString line;
90 int i = 1;
91 while ( !stream.eof() ) {
92 line = stream.readLine(); // line of text excluding '\n'
93 printf( "%3d: %s\n", i++, line.latin1() );
94 lines += line;
95 }
96 file.close();
97 }
98 \endcode
99
100 Writing text is just as easy. The following example shows how to
101 write the data we read into the string list from the previous
102 example:
103 \code
104 QFile file( "file.txt" );
105 if ( file.open( IO_WriteOnly ) ) {
106 QTextStream stream( &file );
107 for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
108 stream << *it << "\n";
109 file.close();
110 }
111 \endcode
112
113 The QFileInfo class holds detailed information about a file, such
114 as access permissions, file dates and file types.
115
116 The QDir class manages directories and lists of file names.
117
118 Qt uses Unicode file names. If you want to do your own I/O on Unix
119 systems you may want to use encodeName() (and decodeName()) to
120 convert the file name into the local encoding.
121
122 \important readAll()
123
124 \sa QDataStream, QTextStream
125*/
126
127/*!
128 \fn Q_LONG QFile::writeBlock( const QByteArray& data )
129
130 \overload
131*/
132
133
134/*!
135 Constructs a QFile with no name.
136*/
137
138QFile::QFile()
139{
140 init();
141}
142
143/*!
144 Constructs a QFile with a file name \a name.
145
146 \sa setName()
147*/
148
149QFile::QFile( const QString &name )
150 : fn(name)
151{
152 init();
153}
154
155
156/*!
157 Destroys a QFile. Calls close().
158*/
159
160QFile::~QFile()
161{
162 close();
163}
164
165
166/*!
167 \internal
168 Initialize internal data.
169*/
170
171void QFile::init()
172{
173 setFlags( IO_Direct );
174 setStatus( IO_Ok );
175 fh = 0;
176 fd = 0;
177 length = 0;
178 ioIndex = 0;
179 ext_f = FALSE; // not an external file handle
180}
181
182
183/*!
184 \fn QString QFile::name() const
185
186 Returns the name set by setName().
187
188 \sa setName(), QFileInfo::fileName()
189*/
190
191/*!
192 Sets the name of the file to \a name. The name can have no path, a
193 relative path or an absolute absolute path.
194
195 Do not call this function if the file has already been opened.
196
197 If the file name has no path or a relative path, the path used
198 will be whatever the application's current directory path is
199 \e{at the time of the open()} call.
200
201 Example:
202 \code
203 QFile file;
204 QDir::setCurrent( "/tmp" );
205 file.setName( "readme.txt" );
206 QDir::setCurrent( "/home" );
207 file.open( IO_ReadOnly ); // opens "/home/readme.txt" under Unix
208 \endcode
209
210 Note that the directory separator "/" works for all operating
211 systems supported by Qt.
212
213 \sa name(), QFileInfo, QDir
214*/
215
216void QFile::setName( const QString &name )
217{
218 if ( isOpen() ) {
219#if defined(QT_CHECK_STATE)
220 qWarning( "QFile::setName: File is open" );
221#endif
222 close();
223 }
224 fn = name;
225}
226
227/*!
228 \overload
229
230 Returns TRUE if this file exists; otherwise returns FALSE.
231
232 \sa name()
233*/
234
235bool QFile::exists() const
236{
237 return qt_file_access( fn, F_OK );
238}
239
240/*!
241 Returns TRUE if the file given by \a fileName exists; otherwise
242 returns FALSE.
243*/
244
245bool QFile::exists( const QString &fileName )
246{
247 return qt_file_access( fileName, F_OK );
248}
249
250
251/*!
252 Removes the file specified by the file name currently set. Returns
253 TRUE if successful; otherwise returns FALSE.
254
255 The file is closed before it is removed.
256*/
257
258bool QFile::remove()
259{
260 close();
261 return remove( fn );
262}
263
264#if defined(Q_OS_MAC) || defined(Q_OS_MSDOS) || defined(Q_OS_WIN32) || defined(Q_OS_OS2)
265 # define HAS_TEXT_FILEMODE // has translate/text filemode
266#endif
267#if defined(O_NONBLOCK)
268# define HAS_ASYNC_FILEMODE
269# define OPEN_ASYNC O_NONBLOCK
270#elif defined(O_NDELAY)
271# define HAS_ASYNC_FILEMODE
272# define OPEN_ASYNC O_NDELAY
273#endif
274
275/*!
276 Flushes the file buffer to the disk.
277
278 close() also flushes the file buffer.
279*/
280
281void QFile::flush()
282{
283 if ( isOpen() && fh ) // can only flush open/buffered
284 fflush( fh ); // file
285}
286
287/*! \reimp
288 \fn QIODevice::Offset QFile::at() const
289*/
290
291/*!
292 Returns TRUE if the end of file has been reached; otherwise returns FALSE.
293
294 \sa size()
295*/
296
297bool QFile::atEnd() const
298{
299 if ( !isOpen() ) {
300#if defined(QT_CHECK_STATE)
301 qWarning( "QFile::atEnd: File is not open" );
302#endif
303 return FALSE;
304 }
305 if ( isDirectAccess() && !isTranslated() ) {
306 if ( at() < length )
307 return FALSE;
308 }
309 return QIODevice::atEnd();
310}
311
312/*!
313 Reads a line of text.
314
315 Reads bytes from the file into the char* \a p, until end-of-line
316 or \a maxlen bytes have been read, whichever occurs first. Returns
317 the number of bytes read, or -1 if there was an error. Any
318 terminating newline is not stripped.
319
320 This function is only efficient for buffered files. Avoid
321 readLine() for files that have been opened with the \c IO_Raw
322 flag.
323
324 \sa readBlock(), QTextStream::readLine()
325*/
326
327Q_LONG QFile::readLine( char *p, Q_ULONG maxlen )
328{
329 if ( maxlen == 0 ) // application bug?
330 return 0;
331#if defined(QT_CHECK_STATE)
332 Q_CHECK_PTR( p );
333 if ( !isOpen() ) { // file not open
334 qWarning( "QFile::readLine: File not open" );
335 return -1;
336 }
337 if ( !isReadable() ) { // reading not permitted
338 qWarning( "QFile::readLine: Read operation not permitted" );
339 return -1;
340 }
341#endif
342 Q_LONG nread; // number of bytes read
343 if ( isRaw() ) { // raw file
344 nread = QIODevice::readLine( p, maxlen );
345 } else { // buffered file
346 p = fgets( p, maxlen, fh );
347 if ( p ) {
348 nread = qstrlen( p );
349 if ( !isSequentialAccess() )
350 ioIndex += nread;
351 } else {
352 nread = -1;
353 setStatus(IO_ReadError);
354 }
355 }
356 return nread;
357}
358
359
360/*!
361 \overload
362
363 Reads a line of text.
364
365 Reads bytes from the file into string \a s, until end-of-line or
366 \a maxlen bytes have been read, whichever occurs first. Returns
367 the number of bytes read, or -1 if there was an error, e.g. end of
368 file. Any terminating newline is not stripped.
369
370 This function is only efficient for buffered files. Avoid using
371 readLine() for files that have been opened with the \c IO_Raw
372 flag.
373
374 Note that the string is read as plain Latin1 bytes, not Unicode.
375
376 \sa readBlock(), QTextStream::readLine()
377*/
378
379Q_LONG QFile::readLine( QString& s, Q_ULONG maxlen )
380{
381 QByteArray ba(maxlen);
382 Q_LONG l = readLine(ba.data(),maxlen);
383 if ( l >= 0 ) {
384 ba.truncate(l);
385 s = QString(ba);
386 }
387 return l;
388}
389
390
391/*!
392 Reads a single byte/character from the file.
393
394 Returns the byte/character read, or -1 if the end of the file has
395 been reached.
396
397 \sa putch(), ungetch()
398*/
399
400int QFile::getch()
401{
402#if defined(QT_CHECK_STATE)
403 if ( !isOpen() ) { // file not open
404 qWarning( "QFile::getch: File not open" );
405 return EOF;
406 }
407 if ( !isReadable() ) { // reading not permitted
408 qWarning( "QFile::getch: Read operation not permitted" );
409 return EOF;
410 }
411#endif
412
413 int ch;
414
415 if ( !ungetchBuffer.isEmpty() ) {
416 int len = ungetchBuffer.length();
417 ch = ungetchBuffer[ len-1 ];
418 ungetchBuffer.truncate( len - 1 );
419 return ch;
420 }
421
422 if ( isRaw() ) { // raw file (inefficient)
423 char buf[1];
424 ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF;
425 } else { // buffered file
426 if ( (ch = getc( fh )) != EOF )
427 if ( !isSequentialAccess() )
428 ioIndex++;
429 else
430 setStatus(IO_ReadError);
431 }
432 return ch;
433}
434
435/*!
436 Writes the character \a ch to the file.
437
438 Returns \a ch, or -1 if some error occurred.
439
440 \sa getch(), ungetch()
441*/
442
443int QFile::putch( int ch )
444{
445#if defined(QT_CHECK_STATE)
446 if ( !isOpen() ) { // file not open
447 qWarning( "QFile::putch: File not open" );
448 return EOF;
449 }
450 if ( !isWritable() ) { // writing not permitted
451 qWarning( "QFile::putch: Write operation not permitted" );
452 return EOF;
453 }
454#endif
455 if ( isRaw() ) { // raw file (inefficient)
456 char buf[1];
457 buf[0] = ch;
458 ch = writeBlock( buf, 1 ) == 1 ? ch : EOF;
459 } else { // buffered file
460 if ( (ch = putc( ch, fh )) != EOF ) {
461 if ( !isSequentialAccess() )
462 ioIndex++;
463 if ( ioIndex > length ) // update file length
464 length = ioIndex;
465 } else {
466 setStatus(IO_WriteError);
467 }
468 }
469 return ch;
470}
471
472/*!
473 Puts the character \a ch back into the file and decrements the
474 index if it is not zero.
475
476 This function is normally called to "undo" a getch() operation.
477
478 Returns \a ch, or -1 if an error occurred.
479
480 \sa getch(), putch()
481*/
482
483int QFile::ungetch( int ch )
484{
485#if defined(QT_CHECK_STATE)
486 if ( !isOpen() ) { // file not open
487 qWarning( "QFile::ungetch: File not open" );
488 return EOF;
489 }
490 if ( !isReadable() ) { // reading not permitted
491 qWarning( "QFile::ungetch: Read operation not permitted" );
492 return EOF;
493 }
494#endif
495 if ( ch == EOF ) // cannot unget EOF
496 return ch;
497
498 if ( isSequentialAccess() && !fh) {
499 // pipe or similar => we cannot ungetch, so do it manually
500 ungetchBuffer +=ch;
501 return ch;
502 }
503
504 if ( isRaw() ) { // raw file (very inefficient)
505 char buf[1];
506 at( ioIndex-1 );
507 buf[0] = ch;
508 if ( writeBlock(buf, 1) == 1 )
509 at ( ioIndex-1 );
510 else
511 ch = EOF;
512 } else { // buffered file
513 if ( (ch = ungetc(ch, fh)) != EOF )
514 if ( !isSequentialAccess() )
515 ioIndex--;
516 else
517 setStatus( IO_ReadError );
518 }
519 return ch;
520}
521
522
523static QCString locale_encoder( const QString &fileName )
524{
525 return fileName.local8Bit();
526}
527
528
529static QFile::EncoderFn encoder = locale_encoder;
530
531/*!
532 When you use QFile, QFileInfo, and QDir to access the file system
533 with Qt, you can use Unicode file names. On Unix, these file names
534 are converted to an 8-bit encoding. If you want to do your own
535 file I/O on Unix, you should convert the file name using this
536 function. On Windows NT/2000, Unicode file names are supported
537 directly in the file system and this function should be avoided.
538 On Windows 95, non-Latin1 locales are not supported.
539
540 By default, this function converts \a fileName to the local 8-bit
541 encoding determined by the user's locale. This is sufficient for
542 file names that the user chooses. File names hard-coded into the
543 application should only use 7-bit ASCII filename characters.
544
545 The conversion scheme can be changed using setEncodingFunction().
546 This might be useful if you wish to give the user an option to
547 store file names in UTF-8, etc., but be aware that such file names
548 would probably then be unrecognizable when seen by other programs.
549
550 \sa decodeName()
551*/
552
553QCString QFile::encodeName( const QString &fileName )
554{
555 return (*encoder)(fileName);
556}
557
558/*!
559 \enum QFile::EncoderFn
560
561 This is used by QFile::setEncodingFunction().
562*/
563
564/*!
565 \nonreentrant
566
567 Sets the function for encoding Unicode file names to \a f. The
568 default encodes in the locale-specific 8-bit encoding.
569
570 \sa encodeName()
571*/
572void QFile::setEncodingFunction( EncoderFn f )
573{
574 encoder = f;
575}
576
577static
578QString locale_decoder( const QCString &localFileName )
579{
580 return QString::fromLocal8Bit(localFileName);
581}
582
583static QFile::DecoderFn decoder = locale_decoder;
584
585/*!
586 This does the reverse of QFile::encodeName() using \a localFileName.
587
588 \sa setDecodingFunction()
589*/
590QString QFile::decodeName( const QCString &localFileName )
591{
592 return (*decoder)(localFileName);
593}
594
595/*!
596 \enum QFile::DecoderFn
597
598 This is used by QFile::setDecodingFunction().
599*/
600
601/*!
602 \nonreentrant
603
604 Sets the function for decoding 8-bit file names to \a f. The
605 default uses the locale-specific 8-bit encoding.
606
607 \sa encodeName(), decodeName()
608*/
609
610void QFile::setDecodingFunction( DecoderFn f )
611{
612 decoder = f;
613}
614
diff --git a/qmake/tools/qfile_unix.cpp b/qmake/tools/qfile_unix.cpp
new file mode 100644
index 0000000..2d5a856
--- a/dev/null
+++ b/qmake/tools/qfile_unix.cpp
@@ -0,0 +1,687 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QFile class
5**
6** Created : 950628
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
23** with the Qt Commercial License Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40// POSIX Large File Support redefines open -> open64
41static inline int qt_open(const char *pathname, int flags, mode_t mode)
42{ return ::open(pathname, flags, mode); }
43#if defined(open)
44# undef open
45#endif
46
47// POSIX Large File Support redefines truncate -> truncate64
48#if defined(truncate)
49# undef truncate
50#endif
51
52#include "qfile.h"
53#include <errno.h>
54#include <limits.h>
55
56
57bool qt_file_access( const QString& fn, int t )
58{
59 if ( fn.isEmpty() )
60 return FALSE;
61 return ::access( QFile::encodeName(fn), t ) == 0;
62}
63
64/*!
65 \overload
66 Removes the file \a fileName.
67 Returns TRUE if successful, otherwise FALSE.
68*/
69
70bool QFile::remove( const QString &fileName )
71{
72 if ( fileName.isEmpty() ) {
73#if defined(QT_CHECK_NULL)
74 qWarning( "QFile::remove: Empty or null file name" );
75#endif
76 return FALSE;
77 }
78 return unlink( QFile::encodeName(fileName) ) == 0;
79}
80
81#if defined(O_NONBLOCK)
82# define HAS_ASYNC_FILEMODE
83# define OPEN_ASYNC O_NONBLOCK
84#elif defined(O_NDELAY)
85# define HAS_ASYNC_FILEMODE
86# define OPEN_ASYNC O_NDELAY
87#endif
88
89/*!
90 Opens the file specified by the file name currently set, using the
91 mode \a m. Returns TRUE if successful, otherwise FALSE.
92
93 \keyword IO_Raw
94 \keyword IO_ReadOnly
95 \keyword IO_WriteOnly
96 \keyword IO_ReadWrite
97 \keyword IO_Append
98 \keyword IO_Truncate
99 \keyword IO_Translate
100
101 The mode parameter \a m must be a combination of the following flags:
102 \table
103 \header \i Flag \i Meaning
104 \row \i IO_Raw
105 \i Raw (non-buffered) file access.
106 \row \i IO_ReadOnly
107 \i Opens the file in read-only mode.
108 \row \i IO_WriteOnly
109 \i Opens the file in write-only mode. If this flag is used
110 with another flag, e.g. \c IO_ReadOnly or \c IO_Raw or \c
111 IO_Append, the file is \e not truncated; but if used on
112 its own (or with \c IO_Truncate), the file is truncated.
113 \row \i IO_ReadWrite
114 \i Opens the file in read/write mode, equivalent to \c
115 (IO_ReadOnly | IO_WriteOnly).
116 \row \i IO_Append
117 \i Opens the file in append mode. (You must actually use \c
118 (IO_WriteOnly | IO_Append) to make the file writable and
119 to go into append mode.) This mode is very useful when you
120 want to write something to a log file. The file index is
121 set to the end of the file. Note that the result is
122 undefined if you position the file index manually using
123 at() in append mode.
124 \row \i IO_Truncate
125 \i Truncates the file.
126 \row \i IO_Translate
127 \i Enables carriage returns and linefeed translation for text
128 files under Windows.
129 \endtable
130
131 The raw access mode is best when I/O is block-operated using a 4KB
132 block size or greater. Buffered access works better when reading
133 small portions of data at a time.
134
135 \warning When working with buffered files, data may not be written
136 to the file at once. Call flush() to make sure that the data is
137 really written.
138
139 \warning If you have a buffered file opened for both reading and
140 writing you must not perform an input operation immediately after
141 an output operation or vice versa. You should always call flush()
142 or a file positioning operation, e.g. at(), between input and
143 output operations, otherwise the buffer may contain garbage.
144
145 If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite
146 is specified, it is created.
147
148 Example:
149 \code
150 QFile f1( "/tmp/data.bin" );
151 f1.open( IO_Raw | IO_ReadWrite );
152
153 QFile f2( "readme.txt" );
154 f2.open( IO_ReadOnly | IO_Translate );
155
156 QFile f3( "audit.log" );
157 f3.open( IO_WriteOnly | IO_Append );
158 \endcode
159
160 \sa name(), close(), isOpen(), flush()
161*/
162
163bool QFile::open( int m )
164{
165 if ( isOpen() ) { // file already open
166#if defined(QT_CHECK_STATE)
167 qWarning( "QFile::open: File already open" );
168#endif
169 return FALSE;
170 }
171 if ( fn.isNull() ) { // no file name defined
172#if defined(QT_CHECK_NULL)
173 qWarning( "QFile::open: No file name specified" );
174#endif
175 return FALSE;
176 }
177 init(); // reset params
178 setMode( m );
179 if ( !(isReadable() || isWritable()) ) {
180#if defined(QT_CHECK_RANGE)
181 qWarning( "QFile::open: File access not specified" );
182#endif
183 return FALSE;
184 }
185 bool ok = TRUE;
186 struct stat st;
187 if ( isRaw() ) {
188 int oflags = O_RDONLY;
189 if ( isReadable() && isWritable() )
190 oflags = O_RDWR;
191 else if ( isWritable() )
192 oflags = O_WRONLY;
193 if ( flags() & IO_Append ) { // append to end of file?
194 if ( flags() & IO_Truncate )
195 oflags |= (O_CREAT | O_TRUNC);
196 else
197 oflags |= (O_APPEND | O_CREAT);
198 setFlags( flags() | IO_WriteOnly ); // append implies write
199 } else if ( isWritable() ) { // create/trunc if writable
200 if ( flags() & IO_Truncate )
201 oflags |= (O_CREAT | O_TRUNC);
202 else
203 oflags |= O_CREAT;
204 }
205#if defined(HAS_TEXT_FILEMODE)
206 if ( isTranslated() )
207 oflags |= OPEN_TEXT;
208 else
209 oflags |= OPEN_BINARY;
210#endif
211#if defined(HAS_ASYNC_FILEMODE)
212 if ( isAsynchronous() )
213 oflags |= OPEN_ASYNC;
214#endif
215 fd = qt_open( QFile::encodeName(fn), oflags, 0666 );
216
217 if ( fd != -1 ) { // open successful
218 ::fstat( fd, &st ); // get the stat for later usage
219 } else {
220 ok = FALSE;
221 }
222 } else { // buffered file I/O
223 QCString perm;
224 char perm2[4];
225 bool try_create = FALSE;
226 if ( flags() & IO_Append ) { // append to end of file?
227 setFlags( flags() | IO_WriteOnly ); // append implies write
228 perm = isReadable() ? "a+" : "a";
229 } else {
230 if ( isReadWrite() ) {
231 if ( flags() & IO_Truncate ) {
232 perm = "w+";
233 } else {
234 perm = "r+";
235 try_create = TRUE; // try to create if not exists
236 }
237 } else if ( isReadable() ) {
238 perm = "r";
239 } else if ( isWritable() ) {
240 perm = "w";
241 }
242 }
243 qstrcpy( perm2, perm );
244#if defined(HAS_TEXT_FILEMODE)
245 if ( isTranslated() )
246 strcat( perm2, "t" );
247 else
248 strcat( perm2, "b" );
249#endif
250 for (;;) { // At most twice
251
252 fh = fopen( QFile::encodeName(fn), perm2 );
253
254 if ( !fh && try_create ) {
255 perm2[0] = 'w'; // try "w+" instead of "r+"
256 try_create = FALSE;
257 } else {
258 break;
259 }
260 }
261 if ( fh ) {
262 ::fstat( fileno(fh), &st ); // get the stat for later usage
263 } else {
264 ok = FALSE;
265 }
266 }
267 if ( ok ) {
268 setState( IO_Open );
269 // on successful open the file stat was got; now test what type
270 // of file we have
271 if ( (st.st_mode & S_IFMT) != S_IFREG ) {
272 // non-seekable
273 setType( IO_Sequential );
274 length = INT_MAX;
275 ioIndex = 0;
276 } else {
277 length = (Offset)st.st_size;
278 ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
279 if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
280 // try if you can read from it (if you can, it's a sequential
281 // device; e.g. a file in the /proc filesystem)
282 int c = getch();
283 if ( c != -1 ) {
284 ungetch(c);
285 setType( IO_Sequential );
286 length = INT_MAX;
287 ioIndex = 0;
288 }
289 }
290 }
291 } else {
292 init();
293 if ( errno == EMFILE ) // no more file handles/descrs
294 setStatus( IO_ResourceError );
295 else
296 setStatus( IO_OpenError );
297 }
298 return ok;
299}
300
301/*!
302 \overload
303 Opens a file in the mode \a m using an existing file handle \a f.
304 Returns TRUE if successful, otherwise FALSE.
305
306 Example:
307 \code
308 #include <stdio.h>
309
310 void printError( const char* msg )
311 {
312 QFile f;
313 f.open( IO_WriteOnly, stderr );
314 f.writeBlock( msg, qstrlen(msg) );// write to stderr
315 f.close();
316 }
317 \endcode
318
319 When a QFile is opened using this function, close() does not actually
320 close the file, only flushes it.
321
322 \warning If \a f is \c stdin, \c stdout, \c stderr, you may not
323 be able to seek. See QIODevice::isSequentialAccess() for more
324 information.
325
326 \sa close()
327*/
328
329bool QFile::open( int m, FILE *f )
330{
331 if ( isOpen() ) {
332#if defined(QT_CHECK_RANGE)
333 qWarning( "QFile::open: File already open" );
334#endif
335 return FALSE;
336 }
337 init();
338 setMode( m &~IO_Raw );
339 setState( IO_Open );
340 fh = f;
341 ext_f = TRUE;
342 struct stat st;
343 ::fstat( fileno(fh), &st );
344#if defined(QT_LARGEFILE_SUPPORT)
345 ioIndex = (Offset)ftello( fh );
346#else
347 ioIndex = (Offset)ftell( fh );
348#endif
349 if ( (st.st_mode & S_IFMT) != S_IFREG || f == stdin ) { //stdin is non seekable
350 // non-seekable
351 setType( IO_Sequential );
352 length = INT_MAX;
353 ioIndex = 0;
354 } else {
355 length = (Offset)st.st_size;
356 if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
357 // try if you can read from it (if you can, it's a sequential
358 // device; e.g. a file in the /proc filesystem)
359 int c = getch();
360 if ( c != -1 ) {
361 ungetch(c);
362 setType( IO_Sequential );
363 length = INT_MAX;
364 ioIndex = 0;
365 }
366 }
367 }
368 return TRUE;
369}
370
371/*!
372 \overload
373 Opens a file in the mode \a m using an existing file descriptor \a f.
374 Returns TRUE if successful, otherwise FALSE.
375
376 When a QFile is opened using this function, close() does not actually
377 close the file.
378
379 The QFile that is opened using this function, is automatically set to be in
380 raw mode; this means that the file input/output functions are slow. If you
381 run into performance issues, you should try to use one of the other open
382 functions.
383
384 \warning If \a f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
385 be able to seek. size() is set to \c INT_MAX (in limits.h).
386
387 \sa close()
388*/
389
390
391bool QFile::open( int m, int f )
392{
393 if ( isOpen() ) {
394#if defined(QT_CHECK_RANGE)
395 qWarning( "QFile::open: File already open" );
396#endif
397 return FALSE;
398 }
399 init();
400 setMode( m |IO_Raw );
401 setState( IO_Open );
402 fd = f;
403 ext_f = TRUE;
404 struct stat st;
405 ::fstat( fd, &st );
406 ioIndex = (Offset)::lseek(fd, 0, SEEK_CUR);
407 if ( (st.st_mode & S_IFMT) != S_IFREG || f == 0 ) { // stdin is not seekable...
408 // non-seekable
409 setType( IO_Sequential );
410 length = INT_MAX;
411 ioIndex = 0;
412 } else {
413 length = (Offset)st.st_size;
414 if ( length == 0 && isReadable() ) {
415 // try if you can read from it (if you can, it's a sequential
416 // device; e.g. a file in the /proc filesystem)
417 int c = getch();
418 if ( c != -1 ) {
419 ungetch(c);
420 setType( IO_Sequential );
421 length = INT_MAX;
422 ioIndex = 0;
423 }
424 resetStatus();
425 }
426 }
427 return TRUE;
428}
429
430/*!
431 Returns the file size.
432 \sa at()
433*/
434
435QIODevice::Offset QFile::size() const
436{
437 struct stat st;
438 if ( isOpen() ) {
439 ::fstat( fh ? fileno(fh) : fd, &st );
440 } else {
441 ::stat( QFile::encodeName(fn), &st );
442 }
443#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET)
444 return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size;
445#else
446 return st.st_size;
447#endif
448}
449
450
451/*!
452 \overload
453
454 Sets the file index to \a pos. Returns TRUE if successful;
455 otherwise returns FALSE.
456
457 Example:
458 \code
459 QFile f( "data.bin" );
460 f.open( IO_ReadOnly ); // index set to 0
461 f.at( 100 ); // set index to 100
462 f.at( f.at()+50 ); // set index to 150
463 f.at( f.size()-80 ); // set index to 80 before EOF
464 f.close();
465 \endcode
466
467 Use \c at() without arguments to retrieve the file offset.
468
469 \warning The result is undefined if the file was open()'ed using
470 the \c IO_Append specifier.
471
472 \sa size(), open()
473*/
474
475bool QFile::at( Offset pos )
476{
477 if ( !isOpen() ) {
478#if defined(QT_CHECK_STATE)
479 qWarning( "QFile::at: File is not open" );
480#endif
481 return FALSE;
482 }
483 if ( isSequentialAccess() )
484 return FALSE;
485 bool ok;
486 if ( isRaw() ) {
487 off_t l = ::lseek( fd, pos, SEEK_SET );
488 ok = ( l != -1 );
489 pos = (Offset)l;
490 } else { // buffered file
491#if defined(QT_LARGEFILE_SUPPORT)
492 ok = ( ::fseeko(fh, pos, SEEK_SET) == 0 );
493#else
494 ok = ( ::fseek(fh, pos, SEEK_SET) == 0 );
495#endif
496 }
497 if ( ok )
498 ioIndex = pos;
499#if defined(QT_CHECK_RANGE)
500 else
501#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
502 qWarning( "QFile::at: Cannot set file position %llu", pos );
503#else
504 qWarning( "QFile::at: Cannot set file position %lu", pos );
505#endif
506#endif
507 return ok;
508}
509
510/*!
511 \reimp
512
513 \warning We have experienced problems with some C libraries when a buffered
514 file is opened for both reading and writing. If a read operation takes place
515 immediately after a write operation, the read buffer contains garbage data.
516 Worse, the same garbage is written to the file. Calling flush() before
517 readBlock() solved this problem.
518*/
519
520Q_LONG QFile::readBlock( char *p, Q_ULONG len )
521{
522#if defined(QT_CHECK_NULL)
523 if ( !p )
524 qWarning( "QFile::readBlock: Null pointer error" );
525#endif
526#if defined(QT_CHECK_STATE)
527 if ( !isOpen() ) {
528 qWarning( "QFile::readBlock: File not open" );
529 return -1;
530 }
531 if ( !isReadable() ) {
532 qWarning( "QFile::readBlock: Read operation not permitted" );
533 return -1;
534 }
535#endif
536 Q_ULONG nread = 0; // number of bytes read
537 if ( !ungetchBuffer.isEmpty() ) {
538 // need to add these to the returned string.
539 uint l = ungetchBuffer.length();
540 while( nread < l ) {
541 *p = ungetchBuffer[ l - nread - 1 ];
542 p++;
543 nread++;
544 }
545 ungetchBuffer.truncate( l - nread );
546 }
547
548 if ( nread < len ) {
549 if ( isRaw() ) { // raw file
550 nread += ::read( fd, p, len-nread );
551 if ( len && nread <= 0 ) {
552 nread = 0;
553 setStatus(IO_ReadError);
554 }
555 } else { // buffered file
556 nread += fread( p, 1, len-nread, fh );
557 if ( (uint)nread != len ) {
558 if ( ferror( fh ) || nread==0 )
559 setStatus(IO_ReadError);
560 }
561 }
562 }
563 if ( !isSequentialAccess() )
564 ioIndex += nread;
565 return nread;
566}
567
568
569/*! \reimp
570
571 Writes \a len bytes from \a p to the file and returns the number of
572 bytes actually written.
573
574 Returns -1 if a serious error occurred.
575
576 \warning When working with buffered files, data may not be written
577 to the file at once. Call flush() to make sure the data is really
578 written.
579
580 \sa readBlock()
581*/
582
583Q_LONG QFile::writeBlock( const char *p, Q_ULONG len )
584{
585#if defined(QT_CHECK_NULL)
586 if ( p == 0 && len != 0 )
587 qWarning( "QFile::writeBlock: Null pointer error" );
588#endif
589#if defined(QT_CHECK_STATE)
590 if ( !isOpen() ) { // file not open
591 qWarning( "QFile::writeBlock: File not open" );
592 return -1;
593 }
594 if ( !isWritable() ) { // writing not permitted
595 qWarning( "QFile::writeBlock: Write operation not permitted" );
596 return -1;
597 }
598#endif
599 Q_ULONG nwritten; // number of bytes written
600 if ( isRaw() ) // raw file
601 nwritten = ::write( fd, (void *)p, len );
602 else // buffered file
603 nwritten = fwrite( p, 1, len, fh );
604 if ( nwritten != len ) { // write error
605 if ( errno == ENOSPC ) // disk is full
606 setStatus( IO_ResourceError );
607 else
608 setStatus( IO_WriteError );
609 if ( !isSequentialAccess() ) {
610 if ( isRaw() ) // recalc file position
611 ioIndex = (Offset)::lseek( fd, 0, SEEK_CUR );
612 else
613#if defined(QT_LARGEFILE_SUPPORT)
614 ioIndex = (Offset)::fseeko( fh, 0, SEEK_CUR );
615#else
616 ioIndex = (Offset)::fseek( fh, 0, SEEK_CUR );
617#endif
618 }
619 } else {
620 if ( !isSequentialAccess() )
621 ioIndex += nwritten;
622 }
623 if ( ioIndex > length ) // update file length
624 length = ioIndex;
625 return nwritten;
626}
627
628/*!
629 Returns the file handle of the file.
630
631 This is a small positive integer, suitable for use with C library
632 functions such as fdopen() and fcntl(), as well as with QSocketNotifier.
633
634 If the file is not open or there is an error, handle() returns -1.
635
636 \sa QSocketNotifier
637*/
638
639int QFile::handle() const
640{
641 if ( !isOpen() )
642 return -1;
643 else if ( fh )
644 return fileno( fh );
645 else
646 return fd;
647}
648
649/*!
650 Closes an open file.
651
652 The file is not closed if it was opened with an existing file handle.
653 If the existing file handle is a \c FILE*, the file is flushed.
654 If the existing file handle is an \c int file descriptor, nothing
655 is done to the file.
656
657 Some "write-behind" filesystems may report an unspecified error on
658 closing the file. These errors only indicate that something may
659 have gone wrong since the previous open(). In such a case status()
660 reports IO_UnspecifiedError after close(), otherwise IO_Ok.
661
662 \sa open(), flush()
663*/
664
665
666void QFile::close()
667{
668 bool ok = FALSE;
669 if ( isOpen() ) { // file is not open
670 if ( fh ) { // buffered file
671 if ( ext_f )
672 ok = fflush( fh ) != -1;// flush instead of closing
673 else
674 ok = fclose( fh ) != -1;
675 } else { // raw file
676 if ( ext_f )
677 ok = TRUE; // cannot close
678 else
679 ok = ::close( fd ) != -1;
680 }
681 init(); // restore internal state
682 }
683 if (!ok)
684 setStatus( IO_UnspecifiedError );
685
686 return;
687}
diff --git a/qmake/tools/qfileinfo.cpp b/qmake/tools/qfileinfo.cpp
new file mode 100644
index 0000000..3af7932
--- a/dev/null
+++ b/qmake/tools/qfileinfo.cpp
@@ -0,0 +1,659 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QFileInfo class
5**
6** Created : 950628
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40#include "qfileinfo.h"
41#include "qdatetime.h"
42#include "qdir.h"
43#include "qfiledefs_p.h"
44#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_QT4)
45#include <limits.h>
46#endif
47
48
49extern bool qt_file_access( const QString& fn, int t );
50
51/*!
52 \class QFileInfo
53 \reentrant
54 \brief The QFileInfo class provides system-independent file information.
55
56 \ingroup io
57
58 QFileInfo provides information about a file's name and position
59 (path) in the file system, its access rights and whether it is a
60 directory or symbolic link, etc. The file's size and last
61 modified/read times are also available.
62
63 A QFileInfo can point to a file with either a relative or an
64 absolute file path. Absolute file paths begin with the directory
65 separator "/" (or with a drive specification on Windows). Relative
66 file names begin with a directory name or a file name and specify
67 a path relative to the current working directory. An example of an
68 absolute path is the string "/tmp/quartz". A relative path might
69 look like "src/fatlib". You can use the function isRelative() to
70 check whether a QFileInfo is using a relative or an absolute file
71 path. You can call the function convertToAbs() to convert a
72 relative QFileInfo's path to an absolute path.
73
74 The file that the QFileInfo works on is set in the constructor or
75 later with setFile(). Use exists() to see if the file exists and
76 size() to get its size.
77
78 To speed up performance, QFileInfo caches information about the
79 file. Because files can be changed by other users or programs, or
80 even by other parts of the same program, there is a function that
81 refreshes the file information: refresh(). If you want to switch
82 off a QFileInfo's caching and force it to access the file system
83 every time you request information from it call setCaching(FALSE).
84
85 The file's type is obtained with isFile(), isDir() and
86 isSymLink(). The readLink() function provides the name of the file
87 the symlink points to.
88
89 Elements of the file's name can be extracted with dirPath() and
90 fileName(). The fileName()'s parts can be extracted with
91 baseName() and extension().
92
93 The file's dates are returned by created(), lastModified() and
94 lastRead(). Information about the file's access permissions is
95 obtained with isReadable(), isWritable() and isExecutable(). The
96 file's ownership is available from owner(), ownerId(), group() and
97 groupId(). You can examine a file's permissions and ownership in a
98 single statement using the permission() function.
99
100 If you need to read and traverse directories, see the QDir class.
101*/
102
103/*!
104 \enum QFileInfo::PermissionSpec
105
106 This enum is used by the permission() function to report the
107 permissions and ownership of a file. The values may be OR-ed
108 together to test multiple permissions and ownership values.
109
110 \value ReadUser The file is readable by the user.
111 \value WriteUser The file is writable by the user.
112 \value ExeUser The file is executable by the user.
113 \value ReadGroup The file is readable by the group.
114 \value WriteGroup The file is writable by the group.
115 \value ExeGroup The file is executable by the group.
116 \value ReadOther The file is readable by anyone.
117 \value WriteOther The file is writable by anyone.
118 \value ExeOther The file is executable by anyone.
119*/
120
121
122/*!
123 Constructs a new empty QFileInfo.
124*/
125
126QFileInfo::QFileInfo()
127{
128 fic = 0;
129 cache = TRUE;
130#if defined(Q_OS_UNIX)
131 symLink = FALSE;
132#endif
133}
134
135/*!
136 Constructs a new QFileInfo that gives information about the given
137 file. The \a file can also include an absolute or relative path.
138
139 \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
140*/
141
142QFileInfo::QFileInfo( const QString &file )
143{
144 fn = file;
145 slashify( fn );
146 fic = 0;
147 cache = TRUE;
148#if defined(Q_OS_UNIX)
149 symLink = FALSE;
150#endif
151}
152
153/*!
154 Constructs a new QFileInfo that gives information about file \a
155 file.
156
157 If the \a file has a relative path, the QFileInfo will also have a
158 relative path.
159
160 \sa isRelative()
161*/
162
163QFileInfo::QFileInfo( const QFile &file )
164{
165 fn = file.name();
166 slashify( fn );
167 fic = 0;
168 cache = TRUE;
169#if defined(Q_OS_UNIX)
170 symLink = FALSE;
171#endif
172}
173
174/*!
175 Constructs a new QFileInfo that gives information about the file
176 called \a fileName in the directory \a d.
177
178 If \a d has a relative path, the QFileInfo will also have a
179 relative path.
180
181 \sa isRelative()
182*/
183#ifndef QT_NO_DIR
184QFileInfo::QFileInfo( const QDir &d, const QString &fileName )
185{
186 fn = d.filePath( fileName );
187 slashify( fn );
188 fic = 0;
189 cache = TRUE;
190#if defined(Q_OS_UNIX)
191 symLink = FALSE;
192#endif
193}
194#endif
195/*!
196 Constructs a new QFileInfo that is a copy of \a fi.
197*/
198
199QFileInfo::QFileInfo( const QFileInfo &fi )
200{
201 fn = fi.fn;
202 if ( fi.fic ) {
203 fic = new QFileInfoCache;
204 *fic = *fi.fic;
205 } else {
206 fic = 0;
207 }
208 cache = fi.cache;
209#if defined(Q_OS_UNIX)
210 symLink = fi.symLink;
211#endif
212}
213
214/*!
215 Destroys the QFileInfo and frees its resources.
216*/
217
218QFileInfo::~QFileInfo()
219{
220 delete fic;
221}
222
223
224/*!
225 Makes a copy of \a fi and assigns it to this QFileInfo.
226*/
227
228QFileInfo &QFileInfo::operator=( const QFileInfo &fi )
229{
230 fn = fi.fn;
231 if ( !fi.fic ) {
232 delete fic;
233 fic = 0;
234 } else {
235 if ( !fic ) {
236 fic = new QFileInfoCache;
237 Q_CHECK_PTR( fic );
238 }
239 *fic = *fi.fic;
240 }
241 cache = fi.cache;
242#if defined(Q_OS_UNIX)
243 symLink = fi.symLink;
244#endif
245 return *this;
246}
247
248
249/*!
250 Sets the file that the QFileInfo provides information about to \a
251 file.
252
253 The \a file can also include an absolute or relative file path.
254 Absolute paths begin with the directory separator (e.g. "/" under
255 Unix) or a drive specification (under Windows). Relative file
256 names begin with a directory name or a file name and specify a
257 path relative to the current directory.
258
259 Example:
260 \code
261 QString absolute = "/local/bin";
262 QString relative = "local/bin";
263 QFileInfo absFile( absolute );
264 QFileInfo relFile( relative );
265
266 QDir::setCurrent( QDir::rootDirPath() );
267 // absFile and relFile now point to the same file
268
269 QDir::setCurrent( "/tmp" );
270 // absFile now points to "/local/bin",
271 // while relFile points to "/tmp/local/bin"
272 \endcode
273
274 \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
275*/
276
277void QFileInfo::setFile( const QString &file )
278{
279 fn = file;
280 slashify( fn );
281 delete fic;
282 fic = 0;
283}
284
285/*!
286 \overload
287
288 Sets the file that the QFileInfo provides information about to \a
289 file.
290
291 If \a file includes a relative path, the QFileInfo will also have
292 a relative path.
293
294 \sa isRelative()
295*/
296
297void QFileInfo::setFile( const QFile &file )
298{
299 fn= file.name();
300 slashify( fn );
301 delete fic;
302 fic = 0;
303}
304
305/*!
306 \overload
307
308 Sets the file that the QFileInfo provides information about to \a
309 fileName in directory \a d.
310
311 If \a fileName includes a relative path, the QFileInfo will also
312 have a relative path.
313
314 \sa isRelative()
315*/
316#ifndef QT_NO_DIR
317void QFileInfo::setFile( const QDir &d, const QString &fileName )
318{
319 fn= d.filePath( fileName );
320 slashify( fn );
321 delete fic;
322 fic = 0;
323}
324#endif
325
326/*!
327 Returns TRUE if the file exists; otherwise returns FALSE.
328*/
329
330bool QFileInfo::exists() const
331{
332 return qt_file_access( fn, F_OK );
333}
334
335/*!
336 Refreshes the information about the file, i.e. reads in information
337 from the file system the next time a cached property is fetched.
338
339 \sa setCaching()
340*/
341
342void QFileInfo::refresh() const
343{
344 QFileInfo *that = (QFileInfo*)this; // Mutable function
345 delete that->fic;
346 that->fic = 0;
347}
348
349/*!
350 \fn bool QFileInfo::caching() const
351
352 Returns TRUE if caching is enabled; otherwise returns FALSE.
353
354 \sa setCaching(), refresh()
355*/
356
357/*!
358 If \a enable is TRUE, enables caching of file information. If \a
359 enable is FALSE caching is disabled.
360
361 When caching is enabled, QFileInfo reads the file information from
362 the file system the first time it's needed, but generally not
363 later.
364
365 Caching is enabled by default.
366
367 \sa refresh(), caching()
368*/
369
370void QFileInfo::setCaching( bool enable )
371{
372 if ( cache == enable )
373 return;
374 cache = enable;
375 if ( cache ) {
376 delete fic;
377 fic = 0;
378 }
379}
380
381
382/*!
383 Returns the file name, including the path (which may be absolute
384 or relative).
385
386 \sa isRelative(), absFilePath()
387*/
388
389QString QFileInfo::filePath() const
390{
391 return fn;
392}
393
394/*!
395 Returns the base name of the file.
396
397 If \a complete is FALSE (the default) the base name consists of
398 all characters in the file name up to (but not including) the \e
399 first '.' character.
400
401 If \a complete is TRUE the base name consists of all characters in
402 the file up to (but not including) the \e last '.' character.
403
404 The path is not included in either case.
405
406 Example:
407 \code
408 QFileInfo fi( "/tmp/archive.tar.gz" );
409 QString base = fi.baseName(); // base = "archive"
410 base = fi.baseName( TRUE ); // base = "archive.tar"
411 \endcode
412
413 \sa fileName(), extension()
414*/
415
416QString QFileInfo::baseName( bool complete ) const
417{
418 QString tmp = fileName();
419 int pos = complete ? tmp.findRev( '.' ) : tmp.find( '.' );
420 if ( pos == -1 )
421 return tmp;
422 else
423 return tmp.left( pos );
424}
425
426/*!
427 Returns the file's extension name.
428
429 If \a complete is TRUE (the default), extension() returns the
430 string of all characters in the file name after (but not
431 including) the first '.' character.
432
433 If \a complete is FALSE, extension() returns the string of all
434 characters in the file name after (but not including) the last '.'
435 character.
436
437 Example:
438 \code
439 QFileInfo fi( "/tmp/archive.tar.gz" );
440 QString ext = fi.extension(); // ext = "tar.gz"
441 ext = fi.extension( FALSE ); // ext = "gz"
442 \endcode
443
444 \sa fileName(), baseName()
445*/
446
447QString QFileInfo::extension( bool complete ) const
448{
449 QString s = fileName();
450 int pos = complete ? s.find( '.' ) : s.findRev( '.' );
451 if ( pos < 0 )
452 return QString::fromLatin1( "" );
453 else
454 return s.right( s.length() - pos - 1 );
455}
456
457/*!
458 Returns the file's path as a QDir object.
459
460 If the QFileInfo is relative and \a absPath is FALSE, the QDir
461 will be relative; otherwise it will be absolute.
462
463 \sa dirPath(), filePath(), fileName(), isRelative()
464*/
465#ifndef QT_NO_DIR
466QDir QFileInfo::dir( bool absPath ) const
467{
468 return QDir( dirPath(absPath) );
469}
470#endif
471
472
473/*!
474 Returns TRUE if the file is readable; otherwise returns FALSE.
475
476 \sa isWritable(), isExecutable(), permission()
477*/
478
479bool QFileInfo::isReadable() const
480{
481 return qt_file_access( fn, R_OK ) && permission( ReadUser );
482}
483
484/*!
485 Returns TRUE if the file is writable; otherwise returns FALSE.
486
487 \sa isReadable(), isExecutable(), permission()
488*/
489
490bool QFileInfo::isWritable() const
491{
492 return qt_file_access( fn, W_OK ) && permission( WriteUser );
493}
494
495/*!
496 Returns TRUE if the file is executable; otherwise returns FALSE.
497
498 \sa isReadable(), isWritable(), permission()
499*/
500
501bool QFileInfo::isExecutable() const
502{
503 return qt_file_access( fn, X_OK ) && permission( ExeUser );
504}
505
506#ifndef Q_WS_WIN
507bool QFileInfo::isHidden() const
508{
509 return fileName()[ 0 ] == QChar( '.' );
510}
511#endif
512
513/*!
514 Returns TRUE if the file path name is relative. Returns FALSE if
515 the path is absolute (e.g. under Unix a path is absolute if it
516 begins with a "/").
517*/
518#ifndef QT_NO_DIR
519bool QFileInfo::isRelative() const
520{
521 return QDir::isRelativePath( fn );
522}
523
524/*!
525 Converts the file's path to an absolute path.
526
527 If it is already absolute, nothing is done.
528
529 \sa filePath(), isRelative()
530*/
531
532bool QFileInfo::convertToAbs()
533{
534 if ( isRelative() )
535 fn = absFilePath();
536 return QDir::isRelativePath( fn );
537}
538#endif
539
540/*!
541 Returns the file size in bytes, or 0 if the file does not exist or
542 if the size is 0 or if the size cannot be fetched.
543*/
544#if defined(QT_ABI_QT4)
545QIODevice::Offset QFileInfo::size() const
546#else
547uint QFileInfo::size() const
548#endif
549{
550 if ( !fic || !cache )
551 doStat();
552 if ( fic )
553#if defined(QT_ABI_QT4)
554 return (QIODevice::Offset)fic->st.st_size;
555#elif defined(QT_LARGEFILE_SUPPORT)
556 return (uint)fic->st.st_size > UINT_MAX ? UINT_MAX : (uint)fic->st.st_size;
557#else
558 return (uint)fic->st.st_size;
559#endif
560 else
561 return 0;
562}
563
564/*!
565 Returns the date and time when the file was created.
566
567 On platforms where this information is not available, returns the
568 same as lastModified().
569
570 \sa created() lastModified() lastRead()
571*/
572
573QDateTime QFileInfo::created() const
574{
575 QDateTime dt;
576 if ( !fic || !cache )
577 doStat();
578 if ( fic && fic->st.st_ctime != 0 ) {
579 dt.setTime_t( fic->st.st_ctime );
580 return dt;
581 } else {
582 return lastModified();
583 }
584}
585
586/*!
587 Returns the date and time when the file was last modified.
588
589 \sa created() lastModified() lastRead()
590*/
591
592QDateTime QFileInfo::lastModified() const
593{
594 QDateTime dt;
595 if ( !fic || !cache )
596 doStat();
597 if ( fic )
598 dt.setTime_t( fic->st.st_mtime );
599 return dt;
600}
601
602/*!
603 Returns the date and time when the file was last read (accessed).
604
605 On platforms where this information is not available, returns the
606 same as lastModified().
607
608 \sa created() lastModified() lastRead()
609*/
610
611QDateTime QFileInfo::lastRead() const
612{
613 QDateTime dt;
614 if ( !fic || !cache )
615 doStat();
616 if ( fic && fic->st.st_atime != 0 ) {
617 dt.setTime_t( fic->st.st_atime );
618 return dt;
619 } else {
620 return lastModified();
621 }
622}
623
624#ifndef QT_NO_DIR
625
626/*!
627 Returns the absolute path including the file name.
628
629 The absolute path name consists of the full path and the file
630 name. On Unix this will always begin with the root, '/',
631 directory. On Windows this will always begin 'D:/' where D is a
632 drive letter, except for network shares that are not mapped to a
633 drive letter, in which case the path will begin '//sharename/'.
634
635 This function returns the same as filePath(), unless isRelative()
636 is TRUE.
637
638 This function can be time consuming under Unix (in the order of
639 milliseconds).
640
641 \sa isRelative(), filePath()
642*/
643QString QFileInfo::absFilePath() const
644{
645 QString tmp;
646 if ( QDir::isRelativePath(fn)
647#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
648 && fn[1] != ':'
649#endif
650 ) {
651 tmp = QDir::currentDirPath();
652 tmp += '/';
653 }
654 tmp += fn;
655 makeAbs( tmp );
656 return QDir::cleanDirPath( tmp );
657}
658
659#endif
diff --git a/qmake/tools/qfileinfo_unix.cpp b/qmake/tools/qfileinfo_unix.cpp
new file mode 100644
index 0000000..f7c3a97
--- a/dev/null
+++ b/qmake/tools/qfileinfo_unix.cpp
@@ -0,0 +1,331 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QFileInfo class
5**
6** Created : 950628
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
23** with the Qt Commercial License Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include "qfileinfo.h"
40#include "qfiledefs_p.h"
41#include "qdatetime.h"
42#include "qdir.h"
43
44#include <limits.h>
45
46
47void QFileInfo::slashify( QString& )
48{
49 return;
50}
51
52
53void QFileInfo::makeAbs( QString & )
54{
55 return;
56}
57
58/*!
59 Returns TRUE if this object points to a file. Returns FALSE if the
60 object points to something which isn't a file, e.g. a directory or
61 a symlink.
62
63 \sa isDir(), isSymLink()
64*/
65bool QFileInfo::isFile() const
66{
67 if ( !fic || !cache )
68 doStat();
69 return fic ? (fic->st.st_mode & S_IFMT) == S_IFREG : FALSE;
70}
71
72/*!
73 Returns TRUE if this object points to a directory or to a symbolic
74 link to a directory; otherwise returns FALSE.
75
76 \sa isFile(), isSymLink()
77*/
78bool QFileInfo::isDir() const
79{
80 if ( !fic || !cache )
81 doStat();
82 return fic ? (fic->st.st_mode & S_IFMT) == S_IFDIR : FALSE;
83}
84
85/*!
86 Returns TRUE if this object points to a symbolic link (or to a
87 shortcut on Windows); otherwise returns FALSE.
88
89 \sa isFile(), isDir(), readLink()
90*/
91
92bool QFileInfo::isSymLink() const
93{
94 if ( !fic || !cache )
95 doStat();
96 return symLink;
97}
98
99/*!
100 Returns the name a symlink (or shortcut on Windows) points to, or
101 a QString::null if the object isn't a symbolic link.
102
103 This name may not represent an existing file; it is only a string.
104 QFileInfo::exists() returns TRUE if the symlink points to an
105 existing file.
106
107 \sa exists(), isSymLink(), isDir(), isFile()
108*/
109
110QString QFileInfo::readLink() const
111{
112 QString r;
113
114#if defined(Q_OS_UNIX) && !defined(Q_OS_OS2EMX)
115 char s[PATH_MAX+1];
116 if ( !isSymLink() )
117 return QString();
118 int len = readlink( QFile::encodeName(fn).data(), s, PATH_MAX );
119 if ( len >= 0 ) {
120 s[len] = '\0';
121 r = QFile::decodeName(s);
122 }
123#endif
124
125 return r;
126}
127
128static const uint nobodyID = (uint) -2;
129
130/*!
131 Returns the owner of the file. On Windows, on systems where files
132 do not have owners, or if an error occurs, QString::null is
133 returned.
134
135 This function can be time consuming under Unix (in the order of
136 milliseconds).
137
138 \sa ownerId(), group(), groupId()
139*/
140
141QString QFileInfo::owner() const
142{
143 passwd *pw = getpwuid( ownerId() );
144 if ( pw )
145 return QFile::decodeName( pw->pw_name );
146 return QString::null;
147}
148
149/*!
150 Returns the id of the owner of the file.
151
152 On Windows and on systems where files do not have owners this
153 function returns ((uint) -2).
154
155 \sa owner(), group(), groupId()
156*/
157
158uint QFileInfo::ownerId() const
159{
160 if ( !fic || !cache )
161 doStat();
162 if ( fic )
163 return fic->st.st_uid;
164 return nobodyID;
165}
166
167/*!
168 Returns the group of the file. On Windows, on systems where files
169 do not have groups, or if an error occurs, QString::null is
170 returned.
171
172 This function can be time consuming under Unix (in the order of
173 milliseconds).
174
175 \sa groupId(), owner(), ownerId()
176*/
177
178QString QFileInfo::group() const
179{
180 struct group *gr = getgrgid( groupId() );
181 if ( gr )
182 return QFile::decodeName( gr->gr_name );
183 return QString::null;
184}
185
186/*!
187 Returns the id of the group the file belongs to.
188
189 On Windows and on systems where files do not have groups this
190 function always returns (uint) -2.
191
192 \sa group(), owner(), ownerId()
193*/
194
195uint QFileInfo::groupId() const
196{
197 if ( !fic || !cache )
198 doStat();
199 if ( fic )
200 return fic->st.st_gid;
201 return nobodyID;
202}
203
204
205/*!
206 Tests for file permissions. The \a permissionSpec argument can be
207 several flags of type \c PermissionSpec OR-ed together to check
208 for permission combinations.
209
210 On systems where files do not have permissions this function
211 always returns TRUE.
212
213 Example:
214 \code
215 QFileInfo fi( "/tmp/archive.tar.gz" );
216 if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
217 qWarning( "I can change the file; my group can read the file.");
218 if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
219 qWarning( "The group or others can change the file!" );
220 \endcode
221
222 \sa isReadable(), isWritable(), isExecutable()
223*/
224
225bool QFileInfo::permission( int permissionSpec ) const
226{
227 if ( !fic || !cache )
228 doStat();
229 if ( fic ) {
230 uint mask = 0;
231 if ( permissionSpec & ReadUser )
232 mask |= S_IRUSR;
233 if ( permissionSpec & WriteUser )
234 mask |= S_IWUSR;
235 if ( permissionSpec & ExeUser )
236 mask |= S_IXUSR;
237 if ( permissionSpec & ReadGroup )
238 mask |= S_IRGRP;
239 if ( permissionSpec & WriteGroup )
240 mask |= S_IWGRP;
241 if ( permissionSpec & ExeGroup )
242 mask |= S_IXGRP;
243 if ( permissionSpec & ReadOther )
244 mask |= S_IROTH;
245 if ( permissionSpec & WriteOther )
246 mask |= S_IWOTH;
247 if ( permissionSpec & ExeOther )
248 mask |= S_IXOTH;
249 if ( mask ) {
250 return (fic->st.st_mode & mask) == mask;
251 } else {
252#if defined(QT_CHECK_NULL)
253 qWarning( "QFileInfo::permission: permissionSpec is 0" );
254#endif
255 return TRUE;
256 }
257 } else {
258 return FALSE;
259 }
260}
261
262void QFileInfo::doStat() const
263{
264 QFileInfo *that = ((QFileInfo*)this);// mutable function
265 if ( !that->fic )
266 that->fic = new QFileInfoCache;
267 that->symLink = FALSE;
268 struct stat *b = &that->fic->st;
269#if defined(Q_OS_UNIX) && defined(S_IFLNK)
270 if ( ::lstat( QFile::encodeName(fn), b ) == 0 ) {
271 if ( S_ISLNK( b->st_mode ) )
272 that->symLink = TRUE;
273 else
274 return;
275 }
276#endif
277
278 int r = ::stat( QFile::encodeName(fn), b );
279 if ( r != 0 && !that->symLink ) {
280 delete that->fic;
281 that->fic = 0;
282 }
283}
284
285/*!
286 Returns the file's path.
287
288 If \a absPath is TRUE an absolute path is returned.
289
290 \sa dir(), filePath(), fileName(), isRelative()
291*/
292#ifndef QT_NO_DIR
293QString QFileInfo::dirPath( bool absPath ) const
294{
295 QString s;
296 if ( absPath )
297 s = absFilePath();
298 else
299 s = fn;
300 int pos = s.findRev( '/' );
301 if ( pos == -1 ) {
302 return QString::fromLatin1( "." );
303 } else {
304 if ( pos == 0 )
305 return QString::fromLatin1( "/" );
306 return s.left( pos );
307 }
308}
309#endif
310
311/*!
312 Returns the name of the file, excluding the path.
313
314 Example:
315 \code
316 QFileInfo fi( "/tmp/archive.tar.gz" );
317 QString name = fi.fileName(); // name = "archive.tar.gz"
318 \endcode
319
320 \sa isRelative(), filePath(), baseName(), extension()
321*/
322
323QString QFileInfo::fileName() const
324{
325 int p = fn.findRev( '/' );
326 if ( p == -1 ) {
327 return fn;
328 } else {
329 return fn.mid( p + 1 );
330 }
331}
diff --git a/qmake/tools/qgarray.cpp b/qmake/tools/qgarray.cpp
new file mode 100644
index 0000000..45c45ce
--- a/dev/null
+++ b/qmake/tools/qgarray.cpp
@@ -0,0 +1,754 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QGArray class
5**
6** Created : 930906
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38 #include "qglobal.h" // needed to define Q_WS_WIN
39#ifdef Q_WS_WIN
40 #include "qt_windows.h" // needed for bsearch on some platforms
41#endif
42
43 #define QGARRAY_CPP
44#include "qgarray.h"
45#include <stdlib.h>
46#include <string.h>
47
48#ifdef QT_THREAD_SUPPORT
49# include <private/qmutexpool_p.h>
50#endif // QT_THREAD_SUPPORT
51
52 #define USE_MALLOC // comment to use new/delete
53
54#undef NEW
55#undef DELETE
56
57#if defined(USE_MALLOC)
58 #define NEW(type,size)((type*)malloc(size*sizeof(type)))
59 #define DELETE(array)(free((char*)array))
60#else
61 #define NEW(type,size)(new type[size])
62 #define DELETE(array)(delete[] array)
63 #define DONT_USE_REALLOC // comment to use realloc()
64#endif
65
66/*!
67 \class QShared qshared.h
68 \reentrant
69 \ingroup shared
70 \brief The QShared class is used internally for implementing shared classes.
71
72 \internal
73
74 It only contains a reference count and member functions to increment and
75 decrement it.
76
77 Shared classes normally have internal classes that inherit QShared and
78 add the shared data.
79
80 \sa \link shclass.html Shared Classes\endlink
81*/
82
83/*!
84 \class QGArray qgarray.h
85 \reentrant
86 \ingroup shared
87 \ingroup collection
88 \brief The QGArray class is an internal class for implementing the QMemArray class.
89
90 \internal
91
92 QGArray is a strictly internal class that acts as base class for the
93 QMemArray template array.
94
95 It contains an array of bytes and has no notion of an array element.
96*/
97
98
99/*!
100 Constructs a null array.
101*/
102
103QGArray::QGArray()
104{
105 shd = newData();
106 Q_CHECK_PTR( shd );
107}
108
109/*!
110 Dummy constructor; does not allocate any data.
111
112 This constructor does not initialize any array data so subclasses
113 must do it. The intention is to make the code more efficient.
114*/
115
116QGArray::QGArray( int, int )
117{
118}
119
120/*!
121 Constructs an array with room for \a size bytes.
122*/
123
124QGArray::QGArray( int size )
125{
126 if ( size < 0 ) {
127#if defined(QT_CHECK_RANGE)
128 qWarning( "QGArray: Cannot allocate array with negative length" );
129#endif
130 size = 0;
131 }
132 shd = newData();
133 Q_CHECK_PTR( shd );
134 if ( size == 0 ) // zero length
135 return;
136 shd->data = NEW(char,size);
137 Q_CHECK_PTR( shd->data );
138 shd->len = size;
139}
140
141/*!
142 Constructs a shallow copy of \a a.
143*/
144
145QGArray::QGArray( const QGArray &a )
146{
147 shd = a.shd;
148 shd->ref();
149}
150
151/*!
152 Dereferences the array data and deletes it if this was the last
153 reference.
154*/
155
156QGArray::~QGArray()
157{
158 if ( shd && shd->deref() ) { // delete when last reference
159 if ( shd->data ) // is lost
160 DELETE(shd->data);
161 deleteData( shd );
162 shd = 0;
163 }
164}
165
166
167/*!
168 \fn QGArray &QGArray::operator=( const QGArray &a )
169
170 Assigns a shallow copy of \a a to this array and returns a reference to
171 this array. Equivalent to assign().
172*/
173
174/*!
175 \fn void QGArray::detach()
176
177 Detaches this array from shared array data.
178*/
179
180/*!
181 \fn char *QGArray::data() const
182
183 Returns a pointer to the actual array data.
184*/
185
186/*!
187 \fn uint QGArray::nrefs() const
188
189 Returns the reference count.
190*/
191
192/*!
193 \fn uint QGArray::size() const
194
195 Returns the size of the array, in bytes.
196*/
197
198
199/*!
200 Returns TRUE if this array is equal to \a a, otherwise FALSE.
201 The comparison is bitwise, of course.
202*/
203
204bool QGArray::isEqual( const QGArray &a ) const
205{
206 if ( size() != a.size() ) // different size
207 return FALSE;
208 if ( data() == a.data() ) // has same data
209 return TRUE;
210 return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;
211}
212
213
214/*!
215 Resizes the array to \a newsize bytes.
216*/
217
218bool QGArray::resize( uint newsize )
219{
220 if ( newsize == shd->len ) // nothing to do
221 return TRUE;
222 if ( newsize == 0 ) { // remove array
223 duplicate( 0, 0 );
224 return TRUE;
225 }
226 if ( shd->data ) { // existing data
227#if defined(DONT_USE_REALLOC)
228 char *newdata = NEW(char,newsize);// manual realloc
229 memcpy( newdata, shd->data, QMIN(shd->len,newsize) );
230 DELETE(shd->data);
231 shd->data = newdata;
232#else
233 shd->data = (char *)realloc( shd->data, newsize );
234#endif
235 } else {
236 shd->data = NEW(char,newsize);
237 }
238 if ( !shd->data ) // no memory
239 return FALSE;
240 shd->len = newsize;
241 return TRUE;
242}
243
244/*!
245 Fills the array with the repeated occurrences of \a d, which is
246 \a sz bytes long.
247 If \a len is specified as different from -1, then the array will be
248 resized to \a len*sz before it is filled.
249
250 Returns TRUE if successful, or FALSE if the memory cannot be allocated
251 (only when \a len != -1).
252
253 \sa resize()
254*/
255
256bool QGArray::fill( const char *d, int len, uint sz )
257{
258 if ( len < 0 )
259 len = shd->len/sz; // default: use array length
260 else if ( !resize( len*sz ) )
261 return FALSE;
262 if ( sz == 1 ) // 8 bit elements
263 memset( data(), *d, len );
264 else if ( sz == 4 ) { // 32 bit elements
265 register Q_INT32 *x = (Q_INT32*)data();
266 Q_INT32 v = *((Q_INT32*)d);
267 while ( len-- )
268 *x++ = v;
269 } else if ( sz == 2 ) { // 16 bit elements
270 register Q_INT16 *x = (Q_INT16*)data();
271 Q_INT16 v = *((Q_INT16*)d);
272 while ( len-- )
273 *x++ = v;
274 } else { // any other size elements
275 register char *x = data();
276 while ( len-- ) { // more complicated
277 memcpy( x, d, sz );
278 x += sz;
279 }
280 }
281 return TRUE;
282}
283
284/*!
285 \overload
286 Shallow copy. Dereference the current array and references the data
287 contained in \a a instead. Returns a reference to this array.
288 \sa operator=()
289*/
290
291QGArray &QGArray::assign( const QGArray &a )
292{
293 a.shd->ref(); // avoid 'a = a'
294 if ( shd->deref() ) { // delete when last reference
295 if ( shd->data ) // is lost
296 DELETE(shd->data);
297 deleteData( shd );
298 }
299 shd = a.shd;
300 return *this;
301}
302
303/*!
304 Shallow copy. Dereference the current array and references the
305 array data \a d, which contains \a len bytes.
306 Returns a reference to this array.
307
308 Do not delete \a d later, because QGArray takes care of that.
309*/
310
311QGArray &QGArray::assign( const char *d, uint len )
312{
313 if ( shd->count > 1 ) { // disconnect this
314 shd->count--;
315 shd = newData();
316 Q_CHECK_PTR( shd );
317 } else {
318 if ( shd->data )
319 DELETE(shd->data);
320 }
321 shd->data = (char *)d;
322 shd->len = len;
323 return *this;
324}
325
326/*!
327 Deep copy. Dereference the current array and obtains a copy of the data
328 contained in \a a instead. Returns a reference to this array.
329 \sa assign(), operator=()
330*/
331
332QGArray &QGArray::duplicate( const QGArray &a )
333{
334 if ( a.shd == shd ) { // a.duplicate(a) !
335 if ( shd->count > 1 ) {
336 shd->count--;
337 register array_data *n = newData();
338 Q_CHECK_PTR( n );
339 if ( (n->len=shd->len) ) {
340 n->data = NEW(char,n->len);
341 Q_CHECK_PTR( n->data );
342 if ( n->data )
343 memcpy( n->data, shd->data, n->len );
344 } else {
345 n->data = 0;
346 }
347 shd = n;
348 }
349 return *this;
350 }
351 char *oldptr = 0;
352 if ( shd->count > 1 ) { // disconnect this
353 shd->count--;
354 shd = newData();
355 Q_CHECK_PTR( shd );
356 } else { // delete after copy was made
357 oldptr = shd->data;
358 }
359 if ( a.shd->len ) { // duplicate data
360 shd->data = NEW(char,a.shd->len);
361 Q_CHECK_PTR( shd->data );
362 if ( shd->data )
363 memcpy( shd->data, a.shd->data, a.shd->len );
364 } else {
365 shd->data = 0;
366 }
367 shd->len = a.shd->len;
368 if ( oldptr )
369 DELETE(oldptr);
370 return *this;
371}
372
373/*!
374 \overload
375 Deep copy. Dereferences the current array and obtains a copy of
376 \a len characters from array data \a d instead. Returns a reference
377 to this array.
378 \sa assign(), operator=()
379*/
380
381QGArray &QGArray::duplicate( const char *d, uint len )
382{
383 char *data;
384 if ( d == 0 || len == 0 ) {
385 data = 0;
386 len = 0;
387 } else {
388 if ( shd->count == 1 && shd->len == len ) {
389 memcpy( shd->data, d, len );// use same buffer
390 return *this;
391 }
392 data = NEW(char,len);
393 Q_CHECK_PTR( data );
394 memcpy( data, d, len );
395 }
396 if ( shd->count > 1 ) { // detach
397 shd->count--;
398 shd = newData();
399 Q_CHECK_PTR( shd );
400 } else { // just a single reference
401 if ( shd->data )
402 DELETE(shd->data);
403 }
404 shd->data = data;
405 shd->len = len;
406 return *this;
407}
408
409/*!
410 Resizes this array to \a len bytes and copies the \a len bytes at
411 address \a d into it.
412
413 \warning This function disregards the reference count mechanism. If
414 other QGArrays reference the same data as this, all will be updated.
415*/
416
417void QGArray::store( const char *d, uint len )
418 { // store, but not deref
419 resize( len );
420 memcpy( shd->data, d, len );
421}
422
423
424/*!
425 \fn array_data *QGArray::sharedBlock() const
426
427 Returns a pointer to the shared array block.
428
429 \warning
430
431 Do not use this function. Using it is begging for trouble. We dare
432 not remove it, for fear of breaking code, but we \e strongly
433 discourage new use of it.
434*/
435
436/*!
437 \fn void QGArray::setSharedBlock( array_data *p )
438
439 Sets the shared array block to \a p.
440
441 \warning
442
443 Do not use this function. Using it is begging for trouble. We dare
444 not remove it, for fear of breaking code, but we \e strongly
445 discourage new use of it.
446*/
447
448
449/*!
450 Sets raw data and returns a reference to the array.
451
452 Dereferences the current array and sets the new array data to \a d and
453 the new array size to \a len. Do not attempt to resize or re-assign the
454 array data when raw data has been set.
455 Call resetRawData(d,len) to reset the array.
456
457 Setting raw data is useful because it sets QMemArray data without
458 allocating memory or copying data.
459
460 Example of intended use:
461 \code
462 static uchar bindata[] = { 231, 1, 44, ... };
463 QByteArraya;
464 a.setRawData( bindata, sizeof(bindata) );// a points to bindata
465 QDataStream s( a, IO_ReadOnly ); // open on a's data
466 s >> <something>; // read raw bindata
467 s.close();
468 a.resetRawData( bindata, sizeof(bindata) ); // finished
469 \endcode
470
471 Example of misuse (do not do this):
472 \code
473 static uchar bindata[] = { 231, 1, 44, ... };
474 QByteArraya, b;
475 a.setRawData( bindata, sizeof(bindata) );// a points to bindata
476 a.resize( 8 ); // will crash
477 b = a; // will crash
478 a[2] = 123; // might crash
479 // forget to resetRawData - will crash
480 \endcode
481
482 \warning If you do not call resetRawData(), QGArray will attempt to
483 deallocate or reallocate the raw data, which might not be too good.
484 Be careful.
485*/
486
487QGArray &QGArray::setRawData( const char *d, uint len )
488{
489 duplicate( 0, 0 ); // set null data
490 shd->data = (char *)d;
491 shd->len = len;
492 return *this;
493}
494
495/*!
496 Resets raw data.
497
498 The arguments must be the data, \a d, and length \a len, that were
499 passed to setRawData(). This is for consistency checking.
500*/
501
502void QGArray::resetRawData( const char *d, uint len )
503{
504 if ( d != shd->data || len != shd->len ) {
505#if defined(QT_CHECK_STATE)
506 qWarning( "QGArray::resetRawData: Inconsistent arguments" );
507#endif
508 return;
509 }
510 shd->data = 0;
511 shd->len = 0;
512}
513
514
515/*!
516 Finds the first occurrence of \a d in the array from position \a index,
517 where \a sz is the size of the \a d element.
518
519 Note that \a index is given in units of \a sz, not bytes.
520
521 This function only compares whole cells, not bytes.
522*/
523
524int QGArray::find( const char *d, uint index, uint sz ) const
525{
526 index *= sz;
527 if ( index >= shd->len ) {
528#if defined(QT_CHECK_RANGE)
529 qWarning( "QGArray::find: Index %d out of range", index/sz );
530#endif
531 return -1;
532 }
533 register uint i;
534 uint ii;
535 switch ( sz ) {
536 case 1: { // 8 bit elements
537 register char *x = data() + index;
538 char v = *d;
539 for ( i=index; i<shd->len; i++ ) {
540 if ( *x++ == v )
541 break;
542 }
543 ii = i;
544 }
545 break;
546 case 2: { // 16 bit elements
547 register Q_INT16 *x = (Q_INT16*)(data() + index);
548 Q_INT16 v = *((Q_INT16*)d);
549 for ( i=index; i<shd->len; i+=2 ) {
550 if ( *x++ == v )
551 break;
552 }
553 ii = i/2;
554 }
555 break;
556 case 4: { // 32 bit elements
557 register Q_INT32 *x = (Q_INT32*)(data() + index);
558 Q_INT32 v = *((Q_INT32*)d);
559 for ( i=index; i<shd->len; i+=4 ) {
560 if ( *x++ == v )
561 break;
562 }
563 ii = i/4;
564 }
565 break;
566 default: { // any size elements
567 for ( i=index; i<shd->len; i+=sz ) {
568 if ( memcmp( d, &shd->data[i], sz ) == 0 )
569 break;
570 }
571 ii = i/sz;
572 }
573 break;
574 }
575 return i<shd->len ? (int)ii : -1;
576}
577
578/*!
579 Returns the number of occurrences of \a d in the array, where \a sz is
580 the size of the \a d element.
581
582 This function only compares whole cells, not bytes.
583*/
584
585int QGArray::contains( const char *d, uint sz ) const
586{
587 register uint i = shd->len;
588 int count = 0;
589 switch ( sz ) {
590 case 1: { // 8 bit elements
591 register char *x = data();
592 char v = *d;
593 while ( i-- ) {
594 if ( *x++ == v )
595 count++;
596 }
597 }
598 break;
599 case 2: { // 16 bit elements
600 register Q_INT16 *x = (Q_INT16*)data();
601 Q_INT16 v = *((Q_INT16*)d);
602 i /= 2;
603 while ( i-- ) {
604 if ( *x++ == v )
605 count++;
606 }
607 }
608 break;
609 case 4: { // 32 bit elements
610 register Q_INT32 *x = (Q_INT32*)data();
611 Q_INT32 v = *((Q_INT32*)d);
612 i /= 4;
613 while ( i-- ) {
614 if ( *x++ == v )
615 count++;
616 }
617 }
618 break;
619 default: { // any size elements
620 for ( i=0; i<shd->len; i+=sz ) {
621 if ( memcmp(d, &shd->data[i], sz) == 0 )
622 count++;
623 }
624 }
625 break;
626 }
627 return count;
628}
629
630static int cmp_item_size = 0;
631
632#if defined(Q_C_CALLBACKS)
633extern "C" {
634#endif
635
636#ifdef Q_OS_TEMP
637static int __cdecl cmp_arr( const void *n1, const void *n2 )
638#else
639static int cmp_arr( const void *n1, const void *n2 )
640#endif
641{
642 return ( n1 && n2 ) ? memcmp( n1, n2, cmp_item_size )
643 : ( n1 ? 1 : ( n2 ? -1 : 0 ) );
644 // ### Qt 3.0: Add a virtual compareItems() method and call that instead
645}
646
647#if defined(Q_C_CALLBACKS)
648}
649#endif
650
651/*!
652 Sorts the first \a sz items of the array.
653*/
654
655void QGArray::sort( uint sz )
656{
657 int numItems = size() / sz;
658 if ( numItems < 2 )
659 return;
660
661#ifdef QT_THREAD_SUPPORT
662 QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) );
663#endif // QT_THREAD_SUPPORT
664
665 cmp_item_size = sz;
666 qsort( shd->data, numItems, sz, cmp_arr );
667}
668
669/*!
670 Binary search; assumes that \a d is a sorted array of size \a sz.
671*/
672
673int QGArray::bsearch( const char *d, uint sz ) const
674{
675 int numItems = size() / sz;
676 if ( !numItems )
677 return -1;
678
679#ifdef QT_THREAD_SUPPORT
680 QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) );
681#endif // QT_THREAD_SUPPORT
682
683 cmp_item_size = sz;
684 char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr );
685 if ( !r )
686 return -1;
687 while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) )
688 r -= sz;// search to first of equal elements; bsearch is undef
689 return (int)(( r - shd->data ) / sz);
690}
691
692
693/*!
694 \fn char *QGArray::at( uint index ) const
695
696 Returns a pointer to the byte at offset \a index in the array.
697*/
698
699/*!
700 Expand the array if necessary, and copies (the first part of) its
701 contents from the \a index * \a sz bytes at \a d.
702
703 Returns TRUE if the operation succeeds, FALSE if it runs out of
704 memory.
705
706 \warning This function disregards the reference count mechanism. If
707 other QGArrays reference the same data as this, all will be changed.
708*/
709
710bool QGArray::setExpand( uint index, const char *d, uint sz )
711{
712 index *= sz;
713 if ( index >= shd->len ) {
714 if ( !resize( index+sz ) ) // no memory
715 return FALSE;
716 }
717 memcpy( data() + index, d, sz );
718 return TRUE;
719}
720
721
722/*!
723 Prints a warning message if at() or [] is given a bad index.
724*/
725
726void QGArray::msg_index( uint index )
727{
728#if defined(QT_CHECK_RANGE)
729 qWarning( "QGArray::at: Absolute index %d out of range", index );
730#else
731 Q_UNUSED( index )
732#endif
733}
734
735
736/*!
737 Returns a new shared array block.
738*/
739
740QGArray::array_data * QGArray::newData()
741{
742 return new array_data;
743}
744
745
746/*!
747 Deletes the shared array block, \a p.
748*/
749
750void QGArray::deleteData( array_data *p )
751{
752 delete p;
753 p = 0;
754}
diff --git a/qmake/tools/qgcache.cpp b/qmake/tools/qgcache.cpp
new file mode 100644
index 0000000..84180b0
--- a/dev/null
+++ b/qmake/tools/qgcache.cpp
@@ -0,0 +1,863 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QGCache and QGCacheIterator classes
5**
6** Created : 950208
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qgcache.h"
39#include "qptrlist.h"
40#include "qdict.h"
41#include "qstring.h"
42
43/*!
44 \class QGCache qgcache.h
45 \reentrant
46 \ingroup shared
47 \ingroup collection
48 \brief The QGCache class is an internal class for implementing QCache
49 template classes.
50
51 \internal
52
53 QGCache is a strictly internal class that acts as a base class for the
54 \link collection.html collection classes\endlink QCache and QIntCache.
55*/
56
57
58/*****************************************************************************
59 QGCacheItem class (internal cache item)
60 *****************************************************************************/
61
62struct QCacheItem
63{
64 QCacheItem( void *k, QPtrCollection::Item d, int c, short p )
65 : priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {}
66 shortpriority;
67 shortskipPriority;
68 int cost;
69 void *key;
70 QPtrCollection::Item data;
71 QLNode *node;
72};
73
74
75/*****************************************************************************
76 QCList class (internal list of cache items)
77 *****************************************************************************/
78
79class QCList : private QPtrList<QCacheItem>
80{
81friend class QGCacheIterator;
82friend class QCListIt;
83public:
84 QCList(){}
85 ~QCList();
86
87 void insert( QCacheItem * ); // insert according to priority
88 voidinsert( int, QCacheItem * );
89 voidtake( QCacheItem * );
90 voidreference( QCacheItem * );
91
92 voidsetAutoDelete( bool del ) { QPtrCollection::setAutoDelete(del); }
93
94 bool removeFirst(){ return QPtrList<QCacheItem>::removeFirst(); }
95 bool removeLast(){ return QPtrList<QCacheItem>::removeLast(); }
96
97 QCacheItem *first() { return QPtrList<QCacheItem>::first(); }
98 QCacheItem *last() { return QPtrList<QCacheItem>::last(); }
99 QCacheItem *prev() { return QPtrList<QCacheItem>::prev(); }
100 QCacheItem *next() { return QPtrList<QCacheItem>::next(); }
101
102#if defined(QT_DEBUG)
103 int inserts; // variables for statistics
104 int insertCosts;
105 int insertMisses;
106 int finds;
107 int hits;
108 int hitCosts;
109 int dumps;
110 int dumpCosts;
111#endif
112};
113
114
115QCList::~QCList()
116{
117#if defined(QT_DEBUG)
118 Q_ASSERT( count() == 0 );
119#endif
120}
121
122
123void QCList::insert( QCacheItem *ci )
124{
125 QCacheItem *item = first();
126 while( item && item->skipPriority > ci->priority ) {
127 item->skipPriority--;
128 item = next();
129 }
130 if ( item )
131 QPtrList<QCacheItem>::insert( at(), ci );
132 else
133 append( ci );
134#if defined(QT_DEBUG)
135 Q_ASSERT( ci->node == 0 );
136#endif
137 ci->node = currentNode();
138}
139
140inline void QCList::insert( int i, QCacheItem *ci )
141{
142 QPtrList<QCacheItem>::insert( i, ci );
143#if defined(QT_DEBUG)
144 Q_ASSERT( ci->node == 0 );
145#endif
146 ci->node = currentNode();
147}
148
149
150void QCList::take( QCacheItem *ci )
151{
152 if ( ci ) {
153#if defined(QT_DEBUG)
154 Q_ASSERT( ci->node != 0 );
155#endif
156 takeNode( ci->node );
157 ci->node = 0;
158 }
159}
160
161
162inline void QCList::reference( QCacheItem *ci )
163{
164#if defined(QT_DEBUG)
165 Q_ASSERT( ci != 0 && ci->node != 0 );
166#endif
167 ci->skipPriority = ci->priority;
168 relinkNode( ci->node ); // relink as first item
169}
170
171
172class QCListIt: public QPtrListIterator<QCacheItem>
173{
174public:
175 QCListIt( const QCList *p ): QPtrListIterator<QCacheItem>( *p ) {}
176 QCListIt( const QCListIt *p ): QPtrListIterator<QCacheItem>( *p ) {}
177};
178
179
180/*****************************************************************************
181 QCDict class (internal dictionary of cache items)
182 *****************************************************************************/
183
184//
185// Since we need to decide if the dictionary should use an int or const
186// char * key (the "bool trivial" argument in the constructor below)
187// we cannot use the macro/template dict, but inherit directly from QGDict.
188//
189
190class QCDict : public QGDict
191{
192public:
193 QCDict( uint size, uint kt, bool caseSensitive, bool copyKeys )
194 : QGDict( size, (KeyType)kt, caseSensitive, copyKeys ) {}
195 ~QCDict();
196
197 void clear() { QGDict::clear(); }
198
199 QCacheItem *find_string(const QString &key) const
200 { return (QCacheItem*)((QCDict*)this)->look_string(key, 0, 0); }
201 QCacheItem *find_ascii(const char *key) const
202 { return (QCacheItem*)((QCDict*)this)->look_ascii(key, 0, 0); }
203 QCacheItem *find_int(long key) const
204 { return (QCacheItem*)((QCDict*)this)->look_int(key, 0, 0); }
205
206 QCacheItem *take_string(const QString &key)
207 { return (QCacheItem*)QGDict::take_string(key); }
208 QCacheItem *take_ascii(const char *key)
209 { return (QCacheItem*)QGDict::take_ascii(key); }
210 QCacheItem *take_int(long key)
211 { return (QCacheItem*)QGDict::take_int(key); }
212
213 bool insert_string( const QString &key, const QCacheItem *ci )
214 { return QGDict::look_string(key,(Item)ci,1)!=0;}
215 bool insert_ascii( const char *key, const QCacheItem *ci )
216 { return QGDict::look_ascii(key,(Item)ci,1)!=0;}
217 bool insert_int( long key, const QCacheItem *ci )
218 { return QGDict::look_int(key,(Item)ci,1)!=0;}
219
220 bool remove_string( QCacheItem *item )
221 { return QGDict::remove_string(*((QString*)(item->key)),item); }
222 bool remove_ascii( QCacheItem *item )
223 { return QGDict::remove_ascii((const char *)item->key,item); }
224 bool remove_int( QCacheItem *item )
225 { return QGDict::remove_int((long)item->key,item);}
226
227 void statistics() { QGDict::statistics(); }
228
229private:
230 void deleteItem( void *item )
231 { if ( del_item ) { QCacheItem *d = (QCacheItem*)item; delete d; } }
232};
233
234inline QCDict::~QCDict()
235{
236 clear();
237}
238
239/*****************************************************************************
240 QGDict member functions
241 *****************************************************************************/
242
243/*!
244 Constructs a cache.
245 The maximum cost of the cache is given by \a maxCost and the size by \a
246 size. The key type is \a kt which may be \c StringKey, \c AsciiKey,
247 \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with
248 \a caseSensitive. Keys are copied if \a copyKeys is TRUE.
249*/
250
251QGCache::QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
252 bool copyKeys )
253{
254 keytype = kt;
255 lruList = new QCList;
256 Q_CHECK_PTR( lruList );
257 lruList->setAutoDelete( TRUE );
258 copyk = ((keytype == AsciiKey) && copyKeys);
259 dict = new QCDict( size, kt, caseSensitive, FALSE );
260 Q_CHECK_PTR( dict );
261 mCost = maxCost;
262 tCost = 0;
263#if defined(QT_DEBUG)
264 lruList->inserts = 0;
265 lruList->insertCosts = 0;
266 lruList->insertMisses = 0;
267 lruList->finds = 0;
268 lruList->hits = 0;
269 lruList->hitCosts = 0;
270 lruList->dumps = 0;
271 lruList->dumpCosts = 0;
272#endif
273}
274
275/*!
276 Cannot copy a cache.
277*/
278
279QGCache::QGCache( const QGCache & )
280 : QPtrCollection()
281{
282#if defined(QT_CHECK_NULL)
283 qFatal( "QGCache::QGCache(QGCache &): Cannot copy a cache" );
284#endif
285}
286
287/*!
288 Removes all items from the cache and destroys it.
289*/
290
291QGCache::~QGCache()
292{
293 clear();
294 delete dict;
295 delete lruList;
296}
297
298/*!
299 Cannot assign a cache.
300*/
301
302QGCache &QGCache::operator=( const QGCache & )
303{
304#if defined(QT_CHECK_NULL)
305 qFatal( "QGCache::operator=: Cannot copy a cache" );
306#endif
307 return *this;
308}
309
310
311/*!
312 Returns the number of items in the cache.
313*/
314
315uint QGCache::count() const
316{
317 return dict->count();
318}
319
320/*!
321 Returns the size of the hash array.
322*/
323
324uint QGCache::size() const
325{
326 return dict->size();
327}
328
329/*!
330 \fn int QGCache::maxCost() const
331
332 Returns the maximum cache cost.
333*/
334
335/*!
336 \fn int QGCache::totalCost() const
337
338 Returns the total cache cost.
339*/
340
341/*!
342 Sets the maximum cache cost to \a maxCost.
343*/
344
345void QGCache::setMaxCost( int maxCost )
346{
347 if ( maxCost < tCost ) {
348 if ( !makeRoomFor(tCost - maxCost) )// remove excess cost
349 return;
350 }
351 mCost = maxCost;
352}
353
354
355/*!
356 Inserts an item with data \a data into the cache using key \a key.
357 The item has cost \a cost and priority \a priority.
358
359 \warning If this function returns FALSE, you must delete \a data
360 yourself. Additionally, be very careful about using \a data after
361 calling this function, as any other insertions into the cache, from
362 anywhere in the application, or within Qt itself, could cause the
363 data to be discarded from the cache, and the pointer to become
364 invalid.
365*/
366
367bool QGCache::insert_string( const QString &key, QPtrCollection::Item data,
368 int cost, int priority)
369{
370 if ( tCost + cost > mCost ) {
371 if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
372#if defined(QT_DEBUG)
373 lruList->insertMisses++;
374#endif
375 return FALSE;
376 }
377 }
378#if defined(QT_DEBUG)
379 Q_ASSERT( keytype == StringKey );
380 lruList->inserts++;
381 lruList->insertCosts += cost;
382#endif
383 if ( priority < -32768 )
384 priority = -32768;
385 else if ( priority > 32767 )
386 priority = 32677;
387 QCacheItem *ci = new QCacheItem( new QString(key), newItem(data),
388 cost, (short)priority );
389 Q_CHECK_PTR( ci );
390 lruList->insert( 0, ci );
391 dict->insert_string( key, ci );
392 tCost += cost;
393 return TRUE;
394}
395
396bool QGCache::insert_other( const char *key, QPtrCollection::Item data,
397 int cost, int priority)
398{
399 if ( tCost + cost > mCost ) {
400 if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
401#if defined(QT_DEBUG)
402 lruList->insertMisses++;
403#endif
404 return FALSE;
405 }
406 }
407#if defined(QT_DEBUG)
408 Q_ASSERT( keytype != StringKey );
409 lruList->inserts++;
410 lruList->insertCosts += cost;
411#endif
412 if ( keytype == AsciiKey && copyk )
413 key = qstrdup( key );
414 if ( priority < -32768 )
415 priority = -32768;
416 else if ( priority > 32767 )
417 priority = 32677;
418 QCacheItem *ci = new QCacheItem( (void*)key, newItem(data), cost,
419 (short)priority );
420 Q_CHECK_PTR( ci );
421 lruList->insert( 0, ci );
422 if ( keytype == AsciiKey )
423 dict->insert_ascii( key, ci );
424 else
425 dict->insert_int( (long)key, ci );
426 tCost += cost;
427 return TRUE;
428}
429
430
431/*!
432 Removes the item with key \a key from the cache. Returns TRUE if the
433 item was removed; otherwise returns FALSE.
434*/
435
436bool QGCache::remove_string( const QString &key )
437{
438 Item d = take_string( key );
439 if ( d )
440 deleteItem( d );
441 return d != 0;
442}
443
444bool QGCache::remove_other( const char *key )
445{
446 Item d = take_other( key );
447 if ( d )
448 deleteItem( d );
449 return d != 0;
450}
451
452
453/*!
454 Takes the item with key \a key out of the cache. The item is not
455 deleted. If no item has this \a key 0 is returned.
456*/
457
458QPtrCollection::Item QGCache::take_string( const QString &key )
459{
460 QCacheItem *ci = dict->take_string( key );// take from dict
461 Item d;
462 if ( ci ) {
463 d = ci->data;
464 tCost -= ci->cost;
465 lruList->take( ci ); // take from list
466 delete (QString*)ci->key;
467 delete ci;
468 } else {
469 d = 0;
470 }
471 return d;
472}
473
474/*!
475 Takes the item with key \a key out of the cache. The item is not
476 deleted. If no item has this \a key 0 is returned.
477*/
478
479QPtrCollection::Item QGCache::take_other( const char *key )
480{
481 QCacheItem *ci;
482 if ( keytype == AsciiKey )
483 ci = dict->take_ascii( key );
484 else
485 ci = dict->take_int( (long)key );
486 Item d;
487 if ( ci ) {
488 d = ci->data;
489 tCost -= ci->cost;
490 lruList->take( ci ); // take from list
491 if ( copyk )
492 delete [] (char *)ci->key;
493 delete ci;
494 } else {
495 d = 0;
496 }
497 return d;
498}
499
500
501/*!
502 Clears the cache.
503*/
504
505void QGCache::clear()
506{
507 QCacheItem *ci;
508 while ( (ci = lruList->first()) ) {
509 switch ( keytype ) {
510 case StringKey:
511 dict->remove_string( ci );
512 delete (QString*)ci->key;
513 break;
514 case AsciiKey:
515 dict->remove_ascii( ci );
516 if ( copyk )
517 delete [] (char*)ci->key;
518 break;
519 case IntKey:
520 dict->remove_int( ci );
521 break;
522 case PtrKey: // unused
523 break;
524 }
525 deleteItem( ci->data ); // delete data
526 lruList->removeFirst(); // remove from list
527 }
528 tCost = 0;
529}
530
531
532/*!
533 Finds an item for \a key in the cache and adds a reference if \a ref is TRUE.
534*/
535
536QPtrCollection::Item QGCache::find_string( const QString &key, bool ref ) const
537{
538 QCacheItem *ci = dict->find_string( key );
539#if defined(QT_DEBUG)
540 lruList->finds++;
541#endif
542 if ( ci ) {
543#if defined(QT_DEBUG)
544 lruList->hits++;
545 lruList->hitCosts += ci->cost;
546#endif
547 if ( ref )
548 lruList->reference( ci );
549 return ci->data;
550 }
551 return 0;
552}
553
554
555/*!
556 Finds an item for \a key in the cache and adds a reference if \a ref is TRUE.
557*/
558
559QPtrCollection::Item QGCache::find_other( const char *key, bool ref ) const
560{
561 QCacheItem *ci = keytype == AsciiKey ? dict->find_ascii(key)
562 : dict->find_int((long)key);
563#if defined(QT_DEBUG)
564 lruList->finds++;
565#endif
566 if ( ci ) {
567#if defined(QT_DEBUG)
568 lruList->hits++;
569 lruList->hitCosts += ci->cost;
570#endif
571 if ( ref )
572 lruList->reference( ci );
573 return ci->data;
574 }
575 return 0;
576}
577
578
579/*!
580 Allocates cache space for one or more items.
581*/
582
583bool QGCache::makeRoomFor( int cost, int priority )
584{
585 if ( cost > mCost ) // cannot make room for more
586 return FALSE; // than maximum cost
587 if ( priority == -1 )
588 priority = 32767;
589 register QCacheItem *ci = lruList->last();
590 int cntCost = 0;
591 int dumps = 0; // number of items to dump
592 while ( cntCost < cost && ci && ci->skipPriority <= priority ) {
593 cntCost += ci->cost;
594 ci = lruList->prev();
595 dumps++;
596 }
597 if ( cntCost < cost ) // can enough cost be dumped?
598 return FALSE; // no
599#if defined(QT_DEBUG)
600 Q_ASSERT( dumps > 0 );
601#endif
602 while ( dumps-- ) {
603 ci = lruList->last();
604#if defined(QT_DEBUG)
605 lruList->dumps++;
606 lruList->dumpCosts += ci->cost;
607#endif
608 switch ( keytype ) {
609 case StringKey:
610 dict->remove_string( ci );
611 delete (QString*)ci->key;
612 break;
613 case AsciiKey:
614 dict->remove_ascii( ci );
615 if ( copyk )
616 delete [] (char *)ci->key;
617 break;
618 case IntKey:
619 dict->remove_int( ci );
620 break;
621 case PtrKey: // unused
622 break;
623 }
624 deleteItem( ci->data ); // delete data
625 lruList->removeLast(); // remove from list
626 }
627 tCost -= cntCost;
628 return TRUE;
629}
630
631
632/*!
633 Outputs debug statistics.
634*/
635
636void QGCache::statistics() const
637{
638#if defined(QT_DEBUG)
639 QString line;
640 line.fill( '*', 80 );
641 qDebug( line.ascii() );
642 qDebug( "CACHE STATISTICS:" );
643 qDebug( "cache contains %d item%s, with a total cost of %d",
644 count(), count() != 1 ? "s" : "", tCost );
645 qDebug( "maximum cost is %d, cache is %d%% full.",
646 mCost, (200*tCost + mCost) / (mCost*2) );
647 qDebug( "find() has been called %d time%s",
648 lruList->finds, lruList->finds != 1 ? "s" : "" );
649 qDebug( "%d of these were hits, items found had a total cost of %d.",
650 lruList->hits,lruList->hitCosts );
651 qDebug( "%d item%s %s been inserted with a total cost of %d.",
652 lruList->inserts,lruList->inserts != 1 ? "s" : "",
653 lruList->inserts != 1 ? "have" : "has", lruList->insertCosts );
654 qDebug( "%d item%s %s too large or had too low priority to be inserted.",
655 lruList->insertMisses, lruList->insertMisses != 1 ? "s" : "",
656 lruList->insertMisses != 1 ? "were" : "was" );
657 qDebug( "%d item%s %s been thrown away with a total cost of %d.",
658 lruList->dumps, lruList->dumps != 1 ? "s" : "",
659 lruList->dumps != 1 ? "have" : "has", lruList->dumpCosts );
660 qDebug( "Statistics from internal dictionary class:" );
661 dict->statistics();
662 qDebug( line.ascii() );
663#endif
664}
665
666
667/*****************************************************************************
668 QGCacheIterator member functions
669 *****************************************************************************/
670
671/*!
672 \class QGCacheIterator qgcache.h
673 \reentrant
674 \ingroup shared
675 \ingroup collection
676 \brief The QGCacheIterator class is an internal class for implementing QCacheIterator and
677 QIntCacheIterator.
678
679 \internal
680
681 QGCacheIterator is a strictly internal class that does the heavy work for
682 QCacheIterator and QIntCacheIterator.
683*/
684
685/*!
686 Constructs an iterator that operates on the cache \a c.
687*/
688
689QGCacheIterator::QGCacheIterator( const QGCache &c )
690{
691 it = new QCListIt( c.lruList );
692#if defined(QT_DEBUG)
693 Q_ASSERT( it != 0 );
694#endif
695}
696
697/*!
698 Constructs an iterator that operates on the same cache as \a ci.
699*/
700
701QGCacheIterator::QGCacheIterator( const QGCacheIterator &ci )
702{
703 it = new QCListIt( ci.it );
704#if defined(QT_DEBUG)
705 Q_ASSERT( it != 0 );
706#endif
707}
708
709/*!
710 Destroys the iterator.
711*/
712
713QGCacheIterator::~QGCacheIterator()
714{
715 delete it;
716}
717
718/*!
719 Assigns the iterator \a ci to this cache iterator.
720*/
721
722QGCacheIterator &QGCacheIterator::operator=( const QGCacheIterator &ci )
723{
724 *it = *ci.it;
725 return *this;
726}
727
728/*!
729 Returns the number of items in the cache.
730*/
731
732uint QGCacheIterator::count() const
733{
734 return it->count();
735}
736
737/*!
738 Returns TRUE if the iterator points to the first item.
739*/
740
741bool QGCacheIterator::atFirst() const
742{
743 return it->atFirst();
744}
745
746/*!
747 Returns TRUE if the iterator points to the last item.
748*/
749
750bool QGCacheIterator::atLast() const
751{
752 return it->atLast();
753}
754
755/*!
756 Sets the list iterator to point to the first item in the cache.
757*/
758
759QPtrCollection::Item QGCacheIterator::toFirst()
760{
761 QCacheItem *item = it->toFirst();
762 return item ? item->data : 0;
763}
764
765/*!
766 Sets the list iterator to point to the last item in the cache.
767*/
768
769QPtrCollection::Item QGCacheIterator::toLast()
770{
771 QCacheItem *item = it->toLast();
772 return item ? item->data : 0;
773}
774
775/*!
776 Returns the current item.
777*/
778
779QPtrCollection::Item QGCacheIterator::get() const
780{
781 QCacheItem *item = it->current();
782 return item ? item->data : 0;
783}
784
785/*!
786 Returns the key of the current item.
787*/
788
789QString QGCacheIterator::getKeyString() const
790{
791 QCacheItem *item = it->current();
792 return item ? *((QString*)item->key) : QString::null;
793}
794
795/*!
796 Returns the key of the current item, as a \0-terminated C string.
797*/
798
799const char *QGCacheIterator::getKeyAscii() const
800{
801 QCacheItem *item = it->current();
802 return item ? (const char *)item->key : 0;
803}
804
805/*!
806 Returns the key of the current item, as a long.
807*/
808
809long QGCacheIterator::getKeyInt() const
810{
811 QCacheItem *item = it->current();
812 return item ? (long)item->key : 0;
813}
814
815/*!
816 Moves to the next item (postfix).
817*/
818
819QPtrCollection::Item QGCacheIterator::operator()()
820{
821 QCacheItem *item = it->operator()();
822 return item ? item->data : 0;
823}
824
825/*!
826 Moves to the next item (prefix).
827*/
828
829QPtrCollection::Item QGCacheIterator::operator++()
830{
831 QCacheItem *item = it->operator++();
832 return item ? item->data : 0;
833}
834
835/*!
836 Moves \a jump positions forward.
837*/
838
839QPtrCollection::Item QGCacheIterator::operator+=( uint jump )
840{
841 QCacheItem *item = it->operator+=(jump);
842 return item ? item->data : 0;
843}
844
845/*!
846 Moves to the previous item (prefix).
847*/
848
849QPtrCollection::Item QGCacheIterator::operator--()
850{
851 QCacheItem *item = it->operator--();
852 return item ? item->data : 0;
853}
854
855/*!
856 Moves \a jump positions backward.
857*/
858
859QPtrCollection::Item QGCacheIterator::operator-=( uint jump )
860{
861 QCacheItem *item = it->operator-=(jump);
862 return item ? item->data : 0;
863}
diff --git a/qmake/tools/qgdict.cpp b/qmake/tools/qgdict.cpp
new file mode 100644
index 0000000..c431ff8
--- a/dev/null
+++ b/qmake/tools/qgdict.cpp
@@ -0,0 +1,1146 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QGDict and QGDictIterator classes
5**
6** Created : 920529
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qgdict.h"
39#include "qptrlist.h"
40#include "qstring.h"
41#include "qdatastream.h"
42#include <ctype.h>
43
44/*!
45 \class QGDict
46 \reentrant
47 \ingroup collection
48 \brief The QGDict class is an internal class for implementing QDict template classes.
49
50 \internal
51
52 QGDict is a strictly internal class that acts as a base class for the
53 \link collection.html collection classes\endlink QDict and QIntDict.
54
55 QGDict has some virtual functions that can be reimplemented to customize
56 the subclasses.
57 \list
58 \i read() reads a collection/dictionary item from a QDataStream.
59 \i write() writes a collection/dictionary item to a QDataStream.
60 \endlist
61 Normally, you do not have to reimplement any of these functions.
62*/
63
64static const int op_find = 0;
65static const int op_insert = 1;
66static const int op_replace = 2;
67
68
69class QGDItList : public QPtrList<QGDictIterator>
70{
71public:
72 QGDItList() : QPtrList<QGDictIterator>() {}
73 QGDItList( const QGDItList &list ) : QPtrList<QGDictIterator>(list) {}
74 ~QGDItList() { clear(); }
75 QGDItList &operator=(const QGDItList &list)
76 { return (QGDItList&)QPtrList<QGDictIterator>::operator=(list); }
77};
78
79
80/*****************************************************************************
81 Default implementation of special and virtual functions
82 *****************************************************************************/
83
84/*!
85 Returns the hash key for \a key, when key is a string.
86*/
87
88int QGDict::hashKeyString( const QString &key )
89{
90#if defined(QT_CHECK_NULL)
91 if ( key.isNull() )
92 qWarning( "QGDict::hashKeyString: Invalid null key" );
93#endif
94 int i;
95 register uint h=0;
96 uint g;
97 const QChar *p = key.unicode();
98 if ( cases ) { // case sensitive
99 for ( i=0; i<(int)key.length(); i++ ) {
100 h = (h<<4) + p[i].cell();
101 if ( (g = h & 0xf0000000) )
102 h ^= g >> 24;
103 h &= ~g;
104 }
105 } else { // case insensitive
106 for ( i=0; i<(int)key.length(); i++ ) {
107 h = (h<<4) + p[i].lower().cell();
108 if ( (g = h & 0xf0000000) )
109 h ^= g >> 24;
110 h &= ~g;
111 }
112 }
113 int index = h;
114 if ( index < 0 ) // adjust index to table size
115 index = -index;
116 return index;
117}
118
119/*!
120 Returns the hash key for \a key, which is a C string.
121*/
122
123int QGDict::hashKeyAscii( const char *key )
124{
125#if defined(QT_CHECK_NULL)
126 if ( key == 0 )
127 qWarning( "QGDict::hashAsciiKey: Invalid null key" );
128#endif
129 register const char *k = key;
130 register uint h=0;
131 uint g;
132 if ( cases ) { // case sensitive
133 while ( *k ) {
134 h = (h<<4) + *k++;
135 if ( (g = h & 0xf0000000) )
136 h ^= g >> 24;
137 h &= ~g;
138 }
139 } else { // case insensitive
140 while ( *k ) {
141 h = (h<<4) + tolower((uchar) *k);
142 if ( (g = h & 0xf0000000) )
143 h ^= g >> 24;
144 h &= ~g;
145 k++;
146 }
147 }
148 int index = h;
149 if ( index < 0 ) // adjust index to table size
150 index = -index;
151 return index;
152}
153
154#ifndef QT_NO_DATASTREAM
155
156/*!
157 \overload
158 Reads a collection/dictionary item from the stream \a s and returns a
159 reference to the stream.
160
161 The default implementation sets \a item to 0.
162
163 \sa write()
164*/
165
166QDataStream& QGDict::read( QDataStream &s, QPtrCollection::Item &item )
167{
168 item = 0;
169 return s;
170}
171
172/*!
173 \overload
174 Writes a collection/dictionary item to the stream \a s and returns a
175 reference to the stream.
176
177 \sa read()
178*/
179
180QDataStream& QGDict::write( QDataStream &s, QPtrCollection::Item ) const
181{
182 return s;
183}
184#endif //QT_NO_DATASTREAM
185
186/*****************************************************************************
187 QGDict member functions
188 *****************************************************************************/
189
190/*!
191 Constructs a dictionary.
192
193 \a len is the initial size of the dictionary.
194 The key type is \a kt which may be \c StringKey, \c AsciiKey,
195 \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with
196 \a caseSensitive. Keys are copied if \a copyKeys is TRUE.
197*/
198
199QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
200{
201 init( len, kt, caseSensitive, copyKeys );
202}
203
204
205void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
206{
207 vec = new QBaseBucket *[vlen = len]; // allocate hash table
208 Q_CHECK_PTR( vec );
209 memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
210 numItems = 0;
211 iterators = 0;
212 // The caseSensitive and copyKey options don't make sense for
213 // all dict types.
214 switch ( (keytype = (uint)kt) ) {
215 case StringKey:
216 cases = caseSensitive;
217 copyk = FALSE;
218 break;
219 case AsciiKey:
220 cases = caseSensitive;
221 copyk = copyKeys;
222 break;
223 default:
224 cases = FALSE;
225 copyk = FALSE;
226 break;
227 }
228}
229
230
231/*!
232 Constructs a copy of \a dict.
233*/
234
235QGDict::QGDict( const QGDict & dict )
236 : QPtrCollection( dict )
237{
238 init( dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk );
239 QGDictIterator it( dict );
240 while ( it.get() ) { // copy from other dict
241 switch ( keytype ) {
242 case StringKey:
243 look_string( it.getKeyString(), it.get(), op_insert );
244 break;
245 case AsciiKey:
246 look_ascii( it.getKeyAscii(), it.get(), op_insert );
247 break;
248 case IntKey:
249 look_int( it.getKeyInt(), it.get(), op_insert );
250 break;
251 case PtrKey:
252 look_ptr( it.getKeyPtr(), it.get(), op_insert );
253 break;
254 }
255 ++it;
256 }
257}
258
259
260/*!
261 Removes all items from the dictionary and destroys it.
262*/
263
264QGDict::~QGDict()
265{
266 clear(); // delete everything
267 delete [] vec;
268 if ( !iterators ) // no iterators for this dict
269 return;
270 QGDictIterator *i = iterators->first();
271 while ( i ) { // notify all iterators that
272 i->dict = 0; // this dict is deleted
273 i = iterators->next();
274 }
275 delete iterators;
276}
277
278
279/*!
280 Assigns \a dict to this dictionary.
281*/
282
283QGDict &QGDict::operator=( const QGDict &dict )
284{
285 if ( &dict == this )
286 return *this;
287 clear();
288 QGDictIterator it( dict );
289 while ( it.get() ) { // copy from other dict
290 switch ( keytype ) {
291 case StringKey:
292 look_string( it.getKeyString(), it.get(), op_insert );
293 break;
294 case AsciiKey:
295 look_ascii( it.getKeyAscii(), it.get(), op_insert );
296 break;
297 case IntKey:
298 look_int( it.getKeyInt(), it.get(), op_insert );
299 break;
300 case PtrKey:
301 look_ptr( it.getKeyPtr(), it.get(), op_insert );
302 break;
303 }
304 ++it;
305 }
306 return *this;
307}
308
309/*!
310 \fn uint QGDict::count() const
311
312 Returns the number of items in the dictionary.
313*/
314
315/*!
316 \fn uint QGDict::size() const
317
318 Returns the size of the hash array.
319*/
320
321/*!
322 The do-it-all function; \a op is one of op_find, op_insert, op_replace.
323 The key is \a key and the item is \a d.
324*/
325
326QPtrCollection::Item QGDict::look_string( const QString &key, QPtrCollection::Item d,
327 int op )
328{
329 QStringBucket *n = 0;
330 intindex = hashKeyString(key) % vlen;
331 if ( op == op_find ) { // find
332 if ( cases ) {
333 n = (QStringBucket*)vec[index];
334 while( n != 0 ) {
335 if ( key == n->getKey() )
336 return n->getData();// item found
337 n = (QStringBucket*)n->getNext();
338 }
339 } else {
340 QString k = key.lower();
341 n = (QStringBucket*)vec[index];
342 while( n != 0 ) {
343 if ( k == n->getKey().lower() )
344 return n->getData();// item found
345 n = (QStringBucket*)n->getNext();
346 }
347 }
348 return 0; // not found
349 }
350 if ( op == op_replace ) { // replace
351 if ( vec[index] != 0 ) // maybe something there
352 remove_string( key );
353 }
354 // op_insert or op_replace
355 n = new QStringBucket(key,newItem(d),vec[index]);
356 Q_CHECK_PTR( n );
357#if defined(QT_CHECK_NULL)
358 if ( n->getData() == 0 )
359 qWarning( "QDict: Cannot insert null item" );
360#endif
361 vec[index] = n;
362 numItems++;
363 return n->getData();
364}
365
366QPtrCollection::Item QGDict::look_ascii( const char *key, QPtrCollection::Item d, int op )
367{
368 QAsciiBucket *n;
369 intindex = hashKeyAscii(key) % vlen;
370 if ( op == op_find ) { // find
371 if ( cases ) {
372 for ( n=(QAsciiBucket*)vec[index]; n;
373 n=(QAsciiBucket*)n->getNext() ) {
374 if ( qstrcmp(n->getKey(),key) == 0 )
375 return n->getData();// item found
376 }
377 } else {
378 for ( n=(QAsciiBucket*)vec[index]; n;
379 n=(QAsciiBucket*)n->getNext() ) {
380 if ( qstricmp(n->getKey(),key) == 0 )
381 return n->getData();// item found
382 }
383 }
384 return 0; // not found
385 }
386 if ( op == op_replace ) { // replace
387 if ( vec[index] != 0 ) // maybe something there
388 remove_ascii( key );
389 }
390 // op_insert or op_replace
391 n = new QAsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]);
392 Q_CHECK_PTR( n );
393#if defined(QT_CHECK_NULL)
394 if ( n->getData() == 0 )
395 qWarning( "QAsciiDict: Cannot insert null item" );
396#endif
397 vec[index] = n;
398 numItems++;
399 return n->getData();
400}
401
402QPtrCollection::Item QGDict::look_int( long key, QPtrCollection::Item d, int op )
403{
404 QIntBucket *n;
405 int index = (int)((ulong)key % vlen);// simple hash
406 if ( op == op_find ) { // find
407 for ( n=(QIntBucket*)vec[index]; n;
408 n=(QIntBucket*)n->getNext() ) {
409 if ( n->getKey() == key )
410 return n->getData(); // item found
411 }
412 return 0; // not found
413 }
414 if ( op == op_replace ) { // replace
415 if ( vec[index] != 0 ) // maybe something there
416 remove_int( key );
417 }
418 // op_insert or op_replace
419 n = new QIntBucket(key,newItem(d),vec[index]);
420 Q_CHECK_PTR( n );
421#if defined(QT_CHECK_NULL)
422 if ( n->getData() == 0 )
423 qWarning( "QIntDict: Cannot insert null item" );
424#endif
425 vec[index] = n;
426 numItems++;
427 return n->getData();
428}
429
430QPtrCollection::Item QGDict::look_ptr( void *key, QPtrCollection::Item d, int op )
431{
432 QPtrBucket *n;
433 int index = (int)((ulong)key % vlen);// simple hash
434 if ( op == op_find ) { // find
435 for ( n=(QPtrBucket*)vec[index]; n;
436 n=(QPtrBucket*)n->getNext() ) {
437 if ( n->getKey() == key )
438 return n->getData(); // item found
439 }
440 return 0; // not found
441 }
442 if ( op == op_replace ) { // replace
443 if ( vec[index] != 0 ) // maybe something there
444 remove_ptr( key );
445 }
446 // op_insert or op_replace
447 n = new QPtrBucket(key,newItem(d),vec[index]);
448 Q_CHECK_PTR( n );
449#if defined(QT_CHECK_NULL)
450 if ( n->getData() == 0 )
451 qWarning( "QPtrDict: Cannot insert null item" );
452#endif
453 vec[index] = n;
454 numItems++;
455 return n->getData();
456}
457
458
459/*!
460 Changes the size of the hashtable to \a newsize.
461 The contents of the dictionary are preserved,
462 but all iterators on the dictionary become invalid.
463*/
464void QGDict::resize( uint newsize )
465{
466 // Save old information
467 QBaseBucket **old_vec = vec;
468 uint old_vlen = vlen;
469 bool old_copyk = copyk;
470
471 vec = new QBaseBucket *[vlen = newsize];
472 Q_CHECK_PTR( vec );
473 memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
474 numItems = 0;
475 copyk = FALSE;
476
477 // Reinsert every item from vec, deleting vec as we go
478 for ( uint index = 0; index < old_vlen; index++ ) {
479 switch ( keytype ) {
480 case StringKey:
481 {
482 QStringBucket *n=(QStringBucket *)old_vec[index];
483 while ( n ) {
484 look_string( n->getKey(), n->getData(), op_insert );
485 QStringBucket *t=(QStringBucket *)n->getNext();
486 delete n;
487 n = t;
488 }
489 }
490 break;
491 case AsciiKey:
492 {
493 QAsciiBucket *n=(QAsciiBucket *)old_vec[index];
494 while ( n ) {
495 look_ascii( n->getKey(), n->getData(), op_insert );
496 QAsciiBucket *t=(QAsciiBucket *)n->getNext();
497 delete n;
498 n = t;
499 }
500 }
501 break;
502 case IntKey:
503 {
504 QIntBucket *n=(QIntBucket *)old_vec[index];
505 while ( n ) {
506 look_int( n->getKey(), n->getData(), op_insert );
507 QIntBucket *t=(QIntBucket *)n->getNext();
508 delete n;
509 n = t;
510 }
511 }
512 break;
513 case PtrKey:
514 {
515 QPtrBucket *n=(QPtrBucket *)old_vec[index];
516 while ( n ) {
517 look_ptr( n->getKey(), n->getData(), op_insert );
518 QPtrBucket *t=(QPtrBucket *)n->getNext();
519 delete n;
520 n = t;
521 }
522 }
523 break;
524 }
525 }
526 delete [] old_vec;
527
528 // Restore state
529 copyk = old_copyk;
530
531 // Invalidate all iterators, since order is lost
532 if ( iterators && iterators->count() ) {
533 QGDictIterator *i = iterators->first();
534 while ( i ) {
535 i->toFirst();
536 i = iterators->next();
537 }
538 }
539}
540
541/*!
542 Unlinks the bucket with the specified key (and specified data pointer,
543 if it is set).
544*/
545
546void QGDict::unlink_common( int index, QBaseBucket *node, QBaseBucket *prev )
547{
548 if ( iterators && iterators->count() ) {// update iterators
549 QGDictIterator *i = iterators->first();
550 while ( i ) { // invalidate all iterators
551 if ( i->curNode == node ) // referring to pending node
552 i->operator++();
553 i = iterators->next();
554 }
555 }
556 if ( prev ) // unlink node
557 prev->setNext( node->getNext() );
558 else
559 vec[index] = node->getNext();
560 numItems--;
561}
562
563QStringBucket *QGDict::unlink_string( const QString &key, QPtrCollection::Item d )
564{
565 if ( numItems == 0 ) // nothing in dictionary
566 return 0;
567 QStringBucket *n;
568 QStringBucket *prev = 0;
569 int index = hashKeyString(key) % vlen;
570 if ( cases ) {
571 for ( n=(QStringBucket*)vec[index]; n;
572 n=(QStringBucket*)n->getNext() ) {
573 bool found = (key == n->getKey());
574 if ( found && d )
575 found = (n->getData() == d);
576 if ( found ) {
577 unlink_common(index,n,prev);
578 return n;
579 }
580 prev = n;
581 }
582 } else {
583 QString k = key.lower();
584 for ( n=(QStringBucket*)vec[index]; n;
585 n=(QStringBucket*)n->getNext() ) {
586 bool found = (k == n->getKey().lower());
587 if ( found && d )
588 found = (n->getData() == d);
589 if ( found ) {
590 unlink_common(index,n,prev);
591 return n;
592 }
593 prev = n;
594 }
595 }
596 return 0;
597}
598
599QAsciiBucket *QGDict::unlink_ascii( const char *key, QPtrCollection::Item d )
600{
601 if ( numItems == 0 ) // nothing in dictionary
602 return 0;
603 QAsciiBucket *n;
604 QAsciiBucket *prev = 0;
605 int index = hashKeyAscii(key) % vlen;
606 for ( n=(QAsciiBucket *)vec[index]; n; n=(QAsciiBucket *)n->getNext() ) {
607 bool found = (cases ? qstrcmp(n->getKey(),key)
608 : qstricmp(n->getKey(),key)) == 0;
609 if ( found && d )
610 found = (n->getData() == d);
611 if ( found ) {
612 unlink_common(index,n,prev);
613 return n;
614 }
615 prev = n;
616 }
617 return 0;
618}
619
620QIntBucket *QGDict::unlink_int( long key, QPtrCollection::Item d )
621{
622 if ( numItems == 0 ) // nothing in dictionary
623 return 0;
624 QIntBucket *n;
625 QIntBucket *prev = 0;
626 int index = (int)((ulong)key % vlen);
627 for ( n=(QIntBucket *)vec[index]; n; n=(QIntBucket *)n->getNext() ) {
628 bool found = (n->getKey() == key);
629 if ( found && d )
630 found = (n->getData() == d);
631 if ( found ) {
632 unlink_common(index,n,prev);
633 return n;
634 }
635 prev = n;
636 }
637 return 0;
638}
639
640QPtrBucket *QGDict::unlink_ptr( void *key, QPtrCollection::Item d )
641{
642 if ( numItems == 0 ) // nothing in dictionary
643 return 0;
644 QPtrBucket *n;
645 QPtrBucket *prev = 0;
646 int index = (int)((ulong)key % vlen);
647 for ( n=(QPtrBucket *)vec[index]; n; n=(QPtrBucket *)n->getNext() ) {
648 bool found = (n->getKey() == key);
649 if ( found && d )
650 found = (n->getData() == d);
651 if ( found ) {
652 unlink_common(index,n,prev);
653 return n;
654 }
655 prev = n;
656 }
657 return 0;
658}
659
660
661/*!
662 Removes the item with the specified \a key. If \a item is not null,
663 the remove will match the \a item as well (used to remove an
664 item when several items have the same key).
665*/
666
667bool QGDict::remove_string( const QString &key, QPtrCollection::Item item )
668{
669 QStringBucket *n = unlink_string( key, item );
670 if ( n ) {
671 deleteItem( n->getData() );
672 delete n;
673 return TRUE;
674 } else {
675 return FALSE;
676 }
677}
678
679bool QGDict::remove_ascii( const char *key, QPtrCollection::Item item )
680{
681 QAsciiBucket *n = unlink_ascii( key, item );
682 if ( n ) {
683 if ( copyk )
684 delete [] (char *)n->getKey();
685 deleteItem( n->getData() );
686 delete n;
687 }
688 return n != 0;
689}
690
691bool QGDict::remove_int( long key, QPtrCollection::Item item )
692{
693 QIntBucket *n = unlink_int( key, item );
694 if ( n ) {
695 deleteItem( n->getData() );
696 delete n;
697 }
698 return n != 0;
699}
700
701bool QGDict::remove_ptr( void *key, QPtrCollection::Item item )
702{
703 QPtrBucket *n = unlink_ptr( key, item );
704 if ( n ) {
705 deleteItem( n->getData() );
706 delete n;
707 }
708 return n != 0;
709}
710
711QPtrCollection::Item QGDict::take_string( const QString &key )
712{
713 QStringBucket *n = unlink_string( key );
714 Item d;
715 if ( n ) {
716 d = n->getData();
717 delete n;
718 } else {
719 d = 0;
720 }
721 return d;
722}
723
724QPtrCollection::Item QGDict::take_ascii( const char *key )
725{
726 QAsciiBucket *n = unlink_ascii( key );
727 Item d;
728 if ( n ) {
729 if ( copyk )
730 delete [] (char *)n->getKey();
731 d = n->getData();
732 delete n;
733 } else {
734 d = 0;
735 }
736 return d;
737}
738
739QPtrCollection::Item QGDict::take_int( long key )
740{
741 QIntBucket *n = unlink_int( key );
742 Item d;
743 if ( n ) {
744 d = n->getData();
745 delete n;
746 } else {
747 d = 0;
748 }
749 return d;
750}
751
752QPtrCollection::Item QGDict::take_ptr( void *key )
753{
754 QPtrBucket *n = unlink_ptr( key );
755 Item d;
756 if ( n ) {
757 d = n->getData();
758 delete n;
759 } else {
760 d = 0;
761 }
762 return d;
763}
764
765/*!
766 Removes all items from the dictionary.
767*/
768void QGDict::clear()
769{
770 if ( !numItems )
771 return;
772 numItems = 0; // disable remove() function
773 for ( uint j=0; j<vlen; j++ ) { // destroy hash table
774 if ( vec[j] ) {
775 switch ( keytype ) {
776 case StringKey:
777 {
778 QStringBucket *n=(QStringBucket *)vec[j];
779 while ( n ) {
780 QStringBucket *next = (QStringBucket*)n->getNext();
781 deleteItem( n->getData() );
782 delete n;
783 n = next;
784 }
785 }
786 break;
787 case AsciiKey:
788 {
789 QAsciiBucket *n=(QAsciiBucket *)vec[j];
790 while ( n ) {
791 QAsciiBucket *next = (QAsciiBucket*)n->getNext();
792 if ( copyk )
793 delete [] (char *)n->getKey();
794 deleteItem( n->getData() );
795 delete n;
796 n = next;
797 }
798 }
799 break;
800 case IntKey:
801 {
802 QIntBucket *n=(QIntBucket *)vec[j];
803 while ( n ) {
804 QIntBucket *next = (QIntBucket*)n->getNext();
805 deleteItem( n->getData() );
806 delete n;
807 n = next;
808 }
809 }
810 break;
811 case PtrKey:
812 {
813 QPtrBucket *n=(QPtrBucket *)vec[j];
814 while ( n ) {
815 QPtrBucket *next = (QPtrBucket*)n->getNext();
816 deleteItem( n->getData() );
817 delete n;
818 n = next;
819 }
820 }
821 break;
822 }
823 vec[j] = 0; // detach list of buckets
824 }
825 }
826 if ( iterators && iterators->count() ) {// invalidate all iterators
827 QGDictIterator *i = iterators->first();
828 while ( i ) {
829 i->curNode = 0;
830 i = iterators->next();
831 }
832 }
833}
834
835/*!
836 Outputs debug statistics.
837*/
838void QGDict::statistics() const
839{
840#if defined(QT_DEBUG)
841 QString line;
842 line.fill( '-', 60 );
843 double real, ideal;
844 qDebug( line.ascii() );
845 qDebug( "DICTIONARY STATISTICS:" );
846 if ( count() == 0 ) {
847 qDebug( "Empty!" );
848 qDebug( line.ascii() );
849 return;
850 }
851 real = 0.0;
852 ideal = (float)count()/(2.0*size())*(count()+2.0*size()-1);
853 uint i = 0;
854 while ( i<size() ) {
855 QBaseBucket *n = vec[i];
856 int b = 0;
857 while ( n ) { // count number of buckets
858 b++;
859 n = n->getNext();
860 }
861 real = real + (double)b * ((double)b+1.0)/2.0;
862 char buf[80], *pbuf;
863 if ( b > 78 )
864 b = 78;
865 pbuf = buf;
866 while ( b-- )
867 *pbuf++ = '*';
868 *pbuf = '\0';
869 qDebug( buf );
870 i++;
871 }
872 qDebug( "Array size = %d", size() );
873 qDebug( "# items = %d", count() );
874 qDebug( "Real dist = %g", real );
875 qDebug( "Rand dist = %g", ideal );
876 qDebug( "Real/Rand = %g", real/ideal );
877 qDebug( line.ascii() );
878#endif // QT_DEBUG
879}
880
881
882/*****************************************************************************
883 QGDict stream functions
884 *****************************************************************************/
885#ifndef QT_NO_DATASTREAM
886QDataStream &operator>>( QDataStream &s, QGDict &dict )
887{
888 return dict.read( s );
889}
890
891QDataStream &operator<<( QDataStream &s, const QGDict &dict )
892{
893 return dict.write( s );
894}
895
896#if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
897#pragma message disable narrowptr
898#endif
899
900/*!
901 Reads a dictionary from the stream \a s.
902*/
903
904QDataStream &QGDict::read( QDataStream &s )
905{
906 uint num;
907 s >> num; // read number of items
908 clear(); // clear dict
909 while ( num-- ) { // read all items
910 Item d;
911 switch ( keytype ) {
912 case StringKey:
913 {
914 QString k;
915 s >> k;
916 read( s, d );
917 look_string( k, d, op_insert );
918 }
919 break;
920 case AsciiKey:
921 {
922 char *k;
923 s >> k;
924 read( s, d );
925 look_ascii( k, d, op_insert );
926 if ( copyk )
927 delete [] k;
928 }
929 break;
930 case IntKey:
931 {
932 Q_UINT32 k;
933 s >> k;
934 read( s, d );
935 look_int( k, d, op_insert );
936 }
937 break;
938 case PtrKey:
939 {
940 Q_UINT32 k;
941 s >> k;
942 read( s, d );
943 // ### cannot insert 0 - this renders the thing
944 // useless since all pointers are written as 0,
945 // but hey, serializing pointers? can it be done
946 // at all, ever?
947 if ( k )
948 look_ptr( (void *)k, d, op_insert );
949 }
950 break;
951 }
952 }
953 return s;
954}
955
956/*!
957 Writes the dictionary to the stream \a s.
958*/
959
960QDataStream& QGDict::write( QDataStream &s ) const
961{
962 s << count(); // write number of items
963 uint i = 0;
964 while ( i<size() ) {
965 QBaseBucket *n = vec[i];
966 while ( n ) { // write all buckets
967 switch ( keytype ) {
968 case StringKey:
969 s << ((QStringBucket*)n)->getKey();
970 break;
971 case AsciiKey:
972 s << ((QAsciiBucket*)n)->getKey();
973 break;
974 case IntKey:
975 s << (Q_UINT32)((QIntBucket*)n)->getKey();
976 break;
977 case PtrKey:
978 s << (Q_UINT32)0; // ### cannot serialize a pointer
979 break;
980 }
981 write( s, n->getData() ); // write data
982 n = n->getNext();
983 }
984 i++;
985 }
986 return s;
987}
988#endif //QT_NO_DATASTREAM
989
990/*****************************************************************************
991 QGDictIterator member functions
992 *****************************************************************************/
993
994/*!
995 \class QGDictIterator qgdict.h
996 \reentrant
997 \ingroup collection
998 \brief The QGDictIterator class is an internal class for implementing QDictIterator and QIntDictIterator.
999
1000 \internal
1001
1002 QGDictIterator is a strictly internal class that does the heavy work for
1003 QDictIterator and QIntDictIterator.
1004*/
1005
1006/*!
1007 Constructs an iterator that operates on the dictionary \a d.
1008*/
1009
1010QGDictIterator::QGDictIterator( const QGDict &d )
1011{
1012 dict = (QGDict *)&d; // get reference to dict
1013 toFirst(); // set to first noe
1014 if ( !dict->iterators ) {
1015 dict->iterators = new QGDItList;// create iterator list
1016 Q_CHECK_PTR( dict->iterators );
1017 }
1018 dict->iterators->append( this ); // attach iterator to dict
1019}
1020
1021/*!
1022 Constructs a copy of the iterator \a it.
1023*/
1024
1025QGDictIterator::QGDictIterator( const QGDictIterator &it )
1026{
1027 dict = it.dict;
1028 curNode = it.curNode;
1029 curIndex = it.curIndex;
1030 if ( dict )
1031 dict->iterators->append( this );// attach iterator to dict
1032}
1033
1034/*!
1035 Assigns a copy of the iterator \a it and returns a reference to this
1036 iterator.
1037*/
1038
1039QGDictIterator &QGDictIterator::operator=( const QGDictIterator &it )
1040{
1041 if ( dict ) // detach from old dict
1042 dict->iterators->removeRef( this );
1043 dict = it.dict;
1044 curNode = it.curNode;
1045 curIndex = it.curIndex;
1046 if ( dict )
1047 dict->iterators->append( this );// attach to new list
1048 return *this;
1049}
1050
1051/*!
1052 Destroys the iterator.
1053*/
1054
1055QGDictIterator::~QGDictIterator()
1056{
1057 if ( dict ) // detach iterator from dict
1058 dict->iterators->removeRef( this );
1059}
1060
1061
1062/*!
1063 Sets the iterator to point to the first item in the dictionary.
1064*/
1065
1066QPtrCollection::Item QGDictIterator::toFirst()
1067{
1068 if ( !dict ) {
1069#if defined(QT_CHECK_NULL)
1070 qWarning( "QGDictIterator::toFirst: Dictionary has been deleted" );
1071#endif
1072 return 0;
1073 }
1074 if ( dict->count() == 0 ) { // empty dictionary
1075 curNode = 0;
1076 return 0;
1077 }
1078 register uint i = 0;
1079 register QBaseBucket **v = dict->vec;
1080 while ( !(*v++) )
1081 i++;
1082 curNode = dict->vec[i];
1083 curIndex = i;
1084 return curNode->getData();
1085}
1086
1087
1088/*!
1089 Moves to the next item (postfix).
1090*/
1091
1092QPtrCollection::Item QGDictIterator::operator()()
1093{
1094 if ( !dict ) {
1095#if defined(QT_CHECK_NULL)
1096 qWarning( "QGDictIterator::operator(): Dictionary has been deleted" );
1097#endif
1098 return 0;
1099 }
1100 if ( !curNode )
1101 return 0;
1102 QPtrCollection::Item d = curNode->getData();
1103 this->operator++();
1104 return d;
1105}
1106
1107/*!
1108 Moves to the next item (prefix).
1109*/
1110
1111QPtrCollection::Item QGDictIterator::operator++()
1112{
1113 if ( !dict ) {
1114#if defined(QT_CHECK_NULL)
1115 qWarning( "QGDictIterator::operator++: Dictionary has been deleted" );
1116#endif
1117 return 0;
1118 }
1119 if ( !curNode )
1120 return 0;
1121 curNode = curNode->getNext();
1122 if ( !curNode ) { // no next bucket
1123 register uint i = curIndex + 1; // look from next vec element
1124 register QBaseBucket **v = &dict->vec[i];
1125 while ( i < dict->size() && !(*v++) )
1126 i++;
1127 if ( i == dict->size() ) { // nothing found
1128 curNode = 0;
1129 return 0;
1130 }
1131 curNode = dict->vec[i];
1132 curIndex = i;
1133 }
1134 return curNode->getData();
1135}
1136
1137/*!
1138 Moves \a jumps positions forward.
1139*/
1140
1141QPtrCollection::Item QGDictIterator::operator+=( uint jumps )
1142{
1143 while ( curNode && jumps-- )
1144 operator++();
1145 return curNode ? curNode->getData() : 0;
1146}
diff --git a/qmake/tools/qglist.cpp b/qmake/tools/qglist.cpp
new file mode 100644
index 0000000..155d585
--- a/dev/null
+++ b/qmake/tools/qglist.cpp
@@ -0,0 +1,1255 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QGList and QGListIterator classes
5**
6** Created : 920624
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qglist.h"
39#include "qgvector.h"
40#include "qdatastream.h"
41#include "qvaluelist.h"
42
43/*!
44 \class QLNode qglist.h
45 \reentrant
46 \ingroup collection
47 \brief The QLNode class is an internal class for the QPtrList template collection.
48
49 \internal
50
51 QLNode is a doubly-linked list node. It has three pointers:
52 \list 1
53 \i Pointer to the previous node.
54 \i Pointer to the next node.
55 \i Pointer to the actual data.
56 \endlist
57
58 It might sometimes be practical to have direct access to the list nodes
59 in a QPtrList, but it is seldom required.
60
61 Be very careful if you want to access the list nodes. The heap can
62 easily get corrupted if you make a mistake.
63
64 \sa QPtrList::currentNode(), QPtrList::removeNode(), QPtrList::takeNode()
65*/
66
67/*!
68 \fn QPtrCollection::Item QLNode::getData()
69 Returns a pointer (\c void*) to the actual data in the list node.
70*/
71
72
73/*!
74 \class QGList qglist.h
75 \reentrant
76 \ingroup collection
77 \brief The QGList class is an internal class for implementing Qt collection classes.
78
79 \internal
80
81 QGList is a strictly internal class that acts as a base class for
82 several collection classes; QPtrList, QPtrQueue and QPtrStack.
83
84 QGList has some virtual functions that can be reimplemented to
85 customize the subclasses, namely compareItems(), read() and
86 write. Normally, you do not have to reimplement any of these
87 functions. If you still want to reimplement them, see the QStrList
88 class (qstrlist.h) for an example.
89*/
90
91
92/* Internal helper class for QGList. Contains some optimization for
93 the typically case where only one iterators is activre on the list.
94 */
95class QGListIteratorList
96{
97public:
98 QGListIteratorList()
99 : list(0), iterator(0) {
100 }
101 ~QGListIteratorList() {
102 notifyClear( TRUE );
103 delete list;
104 }
105
106 void add( QGListIterator* i ) {
107 if ( !iterator ) {
108 iterator = i;
109 } else if ( list ) {
110 list->push_front( i );
111 } else {
112 list = new QValueList<QGListIterator*>;
113 list->push_front( i );
114 }
115 }
116
117 void remove( QGListIterator* i ) {
118 if ( iterator == i ) {
119 iterator = 0;
120 } else if ( list ) {
121 list->remove( i );
122 if ( list->isEmpty() ) {
123 delete list;
124 list = 0;
125 }
126 }
127 }
128
129 void notifyClear( bool zeroList ) {
130 if ( iterator ) {
131 if ( zeroList )
132 iterator->list = 0;
133 iterator->curNode = 0;
134 }
135 if ( list ) {
136 for ( QValueList<QGListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
137 if ( zeroList )
138 (*i)->list = 0;
139 (*i)->curNode = 0;
140 }
141 }
142 }
143
144 void notifyRemove( QLNode* n, QLNode* curNode ) {
145 if ( iterator ) {
146 if ( iterator->curNode == n )
147 iterator->curNode = curNode;
148 }
149 if ( list ) {
150 for ( QValueList<QGListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
151 if ( (*i)->curNode == n )
152 (*i)->curNode = curNode;
153 }
154 }
155 }
156
157private:
158 QValueList<QGListIterator*>* list;
159 QGListIterator* iterator;
160};
161
162
163
164/*****************************************************************************
165 Default implementation of virtual functions
166 *****************************************************************************/
167
168/*!
169 Documented as QPtrList::compareItems().
170
171 Compares \a item1 with \a item2.
172*/
173int QGList::compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 )
174{
175 return item1 != item2; // compare pointers
176}
177
178#ifndef QT_NO_DATASTREAM
179/*!
180 \overload
181 Reads a collection/list item from the stream \a s and returns a reference
182 to the stream.
183
184 The default implementation sets \a item to 0.
185
186 \sa write()
187*/
188
189QDataStream &QGList::read( QDataStream &s, QPtrCollection::Item &item )
190{
191 item = 0;
192 return s;
193}
194
195/*!
196 \overload
197 Writes a collection/list item to the stream \a s and
198 returns a reference to the stream.
199
200 The default implementation does nothing.
201
202 \sa read()
203*/
204
205QDataStream &QGList::write( QDataStream &s, QPtrCollection::Item ) const
206{
207 return s;
208}
209#endif // QT_NO_DATASTREAM
210
211/*****************************************************************************
212 QGList member functions
213 *****************************************************************************/
214
215/*!
216 Constructs an empty list.
217*/
218
219QGList::QGList()
220{
221 firstNode = lastNode = curNode = 0; // initialize list
222 numNodes = 0;
223 curIndex = -1;
224 iterators = 0; // initialize iterator list
225}
226
227/*!
228 Constructs a copy of \a list.
229*/
230
231QGList::QGList( const QGList & list )
232 : QPtrCollection( list )
233{
234 firstNode = lastNode = curNode = 0; // initialize list
235 numNodes = 0;
236 curIndex = -1;
237 iterators = 0; // initialize iterator list
238 QLNode *n = list.firstNode;
239 while ( n ) { // copy all items from list
240 append( n->data );
241 n = n->next;
242 }
243}
244
245/*!
246 Removes all items from the list and destroys the list.
247*/
248
249QGList::~QGList()
250{
251 clear();
252 delete iterators;
253 // Workaround for GCC 2.7.* bug. Compiler constructs 'static' QGList
254 // instances twice on the same address and therefore tries to destruct
255 // twice on the same address! This is insane but let's try not to crash
256 // here.
257 iterators = 0;
258}
259
260
261/*!
262 Assigns \a list to this list.
263*/
264
265QGList& QGList::operator=( const QGList &list )
266{
267 if ( &list == this )
268 return *this;
269
270 clear();
271 if ( list.count() > 0 ) {
272 QLNode *n = list.firstNode;
273 while ( n ) { // copy all items from list
274 append( n->data );
275 n = n->next;
276 }
277 curNode = firstNode;
278 curIndex = 0;
279 }
280 return *this;
281}
282
283/*!
284 Compares this list with \a list. Returns TRUE if the lists
285 contain the same data, otherwise FALSE.
286*/
287
288bool QGList::operator==( const QGList &list ) const
289{
290 if ( count() != list.count() )
291 return FALSE;
292
293 if ( count() == 0 )
294 return TRUE;
295
296 QLNode *n1 = firstNode;
297 QLNode *n2 = list.firstNode;
298 while ( n1 && n2 ) {
299 // should be mutable
300 if ( ( (QGList*)this )->compareItems( n1->data, n2->data ) != 0 )
301 return FALSE;
302 n1 = n1->next;
303 n2 = n2->next;
304 }
305
306 return TRUE;
307}
308
309/*!
310 \fn uint QGList::count() const
311
312 Returns the number of items in the list.
313*/
314
315
316/*!
317 Returns the node at position \a index. Sets this node to current.
318*/
319
320QLNode *QGList::locate( uint index )
321{
322 if ( index == (uint)curIndex ) // current node ?
323 return curNode;
324 if ( !curNode && firstNode ) { // set current node
325 curNode = firstNode;
326 curIndex = 0;
327 }
328 register QLNode *node;
329 int distance = index - curIndex; // node distance to cur node
330 bool forward; // direction to traverse
331
332 if ( index >= numNodes ) {
333#if defined(QT_CHECK_RANGE)
334 qWarning( "QGList::locate: Index %d out of range", index );
335#endif
336 return 0;
337 }
338
339 if ( distance < 0 )
340 distance = -distance;
341 if ( (uint)distance < index && (uint)distance < numNodes - index ) {
342 node = curNode; // start from current node
343 forward = index > (uint)curIndex;
344 } else if ( index < numNodes - index ) {// start from first node
345 node = firstNode;
346 distance = index;
347 forward = TRUE;
348 } else { // start from last node
349 node = lastNode;
350 distance = numNodes - index - 1;
351 if ( distance < 0 )
352 distance = 0;
353 forward = FALSE;
354 }
355 if ( forward ) { // now run through nodes
356 while ( distance-- )
357 node = node->next;
358 } else {
359 while ( distance-- )
360 node = node->prev;
361 }
362 curIndex = index; // must update index
363 return curNode = node;
364}
365
366
367/*!
368 Inserts item \a d at its sorted position in the list.
369*/
370
371void QGList::inSort( QPtrCollection::Item d )
372{
373 int index = 0;
374 register QLNode *n = firstNode;
375 while ( n && compareItems(n->data,d) < 0 ){ // find position in list
376 n = n->next;
377 index++;
378 }
379 insertAt( index, d );
380}
381
382
383/*!
384 Inserts item \a d at the start of the list.
385*/
386
387void QGList::prepend( QPtrCollection::Item d )
388{
389 register QLNode *n = new QLNode( newItem(d) );
390 Q_CHECK_PTR( n );
391 n->prev = 0;
392 if ( (n->next = firstNode) ) // list is not empty
393 firstNode->prev = n;
394 else // initialize list
395 lastNode = n;
396 firstNode = curNode = n; // curNode affected
397 numNodes++;
398 curIndex = 0;
399}
400
401
402/*!
403 Inserts item \a d at the end of the list.
404*/
405
406void QGList::append( QPtrCollection::Item d )
407{
408 register QLNode *n = new QLNode( newItem(d) );
409 Q_CHECK_PTR( n );
410 n->next = 0;
411 if ( (n->prev = lastNode) ) // list is not empty
412 lastNode->next = n;
413 else // initialize list
414 firstNode = n;
415 lastNode = curNode = n; // curNode affected
416 curIndex = numNodes;
417 numNodes++;
418}
419
420
421/*!
422 Inserts item \a d at position \a index in the list.
423*/
424
425bool QGList::insertAt( uint index, QPtrCollection::Item d )
426{
427 if ( index == 0 ) {
428 prepend( d );
429 return TRUE;
430 } else if ( index == numNodes ) {
431 append( d );
432 return TRUE;
433 }
434 QLNode *nextNode = locate( index );
435 if ( !nextNode )
436 return FALSE;
437 QLNode *prevNode = nextNode->prev;
438 register QLNode *n = new QLNode( newItem(d) );
439 Q_CHECK_PTR( n );
440 nextNode->prev = n;
441 prevNode->next = n;
442 n->prev = prevNode; // link new node into list
443 n->next = nextNode;
444 curNode = n; // curIndex set by locate()
445 numNodes++;
446 return TRUE;
447}
448
449
450/*!
451 Relinks node \a n and makes it the first node in the list.
452*/
453
454void QGList::relinkNode( QLNode *n )
455{
456 if ( n == firstNode ) // already first
457 return;
458 curNode = n;
459 unlink();
460 n->prev = 0;
461 if ( (n->next = firstNode) ) // list is not empty
462 firstNode->prev = n;
463 else // initialize list
464 lastNode = n;
465 firstNode = curNode = n; // curNode affected
466 numNodes++;
467 curIndex = 0;
468}
469
470
471/*!
472 Unlinks the current list node and returns a pointer to this node.
473*/
474
475QLNode *QGList::unlink()
476{
477 if ( curNode == 0 ) // null current node
478 return 0;
479 register QLNode *n = curNode; // unlink this node
480 if ( n == firstNode ) { // removing first node ?
481 if ( (firstNode = n->next) ) {
482 firstNode->prev = 0;
483 } else {
484 lastNode = curNode = 0; // list becomes empty
485 curIndex = -1;
486 }
487 } else {
488 if ( n == lastNode ) { // removing last node ?
489 lastNode = n->prev;
490 lastNode->next = 0;
491 } else { // neither last nor first node
492 n->prev->next = n->next;
493 n->next->prev = n->prev;
494 }
495 }
496
497 if ( n->next ) { // change current node
498 curNode = n->next;
499 } else if ( n->prev ) {
500 curNode = n->prev;
501 curIndex--;
502 }
503
504 if ( iterators )
505 iterators->notifyRemove( n, curNode );
506 numNodes--;
507 return n;
508}
509
510
511/*!
512 Removes the node \a n from the list.
513*/
514
515bool QGList::removeNode( QLNode *n )
516{
517#if defined(QT_CHECK_NULL)
518 if ( n == 0 || (n->prev && n->prev->next != n) ||
519 (n->next && n->next->prev != n) ) {
520 qWarning( "QGList::removeNode: Corrupted node" );
521 return FALSE;
522 }
523#endif
524 curNode = n;
525 unlink(); // unlink node
526 deleteItem( n->data ); // deallocate this node
527 delete n;
528 curNode = firstNode;
529 curIndex = curNode ? 0 : -1;
530 return TRUE;
531}
532
533/*!
534 Removes the item \a d from the list.Uses compareItems() to find the item.
535
536 If \a d is 0, removes the current item.
537*/
538
539bool QGList::remove( QPtrCollection::Item d )
540{
541 if ( d && find(d) == -1 )
542 return FALSE;
543 QLNode *n = unlink();
544 if ( !n )
545 return FALSE;
546 deleteItem( n->data );
547 delete n;
548 return TRUE;
549}
550
551/*!
552 Removes the item \a d from the list.
553*/
554
555bool QGList::removeRef( QPtrCollection::Item d )
556{
557 if ( findRef(d) == -1 )
558 return FALSE;
559 QLNode *n = unlink();
560 if ( !n )
561 return FALSE;
562 deleteItem( n->data );
563 delete n;
564 return TRUE;
565}
566
567/*!
568 \fn bool QGList::removeFirst()
569
570 Removes the first item in the list.
571*/
572
573/*!
574 \fn bool QGList::removeLast()
575
576 Removes the last item in the list.
577*/
578
579/*!
580 Removes the item at position \a index from the list.
581*/
582
583bool QGList::removeAt( uint index )
584{
585 if ( !locate(index) )
586 return FALSE;
587 QLNode *n = unlink();
588 if ( !n )
589 return FALSE;
590 deleteItem( n->data );
591 delete n;
592 return TRUE;
593}
594
595
596/*!
597 Replaces the item at index \a index with \a d.
598*/
599bool QGList::replaceAt( uint index, QPtrCollection::Item d )
600{
601 QLNode *n = locate( index );
602 if ( !n )
603 return FALSE;
604 if ( n->data != d ) {
605 deleteItem( n->data );
606 n->data = newItem( d );
607 }
608 return TRUE;
609}
610
611
612
613/*!
614 Takes the node \a n out of the list.
615*/
616
617QPtrCollection::Item QGList::takeNode( QLNode *n )
618{
619#if defined(QT_CHECK_NULL)
620 if ( n == 0 || (n->prev && n->prev->next != n) ||
621 (n->next && n->next->prev != n) ) {
622 qWarning( "QGList::takeNode: Corrupted node" );
623 return 0;
624 }
625#endif
626 curNode = n;
627 unlink(); // unlink node
628 Item d = n->data;
629 delete n; // delete the node, not data
630 curNode = firstNode;
631 curIndex = curNode ? 0 : -1;
632 return d;
633}
634
635/*!
636 Takes the current item out of the list.
637*/
638
639QPtrCollection::Item QGList::take()
640{
641 QLNode *n = unlink(); // unlink node
642 Item d = n ? n->data : 0;
643 delete n; // delete node, keep contents
644 return d;
645}
646
647/*!
648 Takes the item at position \a index out of the list.
649*/
650
651QPtrCollection::Item QGList::takeAt( uint index )
652{
653 if ( !locate(index) )
654 return 0;
655 QLNode *n = unlink(); // unlink node
656 Item d = n ? n->data : 0;
657 delete n; // delete node, keep contents
658 return d;
659}
660
661/*!
662 Takes the first item out of the list.
663*/
664
665QPtrCollection::Item QGList::takeFirst()
666{
667 first();
668 QLNode *n = unlink(); // unlink node
669 Item d = n ? n->data : 0;
670 delete n;
671 return d;
672}
673
674/*!
675 Takes the last item out of the list.
676*/
677
678QPtrCollection::Item QGList::takeLast()
679{
680 last();
681 QLNode *n = unlink(); // unlink node
682 Item d = n ? n->data : 0;
683 delete n;
684 return d;
685}
686
687
688/*!
689 Removes all items from the list.
690*/
691
692void QGList::clear()
693{
694 register QLNode *n = firstNode;
695
696 firstNode = lastNode = curNode = 0; // initialize list
697 numNodes = 0;
698 curIndex = -1;
699
700 if ( iterators )
701 iterators->notifyClear( FALSE );
702
703 QLNode *prevNode;
704 while ( n ) { // for all nodes ...
705 deleteItem( n->data ); // deallocate data
706 prevNode = n;
707 n = n->next;
708 delete prevNode; // deallocate node
709 }
710}
711
712
713/*!
714 Finds item \a d in the list. If \a fromStart is TRUE the search
715 begins at the first node; otherwise it begins at the current node.
716*/
717
718int QGList::findRef( QPtrCollection::Item d, bool fromStart )
719{
720 register QLNode *n;
721 int index;
722 if ( fromStart ) { // start from first node
723 n = firstNode;
724 index = 0;
725 } else { // start from current node
726 n = curNode;
727 index = curIndex;
728 }
729 while ( n && n->data != d ) { // find exact match
730 n = n->next;
731 index++;
732 }
733 curNode = n;
734 curIndex = n ? index : -1;
735 return curIndex; // return position of item
736}
737
738/*!
739 Finds item \a d in the list using compareItems(). If \a fromStart is
740 TRUE the search begins at the first node; otherwise it begins at the
741 current node.
742*/
743
744int QGList::find( QPtrCollection::Item d, bool fromStart )
745{
746 register QLNode *n;
747 int index;
748 if ( fromStart ) { // start from first node
749 n = firstNode;
750 index = 0;
751 } else { // start from current node
752 n = curNode;
753 index = curIndex;
754 }
755 while ( n && compareItems(n->data,d) ){// find equal match
756 n = n->next;
757 index++;
758 }
759 curNode = n;
760 curIndex = n ? index : -1;
761 return curIndex; // return position of item
762}
763
764
765/*!
766 Counts the number item \a d occurs in the list.
767*/
768
769uint QGList::containsRef( QPtrCollection::Item d ) const
770{
771 register QLNode *n = firstNode;
772 uint count = 0;
773 while ( n ) { // for all nodes...
774 if ( n->data == d ) // count # exact matches
775 count++;
776 n = n->next;
777 }
778 return count;
779}
780
781/*!
782 Counts the number of times item \a d occurs in the list. Uses
783 compareItems().
784*/
785
786uint QGList::contains( QPtrCollection::Item d ) const
787{
788 register QLNode *n = firstNode;
789 uint count = 0;
790 QGList *that = (QGList*)this; // mutable for compareItems()
791 while ( n ) { // for all nodes...
792 if ( !that->compareItems(n->data,d) )// count # equal matches
793 count++;
794 n = n->next;
795 }
796 return count;
797}
798
799
800/*!
801 \overload QPtrCollection::Item QGList::at( uint index )
802
803 Sets the item at position \a index to the current item.
804*/
805
806/*!
807 \fn int QGList::at() const
808
809 Returns the current index.
810*/
811
812/*!
813 \fn QLNode *QGList::currentNode() const
814
815 Returns the current node.
816*/
817
818/*!
819 \fn QPtrCollection::Item QGList::get() const
820
821 Returns the current item.
822*/
823
824/*!
825 \fn QPtrCollection::Item QGList::cfirst() const
826
827 Returns the first item in the list.
828*/
829
830/*!
831 \fn QPtrCollection::Item QGList::clast() const
832
833 Returns the last item in the list.
834*/
835
836
837/*!
838 Returns the first list item.Sets this to current.
839*/
840
841QPtrCollection::Item QGList::first()
842{
843 if ( firstNode ) {
844 curIndex = 0;
845 return (curNode=firstNode)->data;
846 }
847 return 0;
848}
849
850/*!
851 Returns the last list item. Sets this to current.
852*/
853
854QPtrCollection::Item QGList::last()
855{
856 if ( lastNode ) {
857 curIndex = numNodes-1;
858 return (curNode=lastNode)->data;
859 }
860 return 0;
861}
862
863/*!
864 Returns the next list item (after current). Sets this to current.
865*/
866
867QPtrCollection::Item QGList::next()
868{
869 if ( curNode ) {
870 if ( curNode->next ) {
871 curIndex++;
872 curNode = curNode->next;
873 return curNode->data;
874 }
875 curIndex = -1;
876 curNode = 0;
877 }
878 return 0;
879}
880
881/*!
882 Returns the previous list item (before current). Sets this to current.
883*/
884
885QPtrCollection::Item QGList::prev()
886{
887 if ( curNode ) {
888 if ( curNode->prev ) {
889 curIndex--;
890 curNode = curNode->prev;
891 return curNode->data;
892 }
893 curIndex = -1;
894 curNode = 0;
895 }
896 return 0;
897}
898
899
900/*!
901 Converts the list to a vector, \a vector.
902*/
903
904void QGList::toVector( QGVector *vector ) const
905{
906 vector->clear();
907 if ( !vector->resize( count() ) )
908 return;
909 register QLNode *n = firstNode;
910 uint i = 0;
911 while ( n ) {
912 vector->insert( i, n->data );
913 n = n->next;
914 i++;
915 }
916}
917
918void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last )
919{
920 int r = first;
921 while( r <= last/2 ) {
922 // Node r has only one child ?
923 if ( last == 2*r ) {
924 // Need for swapping ?
925 if ( compareItems( heap[r], heap[ 2*r ] ) > 0 ) {
926 QPtrCollection::Item tmp = heap[r];
927 heap[ r ] = heap[ 2*r ];
928 heap[ 2*r ] = tmp;
929 }
930 // That's it ...
931 r = last;
932 } else {
933 // Node has two children
934 if ( compareItems( heap[r], heap[ 2*r ] ) > 0 &&
935 compareItems( heap[ 2*r ], heap[ 2*r+1 ] ) <= 0 ) {
936 // Swap with left child
937 QPtrCollection::Item tmp = heap[r];
938 heap[ r ] = heap[ 2*r ];
939 heap[ 2*r ] = tmp;
940 r *= 2;
941 } else if ( compareItems( heap[r], heap[ 2*r+1 ] ) > 0 &&
942 compareItems( heap[ 2*r+1 ], heap[ 2*r ] ) < 0 ) {
943 // Swap with right child
944 QPtrCollection::Item tmp = heap[r];
945 heap[ r ] = heap[ 2*r+1 ];
946 heap[ 2*r+1 ] = tmp;
947 r = 2*r+1;
948 } else {
949 // We are done
950 r = last;
951 }
952 }
953 }
954}
955
956
957/*! Sorts the list by the result of the virtual compareItems() function.
958
959 The Heap-Sort algorithm is used for sorting. It sorts n items with
960 O(n*log n) compares. This is the asymptotic optimal solution of the
961 sorting problem.
962*/
963
964void QGList::sort()
965{
966 uint n = count();
967 if ( n < 2 )
968 return;
969
970 // Create the heap
971 QPtrCollection::Item* realheap = new QPtrCollection::Item[ n ];
972 // Wow, what a fake. But I want the heap to be indexed as 1...n
973 QPtrCollection::Item* heap = realheap - 1;
974 int size = 0;
975 QLNode* insert = firstNode;
976 for( ; insert != 0; insert = insert->next ) {
977 heap[++size] = insert->data;
978 int i = size;
979 while( i > 1 && compareItems( heap[i], heap[ i / 2 ] ) < 0 ) {
980 QPtrCollection::Item tmp = heap[ i ];
981 heap[ i ] = heap[ i/2 ];
982 heap[ i/2 ] = tmp;
983 i /= 2;
984 }
985 }
986
987 insert = firstNode;
988 // Now do the sorting
989 for ( int i = n; i > 0; i-- ) {
990 insert->data = heap[1];
991 insert = insert->next;
992 if ( i > 1 ) {
993 heap[1] = heap[i];
994 heapSortPushDown( heap, 1, i - 1 );
995 }
996 }
997
998 delete [] realheap;
999}
1000
1001
1002/*****************************************************************************
1003 QGList stream functions
1004 *****************************************************************************/
1005
1006#ifndef QT_NO_DATASTREAM
1007QDataStream &operator>>( QDataStream &s, QGList &list )
1008 { // read list
1009 return list.read( s );
1010}
1011
1012QDataStream &operator<<( QDataStream &s, const QGList &list )
1013 { // write list
1014 return list.write( s );
1015}
1016
1017/*!
1018 Reads a list from the stream \a s.
1019*/
1020
1021QDataStream &QGList::read( QDataStream &s )
1022{
1023 uint num;
1024 s >> num; // read number of items
1025 clear(); // clear list
1026 while ( num-- ) { // read all items
1027 Item d;
1028 read( s, d );
1029 Q_CHECK_PTR( d );
1030 if ( !d ) // no memory
1031 break;
1032 QLNode *n = new QLNode( d );
1033 Q_CHECK_PTR( n );
1034 if ( !n ) // no memory
1035 break;
1036 n->next = 0;
1037 if ( (n->prev = lastNode) ) // list is not empty
1038 lastNode->next = n;
1039 else // initialize list
1040 firstNode = n;
1041 lastNode = n;
1042 numNodes++;
1043 }
1044 curNode = firstNode;
1045 curIndex = curNode ? 0 : -1;
1046 return s;
1047}
1048
1049/*!
1050 Writes the list to the stream \a s.
1051*/
1052
1053QDataStream &QGList::write( QDataStream &s ) const
1054{
1055 s << count(); // write number of items
1056 QLNode *n = firstNode;
1057 while ( n ) { // write all items
1058 write( s, n->data );
1059 n = n->next;
1060 }
1061 return s;
1062}
1063
1064#endif // QT_NO_DATASTREAM
1065
1066/*****************************************************************************
1067 QGListIterator member functions
1068 *****************************************************************************/
1069
1070/*!
1071 \class QGListIterator qglist.h
1072 \reentrant
1073 \ingroup collection
1074 \brief The QGListIterator class is an internal class for implementing QPtrListIterator.
1075
1076 \internal
1077
1078 QGListIterator is a strictly internal class that does the heavy work for
1079 QPtrListIterator.
1080*/
1081
1082/*!
1083 \internal
1084 Constructs an iterator that operates on the list \a l.
1085*/
1086
1087QGListIterator::QGListIterator( const QGList &l )
1088{
1089 list = (QGList *)&l; // get reference to list
1090 curNode = list->firstNode; // set to first node
1091 if ( !list->iterators ) {
1092 list->iterators = new QGListIteratorList; // create iterator list
1093 Q_CHECK_PTR( list->iterators );
1094 }
1095 list->iterators->add( this ); // attach iterator to list
1096}
1097
1098/*!
1099 \internal
1100 Constructs a copy of the iterator \a it.
1101*/
1102
1103QGListIterator::QGListIterator( const QGListIterator &it )
1104{
1105 list = it.list;
1106 curNode = it.curNode;
1107 if ( list )
1108 list->iterators->add( this );// attach iterator to list
1109}
1110
1111/*!
1112 \internal
1113 Assigns a copy of the iterator \a it and returns a reference to this
1114 iterator.
1115*/
1116
1117QGListIterator &QGListIterator::operator=( const QGListIterator &it )
1118{
1119 if ( list ) // detach from old list
1120 list->iterators->remove( this );
1121 list = it.list;
1122 curNode = it.curNode;
1123 if ( list )
1124 list->iterators->add( this );// attach to new list
1125 return *this;
1126}
1127
1128/*!
1129 \internal
1130 Destroys the iterator.
1131*/
1132
1133QGListIterator::~QGListIterator()
1134{
1135 if ( list ) // detach iterator from list
1136 list->iterators->remove(this);
1137}
1138
1139
1140/*!
1141 \fn bool QGListIterator::atFirst() const
1142 \internal
1143 Returns TRUE if the iterator points to the first item, otherwise FALSE.
1144*/
1145
1146/*!
1147 \fn bool QGListIterator::atLast() const
1148 \internal
1149 Returns TRUE if the iterator points to the last item, otherwise FALSE.
1150*/
1151
1152
1153/*!
1154 \internal
1155 Sets the list iterator to point to the first item in the list.
1156*/
1157
1158QPtrCollection::Item QGListIterator::toFirst()
1159{
1160 if ( !list ) {
1161#if defined(QT_CHECK_NULL)
1162 qWarning( "QGListIterator::toFirst: List has been deleted" );
1163#endif
1164 return 0;
1165 }
1166 return list->firstNode ? (curNode = list->firstNode)->getData() : 0;
1167}
1168
1169/*!
1170 \internal
1171 Sets the list iterator to point to the last item in the list.
1172*/
1173
1174QPtrCollection::Item QGListIterator::toLast()
1175{
1176 if ( !list ) {
1177#if defined(QT_CHECK_NULL)
1178 qWarning( "QGListIterator::toLast: List has been deleted" );
1179#endif
1180 return 0;
1181 }
1182 return list->lastNode ? (curNode = list->lastNode)->getData() : 0;
1183}
1184
1185
1186/*!
1187 \fn QPtrCollection::Item QGListIterator::get() const
1188 \internal
1189 Returns the iterator item.
1190*/
1191
1192
1193/*!
1194 \internal
1195 Moves to the next item (postfix).
1196*/
1197
1198QPtrCollection::Item QGListIterator::operator()()
1199{
1200 if ( !curNode )
1201 return 0;
1202 QPtrCollection::Item d = curNode->getData();
1203 curNode = curNode->next;
1204 return d;
1205}
1206
1207/*!
1208 \internal
1209 Moves to the next item (prefix).
1210*/
1211
1212QPtrCollection::Item QGListIterator::operator++()
1213{
1214 if ( !curNode )
1215 return 0;
1216 curNode = curNode->next;
1217 return curNode ? curNode->getData() : 0;
1218}
1219
1220/*!
1221 \internal
1222 Moves \a jumps positions forward.
1223*/
1224
1225QPtrCollection::Item QGListIterator::operator+=( uint jumps )
1226{
1227 while ( curNode && jumps-- )
1228 curNode = curNode->next;
1229 return curNode ? curNode->getData() : 0;
1230}
1231
1232/*!
1233 \internal
1234 Moves to the previous item (prefix).
1235*/
1236
1237QPtrCollection::Item QGListIterator::operator--()
1238{
1239 if ( !curNode )
1240 return 0;
1241 curNode = curNode->prev;
1242 return curNode ? curNode->getData() : 0;
1243}
1244
1245/*!
1246 \internal
1247 Moves \a jumps positions backward.
1248*/
1249
1250QPtrCollection::Item QGListIterator::operator-=( uint jumps )
1251{
1252 while ( curNode && jumps-- )
1253 curNode = curNode->prev;
1254 return curNode ? curNode->getData() : 0;
1255}
diff --git a/qmake/tools/qglobal.cpp b/qmake/tools/qglobal.cpp
new file mode 100644
index 0000000..47cd6bd
--- a/dev/null
+++ b/qmake/tools/qglobal.cpp
@@ -0,0 +1,835 @@
1/****************************************************************************
2** $Id$
3**
4** Global functions
5**
6** Created : 920604
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40#include "qasciidict.h"
41#include <limits.h>
42#include <stdio.h>
43#include <limits.h>
44#include <stdarg.h>
45#include <stdlib.h>
46
47
48/*!
49 \relates QApplication
50
51 Returns the Qt version number as a string, for example, "2.3.0" or
52 "3.0.5".
53
54 The \c QT_VERSION define has the numeric value in the form:
55 0xmmiibb (m = major, i = minor, b = bugfix). For example, Qt
56 3.0.5's \c QT_VERSION is 0x030005.
57*/
58
59const char *qVersion()
60{
61 return QT_VERSION_STR;
62}
63
64
65/*****************************************************************************
66 System detection routines
67 *****************************************************************************/
68
69static bool si_alreadyDone = FALSE;
70static int si_wordSize;
71static bool si_bigEndian;
72
73/*!
74 \relates QApplication
75
76 Obtains information about the system.
77
78 The system's word size in bits (typically 32) is returned in \a
79 *wordSize. The \a *bigEndian is set to TRUE if this is a big-endian
80 machine, or to FALSE if this is a little-endian machine.
81
82 In debug mode, this function calls qFatal() with a message if the
83 computer is truly weird (i.e. different endianness for 16 bit and
84 32 bit integers); in release mode it returns FALSE.
85*/
86
87bool qSysInfo( int *wordSize, bool *bigEndian )
88{
89#if defined(QT_CHECK_NULL)
90 Q_ASSERT( wordSize != 0 );
91 Q_ASSERT( bigEndian != 0 );
92#endif
93
94 if ( si_alreadyDone ) { // run it only once
95 *wordSize = si_wordSize;
96 *bigEndian = si_bigEndian;
97 return TRUE;
98 }
99
100 si_wordSize = 0;
101 Q_ULONG n = (Q_ULONG)(~0);
102 while ( n ) { // detect word size
103 si_wordSize++;
104 n /= 2;
105 }
106 *wordSize = si_wordSize;
107
108 if ( *wordSize != 64 &&
109 *wordSize != 32 &&
110 *wordSize != 16 ) { // word size: 16, 32 or 64
111#if defined(QT_CHECK_RANGE)
112 qFatal( "qSysInfo: Unsupported system word size %d", *wordSize );
113#endif
114 return FALSE;
115 }
116 if ( sizeof(Q_INT8) != 1 || sizeof(Q_INT16) != 2 || sizeof(Q_INT32) != 4 ||
117 sizeof(Q_ULONG)*8 != si_wordSize || sizeof(float) != 4 || sizeof(double) != 8 ) {
118#if defined(QT_CHECK_RANGE)
119 qFatal( "qSysInfo: Unsupported system data type size" );
120#endif
121 return FALSE;
122 }
123
124 bool be16, be32; // determine byte ordering
125 short ns = 0x1234;
126 int nl = 0x12345678;
127
128 unsigned char *p = (unsigned char *)(&ns);// 16-bit integer
129 be16 = *p == 0x12;
130
131 p = (unsigned char *)(&nl); // 32-bit integer
132 if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
133 be32 = TRUE;
134 else
135 if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
136 be32 = FALSE;
137 else
138 be32 = !be16;
139
140 if ( be16 != be32 ) { // strange machine!
141#if defined(QT_CHECK_RANGE)
142 qFatal( "qSysInfo: Inconsistent system byte order" );
143#endif
144 return FALSE;
145 }
146
147 *bigEndian = si_bigEndian = be32;
148 si_alreadyDone = TRUE;
149 return TRUE;
150}
151
152#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
153bool qt_winunicode;
154
155#include "qt_windows.h"
156
157int qWinVersion()
158{
159#ifndef VER_PLATFORM_WIN32s
160 #define VER_PLATFORM_WIN32s 0
161#endif
162#ifndef VER_PLATFORM_WIN32_WINDOWS
163#define VER_PLATFORM_WIN32_WINDOWS 1
164#endif
165#ifndef VER_PLATFORM_WIN32_NT
166 #define VER_PLATFORM_WIN32_NT 2
167#endif
168
169 static int winver = Qt::WV_NT;
170 static int t=0;
171 if ( !t ) {
172 t=1;
173#ifdef Q_OS_TEMP
174 OSVERSIONINFOW osver;
175 osver.dwOSVersionInfoSize = sizeof(osver);
176 GetVersionEx( &osver );
177#else
178 OSVERSIONINFOA osver;
179 osver.dwOSVersionInfoSize = sizeof(osver);
180 GetVersionExA( &osver );
181#endif
182 switch ( osver.dwPlatformId ) {
183 case VER_PLATFORM_WIN32s:
184 winver = Qt::WV_32s;
185 break;
186 case VER_PLATFORM_WIN32_WINDOWS:
187 // We treat Windows Me (minor 90) the same as Windows 98
188 if ( ( osver.dwMinorVersion == 10 ) || ( osver.dwMinorVersion == 90 ) )
189 winver = Qt::WV_98;
190 else
191 winver = Qt::WV_95;
192 break;
193 default: // VER_PLATFORM_WIN32_NT
194 if ( osver.dwMajorVersion < 5 ) {
195 winver = Qt::WV_NT;
196 } else if ( osver.dwMinorVersion == 0 ) {
197 winver = Qt::WV_2000;
198 } else {
199 winver = Qt::WV_XP;
200 }
201 }
202 }
203
204#if defined(UNICODE)
205 if ( winver & Qt::WV_NT_based )
206 qt_winunicode = TRUE;
207 else
208#endif
209 qt_winunicode = FALSE;
210
211 return winver;
212}
213
214Qt::WindowsVersion qt_winver = (Qt::WindowsVersion)qWinVersion();
215#endif
216
217
218/*****************************************************************************
219 Debug output routines
220 *****************************************************************************/
221
222/*!
223 \fn void qDebug( const char *msg, ... )
224
225 \relates QApplication
226
227 Prints a debug message \a msg, or calls the message handler (if it
228 has been installed).
229
230 This function takes a format string and a list of arguments,
231 similar to the C printf() function.
232
233 Example:
234 \code
235 qDebug( "my window handle = %x", myWidget->id() );
236 \endcode
237
238 Under X11, the text is printed to stderr. Under Windows, the text
239 is sent to the debugger.
240
241 \warning The internal buffer is limited to 8196 bytes (including
242 the '\0'-terminator).
243
244 \warning Passing (const char *)0 as argument to qDebug might lead
245 to crashes on certain platforms due to the platforms printf implementation.
246
247 \sa qWarning(), qFatal(), qInstallMsgHandler(),
248 \link debug.html Debugging\endlink
249*/
250
251/*!
252 \fn void qWarning( const char *msg, ... )
253
254 \relates QApplication
255
256 Prints a warning message \a msg, or calls the message handler (if
257 it has been installed).
258
259 This function takes a format string and a list of arguments,
260 similar to the C printf() function.
261
262 Example:
263 \code
264 void f( int c )
265 {
266 if ( c > 200 )
267 qWarning( "f: bad argument, c == %d", c );
268 }
269 \endcode
270
271 Under X11, the text is printed to stderr. Under Windows, the text
272 is sent to the debugger.
273
274 \warning The internal buffer is limited to 8196 bytes (including
275 the '\0'-terminator).
276
277 \warning Passing (const char *)0 as argument to qWarning might lead
278 to crashes on certain platforms due to the platforms printf implementation.
279
280 \sa qDebug(), qFatal(), qInstallMsgHandler(),
281 \link debug.html Debugging\endlink
282*/
283
284/*!
285 \fn void qFatal( const char *msg, ... )
286
287 \relates QApplication
288
289 Prints a fatal error message \a msg and exits, or calls the
290 message handler (if it has been installed).
291
292 This function takes a format string and a list of arguments,
293 similar to the C printf() function.
294
295 Example:
296 \code
297 int divide( int a, int b )
298 {
299 if ( b == 0 ) // program error
300 qFatal( "divide: cannot divide by zero" );
301 return a/b;
302 }
303 \endcode
304
305 Under X11, the text is printed to stderr. Under Windows, the text
306 is sent to the debugger.
307
308 \warning The internal buffer is limited to 8196 bytes (including
309 the '\0'-terminator).
310
311 \warning Passing (const char *)0 as argument to qFatal might lead
312 to crashes on certain platforms due to the platforms printf implementation.
313
314 \sa qDebug(), qWarning(), qInstallMsgHandler(),
315 \link debug.html Debugging\endlink
316*/
317
318
319 static QtMsgHandler handler = 0; // pointer to debug handler
320 static const int QT_BUFFER_LENGTH = 8196;// internal buffer length
321
322
323#ifdef Q_OS_MAC
324const unsigned char * p_str(const char * c, int len=-1)
325{
326 const int maxlen = 255;
327 if(len == -1)
328 len = qstrlen(c);
329 if(len > maxlen) {
330 qWarning( "p_str len must never exceed %d", maxlen );
331 len = maxlen;
332 }
333 unsigned char *ret = (unsigned char*)malloc(len+2);
334 *ret=len;
335 memcpy(((char *)ret)+1,c,len);
336 *(ret+len+1) = '\0';
337 return ret;
338}
339
340const unsigned char * p_str(const QString &s)
341{
342 return p_str(s, s.length());
343}
344
345QCString p2qstring(const unsigned char *c) {
346 char *arr = (char *)malloc(c[0] + 1);
347 memcpy(arr, c+1, c[0]);
348 arr[c[0]] = '\0';
349 QCString ret = arr;
350 delete arr;
351 return ret;
352}
353#endif
354
355
356#ifdef Q_CC_MWERKS
357
358#include "qt_mac.h"
359
360extern bool qt_is_gui_used;
361static void mac_default_handler( const char *msg )
362{
363 if ( qt_is_gui_used ) {
364 const char *p = p_str(msg);
365 DebugStr(p);
366 free(p);
367 } else {
368 fprintf( stderr, msg );
369 }
370}
371
372#endif
373
374
375void qDebug( const char *msg, ... )
376{
377 char buf[QT_BUFFER_LENGTH];
378 va_list ap;
379 va_start( ap, msg ); // use variable arg list
380 if ( handler ) {
381#if defined(QT_VSNPRINTF)
382 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
383#else
384 vsprintf( buf, msg, ap );
385#endif
386 va_end( ap );
387 (*handler)( QtDebugMsg, buf );
388 } else {
389#if defined(Q_CC_MWERKS)
390 vsprintf( buf, msg, ap ); // ### is there no vsnprintf()?
391 va_end( ap );
392 mac_default_handler(buf);
393#else
394 vfprintf( stderr, msg, ap );
395 va_end( ap );
396 fprintf( stderr, "\n" ); // add newline
397#endif
398 }
399}
400
401// copied... this looks really bad.
402void debug( const char *msg, ... )
403{
404 char buf[QT_BUFFER_LENGTH];
405 va_list ap;
406 va_start( ap, msg ); // use variable arg list
407 if ( handler ) {
408#if defined(QT_VSNPRINTF)
409 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
410#else
411 vsprintf( buf, msg, ap );
412#endif
413 va_end( ap );
414 (*handler)( QtDebugMsg, buf );
415 } else {
416#ifdef Q_CC_MWERKS
417 vsprintf( buf, msg, ap ); // ### is there no vsnprintf()?
418 va_end( ap );
419 mac_default_handler(buf);
420#else
421 vfprintf( stderr, msg, ap );
422 va_end( ap );
423 fprintf( stderr, "\n" ); // add newline
424#endif
425 }
426}
427
428void qWarning( const char *msg, ... )
429{
430 char buf[QT_BUFFER_LENGTH];
431 va_list ap;
432 va_start( ap, msg ); // use variable arg list
433 if ( handler ) {
434#if defined(QT_VSNPRINTF)
435 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
436#else
437 vsprintf( buf, msg, ap );
438#endif
439 va_end( ap );
440 (*handler)( QtWarningMsg, buf );
441 } else {
442#ifdef Q_CC_MWERKS
443 vsprintf( buf, msg, ap ); // ### is there no vsnprintf()?
444 va_end( ap );
445 mac_default_handler(buf);
446#else
447 vfprintf( stderr, msg, ap );
448 va_end( ap );
449 fprintf( stderr, "\n" ); // add newline
450#endif
451 }
452}
453
454
455// again, copied
456void warning( const char *msg, ... )
457{
458 char buf[QT_BUFFER_LENGTH];
459 va_list ap;
460 va_start( ap, msg ); // use variable arg list
461 if ( handler ) {
462#if defined(QT_VSNPRINTF)
463 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
464#else
465 vsprintf( buf, msg, ap );
466#endif
467 va_end( ap );
468 (*handler)( QtWarningMsg, buf );
469 } else {
470#ifdef Q_CC_MWERKS
471 vsprintf( buf, msg, ap ); // ### is there no vsnprintf()?
472 va_end( ap );
473 mac_default_handler(buf);
474#else
475 vfprintf( stderr, msg, ap );
476 va_end( ap );
477 fprintf( stderr, "\n" ); // add newline
478#endif
479 }
480}
481
482void qFatal( const char *msg, ... )
483{
484 char buf[QT_BUFFER_LENGTH];
485 va_list ap;
486 va_start( ap, msg ); // use variable arg list
487 if ( handler ) {
488#if defined(QT_VSNPRINTF)
489 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
490#else
491 vsprintf( buf, msg, ap );
492#endif
493 va_end( ap );
494 (*handler)( QtFatalMsg, buf );
495 } else {
496#ifdef Q_CC_MWERKS
497 vsprintf( buf, msg, ap ); // ### is there no vsnprintf()?
498 va_end( ap );
499 mac_default_handler(buf);
500#else
501 vfprintf( stderr, msg, ap );
502 va_end( ap );
503 fprintf( stderr, "\n" ); // add newline
504#endif
505#if defined(Q_OS_UNIX) && defined(QT_DEBUG)
506 abort(); // trap; generates core dump
507#else
508 exit( 1 ); // goodbye cruel world
509#endif
510 }
511}
512
513// yet again, copied
514void fatal( const char *msg, ... )
515{
516 char buf[QT_BUFFER_LENGTH];
517 va_list ap;
518 va_start( ap, msg ); // use variable arg list
519 if ( handler ) {
520#if defined(QT_VSNPRINTF)
521 QT_VSNPRINTF( buf, QT_BUFFER_LENGTH, msg, ap );
522#else
523 vsprintf( buf, msg, ap );
524#endif
525 va_end( ap );
526 (*handler)( QtFatalMsg, buf );
527 } else {
528#ifdef Q_CC_MWERKS
529 vsprintf( buf, msg, ap ); // ### is there no vsnprintf()?
530 va_end( ap );
531 mac_default_handler(buf);
532#else
533 vfprintf( stderr, msg, ap );
534 va_end( ap );
535 fprintf( stderr, "\n" ); // add newline
536#endif
537#if defined(Q_OS_UNIX) && defined(QT_DEBUG)
538 abort(); // trap; generates core dump
539#else
540 exit( 1 ); // goodbye cruel world
541#endif
542 }
543}
544
545/*!
546 \relates QApplication
547
548 Prints the message \a msg and uses \a code to get a system specific
549 error message. When \a code is -1 (the default), the system's last
550 error code will be used if possible. Use this method to handle
551 failures in platform specific API calls.
552
553 This function does nothing when Qt is built with \c QT_NO_DEBUG
554 defined.
555*/
556void qSystemWarning( const char* msg, int code )
557{
558#ifndef QT_NO_DEBUG
559#if defined(Q_OS_WIN32)
560 if ( code == -1 )
561 code = GetLastError();
562
563 if ( !code )
564 return;
565
566#ifdef Q_OS_TEMP
567 unsigned short *string;
568
569 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
570 NULL,
571 code,
572 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
573 (LPTSTR)&string,
574 0,
575 NULL );
576
577 qWarning( "%s\n\tError code %d - %s (###may need fixing in qglobal.h)", msg, code, (const char *)string );
578#else
579 char* string;
580
581 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
582 NULL,
583 code,
584 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
585 (char*)&string,
586 0,
587 NULL );
588
589 qWarning( "%s\n\tError code %d - %s", msg, code, (const char*)string );
590#endif
591
592 LocalFree( (HLOCAL)string );
593#else
594 if ( code != -1 )
595 qWarning( "%s\n\tError code %d - %s", msg, code, strerror( code ) );
596 else
597 qWarning( msg );
598#endif
599#endif
600}
601
602/*!
603 \fn void Q_ASSERT( bool test )
604
605 \relates QApplication
606
607 Prints a warning message containing the source code file name and
608 line number if \a test is FALSE.
609
610 This is really a macro defined in \c qglobal.h.
611
612 Q_ASSERT is useful for testing pre- and post-conditions.
613
614 Example:
615 \code
616 //
617 // File: div.cpp
618 //
619
620 #include <qglobal.h>
621
622 int divide( int a, int b )
623 {
624 Q_ASSERT( b != 0 ); // this is line 9
625 return a/b;
626 }
627 \endcode
628
629 If \c b is zero, the Q_ASSERT statement will output the following
630 message using the qWarning() function:
631 \code
632 ASSERT: "b == 0" in div.cpp (9)
633 \endcode
634
635 \sa qWarning(), \link debug.html Debugging\endlink
636*/
637
638
639/*!
640 \fn void Q_CHECK_PTR( void *p )
641
642 \relates QApplication
643
644 If \a p is null, a fatal messages says that the program ran out of
645 memory and exits. If \e p is not null, nothing happens.
646
647 This is really a macro defined in \c qglobal.h.
648
649 Example:
650 \code
651 int *a;
652
653 Q_CHECK_PTR( a = new int[80] ); // WRONG!
654
655 a = new int[80]; // Right
656 Q_CHECK_PTR( a );
657 \endcode
658
659 \sa qFatal(), \link debug.html Debugging\endlink
660*/
661
662
663//
664// The Q_CHECK_PTR macro calls this function to check if an allocation went ok.
665//
666#if (QT_VERSION-0 >= 0x040000)
667#if defined(Q_CC_GNU)
668#warning "Change Q_CHECK_PTR to '{if ((p)==0) qt_check_pointer(__FILE__,__LINE__);}'"
669#warning "No need for qt_check_pointer() to return a value - make it void!"
670#endif
671#endif
672bool qt_check_pointer( bool c, const char *n, int l )
673{
674 if ( c )
675 qWarning( "In file %s, line %d: Out of memory", n, l );
676 return TRUE;
677}
678
679
680static bool firstObsoleteWarning(const char *obj, const char *oldfunc )
681{
682 static QAsciiDict<int> *obsoleteDict = 0;
683 if ( !obsoleteDict ) { // first time func is called
684 obsoleteDict = new QAsciiDict<int>;
685#if defined(QT_DEBUG)
686 qDebug(
687 "You are using obsolete functions in the Qt library. Call the function\n"
688 "qSuppressObsoleteWarnings() to suppress obsolete warnings.\n"
689 );
690#endif
691 }
692 QCString s( obj );
693 s += "::";
694 s += oldfunc;
695 if ( obsoleteDict->find(s.data()) == 0 ) {
696 obsoleteDict->insert( s.data(), (int*)1 );// anything different from 0
697 return TRUE;
698 }
699 return FALSE;
700}
701
702static bool suppressObsolete = FALSE;
703
704void qSuppressObsoleteWarnings( bool suppress )
705{
706 suppressObsolete = suppress;
707}
708
709 void qObsolete( const char *obj, const char *oldfunc, const char *newfunc )
710{
711 if ( suppressObsolete )
712 return;
713 if ( !firstObsoleteWarning(obj, oldfunc) )
714 return;
715 if ( obj )
716 qDebug( "%s::%s: This function is obsolete, use %s instead.",
717 obj, oldfunc, newfunc );
718 else
719 qDebug( "%s: This function is obsolete, use %s instead.",
720 oldfunc, newfunc );
721}
722
723 void qObsolete( const char *obj, const char *oldfunc )
724{
725 if ( suppressObsolete )
726 return;
727 if ( !firstObsoleteWarning(obj, oldfunc) )
728 return;
729 if ( obj )
730 qDebug( "%s::%s: This function is obsolete.", obj, oldfunc );
731 else
732 qDebug( "%s: This function is obsolete.", oldfunc );
733}
734
735 void qObsolete( const char *message )
736{
737 if ( suppressObsolete )
738 return;
739 if ( !firstObsoleteWarning( "Qt", message) )
740 return;
741 qDebug( "%s", message );
742}
743
744
745/*!
746 \relates QApplication
747
748 Installs a Qt message handler \a h. Returns a pointer to the
749 message handler previously defined.
750
751 The message handler is a function that prints out debug messages,
752 warnings and fatal error messages. The Qt library (debug version)
753 contains hundreds of warning messages that are printed when
754 internal errors (usually invalid function arguments) occur. If you
755 implement your own message handler, you get total control of these
756 messages.
757
758 The default message handler prints the message to the standard
759 output under X11 or to the debugger under Windows. If it is a
760 fatal message, the application aborts immediately.
761
762 Only one message handler can be defined, since this is usually
763 done on an application-wide basis to control debug output.
764
765 To restore the message handler, call \c qInstallMsgHandler(0).
766
767 Example:
768 \code
769 #include <qapplication.h>
770 #include <stdio.h>
771 #include <stdlib.h>
772
773 void myMessageOutput( QtMsgType type, const char *msg )
774 {
775 switch ( type ) {
776 case QtDebugMsg:
777 fprintf( stderr, "Debug: %s\n", msg );
778 break;
779 case QtWarningMsg:
780 fprintf( stderr, "Warning: %s\n", msg );
781 break;
782 case QtFatalMsg:
783 fprintf( stderr, "Fatal: %s\n", msg );
784 abort(); // deliberately core dump
785 }
786 }
787
788 int main( int argc, char **argv )
789 {
790 qInstallMsgHandler( myMessageOutput );
791 QApplication a( argc, argv );
792 ...
793 return a.exec();
794 }
795 \endcode
796
797 \sa qDebug(), qWarning(), qFatal(), \link debug.html Debugging\endlink
798*/
799
800QtMsgHandler qInstallMsgHandler( QtMsgHandler h )
801{
802 QtMsgHandler old = handler;
803 handler = h;
804 return old;
805}
806
807
808/*
809 Dijkstra's bisection algorithm to find the square root as an integer.
810 Deliberately not exported as part of the Qt API, but used in both
811 qsimplerichtext.cpp and qgfxraster_qws.cpp
812*/
813unsigned int qt_int_sqrt( unsigned int n )
814{
815 // n must be in the range 0...UINT_MAX/2-1
816 if ( n >= ( UINT_MAX>>2 ) ) {
817 unsigned int r = 2 * qt_int_sqrt( n / 4 );
818 unsigned int r2 = r + 1;
819 return ( n >= r2 * r2 ) ? r2 : r;
820 }
821 uint h, p= 0, q= 1, r= n;
822 while ( q <= n )
823 q <<= 2;
824 while ( q != 1 ) {
825 q >>= 2;
826 h= p + q;
827 p >>= 1;
828 if ( r >= h ) {
829 p += q;
830 r -= h;
831 }
832 }
833 return p;
834}
835
diff --git a/qmake/tools/qgpluginmanager.cpp b/qmake/tools/qgpluginmanager.cpp
new file mode 100644
index 0000000..46c85f5
--- a/dev/null
+++ b/qmake/tools/qgpluginmanager.cpp
@@ -0,0 +1,544 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QGPluginManager class
5**
6** Copyright (C) 2000-2001 Trolltech AS. All rights reserved.
7**
8** This file is part of the tools module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "qgpluginmanager_p.h"
37#ifndef QT_NO_COMPONENT
38#include "qcomlibrary_p.h"
39#include "qmap.h"
40#include "qdir.h"
41
42/*
43 The following co-occurrence code is borrowed from Qt Linguist.
44
45 How similar are two texts? The approach used here relies on
46 co-occurrence matrices and is very efficient.
47
48 Let's see with an example: how similar are "here" and "hither"? The
49 co-occurrence matrix M for "here" is M[h,e] = 1, M[e,r] = 1,
50 M[r,e] = 1 and 0 elsewhere; the matrix N for "hither" is N[h,i] = 1,
51 N[i,t] = 1, ..., N[h,e] = 1, N[e,r] = 1 and 0 elsewhere. The union
52 U of both matrices is the matrix U[i,j] = max { M[i,j], N[i,j] },
53 and the intersection V is V[i,j] = min { M[i,j], N[i,j] }. The score
54 for a pair of texts is
55
56 score = (sum of V[i,j] over all i, j) / (sum of U[i,j] over all i, j),
57
58 a formula suggested by Arnt Gulbrandsen. Here we have
59
60 score = 2 / 6,
61
62 or one third.
63
64 The implementation differs from this in a few details. Most
65 importantly, repetitions are ignored; for input "xxx", M[x,x] equals
66 1, not 2.
67*/
68
69/*
70 Every character is assigned to one of 20 buckets so that the
71 co-occurrence matrix requires only 20 * 20 = 400 bits, not
72 256 * 256 = 65536 bits or even more if we want the whole Unicode.
73 Which character falls in which bucket is arbitrary.
74
75 The second half of the table is a replica of the first half, because of
76 laziness.
77*/
78static const char indexOf[256] = {
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81// ! " # $ % & ' ( ) * + , - . /
82 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
83// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
84 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
85// @ A B C D E F G H I J K L M N O
86 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
87// P Q R S T U V W X Y Z [ \ ] ^ _
88 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
89// ` a b c d e f g h i j k l m n o
90 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
91// p q r s t u v w x y z { | } ~
92 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
93
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
97 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
99 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
100 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
101 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0
102};
103
104/*
105 The entry bitCount[i] (for i between 0 and 255) is the number of
106 bits used to represent i in binary.
107*/
108static const char bitCount[256] = {
109 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
110 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
111 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
112 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
113 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
114 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
115 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
116 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
117 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
118 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
119 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
120 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
121 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
122 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
123 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
124 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
125};
126
127class QCoMatrix
128{
129public:
130 /*
131 The matrix has 20 * 20 = 400 entries. This requires 50 bytes, or
132 13 words. Some operations are performed on words for more
133 efficiency.
134 */
135 union {
136 Q_UINT8 b[52];
137 Q_UINT32 w[13];
138 };
139
140 QCoMatrix() { memset( b, 0, 52 ); }
141 QCoMatrix( const char *text ) {
142 char c = '\0', d;
143 memset( b, 0, 52 );
144 while ( (d = *text) != '\0' ) {
145 setCoocc( c, d );
146 if ( (c = *++text) != '\0' ) {
147 setCoocc( d, c );
148 text++;
149 }
150 }
151 }
152
153 void setCoocc( char c, char d ) {
154 int k = indexOf[(uchar) c] + 20 * indexOf[(uchar) d];
155 b[k >> 3] |= k & 0x7;
156 }
157
158 int worth() const {
159 int result = 0;
160 for ( int i = 0; i < 50; i++ )
161 result += bitCount[b[i]];
162 return result;
163 }
164
165 static QCoMatrix reunion( const QCoMatrix& m, const QCoMatrix& n )
166 {
167 QCoMatrix p;
168 for ( int i = 0; i < 13; i++ )
169 p.w[i] = m.w[i] | n.w[i];
170 return p;
171 }
172 static QCoMatrix intersection( const QCoMatrix& m, const QCoMatrix& n )
173 {
174 QCoMatrix p;
175 for ( int i = 0; i < 13; i++ )
176 p.w[i] = m.w[i] & n.w[i];
177 return p;
178 }
179};
180
181/*
182 Returns an integer between 0 (dissimilar) and 15 (very similar)
183 depending on how similar the string is to \a target.
184
185 This function is efficient, but its results might change in future
186 versions of Qt as the algorithm evolves.
187
188 \code
189 QString s( "color" );
190 a = similarity( s, "color" ); // a == 15
191 a = similarity( s, "colour" ); // a == 8
192 a = similarity( s, "flavor" ); // a == 4
193 a = similarity( s, "dahlia" ); // a == 0
194 \endcode
195*/
196static int similarity( const QString& s1, const QString& s2 )
197{
198 QCoMatrix m1( s1 );
199 QCoMatrix m2( s2 );
200 return ( 15 * (QCoMatrix::intersection(m1, m2).worth() + 1) ) /
201 ( QCoMatrix::reunion(m1, m2).worth() + 1 );
202}
203
204/*!
205 \class QPluginManager qpluginmanager.h
206 \reentrant
207 \brief The QPluginManager class provides basic functions to access a certain kind of functionality in libraries.
208 \ingroup componentmodel
209
210 \internal
211
212 A common usage of components is to extend the existing functionality in an application using plugins. The application
213 defines interfaces that abstract a certain group of functionality, and a plugin provides a specialized implementation
214 of one or more of those interfaces.
215
216 The QPluginManager template has to be instantiated with an interface definition and the IID for this interface.
217
218 \code
219 QPluginManager<MyPluginInterface> *manager = new QPluginManager<MyPluginInterface>( IID_MyPluginInterface );
220 \endcode
221
222 It searches a specified directory for all shared libraries, queries for components that implement the specific interface and
223 reads information about the features the plugin wants to add to the application. The component can provide the set of features
224 provided by implementing either the QFeatureListInterface or the QComponentInformationInterface. The strings returned by the implementations
225 of
226
227 \code
228 QStringList QFeatureListInterface::featureList() const
229 \endcode
230
231 or
232
233 \code
234 QString QComponentInformationInterface::name() const
235 \endcode
236
237 respectively, can then be used to access the component that provides the requested feature:
238
239 \code
240 MyPluginInterface *iface;
241 manager->queryInterface( "feature", &iface );
242 if ( iface )
243 iface->execute( "feature" );
244 \endcode
245
246 The application can use a QPluginManager instance to create parts of the user interface based on the list of features
247 found in plugins:
248
249 \code
250 QPluginManager<MyPluginInterface> *manager = new QPluginManager<MyPluginInterface>( IID_ImageFilterInterface );
251 manager->addLibraryPath(...);
252
253 QStringList features = manager->featureList();
254 for ( QStringList::Iterator it = features.begin(); it != features.end(); ++it ) {
255 MyPluginInterface *iface;
256 manager->queryInterface( *it, &iface );
257
258 // use QAction to provide toolbuttons and menuitems for each feature...
259 }
260 \endcode
261*/
262
263/*!
264 \fn QPluginManager::QPluginManager( const QUuid& id, const QStringList& paths = QString::null, const QString &suffix = QString::null, bool cs = TRUE )
265
266 Creates an QPluginManager for interfaces \a id that will load all shared library files in the \a paths + \a suffix.
267 If \a cs is FALSE the manager will handle feature strings case insensitive.
268
269 \warning
270 Setting the cs flag to FALSE requires that components also convert to lower case when comparing with passed strings, so this has
271 to be handled with care and documented very well.
272
273 \sa QApplication::libraryPaths()
274*/
275
276
277/*!
278 \fn QRESULT QPluginManager::queryInterface(const QString& feature, Type** iface) const
279
280 Sets \a iface to point to the interface providing \a feature.
281
282 \sa featureList(), library()
283*/
284
285
286
287#include <qptrlist.h>
288
289QGPluginManager::QGPluginManager( const QUuid& id, const QStringList& paths, const QString &suffix, bool cs )
290 : interfaceId( id ), plugDict( 17, cs ), casesens( cs ), autounload( TRUE )
291{
292 // Every QLibrary object is destroyed on destruction of the manager
293 libDict.setAutoDelete( TRUE );
294 for ( QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it ) {
295 QString path = *it;
296 addLibraryPath( path + suffix );
297 }
298}
299
300QGPluginManager::~QGPluginManager()
301{
302 if ( !autounload ) {
303 QDictIterator<QLibrary> it( libDict );
304 while ( it.current() ) {
305 QLibrary *lib = it.current();
306 ++it;
307 lib->setAutoUnload( FALSE );
308 }
309 }
310}
311
312void QGPluginManager::addLibraryPath( const QString& path )
313{
314 if ( !enabled() || !QDir( path ).exists( ".", TRUE ) )
315 return;
316
317#if defined(Q_OS_WIN32)
318 QString filter = "dll";
319#elif defined(Q_OS_MACX)
320 QString filter = "dylib";
321#elif defined(Q_OS_UNIX)
322 QString filter = "so";
323#endif
324
325 QStringList plugins = QDir(path).entryList( "*." + filter );
326 for ( QStringList::Iterator p = plugins.begin(); p != plugins.end(); ++p ) {
327 QString lib = QDir::cleanDirPath( path + "/" + *p );
328 if ( libList.contains( lib ) )
329 continue;
330 libList.append( lib );
331 }
332}
333
334const QLibrary* QGPluginManager::library( const QString& feature ) const
335{
336 if ( !enabled() || feature.isEmpty() )
337 return 0;
338
339 // We already have a QLibrary object for this feature
340 QLibrary *library = 0;
341 if ( ( library = plugDict[feature] ) )
342 return library;
343
344 // Find the filename that matches the feature request best
345 QMap<int, QStringList> map;
346 QStringList::ConstIterator it = libList.begin();
347 int best = 0;
348 int worst = 15;
349 while ( it != libList.end() ) {
350 if ( (*it).isEmpty() || libDict[*it] ) {
351 ++it;
352 continue;
353 }
354 QString basename = QFileInfo(*it).baseName();
355 int s = similarity( feature, basename );
356 if ( s < worst )
357 worst = s;
358 if ( s > best )
359 best = s;
360 map[s].append( basename + QChar(0xfffd) + *it );
361 ++it;
362 }
363
364 if ( map.isEmpty() )
365 return 0; // no libraries to add
366
367 // Start with the best match to get the library object
368 QGPluginManager *that = (QGPluginManager*)this;
369 for ( int s = best; s >= worst; --s ) {
370 QStringList group = map[s];
371 group.sort(); // sort according to the base name
372 QStringList::ConstIterator git = group.begin();
373 while ( git != group.end() ) {
374 QString lib = (*git).mid( (*git).find( QChar(0xfffd) ) + 1 );
375 QString basename = (*git).left( (*git).find( QChar(0xfffd) ) );
376 ++git;
377
378 QStringList sameBasename;
379 while( git != group.end() &&
380 basename == (*git).left( (*git).find( QChar(0xfffd) ) ) ) {
381 sameBasename << (*git).mid( (*git).find( QChar(0xfffd) ) + 1 );
382 ++git;
383 }
384
385 if ( sameBasename.isEmpty() ) {
386 that->addLibrary( new QComLibrary( lib ) );
387 } else {
388 QPtrList<QComLibrary> same;
389 same.setAutoDelete( TRUE );
390 for ( QStringList::ConstIterator bit = sameBasename.begin();
391 bit != sameBasename.end(); ++bit )
392 same.append( new QComLibrary( *bit ) );
393 QComLibrary* bestMatch = 0;
394 for ( QComLibrary* candidate = same.first(); candidate; candidate = same.next() )
395 if ( candidate->qtVersion() && candidate->qtVersion() <= QT_VERSION
396 && ( !bestMatch || candidate->qtVersion() > bestMatch->qtVersion() ) )
397 bestMatch = candidate;
398 if ( bestMatch ) {
399 same.find( bestMatch );
400 that->addLibrary( same.take() );
401 }
402 }
403
404 if ( ( library = that->plugDict[feature] ) )
405 return library;
406 }
407 }
408 return 0;
409}
410
411QStringList QGPluginManager::featureList() const
412{
413 QStringList features;
414
415 if ( !enabled() )
416 return features;
417
418 QGPluginManager *that = (QGPluginManager*)this;
419 QStringList theLibs = libList;
420 QStringList phase2Libs;
421 QStringList phase2Deny;
422
423 /* In order to get the feature list we need to add all interesting
424 libraries. If there are libraries with the same base name, we
425 prioritze the one that fits our Qt version number and ignore the
426 others */
427 QStringList::Iterator it;
428 for ( it = theLibs.begin(); it != theLibs.end(); ++it ) {
429 if ( (*it).isEmpty() || libDict[*it] )
430 continue;
431 QComLibrary* library = new QComLibrary( *it );
432 if ( library->qtVersion() == QT_VERSION ) {
433 that->addLibrary( library );
434 phase2Deny << QFileInfo( *it ).baseName();
435 } else {
436 delete library;
437 phase2Libs << *it;
438 }
439 }
440 for ( it = phase2Libs.begin(); it != phase2Libs.end(); ++it )
441 if ( !phase2Deny.contains( QFileInfo( *it ).baseName() ) )
442 that->addLibrary( new QComLibrary( *it ) );
443
444 for ( QDictIterator<QLibrary> pit( plugDict ); pit.current(); ++pit )
445 features << pit.currentKey();
446
447 return features;
448}
449
450bool QGPluginManager::addLibrary( QLibrary* lib )
451{
452 if ( !enabled() || !lib )
453 return FALSE;
454
455 QComLibrary* plugin = (QComLibrary*)lib;
456 bool useful = FALSE;
457
458 QUnknownInterface* iFace = 0;
459 plugin->queryInterface( interfaceId, &iFace );
460 if ( iFace ) {
461 QFeatureListInterface *fliFace = 0;
462 QComponentInformationInterface *cpiFace = 0;
463 iFace->queryInterface( IID_QFeatureList, (QUnknownInterface**)&fliFace );
464 if ( !fliFace )
465 plugin->queryInterface( IID_QFeatureList, (QUnknownInterface**)&fliFace );
466 if ( !fliFace ) {
467 iFace->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace );
468 if ( !cpiFace )
469 plugin->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace );
470 }
471 QStringList fl;
472 if ( fliFace )
473 // Map all found features to the library
474 fl = fliFace->featureList();
475 else if ( cpiFace )
476 fl << cpiFace->name();
477
478 for ( QStringList::Iterator f = fl.begin(); f != fl.end(); f++ ) {
479 QLibrary *old = plugDict[*f];
480 if ( !old ) {
481 useful = TRUE;
482 plugDict.replace( *f, plugin );
483 } else {
484 // we have old *and* plugin, which one to pick?
485 QComLibrary* first = (QComLibrary*)old;
486 QComLibrary* second = (QComLibrary*)plugin;
487 bool takeFirst = TRUE;
488 if ( first->qtVersion() != QT_VERSION ) {
489 if ( second->qtVersion() == QT_VERSION )
490 takeFirst = FALSE;
491 else if ( second->qtVersion() < QT_VERSION &&
492 first->qtVersion() > QT_VERSION )
493 takeFirst = FALSE;
494 }
495 if ( !takeFirst ) {
496 useful = TRUE;
497 plugDict.replace( *f, plugin );
498 qWarning("%s: Discarding feature %s in %s!",
499 (const char*) QFile::encodeName( plugin->library()),
500 (*f).latin1(),
501 (const char*) QFile::encodeName( old->library() ) );
502 } else {
503 qWarning("%s: Feature %s already defined in %s!",
504 (const char*) QFile::encodeName( old->library() ),
505 (*f).latin1(),
506 (const char*) QFile::encodeName( plugin->library() ) );
507 }
508 }
509 }
510 if ( fliFace )
511 fliFace->release();
512 if ( cpiFace )
513 cpiFace->release();
514 iFace->release();
515 }
516
517 if ( useful ) {
518 libDict.replace( plugin->library(), plugin );
519 if ( !libList.contains( plugin->library() ) )
520 libList.append( plugin->library() );
521 return TRUE;
522 }
523 delete plugin;
524 return FALSE;
525}
526
527
528bool QGPluginManager::enabled() const
529{
530#ifdef QT_SHARED
531 return TRUE;
532#else
533 return FALSE;
534#endif
535}
536
537QRESULT QGPluginManager::queryUnknownInterface(const QString& feature, QUnknownInterface** iface) const
538{
539 QComLibrary* plugin = 0;
540 plugin = (QComLibrary*)library( feature );
541 return plugin ? plugin->queryInterface( interfaceId, (QUnknownInterface**)iface ) : QE_NOINTERFACE;
542}
543
544#endif //QT_NO_COMPONENT
diff --git a/qmake/tools/qgvector.cpp b/qmake/tools/qgvector.cpp
new file mode 100644
index 0000000..1985f03
--- a/dev/null
+++ b/qmake/tools/qgvector.cpp
@@ -0,0 +1,584 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QGVector class
5**
6** Created : 930907
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38 #define QGVECTOR_CPP
39#include "qgvector.h"
40#include "qglist.h"
41#include "qstring.h"
42#include "qdatastream.h"
43#include <stdlib.h>
44
45#ifdef QT_THREAD_SUPPORT
46# include <private/qmutexpool_p.h>
47#endif // QT_THREAD_SUPPORT
48
49 #define USE_MALLOC // comment to use new/delete
50
51#undef NEW
52#undef DELETE
53
54#if defined(USE_MALLOC)
55 #define NEW(type,size)((type*)malloc(size*sizeof(type)))
56 #define DELETE(array)(free((char*)array))
57#else
58 #define NEW(type,size)(new type[size])
59 #define DELETE(array)(delete[] array)
60 #define DONT_USE_REALLOC // comment to use realloc()
61#endif
62
63/*!
64 \class QGVector
65 \reentrant
66 \ingroup collection
67
68 \brief The QGVector class is an internal class for implementing Qt
69 collection classes.
70
71 \internal
72
73 QGVector is an internal class that acts as a base class for the
74 QPtrVector collection class.
75
76 QGVector has some virtual functions that may be reimplemented in
77 subclasses to customize behavior.
78
79 \list
80 \i compareItems() compares two collection/vector items.
81 \i read() reads a collection/vector item from a QDataStream.
82 \i write() writes a collection/vector item to a QDataStream.
83 \endlist
84*/
85
86/*****************************************************************************
87 Default implementation of virtual functions
88 *****************************************************************************/
89
90/*!
91 This virtual function compares two list items.
92
93 Returns:
94 <ul>
95 <li> 0 if \a d1 == \a d2
96 <li> non-zero if \a d1 != \a d2
97 </ul>
98
99 This function returns \e int rather than \e bool so that
100 reimplementations can return one of three values and use it to sort
101 by:
102 <ul>
103 <li> 0 if \a d1 == \a d2
104 <li> \> 0 (positive integer) if \a d1 \> \a d2
105 <li> \< 0 (negative integer) if \a d1 \< \a d2
106 </ul>
107
108 The QPtrVector::sort() and QPtrVector::bsearch() functions require that
109 compareItems() is implemented as described here.
110
111 This function should not modify the vector because some const
112 functions call compareItems().
113*/
114
115int QGVector::compareItems( Item d1, Item d2 )
116{
117 return d1 != d2; // compare pointers
118}
119
120#ifndef QT_NO_DATASTREAM
121/*!
122 Reads a collection/vector item from the stream \a s and returns a reference
123 to the stream.
124
125 The default implementation sets \a d to 0.
126
127 \sa write()
128*/
129
130QDataStream &QGVector::read( QDataStream &s, Item &d )
131 { // read item from stream
132 d = 0;
133 return s;
134}
135
136/*!
137 Writes a collection/vector item to the stream \a s and returns a reference
138 to the stream.
139
140 The default implementation does nothing.
141
142 \sa read()
143*/
144
145QDataStream &QGVector::write( QDataStream &s, Item ) const
146 { // write item to stream
147 return s;
148}
149#endif // QT_NO_DATASTREAM
150
151/*****************************************************************************
152 QGVector member functions
153 *****************************************************************************/
154
155 QGVector::QGVector() // create empty vector
156{
157 vec = 0;
158 len = numItems = 0;
159}
160
161 QGVector::QGVector( uint size ) // create vectors with nullptrs
162{
163 len = size;
164 numItems = 0;
165 if ( len == 0 ) { // zero length
166 vec = 0;
167 return;
168 }
169 vec = NEW(Item,len);
170 Q_CHECK_PTR( vec );
171 memset( (void*)vec, 0, len*sizeof(Item) );// fill with nulls
172}
173
174 QGVector::QGVector( const QGVector &a ) // make copy of other vector
175 : QPtrCollection( a )
176{
177 len = a.len;
178 numItems = a.numItems;
179 if ( len == 0 ) {
180 vec = 0;
181 return;
182 }
183 vec = NEW( Item, len );
184 Q_CHECK_PTR( vec );
185 for ( uint i = 0; i < len; i++ ) {
186 if ( a.vec[i] ) {
187 vec[i] = newItem( a.vec[i] );
188 Q_CHECK_PTR( vec[i] );
189 } else {
190 vec[i] = 0;
191 }
192 }
193}
194
195QGVector::~QGVector()
196{
197 clear();
198}
199
200QGVector& QGVector::operator=( const QGVector &v )
201{
202 if ( &v == this )
203 return *this;
204
205 clear();
206 len = v.len;
207 numItems = v.numItems;
208 if ( len == 0 ) {
209 vec = 0;
210 return *this;
211 }
212 vec = NEW( Item, len );
213 Q_CHECK_PTR( vec );
214 for ( uint i = 0; i < len; i++ ) {
215 if ( v.vec[i] ) {
216 vec[i] = newItem( v.vec[i] );
217 Q_CHECK_PTR( vec[i] );
218 } else {
219 vec[i] = 0;
220 }
221 }
222 return *this;
223}
224
225
226 bool QGVector::insert( uint index, Item d )// insert item at index
227{
228#if defined(QT_CHECK_RANGE)
229 if ( index >= len ) { // range error
230 qWarning( "QGVector::insert: Index %d out of range", index );
231 return FALSE;
232 }
233#endif
234 if ( vec[index] ) { // remove old item
235 deleteItem( vec[index] );
236 numItems--;
237 }
238 if ( d ) {
239 vec[index] = newItem( d );
240 Q_CHECK_PTR( vec[index] );
241 numItems++;
242 return vec[index] != 0;
243 } else {
244 vec[index] = 0; // reset item
245 }
246 return TRUE;
247}
248
249 bool QGVector::remove( uint index ) // remove item at index
250{
251#if defined(QT_CHECK_RANGE)
252 if ( index >= len ) { // range error
253 qWarning( "QGVector::remove: Index %d out of range", index );
254 return FALSE;
255 }
256#endif
257 if ( vec[index] ) { // valid item
258 deleteItem( vec[index] ); // delete it
259 vec[index] = 0; // reset pointer
260 numItems--;
261 }
262 return TRUE;
263}
264
265 QPtrCollection::Item QGVector::take( uint index ) // take out item
266{
267#if defined(QT_CHECK_RANGE)
268 if ( index >= len ) { // range error
269 qWarning( "QGVector::take: Index %d out of range", index );
270 return 0;
271 }
272#endif
273 Item d = vec[index]; // don't delete item
274 if ( d )
275 numItems--;
276 vec[index] = 0;
277 return d;
278}
279
280 void QGVector::clear() // clear vector
281{
282 if ( vec ) {
283 for ( uint i=0; i<len; i++ ) { // delete each item
284 if ( vec[i] )
285 deleteItem( vec[i] );
286 }
287 DELETE(vec);
288 vec = 0;
289 len = numItems = 0;
290 }
291}
292
293 bool QGVector::resize( uint newsize ) // resize array
294{
295 if ( newsize == len ) // nothing to do
296 return TRUE;
297 if ( vec ) { // existing data
298 if ( newsize < len ) { // shrink vector
299 uint i = newsize;
300 while ( i < len ) { // delete lost items
301 if ( vec[i] ) {
302 deleteItem( vec[i] );
303 numItems--;
304 }
305 i++;
306 }
307 }
308 if ( newsize == 0 ) { // vector becomes empty
309 DELETE(vec);
310 vec = 0;
311 len = numItems = 0;
312 return TRUE;
313 }
314#if defined(DONT_USE_REALLOC)
315 if ( newsize == 0 ) {
316 DELETE(vec);
317 vec = 0;
318 return FALSE;
319 }
320 Item *newvec = NEW(Item,newsize); // manual realloc
321 memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) );
322 DELETE(vec);
323 vec = newvec;
324#else
325 vec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) );
326#endif
327 } else { // create new vector
328 vec = NEW(Item,newsize);
329 len = numItems = 0;
330 }
331 Q_CHECK_PTR( vec );
332 if ( !vec ) // no memory
333 return FALSE;
334 if ( newsize > len ) // init extra space added
335 memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) );
336 len = newsize;
337 return TRUE;
338}
339
340
341 bool QGVector::fill( Item d, int flen ) // resize and fill vector
342{
343 if ( flen < 0 )
344 flen = len; // default: use vector length
345 else if ( !resize( flen ) )
346 return FALSE;
347 for ( uint i=0; i<(uint)flen; i++ ) // insert d at every index
348 insert( i, d );
349 return TRUE;
350}
351
352
353 static QGVector *sort_vec=0; // current sort vector
354
355
356#if defined(Q_C_CALLBACKS)
357extern "C" {
358#endif
359
360#ifdef Q_OS_TEMP
361static int _cdecl cmp_vec( const void *n1, const void *n2 )
362#else
363static int cmp_vec( const void *n1, const void *n2 )
364#endif
365{
366 return sort_vec->compareItems( *((QPtrCollection::Item*)n1), *((QPtrCollection::Item*)n2) );
367}
368
369#if defined(Q_C_CALLBACKS)
370}
371#endif
372
373
374 void QGVector::sort() // sort vector
375{
376 if ( count() == 0 ) // no elements
377 return;
378 register Item *start = &vec[0];
379 register Item *end= &vec[len-1];
380 Item tmp;
381 for (;;) { // put all zero elements behind
382 while ( start < end && *start != 0 )
383 start++;
384 while ( end > start && *end == 0 )
385 end--;
386 if ( start < end ) {
387 tmp = *start;
388 *start = *end;
389 *end = tmp;
390 } else {
391 break;
392 }
393 }
394
395#ifdef QT_THREAD_SUPPORT
396 QMutexLocker locker( qt_global_mutexpool->get( &sort_vec ) );
397#endif // QT_THREAD_SUPPORT
398
399 sort_vec = (QGVector*)this;
400 qsort( vec, count(), sizeof(Item), cmp_vec );
401 sort_vec = 0;
402}
403
404 int QGVector::bsearch( Item d ) const // binary search; when sorted
405{
406 if ( !len )
407 return -1;
408 if ( !d ) {
409#if defined(QT_CHECK_NULL)
410 qWarning( "QGVector::bsearch: Cannot search for null object" );
411#endif
412 return -1;
413 }
414 int n1 = 0;
415 int n2 = len - 1;
416 int mid = 0;
417 bool found = FALSE;
418 while ( n1 <= n2 ) {
419 int res;
420 mid = (n1 + n2)/2;
421 if ( vec[mid] == 0 ) // null item greater
422 res = -1;
423 else
424 res = ((QGVector*)this)->compareItems( d, vec[mid] );
425 if ( res < 0 )
426 n2 = mid - 1;
427 else if ( res > 0 )
428 n1 = mid + 1;
429 else { // found it
430 found = TRUE;
431 break;
432 }
433 }
434 if ( !found )
435 return -1;
436 // search to first of equal items
437 while ( (mid - 1 >= 0) && !((QGVector*)this)->compareItems(d, vec[mid-1]) )
438 mid--;
439 return mid;
440}
441
442int QGVector::findRef( Item d, uint index) const // find exact item in vector
443{
444#if defined(QT_CHECK_RANGE)
445 if ( index > len ) { // range error
446 qWarning( "QGVector::findRef: Index %d out of range", index );
447 return -1;
448 }
449#endif
450 for ( uint i=index; i<len; i++ ) {
451 if ( vec[i] == d )
452 return i;
453 }
454 return -1;
455}
456
457 int QGVector::find( Item d, uint index ) const// find equal item in vector
458{
459#if defined(QT_CHECK_RANGE)
460 if ( index >= len ) { // range error
461 qWarning( "QGVector::find: Index %d out of range", index );
462 return -1;
463 }
464#endif
465 for ( uint i=index; i<len; i++ ) {
466 if ( vec[i] == 0 && d == 0 ) // found null item
467 return i;
468 if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
469 return i;
470 }
471 return -1;
472}
473
474 uint QGVector::containsRef( Item d ) const// get number of exact matches
475{
476 uint count = 0;
477 for ( uint i=0; i<len; i++ ) {
478 if ( vec[i] == d )
479 count++;
480 }
481 return count;
482}
483
484 uint QGVector::contains( Item d ) const // get number of equal matches
485{
486 uint count = 0;
487 for ( uint i=0; i<len; i++ ) {
488 if ( vec[i] == 0 && d == 0 ) // count null items
489 count++;
490 if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
491 count++;
492 }
493 return count;
494}
495
496bool QGVector::insertExpand( uint index, Item d )// insert and grow if necessary
497{
498 if ( index >= len ) {
499 if ( !resize( index+1 ) ) // no memory
500 return FALSE;
501 }
502 insert( index, d );
503 return TRUE;
504}
505
506 void QGVector::toList( QGList *list ) const// store items in list
507{
508 list->clear();
509 for ( uint i=0; i<len; i++ ) {
510 if ( vec[i] )
511 list->append( vec[i] );
512 }
513}
514
515
516void QGVector::warningIndexRange( uint i )
517{
518#if defined(QT_CHECK_RANGE)
519 qWarning( "QGVector::operator[]: Index %d out of range", i );
520#else
521 Q_UNUSED( i )
522#endif
523}
524
525
526/*****************************************************************************
527 QGVector stream functions
528 *****************************************************************************/
529#ifndef QT_NO_DATASTREAM
530QDataStream &operator>>( QDataStream &s, QGVector &vec )
531 { // read vector
532 return vec.read( s );
533}
534
535QDataStream &operator<<( QDataStream &s, const QGVector &vec )
536 { // write vector
537 return vec.write( s );
538}
539
540 QDataStream &QGVector::read( QDataStream &s )// read vector from stream
541{
542 uint num;
543 s >> num; // read number of items
544 clear(); // clear vector
545 resize( num );
546 for (uint i=0; i<num; i++) { // read all items
547 Item d;
548 read( s, d );
549 Q_CHECK_PTR( d );
550 if ( !d ) // no memory
551 break;
552 vec[i] = d;
553 }
554 return s;
555}
556
557QDataStream &QGVector::write( QDataStream &s ) const
558 { // write vector to stream
559 uint num = count();
560 s << num; // number of items to write
561 num = size();
562 for (uint i=0; i<num; i++) { // write non-null items
563 if ( vec[i] )
564 write( s, vec[i] );
565 }
566 return s;
567}
568
569/* Returns whether v equals this vector or not */
570
571bool QGVector::operator==( const QGVector &v ) const
572{
573 if ( size() != v.size() )
574 return FALSE;
575 if ( count() != v.count() )
576 return FALSE;
577 for ( int i = 0; i < (int)size(); ++i ) {
578 if ( ( (QGVector*)this )->compareItems( at( i ), v.at( i ) ) != 0 )
579 return FALSE;
580 }
581 return TRUE;
582}
583
584#endif // QT_NO_DATASTREAM
diff --git a/qmake/tools/qiodevice.cpp b/qmake/tools/qiodevice.cpp
new file mode 100644
index 0000000..93969e4
--- a/dev/null
+++ b/qmake/tools/qiodevice.cpp
@@ -0,0 +1,755 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QIODevice class
5**
6** Created : 940913
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qiodevice.h"
39
40/*!
41 \class QIODevice qiodevice.h
42 \reentrant
43
44 \brief The QIODevice class is the base class of I/O devices.
45
46 \ingroup io
47
48 An I/O device represents a medium that one can read bytes from
49 and/or write bytes to. The QIODevice class is the abstract
50 superclass of all such devices; classes such as QFile, QBuffer and
51 QSocket inherit QIODevice and implement virtual functions such as
52 write() appropriately.
53
54 Although applications sometimes use QIODevice directly, it is
55 usually better to use QTextStream and QDataStream, which provide
56 stream operations on any QIODevice subclass. QTextStream provides
57 text-oriented stream functionality (for human-readable ASCII
58 files, for example), whereas QDataStream deals with binary data in
59 a totally platform-independent manner.
60
61 The public member functions in QIODevice roughly fall into two
62 groups: the action functions and the state access functions. The
63 most important action functions are:
64
65 \list
66
67 \i open() opens a device for reading and/or writing, depending on
68 the mode argument.
69
70 \i close() closes the device and tidies up (e.g. flushes buffered
71 data)
72
73 \i readBlock() reads a block of data from the device.
74
75 \i writeBlock() writes a block of data to the device.
76
77 \i readLine() reads a line (of text, usually) from the device.
78
79 \i flush() ensures that all buffered data are written to the real device.
80
81 \endlist
82
83 There are also some other, less used, action functions:
84
85 \list
86
87 \i getch() reads a single character.
88
89 \i ungetch() forgets the last call to getch(), if possible.
90
91 \i putch() writes a single character.
92
93 \i size() returns the size of the device, if there is one.
94
95 \i at() returns the current read/write pointer's position, if there
96 is one for this device, or it moves the pointer if given an offset.
97
98 \i atEnd() indicates whether there is more to read, if this is
99 meaningful for this device.
100
101 \i reset() moves the read/write pointer to the start of the
102 device, if that is possible for this device.
103
104 \endlist
105
106 The state access are all "get" functions. The QIODevice subclass
107 calls setState() to update the state, and simple access functions
108 tell the user of the device what the device's state is. Here are
109 the settings, and their associated access functions:
110
111 \list
112
113 \i Access type. Some devices are direct access (it is possible
114 to read/write anywhere), whereas others are sequential. QIODevice
115 provides the access functions (isDirectAccess(),
116 isSequentialAccess(), and isCombinedAccess()) to tell users what a
117 given I/O device supports.
118
119 \i Buffering. Some devices are accessed in raw mode, whereas
120 others are buffered. Buffering usually provides greater
121 efficiency, particularly for small read/write operations.
122 isBuffered() tells the user whether a given device is buffered.
123 (This can often be set by the application in the call to open().)
124
125 \i Synchronicity. Synchronous devices work immediately (for
126 example, files). When you read from a file, the file delivers its
127 data straight away. Other kinds of device, such as a socket
128 connected to a HTTP server, may not deliver the data until seconds
129 after you ask to read it. isSynchronous() and isAsynchronous()
130 tell the user how this device operates.
131
132 \i CR/LF translation. For simplicity, applications often like to
133 see just a single CR/LF style, and QIODevice subclasses can
134 provide this. isTranslated() returns TRUE if this object
135 translates CR/LF to just LF. (This can often be set by the
136 application in the call to open().)
137
138 \i Permissions. Some files cannot be written. For example,
139 isReadable(), isWritable() and isReadWrite() tell the application
140 whether it can read from and write to a given device. (This can
141 often be set by the application in the call to open().)
142
143 \i Finally, isOpen() returns TRUE if the device is open, i.e.
144 after an open() call.
145
146 \endlist
147
148 QIODevice provides numerous pure virtual functions that you need
149 to implement when subclassing it. Here is a skeleton subclass with
150 all the members you are sure to need and some that you will
151 probably need:
152
153 \code
154 class MyDevice : public QIODevice
155 {
156 public:
157 MyDevice();
158 ~MyDevice();
159
160 bool open( int mode );
161 void close();
162 void flush();
163
164 uint size() const;
165 int at() const;// non-pure virtual
166 bool at( int ); // non-pure virtual
167 bool atEnd() const;// non-pure virtual
168
169 int readBlock( char *data, uint maxlen );
170 int writeBlock( const char *data, uint len );
171 int readLine( char *data, uint maxlen );
172
173 int getch();
174 int putch( int );
175 int ungetch( int );
176 };
177 \endcode
178
179 The three non-pure virtual functions need not be reimplemented for
180 sequential devices.
181
182 \sa QDataStream, QTextStream
183*/
184
185/*!
186 \enum QIODevice::Offset
187
188 The offset within the device.
189*/
190
191
192/*!
193 Constructs an I/O device.
194*/
195
196QIODevice::QIODevice()
197{
198 ioMode = 0; // initial mode
199 ioSt = IO_Ok;
200 ioIndex = 0;
201}
202
203/*!
204 Destroys the I/O device.
205*/
206
207QIODevice::~QIODevice()
208{
209}
210
211
212/*!
213 \fn int QIODevice::flags() const
214
215 Returns the current I/O device flags setting.
216
217 Flags consists of mode flags and state flags.
218
219 \sa mode(), state()
220*/
221
222/*!
223 \fn int QIODevice::mode() const
224
225 Returns bits OR'ed together that specify the current operation
226 mode.
227
228 These are the flags that were given to the open() function.
229
230 The flags are \c IO_ReadOnly, \c IO_WriteOnly, \c IO_ReadWrite,
231 \c IO_Append, \c IO_Truncate and \c IO_Translate.
232*/
233
234/*!
235 \fn int QIODevice::state() const
236
237 Returns bits OR'ed together that specify the current state.
238
239 The flags are: \c IO_Open.
240
241 Subclasses may define additional flags.
242*/
243
244/*!
245 \fn bool QIODevice::isDirectAccess() const
246
247 Returns TRUE if the I/O device is a direct access device;
248 otherwise returns FALSE, i.e. if the device is a sequential access
249 device.
250
251 \sa isSequentialAccess()
252*/
253
254/*!
255 \fn bool QIODevice::isSequentialAccess() const
256
257 Returns TRUE if the device is a sequential access device;
258 otherwise returns FALSE, i.e. if the device is a direct access
259 device.
260
261 Operations involving size() and at(int) are not valid on
262 sequential devices.
263
264 \sa isDirectAccess()
265*/
266
267/*!
268 \fn bool QIODevice::isCombinedAccess() const
269
270 Returns TRUE if the I/O device is a combined access (both direct
271 and sequential) device; otherwise returns FALSE.
272
273 This access method is currently not in use.
274*/
275
276/*!
277 \fn bool QIODevice::isBuffered() const
278
279 Returns TRUE if the I/O device is a buffered device; otherwise
280 returns FALSE, i.e. the device is a raw device.
281
282 \sa isRaw()
283*/
284
285/*!
286 \fn bool QIODevice::isRaw() const
287
288 Returns TRUE if the device is a raw device; otherwise returns
289 FALSE, i.e. if the device is a buffered device.
290
291 \sa isBuffered()
292*/
293
294/*!
295 \fn bool QIODevice::isSynchronous() const
296
297 Returns TRUE if the I/O device is a synchronous device; otherwise
298 returns FALSE, i.e. the device is an asynchronous device.
299
300 \sa isAsynchronous()
301*/
302
303/*!
304 \fn bool QIODevice::isAsynchronous() const
305
306 Returns TRUE if the device is an asynchronous device; otherwise
307 returns FALSE, i.e. if the device is a synchronous device.
308
309 This mode is currently not in use.
310
311 \sa isSynchronous()
312*/
313
314/*!
315 \fn bool QIODevice::isTranslated() const
316
317 Returns TRUE if the I/O device translates carriage-return and
318 linefeed characters; otherwise returns FALSE.
319
320 A QFile is translated if it is opened with the \c IO_Translate
321 mode flag.
322*/
323
324/*!
325 \fn bool QIODevice::isReadable() const
326
327 Returns TRUE if the I/O device was opened using \c IO_ReadOnly or
328 \c IO_ReadWrite mode; otherwise returns FALSE.
329
330 \sa isWritable(), isReadWrite()
331*/
332
333/*!
334 \fn bool QIODevice::isWritable() const
335
336 Returns TRUE if the I/O device was opened using \c IO_WriteOnly or
337 \c IO_ReadWrite mode; otherwise returns FALSE.
338
339 \sa isReadable(), isReadWrite()
340*/
341
342/*!
343 \fn bool QIODevice::isReadWrite() const
344
345 Returns TRUE if the I/O device was opened using \c IO_ReadWrite
346 mode; otherwise returns FALSE.
347
348 \sa isReadable(), isWritable()
349*/
350
351/*!
352 \fn bool QIODevice::isInactive() const
353
354 Returns TRUE if the I/O device state is 0, i.e. the device is not
355 open; otherwise returns FALSE.
356
357 \sa isOpen()
358*/
359
360/*!
361 \fn bool QIODevice::isOpen() const
362
363 Returns TRUE if the I/O device has been opened; otherwise returns
364 FALSE.
365
366 \sa isInactive()
367*/
368
369
370/*!
371 \fn int QIODevice::status() const
372
373 Returns the I/O device status.
374
375 The I/O device status returns an error code. If open() returns
376 FALSE or readBlock() or writeBlock() return -1, this function can
377 be called to find out the reason why the operation failed.
378
379 \keyword IO_Ok
380 \keyword IO_ReadError
381 \keyword IO_WriteError
382 \keyword IO_FatalError
383 \keyword IO_OpenError
384 \keyword IO_ConnectError
385 \keyword IO_AbortError
386 \keyword IO_TimeOutError
387 \keyword IO_UnspecifiedError
388
389 The status codes are:
390 \table
391 \header \i Status code \i Meaning
392 \row \i \c IO_Ok \i The operation was successful.
393 \row \i \c IO_ReadError \i Could not read from the device.
394 \row \i \c IO_WriteError \i Could not write to the device.
395 \row \i \c IO_FatalError \i A fatal unrecoverable error occurred.
396 \row \i \c IO_OpenError \i Could not open the device.
397 \row \i \c IO_ConnectError \i Could not connect to the device.
398 \row \i \c IO_AbortError \i The operation was unexpectedly aborted.
399 \row \i \c IO_TimeOutError \i The operation timed out.
400 \row \i \c IO_UnspecifiedError \i An unspecified error happened on close.
401 \endtable
402
403 \sa resetStatus()
404*/
405
406/*!
407 \fn void QIODevice::resetStatus()
408
409 Sets the I/O device status to \c IO_Ok.
410
411 \sa status()
412*/
413
414
415/*!
416 \fn void QIODevice::setFlags( int f )
417 \internal
418 Used by subclasses to set the device flags.
419*/
420
421/*!
422 \internal
423 Used by subclasses to set the device type.
424*/
425
426void QIODevice::setType( int t )
427{
428#if defined(QT_CHECK_RANGE)
429 if ( (t & IO_TypeMask) != t )
430 qWarning( "QIODevice::setType: Specified type out of range" );
431#endif
432 ioMode &= ~IO_TypeMask; // reset type bits
433 ioMode |= t;
434}
435
436/*!
437 \internal
438 Used by subclasses to set the device mode.
439*/
440
441void QIODevice::setMode( int m )
442{
443#if defined(QT_CHECK_RANGE)
444 if ( (m & IO_ModeMask) != m )
445 qWarning( "QIODevice::setMode: Specified mode out of range" );
446#endif
447 ioMode &= ~IO_ModeMask; // reset mode bits
448 ioMode |= m;
449}
450
451/*!
452 \internal
453 Used by subclasses to set the device state.
454*/
455
456void QIODevice::setState( int s )
457{
458#if defined(QT_CHECK_RANGE)
459 if ( ((uint)s & IO_StateMask) != (uint)s )
460 qWarning( "QIODevice::setState: Specified state out of range" );
461#endif
462 ioMode &= ~IO_StateMask; // reset state bits
463 ioMode |= (uint)s;
464}
465
466/*!
467 \internal
468 Used by subclasses to set the device status (not state) to \a s.
469*/
470
471void QIODevice::setStatus( int s )
472{
473 ioSt = s;
474}
475
476
477/*!
478 \fn bool QIODevice::open( int mode )
479
480 Opens the I/O device using the specified \a mode. Returns TRUE if
481 the device was successfully opened; otherwise returns FALSE.
482
483 The mode parameter \a mode must be an OR'ed combination of the
484 following flags.
485 \table
486 \header \i Mode flags \i Meaning
487 \row \i \c IO_Raw \i specifies raw (unbuffered) file access.
488 \row \i \c IO_ReadOnly \i opens a file in read-only mode.
489 \row \i \c IO_WriteOnly \i opens a file in write-only mode.
490 \row \i \c IO_ReadWrite \i opens a file in read/write mode.
491 \row \i \c IO_Append \i sets the file index to the end of the file.
492 \row \i \c IO_Truncate \i truncates the file.
493 \row \i \c IO_Translate \i enables carriage returns and linefeed
494 translation for text files under MS-DOS, Windows and Macintosh. On
495 Unix systems this flag has no effect. Use with caution as it will
496 also transform every linefeed written to the file into a CRLF
497 pair. This is likely to corrupt your file if you write write
498 binary data. Cannot be combined with \c IO_Raw.
499 \endtable
500
501 This virtual function must be reimplemented by all subclasses.
502
503 \sa close()
504*/
505
506/*!
507 \fn void QIODevice::close()
508
509 Closes the I/O device.
510
511 This virtual function must be reimplemented by all subclasses.
512
513 \sa open()
514*/
515
516/*!
517 \fn void QIODevice::flush()
518
519 Flushes an open I/O device.
520
521 This virtual function must be reimplemented by all subclasses.
522*/
523
524
525/*!
526 \fn QIODevice::Offset QIODevice::size() const
527
528 Virtual function that returns the size of the I/O device.
529
530 \sa at()
531*/
532
533/*!
534 Virtual function that returns the current I/O device position.
535
536 This is the position of the data read/write head of the I/O
537 device.
538
539 \sa size()
540*/
541
542QIODevice::Offset QIODevice::at() const
543{
544 return ioIndex;
545}
546
547
548/*
549 The following is a "bad" overload, since it does "not behave essentially
550 the same" like the above. So don't use \overload in the documentation of
551 this function and we have to live with the qdoc warning which is generated
552 for this.
553*/
554/*!
555 Virtual function that sets the I/O device position to \a pos.
556 Returns TRUE if the position was successfully set, i.e. \a pos is
557 within range; otherwise returns FALSE.
558
559 \sa size()
560*/
561
562bool QIODevice::at( Offset pos )
563{
564#if defined(QT_CHECK_RANGE)
565 if ( pos > size() ) {
566#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
567 qWarning( "QIODevice::at: Index %llu out of range", pos );
568#else
569 qWarning( "QIODevice::at: Index %lu out of range", pos );
570#endif
571 return FALSE;
572 }
573#endif
574 ioIndex = pos;
575 return TRUE;
576}
577
578/*!
579 Virtual function that returns TRUE if the I/O device position is
580 at the end of the input; otherwise returns FALSE.
581*/
582
583bool QIODevice::atEnd() const
584{
585 if ( isSequentialAccess() || isTranslated() ) {
586 QIODevice* that = (QIODevice*)this;
587 int c = that->getch();
588 bool result = c < 0;
589 that->ungetch(c);
590 return result;
591 } else {
592 return at() == size();
593 }
594}
595
596/*!
597 \fn bool QIODevice::reset()
598
599 Sets the device index position to 0.
600
601 \sa at()
602*/
603
604
605/*!
606 \fn int QIODevice::readBlock( char *data, Q_ULONG maxlen )
607
608 Reads at most \a maxlen bytes from the I/O device into \a data and
609 returns the number of bytes actually read.
610
611 This function should return -1 if a fatal error occurs and should
612 return 0 if there are no bytes to read.
613
614 The device must be opened for reading, and \a data must not be 0.
615
616 This virtual function must be reimplemented by all subclasses.
617
618 \sa writeBlock() isOpen() isReadable()
619*/
620
621/*!
622 This convenience function returns all of the remaining data in the
623 device.
624*/
625QByteArray QIODevice::readAll()
626{
627 if ( isDirectAccess() ) {
628 // we know the size
629 int n = size()-at(); // ### fix for 64-bit or large files?
630 int totalRead = 0;
631 QByteArray ba( n );
632 char* c = ba.data();
633 while ( n ) {
634 int r = readBlock( c, n );
635 if ( r < 0 )
636 return QByteArray();
637 n -= r;
638 c += r;
639 totalRead += r;
640 // If we have a translated file, then it is possible that
641 // we read less bytes than size() reports
642 if ( atEnd() ) {
643 ba.resize( totalRead );
644 break;
645 }
646 }
647 return ba;
648 } else {
649 // read until we reach the end
650 const int blocksize = 512;
651 int nread = 0;
652 QByteArray ba;
653 while ( !atEnd() ) {
654 ba.resize( nread + blocksize );
655 int r = readBlock( ba.data()+nread, blocksize );
656 if ( r < 0 )
657 return QByteArray();
658 nread += r;
659 }
660 ba.resize( nread );
661 return ba;
662 }
663}
664
665/*!
666 \fn int QIODevice::writeBlock( const char *data, Q_ULONG len )
667
668 Writes \a len bytes from \a data to the I/O device and returns the
669 number of bytes actually written.
670
671 This function should return -1 if a fatal error occurs.
672
673 This virtual function must be reimplemented by all subclasses.
674
675 \sa readBlock()
676*/
677
678/*!
679 \overload
680
681 This convenience function is the same as calling writeBlock(
682 data.data(), data.size() ).
683*/
684Q_LONG QIODevice::writeBlock( const QByteArray& data )
685{
686 return writeBlock( data.data(), data.size() );
687}
688
689/*!
690 Reads a line of text, (or up to \a maxlen bytes if a newline isn't
691 encountered) plus a terminating '\0' into \a data. If there is a
692 newline at the end if the line, it is not stripped.
693
694 Returns the number of bytes read including the terminating '\0',
695 or -1 if an error occurred.
696
697 This virtual function can be reimplemented much more efficiently
698 by the most subclasses.
699
700 \sa readBlock(), QTextStream::readLine()
701*/
702
703Q_LONG QIODevice::readLine( char *data, Q_ULONG maxlen )
704{
705 if ( maxlen == 0 ) // application bug?
706 return 0;
707 char *p = data;
708 while ( --maxlen && (readBlock(p,1)>0) ) {// read one byte at a time
709 if ( *p++ == '\n' ) // end of line
710 break;
711 }
712 *p++ = '\0';
713 return p - data;
714}
715
716
717/*!
718 \fn int QIODevice::getch()
719
720 Reads a single byte/character from the I/O device.
721
722 Returns the byte/character read, or -1 if the end of the I/O
723 device has been reached.
724
725 This virtual function must be reimplemented by all subclasses.
726
727 \sa putch(), ungetch()
728*/
729
730/*!
731 \fn int QIODevice::putch( int ch )
732
733 Writes the character \a ch to the I/O device.
734
735 Returns \a ch, or -1 if an error occurred.
736
737 This virtual function must be reimplemented by all subclasses.
738
739 \sa getch(), ungetch()
740*/
741
742/*!
743 \fn int QIODevice::ungetch( int ch )
744
745 Puts the character \a ch back into the I/O device and decrements
746 the index position if it is not zero.
747
748 This function is normally called to "undo" a getch() operation.
749
750 Returns \a ch, or -1 if an error occurred.
751
752 This virtual function must be reimplemented by all subclasses.
753
754 \sa getch(), putch()
755*/
diff --git a/qmake/tools/qlibrary.cpp b/qmake/tools/qlibrary.cpp
new file mode 100644
index 0000000..564db30
--- a/dev/null
+++ b/qmake/tools/qlibrary.cpp
@@ -0,0 +1,343 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QLibrary class
5**
6** Created : 2000-01-01
7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include <private/qlibrary_p.h>
40
41#ifndef QT_NO_LIBRARY
42
43// uncomment this to get error messages
44//#define QT_DEBUG_COMPONENT 1
45// uncomment this to get error and success messages
46//#define QT_DEBUG_COMPONENT 2
47
48#ifndef QT_DEBUG_COMPONENT
49# if defined(QT_DEBUG)
50# define QT_DEBUG_COMPONENT 1
51# endif
52#endif
53
54#if defined(QT_DEBUG_COMPONENT)
55#include <qfile.h>
56#endif
57
58#if defined(Q_WS_WIN) && !defined(QT_MAKEDLL)
59#define QT_NO_LIBRARY_UNLOAD
60#endif
61
62QLibraryPrivate::QLibraryPrivate( QLibrary *lib )
63 : pHnd( 0 ), library( lib )
64{
65}
66
67
68/*!
69 \class QLibrary qlibrary.h
70 \reentrant
71 \brief The QLibrary class provides a wrapper for handling shared libraries.
72
73 \mainclass
74 \group plugins
75
76 An instance of a QLibrary object can handle a single shared
77 library and provide access to the functionality in the library in
78 a platform independent way. If the library is a component server,
79 QLibrary provides access to the exported component and can
80 directly query this component for interfaces.
81
82 QLibrary ensures that the shared library is loaded and stays in
83 memory whilst it is in use. QLibrary can also unload the library
84 on destruction and release unused resources.
85
86 A typical use of QLibrary is to resolve an exported symbol in a
87 shared object, and to call the function that this symbol
88 represents. This is called "explicit linking" in contrast to
89 "implicit linking", which is done by the link step in the build
90 process when linking an executable against a library.
91
92 The following code snippet loads a library, resolves the symbol
93 "mysymbol", and calls the function if everything succeeded. If
94 something went wrong, e.g. the library file does not exist or the
95 symbol is not defined, the function pointer will be 0 and won't be
96 called. When the QLibrary object is destroyed the library will be
97 unloaded, making all references to memory allocated in the library
98 invalid.
99
100 \code
101 typedef void (*MyPrototype)();
102 MyPrototype myFunction;
103
104 QLibrary myLib( "mylib" );
105 myFunction = (MyProtoype) myLib.resolve( "mysymbol" );
106 if ( myFunction ) {
107 myFunction();
108 }
109 \endcode
110*/
111
112/*!
113 Creates a QLibrary object for the shared library \a filename. The
114 library will be unloaded in the destructor.
115
116 Note that \a filename does not need to include the (platform specific)
117 file extension, so calling
118 \code
119 QLibrary lib( "mylib" );
120 \endcode
121 is equivalent to calling
122 \code
123 QLibrary lib( "mylib.dll" );
124 \endcode
125 on Windows, and
126 \code
127 QLibrary lib( "libmylib.so" );
128 \endcode
129 on Unix. Specifying the extension is not recommended, since
130 doing so introduces a platform dependency.
131
132 If \a filename does not include a path, the library loader will
133 look for the file in the platform specific search paths.
134
135 \sa load() unload(), setAutoUnload()
136*/
137QLibrary::QLibrary( const QString& filename )
138 : libfile( filename ), aunload( TRUE )
139{
140 libfile.replace( '\\', '/' );
141 d = new QLibraryPrivate( this );
142}
143
144/*!
145 Deletes the QLibrary object.
146
147 The library will be unloaded if autoUnload() is TRUE (the
148 default), otherwise it stays in memory until the application
149 exits.
150
151 \sa unload(), setAutoUnload()
152*/
153QLibrary::~QLibrary()
154{
155 if ( autoUnload() )
156 unload();
157
158 delete d;
159}
160
161/*!
162 Returns the address of the exported symbol \a symb. The library is
163 loaded if necessary. The function returns 0 if the symbol could
164 not be resolved or the library could not be loaded.
165
166 \code
167 typedef int (*avgProc)( int, int );
168
169 avgProc avg = (avgProc) library->resolve( "avg" );
170 if ( avg )
171 return avg( 5, 8 );
172 else
173 return -1;
174 \endcode
175
176*/
177void *QLibrary::resolve( const char* symb )
178{
179 if ( !d->pHnd )
180 load();
181 if ( !d->pHnd )
182 return 0;
183
184 void *address = d->resolveSymbol( symb );
185
186 return address;
187}
188
189/*!
190 \overload
191
192 Loads the library \a filename and returns the address of the
193 exported symbol \a symb. Note that like the constructor, \a
194 filename does not need to include the (platform specific) file
195 extension. The library remains loaded until the process exits.
196
197 The function returns 0 if the symbol could not be resolved or the
198 library could not be loaded.
199
200 This function is useful only if you want to resolve a single
201 symbol, e.g. a function pointer from a specific library once:
202
203 \code
204 typedef void (*FunctionType)();
205 static FunctionType *ptrFunction = 0;
206 static bool triedResolve = FALSE;
207 if ( !ptrFunction && !triedResolve )
208 ptrFunction = QLibrary::resolve( "mylib", "mysymb" );
209
210 if ( ptrFunction )
211 ptrFunction();
212 else
213 ...
214 \endcode
215
216 If you want to resolve multiple symbols, use a QLibrary object and
217 call the non-static version of resolve().
218
219 \sa resolve()
220*/
221void *QLibrary::resolve( const QString &filename, const char *symb )
222{
223 QLibrary lib( filename );
224 lib.setAutoUnload( FALSE );
225 return lib.resolve( symb );
226}
227
228/*!
229 Returns TRUE if the library is loaded; otherwise returns FALSE.
230
231 \sa unload()
232*/
233bool QLibrary::isLoaded() const
234{
235 return d->pHnd != 0;
236}
237
238/*!
239 Loads the library. Since resolve() always calls this function
240 before resolving any symbols it is not necessary to call it
241 explicitly. In some situations you might want the library loaded
242 in advance, in which case you would use this function.
243*/
244bool QLibrary::load()
245{
246 return d->loadLibrary();
247}
248
249/*!
250 Unloads the library and returns TRUE if the library could be
251 unloaded; otherwise returns FALSE.
252
253 This function is called by the destructor if autoUnload() is
254 enabled.
255
256 \sa resolve()
257*/
258bool QLibrary::unload()
259{
260 if ( !d->pHnd )
261 return TRUE;
262
263#if !defined(QT_NO_LIBRARY_UNLOAD)
264 if ( !d->freeLibrary() ) {
265# if defined(QT_DEBUG_COMPONENT)
266 qWarning( "%s could not be unloaded", (const char*) QFile::encodeName(library()) );
267# endif
268 return FALSE;
269 }
270
271# if defined(QT_DEBUG_COMPONENT) && QT_DEBUG_COMPONENT == 2
272 qWarning( "%s has been unloaded", (const char*) QFile::encodeName(library()) );
273# endif
274 d->pHnd = 0;
275#endif
276 return TRUE;
277}
278
279/*!
280 Returns TRUE if the library will be automatically unloaded when
281 this wrapper object is destructed; otherwise returns FALSE. The
282 default is TRUE.
283
284 \sa setAutoUnload()
285*/
286bool QLibrary::autoUnload() const
287{
288 return (bool)aunload;
289}
290
291/*!
292 If \a enabled is TRUE (the default), the wrapper object is set to
293 automatically unload the library upon destruction. If \a enabled
294 is FALSE, the wrapper object is not unloaded unless you explicitly
295 call unload().
296
297 \sa autoUnload()
298*/
299void QLibrary::setAutoUnload( bool enabled )
300{
301 aunload = enabled;
302}
303
304/*!
305 Returns the filename of the shared library this QLibrary object
306 handles, including the platform specific file extension.
307
308 For example:
309 \code
310 QLibrary lib( "mylib" );
311 QString str = lib.library();
312 \endcode
313 will set \e str to "mylib.dll" on Windows, and "libmylib.so" on Linux.
314*/
315QString QLibrary::library() const
316{
317 if ( libfile.isEmpty() )
318 return libfile;
319
320 QString filename = libfile;
321
322#if defined(Q_WS_WIN)
323 if ( filename.findRev( '.' ) <= filename.findRev( '/' ) )
324 filename += ".dll";
325#elif defined(Q_OS_MACX)
326 if ( filename.find( ".dylib" ) == -1 )
327 filename += ".dylib";
328#else
329 if ( filename.find( ".so" ) == -1 ) {
330 const int x = filename.findRev( "/" );
331 if ( x != -1 ) {
332 QString path = filename.left( x + 1 );
333 QString file = filename.right( filename.length() - x - 1 );
334 filename = QString( "%1lib%2.so" ).arg( path ).arg( file );
335 } else {
336 filename = QString( "lib%1.so" ).arg( filename );
337 }
338 }
339#endif
340
341 return filename;
342}
343#endif //QT_NO_LIBRARY
diff --git a/qmake/tools/qlibrary_unix.cpp b/qmake/tools/qlibrary_unix.cpp
new file mode 100644
index 0000000..f0fbdf6
--- a/dev/null
+++ b/qmake/tools/qlibrary_unix.cpp
@@ -0,0 +1,163 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QLibraryPrivate class
5**
6** Created : 2000-01-01
7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include "private/qlibrary_p.h"
40
41#ifndef QT_NO_LIBRARY
42
43#if defined(QT_AOUT_UNDERSCORE)
44#include <string.h>
45#endif
46
47/*
48 The platform dependent implementations of
49 - loadLibrary
50 - freeLibrary
51 - resolveSymbol
52
53 It's not too hard to guess what the functions do.
54*/
55
56#if defined(QT_HPUX_LD) // for HP-UX < 11.x and 32 bit
57
58bool QLibraryPrivate::loadLibrary()
59{
60 if ( pHnd )
61 return TRUE;
62
63 QString filename = library->library();
64
65 pHnd = (void*)shl_load( filename.latin1(), BIND_DEFERRED | BIND_NONFATAL | DYNAMIC_PATH, 0 );
66#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
67 if ( !pHnd )
68 qWarning( "%s: failed to load library!", filename.latin1() );
69#endif
70 return pHnd != 0;
71}
72
73bool QLibraryPrivate::freeLibrary()
74{
75 if ( !pHnd )
76 return TRUE;
77
78 if ( shl_unload( (shl_t)pHnd ) ) {
79#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
80 QString filename = library->library();
81 qWarning( "%s: Failed to unload library!", filename.latin1() );
82#endif
83 return FALSE;
84 }
85 pHnd = 0;
86 return TRUE;
87}
88
89void* QLibraryPrivate::resolveSymbol( const char* symbol )
90{
91 if ( !pHnd )
92 return 0;
93
94 void* address = 0;
95 if ( shl_findsym( (shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address ) < 0 ) {
96#if defined(QT_DEBUG_COMPONENT)
97 QString filename = library->library();
98 qWarning( "%s: couldn't resolve symbol \"%s\"", filename.latin1(), symbol );
99#endif
100 }
101 return address;
102}
103
104#else // POSIX
105#include <dlfcn.h>
106
107bool QLibraryPrivate::loadLibrary()
108{
109 if ( pHnd )
110 return TRUE;
111
112 QString filename = library->library();
113
114 pHnd = dlopen( filename.latin1(), RTLD_LAZY );
115#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
116 if ( !pHnd )
117 qWarning( "%s", dlerror() );
118#endif
119 return pHnd != 0;
120}
121
122bool QLibraryPrivate::freeLibrary()
123{
124 if ( !pHnd )
125 return TRUE;
126
127 if ( dlclose( pHnd ) ) {
128#if defined(QT_DEBUG) || defined(QT_DEBUG_COMPONENT)
129 qWarning( "%s", dlerror() );
130#endif
131 return FALSE;
132 }
133
134 pHnd = 0;
135 return TRUE;
136}
137
138void* QLibraryPrivate::resolveSymbol( const char* symbol )
139{
140 if ( !pHnd )
141 return 0;
142
143#if defined(QT_AOUT_UNDERSCORE)
144 // older a.out systems add an underscore in front of symbols
145 char* undrscr_symbol = new char[strlen(symbol)+2];
146 undrscr_symbol[0] = '_';
147 strcpy(undrscr_symbol+1, symbol);
148 void* address = dlsym( pHnd, undrscr_symbol );
149 delete [] undrscr_symbol;
150#else
151 void* address = dlsym( pHnd, symbol );
152#endif
153#if defined(QT_DEBUG_COMPONENT)
154 const char* error = dlerror();
155 if ( error )
156 qWarning( "%s", error );
157#endif
158 return address;
159}
160
161#endif // POSIX
162
163#endif
diff --git a/qmake/tools/qmap.cpp b/qmake/tools/qmap.cpp
new file mode 100644
index 0000000..3f73f81
--- a/dev/null
+++ b/qmake/tools/qmap.cpp
@@ -0,0 +1,254 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QMap
5**
6** Created : 990406
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qmap.h"
39
40typedef QMapNodeBase* NodePtr;
41typedef QMapNodeBase Node;
42
43
44void QMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
45{
46 NodePtr y = x->right;
47 x->right = y->left;
48 if (y->left !=0)
49 y->left->parent = x;
50 y->parent = x->parent;
51 if (x == root)
52 root = y;
53 else if (x == x->parent->left)
54 x->parent->left = y;
55 else
56 x->parent->right = y;
57 y->left = x;
58 x->parent = y;
59}
60
61
62void QMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
63{
64 NodePtr y = x->left;
65 x->left = y->right;
66 if (y->right != 0)
67 y->right->parent = x;
68 y->parent = x->parent;
69 if (x == root)
70 root = y;
71 else if (x == x->parent->right)
72 x->parent->right = y;
73 else
74 x->parent->left = y;
75 y->right = x;
76 x->parent = y;
77}
78
79
80void QMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
81{
82 x->color = Node::Red;
83 while ( x != root && x->parent->color == Node::Red ) {
84 if ( x->parent == x->parent->parent->left ) {
85 NodePtr y = x->parent->parent->right;
86 if (y && y->color == Node::Red) {
87 x->parent->color = Node::Black;
88 y->color = Node::Black;
89 x->parent->parent->color = Node::Red;
90 x = x->parent->parent;
91 } else {
92 if (x == x->parent->right) {
93 x = x->parent;
94 rotateLeft( x, root );
95 }
96 x->parent->color = Node::Black;
97 x->parent->parent->color = Node::Red;
98 rotateRight (x->parent->parent, root );
99 }
100 } else {
101 NodePtr y = x->parent->parent->left;
102 if ( y && y->color == Node::Red ) {
103 x->parent->color = Node::Black;
104 y->color = Node::Black;
105 x->parent->parent->color = Node::Red;
106 x = x->parent->parent;
107 } else {
108 if (x == x->parent->left) {
109 x = x->parent;
110 rotateRight( x, root );
111 }
112 x->parent->color = Node::Black;
113 x->parent->parent->color = Node::Red;
114 rotateLeft( x->parent->parent, root );
115 }
116 }
117 }
118 root->color = Node::Black;
119}
120
121
122NodePtr QMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
123 NodePtr& leftmost,
124 NodePtr& rightmost )
125{
126 NodePtr y = z;
127 NodePtr x;
128 NodePtr x_parent;
129 if (y->left == 0) {
130 x = y->right;
131 } else {
132 if (y->right == 0)
133 x = y->left;
134 else
135 {
136 y = y->right;
137 while (y->left != 0)
138 y = y->left;
139 x = y->right;
140 }
141 }
142 if (y != z) {
143 z->left->parent = y;
144 y->left = z->left;
145 if (y != z->right) {
146 x_parent = y->parent;
147 if (x)
148 x->parent = y->parent;
149 y->parent->left = x;
150 y->right = z->right;
151 z->right->parent = y;
152 } else {
153 x_parent = y;
154 }
155 if (root == z)
156 root = y;
157 else if (z->parent->left == z)
158 z->parent->left = y;
159 else
160 z->parent->right = y;
161 y->parent = z->parent;
162 // Swap the colors
163 Node::Color c = y->color;
164 y->color = z->color;
165 z->color = c;
166 y = z;
167 } else {
168 x_parent = y->parent;
169 if (x)
170 x->parent = y->parent;
171 if (root == z)
172 root = x;
173 else if (z->parent->left == z)
174 z->parent->left = x;
175 else
176 z->parent->right = x;
177 if ( leftmost == z ) {
178 if (z->right == 0)
179 leftmost = z->parent;
180 else
181 leftmost = x->minimum();
182 }
183 if (rightmost == z) {
184 if (z->left == 0)
185 rightmost = z->parent;
186 else
187 rightmost = x->maximum();
188 }
189 }
190 if (y->color != Node::Red) {
191 while (x != root && (x == 0 || x->color == Node::Black)) {
192 if (x == x_parent->left) {
193 NodePtr w = x_parent->right;
194 if (w->color == Node::Red) {
195 w->color = Node::Black;
196 x_parent->color = Node::Red;
197 rotateLeft(x_parent, root);
198 w = x_parent->right;
199 }
200 if ((w->left == 0 || w->left->color == Node::Black) &&
201 (w->right == 0 || w->right->color == Node::Black)) {
202 w->color = Node::Red;
203 x = x_parent;
204 x_parent = x_parent->parent;
205 } else {
206 if (w->right == 0 || w->right->color == Node::Black) {
207 if (w->left)
208 w->left->color = Node::Black;
209 w->color = Node::Red;
210 rotateRight(w, root);
211 w = x_parent->right;
212 }
213 w->color = x_parent->color;
214 x_parent->color = Node::Black;
215 if (w->right)
216 w->right->color = Node::Black;
217 rotateLeft(x_parent, root);
218 break;
219 }
220 } else {
221 NodePtr w = x_parent->left;
222 if (w->color == Node::Red) {
223 w->color = Node::Black;
224 x_parent->color = Node::Red;
225 rotateRight(x_parent, root);
226 w = x_parent->left;
227 }
228 if ((w->right == 0 || w->right->color == Node::Black) &&
229 (w->left == 0 || w->left->color == Node::Black)) {
230 w->color = Node::Red;
231 x = x_parent;
232 x_parent = x_parent->parent;
233 } else {
234 if (w->left == 0 || w->left->color == Node::Black) {
235 if (w->right)
236 w->right->color = Node::Black;
237 w->color = Node::Red;
238 rotateLeft(w, root);
239 w = x_parent->left;
240 }
241 w->color = x_parent->color;
242 x_parent->color = Node::Black;
243 if (w->left)
244 w->left->color = Node::Black;
245 rotateRight(x_parent, root);
246 break;
247 }
248 }
249 }
250 if (x)
251 x->color = Node::Black;
252 }
253 return y;
254}
diff --git a/qmake/tools/qmutex_unix.cpp b/qmake/tools/qmutex_unix.cpp
new file mode 100644
index 0000000..c861b2d
--- a/dev/null
+++ b/qmake/tools/qmutex_unix.cpp
@@ -0,0 +1,687 @@
1/****************************************************************************
2** $Id$
3**
4** QMutex class for Unix
5**
6** Created : 20010725
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#if defined(QT_THREAD_SUPPORT)
39
40#include "qplatformdefs.h"
41
42typedef pthread_mutex_t Q_MUTEX_T;
43
44// POSIX threads mutex types
45#if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \
46 defined(Q_OS_FREEBSD)) && !defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS)
47 // POSIX 1003.1c-1995 - We love this OS
48# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b))
49# if defined(QT_CHECK_RANGE)
50# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK
51# else
52# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
53# endif
54# define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE
55#elif defined(MUTEX_NONRECURSIVE_NP) && defined(MUTEX_RECURSIVE_NP)
56// POSIX 1003.4a pthreads draft extensions
57# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_setkind_np((a), (b));
58# define Q_NORMAL_MUTEX_TYPE MUTEX_NONRECURSIVE_NP
59# define Q_RECURSIVE_MUTEX_TYPE MUTEX_RECURSIVE_NP
60#else
61// Unknown mutex types - skip them
62# define Q_MUTEX_SET_TYPE(a, b)
63# undef Q_NORMAL_MUTEX_TYPE
64# undef Q_RECURSIVE_MUTEX_TYPE
65#endif
66
67#include "qmutex.h"
68#include "qmutex_p.h"
69
70#include <errno.h>
71#include <string.h>
72
73
74// Private class declarations
75
76class QRealMutexPrivate : public QMutexPrivate {
77public:
78 QRealMutexPrivate(bool = FALSE);
79
80 void lock();
81 void unlock();
82 bool locked();
83 bool trylock();
84 int type() const;
85
86 bool recursive;
87};
88
89#ifndef Q_RECURSIVE_MUTEX_TYPE
90class QRecursiveMutexPrivate : public QMutexPrivate
91{
92public:
93 QRecursiveMutexPrivate();
94 ~QRecursiveMutexPrivate();
95
96 void lock();
97 void unlock();
98 bool locked();
99 bool trylock();
100 int type() const;
101
102 int count;
103 unsigned long owner;
104 pthread_mutex_t handle2;
105};
106#endif // !Q_RECURSIVE_MUTEX_TYPE
107
108
109// Private class implementation
110
111// base destructor
112QMutexPrivate::~QMutexPrivate()
113{
114 int ret = pthread_mutex_destroy(&handle);
115
116#ifdef QT_CHECK_RANGE
117 if ( ret )
118 qWarning( "Mutex destroy failure: %s", strerror( ret ) );
119#endif
120}
121
122// real mutex class
123QRealMutexPrivate::QRealMutexPrivate(bool recurs)
124 : recursive(recurs)
125{
126 pthread_mutexattr_t attr;
127 pthread_mutexattr_init(&attr);
128 Q_MUTEX_SET_TYPE(&attr, recursive ? Q_RECURSIVE_MUTEX_TYPE : Q_NORMAL_MUTEX_TYPE);
129 Q_UNUSED(recursive);
130 int ret = pthread_mutex_init(&handle, &attr);
131 pthread_mutexattr_destroy(&attr);
132
133#ifdef QT_CHECK_RANGE
134 if( ret )
135 qWarning( "Mutex init failure: %s", strerror( ret ) );
136#endif // QT_CHECK_RANGE
137}
138
139void QRealMutexPrivate::lock()
140{
141 int ret = pthread_mutex_lock(&handle);
142
143#ifdef QT_CHECK_RANGE
144 if (ret)
145 qWarning("Mutex lock failure: %s", strerror(ret));
146#endif
147}
148
149void QRealMutexPrivate::unlock()
150{
151 int ret = pthread_mutex_unlock(&handle);
152
153#ifdef QT_CHECK_RANGE
154 if (ret)
155 qWarning("Mutex unlock failure: %s", strerror(ret));
156#endif
157}
158
159bool QRealMutexPrivate::locked()
160{
161 int ret = pthread_mutex_trylock(&handle);
162
163 if (ret == EBUSY) {
164 return TRUE;
165 } else if (ret) {
166#ifdef QT_CHECK_RANGE
167 qWarning("Mutex locktest failure: %s", strerror(ret));
168#endif
169 } else
170 pthread_mutex_unlock(&handle);
171
172 return FALSE;
173}
174
175bool QRealMutexPrivate::trylock()
176{
177 int ret = pthread_mutex_trylock(&handle);
178
179 if (ret == EBUSY) {
180 return FALSE;
181 } else if (ret) {
182#ifdef QT_CHECK_RANGE
183 qWarning("Mutex trylock failure: %s", strerror(ret));
184#endif
185 return FALSE;
186 }
187
188 return TRUE;
189}
190
191int QRealMutexPrivate::type() const
192{
193 return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL;
194}
195
196
197#ifndef Q_RECURSIVE_MUTEX_TYPE
198QRecursiveMutexPrivate::QRecursiveMutexPrivate()
199 : count(0), owner(0)
200{
201 pthread_mutexattr_t attr;
202 pthread_mutexattr_init(&attr);
203 Q_MUTEX_SET_TYPE(&attr, Q_NORMAL_MUTEX_TYPE);
204 int ret = pthread_mutex_init(&handle, &attr);
205 pthread_mutexattr_destroy(&attr);
206
207# ifdef QT_CHECK_RANGE
208 if (ret)
209 qWarning( "Mutex init failure: %s", strerror(ret) );
210# endif
211
212 pthread_mutexattr_init(&attr);
213 ret = pthread_mutex_init( &handle2, &attr );
214 pthread_mutexattr_destroy(&attr);
215
216# ifdef QT_CHECK_RANGE
217 if (ret)
218 qWarning( "Mutex init failure: %s", strerror(ret) );
219# endif
220}
221
222QRecursiveMutexPrivate::~QRecursiveMutexPrivate()
223{
224 int ret = pthread_mutex_destroy(&handle2);
225
226# ifdef QT_CHECK_RANGE
227 if (ret)
228 qWarning( "Mutex destroy failure: %s", strerror(ret) );
229# endif
230}
231
232void QRecursiveMutexPrivate::lock()
233{
234 pthread_mutex_lock(&handle2);
235
236 if (count > 0 && owner == (unsigned long) pthread_self()) {
237 count++;
238 } else {
239 pthread_mutex_unlock(&handle2);
240 pthread_mutex_lock(&handle);
241 pthread_mutex_lock(&handle2);
242 count = 1;
243 owner = (unsigned long) pthread_self();
244 }
245
246 pthread_mutex_unlock(&handle2);
247}
248
249void QRecursiveMutexPrivate::unlock()
250{
251 pthread_mutex_lock(&handle2);
252
253 if (owner == (unsigned long) pthread_self()) {
254 // do nothing if the count is already 0... to reflect the behaviour described
255 // in the docs
256 if (count && (--count) < 1) {
257 count = 0;
258 pthread_mutex_unlock(&handle);
259 }
260 } else {
261#ifdef QT_CHECK_RANGE
262 qWarning("QMutex::unlock: unlock from different thread than locker");
263 qWarning(" was locked by %d, unlock attempt from %d",
264 (int)owner, (int)pthread_self());
265#endif
266 }
267
268 pthread_mutex_unlock(&handle2);
269}
270
271bool QRecursiveMutexPrivate::locked()
272{
273 pthread_mutex_lock(&handle2);
274
275 bool ret;
276 int code = pthread_mutex_trylock(&handle);
277
278 if (code == EBUSY) {
279 ret = TRUE;
280 } else {
281#ifdef QT_CHECK_RANGE
282 if (code)
283 qWarning("Mutex trylock failure: %s", strerror(code));
284#endif
285
286 pthread_mutex_unlock(&handle);
287 ret = FALSE;
288 }
289
290 pthread_mutex_unlock(&handle2);
291
292 return ret;
293}
294
295bool QRecursiveMutexPrivate::trylock()
296{
297 bool ret = TRUE;
298
299 pthread_mutex_lock(&handle2);
300
301 if ( count > 0 && owner == (unsigned long) pthread_self() ) {
302 count++;
303 } else {
304 int code = pthread_mutex_trylock(&handle);
305
306 if (code == EBUSY) {
307 ret = FALSE;
308 } else if (code) {
309#ifdef QT_CHECK_RANGE
310 qWarning("Mutex trylock failure: %s", strerror(code));
311#endif
312 ret = FALSE;
313 } else {
314 count = 1;
315 owner = (unsigned long) pthread_self();
316 }
317 }
318
319 pthread_mutex_unlock(&handle2);
320
321 return ret;
322}
323
324int QRecursiveMutexPrivate::type() const
325{
326 return Q_MUTEX_RECURSIVE;
327}
328
329#endif // !Q_RECURSIVE_MUTEX_TYPE
330
331
332/*!
333 \class QMutex qmutex.h
334 \threadsafe
335 \brief The QMutex class provides access serialization between threads.
336
337 \ingroup thread
338 \ingroup environment
339
340 The purpose of a QMutex is to protect an object, data structure or
341 section of code so that only one thread can access it at a time
342 (This is similar to the Java \c synchronized keyword). For
343 example, say there is a method which prints a message to the user
344 on two lines:
345
346 \code
347 int number = 6;
348
349 void method1()
350 {
351 number *= 5;
352 number /= 4;
353 }
354
355 void method1()
356 {
357 number *= 3;
358 number /= 2;
359 }
360 \endcode
361
362 If these two methods are called in succession, the following happens:
363
364 \code
365 // method1()
366 number *= 5;// number is now 30
367 number /= 4;// number is now 7
368
369 // method2()
370 number *= 3;// nubmer is now 21
371 number /= 2;// number is now 10
372 \endcode
373
374 If these two methods are called simultaneously from two threads then the
375 following sequence could result:
376
377 \code
378 // Thread 1 calls method1()
379 number *= 5;// number is now 30
380
381 // Thread 2 calls method2().
382 //
383 // Most likely Thread 1 has been put to sleep by the operating
384 // system to allow Thread 2 to run.
385 number *= 3;// number is now 90
386 number /= 2;// number is now 45
387
388 // Thread 1 finishes executing.
389 number /= 4;// number is now 11, instead of 10
390 \endcode
391
392 If we add a mutex, we should get the result we want:
393
394 \code
395 QMutex mutex;
396 int number = 6;
397
398 void method1()
399 {
400 mutex.lock();
401 number *= 5;
402 number /= 4;
403 mutex.unlock();
404 }
405
406 void method2()
407 {
408 mutex.lock();
409 number *= 3;
410 number /= 2;
411 mutex.unlock();
412 }
413 \endcode
414
415 Then only one thread can modify \c number at any given time and
416 the result is correct. This is a trivial example, of course, but
417 applies to any other case where things need to happen in a
418 particular sequence.
419
420 When you call lock() in a thread, other threads that try to call
421 lock() in the same place will block until the thread that got the
422 lock calls unlock(). A non-blocking alternative to lock() is
423 tryLock().
424*/
425
426/*!
427 Constructs a new mutex. The mutex is created in an unlocked state.
428 A recursive mutex is created if \a recursive is TRUE; a normal
429 mutex is created if \a recursive is FALSE (the default). With a
430 recursive mutex, a thread can lock the same mutex multiple times
431 and it will not be unlocked until a corresponding number of
432 unlock() calls have been made.
433*/
434QMutex::QMutex(bool recursive)
435{
436#ifndef Q_RECURSIVE_MUTEX_TYPE
437 if ( recursive )
438 d = new QRecursiveMutexPrivate();
439 else
440#endif // !Q_RECURSIVE_MUTEX_TYPE
441 d = new QRealMutexPrivate(recursive);
442}
443
444/*!
445 Destroys the mutex.
446
447 \warning If you destroy a mutex that still holds a lock the
448 resultant behavior is undefined.
449*/
450QMutex::~QMutex()
451{
452 delete d;
453}
454
455/*!
456 Attempt to lock the mutex. If another thread has locked the mutex
457 then this call will \e block until that thread has unlocked it.
458
459 \sa unlock(), locked()
460*/
461void QMutex::lock()
462{
463 d->lock();
464}
465
466/*!
467 Unlocks the mutex. Attempting to unlock a mutex in a different
468 thread to the one that locked it results in an error. Unlocking a
469 mutex that is not locked results in undefined behaviour (varies
470 between different Operating Systems' thread implementations).
471
472 \sa lock(), locked()
473*/
474void QMutex::unlock()
475{
476 d->unlock();
477}
478
479/*!
480 Returns TRUE if the mutex is locked by another thread; otherwise
481 returns FALSE.
482
483 \warning Due to differing implementations of recursive mutexes on
484 various platforms, calling this function from the same thread that
485 previously locked the mutex will return undefined results.
486
487 \sa lock(), unlock()
488*/
489bool QMutex::locked()
490{
491 return d->locked();
492}
493
494/*!
495 Attempt to lock the mutex. If the lock was obtained, this function
496 returns TRUE. If another thread has locked the mutex, this
497 function returns FALSE, instead of waiting for the mutex to become
498 available, i.e. it does not block.
499
500 If the lock was obtained, the mutex must be unlocked with unlock()
501 before another thread can successfully lock it.
502
503 \sa lock(), unlock(), locked()
504*/
505bool QMutex::tryLock()
506{
507 return d->trylock();
508}
509
510/*!
511 \class QMutexLocker qmutex.h
512 \brief The QMutexLocker class simplifies locking and unlocking QMutexes.
513
514 \threadsafe
515
516 \ingroup thread
517 \ingroup environment
518
519 The purpose of QMutexLocker is to simplify QMutex locking and
520 unlocking. Locking and unlocking a QMutex in complex functions and
521 statements or in exception handling code is error prone and
522 difficult to debug. QMutexLocker should be used in such situations
523 to ensure that the state of the mutex is well defined and always
524 locked and unlocked properly.
525
526 QMutexLocker should be created within a function where a QMutex
527 needs to be locked. The mutex is locked when QMutexLocker is
528 created, and unlocked when QMutexLocker is destroyed.
529
530 For example, this complex function locks a QMutex upon entering
531 the function and unlocks the mutex at all the exit points:
532
533 \code
534 int complexFunction( int flag )
535 {
536 mutex.lock();
537
538 int return_value = 0;
539
540 switch ( flag ) {
541 case 0:
542 case 1:
543 {
544 mutex.unlock();
545 return moreComplexFunction( flag );
546 }
547
548 case 2:
549 {
550 int status = anotherFunction();
551 if ( status < 0 ) {
552 mutex.unlock();
553 return -2;
554 }
555 return_value = status + flag;
556 break;
557 }
558
559 default:
560 {
561 if ( flag > 10 ) {
562 mutex.unlock();
563 return -1;
564 }
565 break;
566 }
567 }
568
569 mutex.unlock();
570 return return_value;
571 }
572 \endcode
573
574 This example function will get more complicated as it is
575 developed, which increases the likelihood that errors will occur.
576
577 Using QMutexLocker greatly simplifies the code, and makes it more
578 readable:
579
580 \code
581 int complexFunction( int flag )
582 {
583 QMutexLocker locker( &mutex );
584
585 int return_value = 0;
586
587 switch ( flag ) {
588 case 0:
589 case 1:
590 {
591 return moreComplexFunction( flag );
592 }
593
594 case 2:
595 {
596 int status = anotherFunction();
597 if ( status < 0 )
598 return -2;
599 return_value = status + flag;
600 break;
601 }
602
603 default:
604 {
605 if ( flag > 10 )
606 return -1;
607 break;
608 }
609 }
610
611 return return_value;
612 }
613 \endcode
614
615 Now, the mutex will always be unlocked when the QMutexLocker
616 object is destroyed (when the function returns since \c locker is
617 an auto variable).
618
619 The same principle applies to code that throws and catches
620 exceptions. An exception that is not caught in the function that
621 has locked the mutex has no way of unlocking the mutex before the
622 exception is passed up the stack to the calling function.
623
624 QMutexLocker also provides a mutex() member function that returns
625 the mutex on which the QMutexLocker is operating. This is useful
626 for code that needs access to the mutex, such as
627 QWaitCondition::wait(). For example:
628
629 \code
630 class SignalWaiter
631 {
632 private:
633 QMutexLocker locker;
634
635 public:
636 SignalWaiter( QMutex *mutex )
637 : locker( mutex )
638 {
639 }
640
641 void waitForSignal()
642 {
643 ...
644 ...
645 ...
646
647 while ( ! signalled )
648 waitcondition.wait( locker.mutex() );
649
650 ...
651 ...
652 ...
653 }
654 };
655 \endcode
656
657 \sa QMutex, QWaitCondition
658*/
659
660/*!
661 \fn QMutexLocker::QMutexLocker( QMutex *mutex )
662
663 Constructs a QMutexLocker and locks \a mutex. The mutex will be
664 unlocked when the QMutexLocker is destroyed.
665
666 \sa QMutex::lock()
667*/
668
669/*!
670 \fn QMutexLocker::~QMutexLocker()
671
672 Destroys the QMutexLocker and unlocks the mutex which was locked
673 in the constructor.
674
675 \sa QMutexLocker::QMutexLocker(), QMutex::unlock()
676*/
677
678/*!
679 \fn QMutex *QMutexLocker::mutex() const
680
681 Returns a pointer to the mutex which was locked in the
682 constructor.
683
684 \sa QMutexLocker::QMutexLocker()
685*/
686
687#endif // QT_THREAD_SUPPORT
diff --git a/qmake/tools/qmutexpool.cpp b/qmake/tools/qmutexpool.cpp
new file mode 100644
index 0000000..9ed2829
--- a/dev/null
+++ b/qmake/tools/qmutexpool.cpp
@@ -0,0 +1,130 @@
1#include "qmutexpool_p.h"
2
3#ifdef QT_THREAD_SUPPORT
4
5#include <qthread.h>
6#include <stdio.h>
7
8QMutexPool *qt_global_mutexpool = 0;
9
10// this is an internal class used only for inititalizing the global mutexpool
11class QGlobalMutexPoolInitializer
12{
13public:
14 inline QGlobalMutexPoolInitializer()
15 {
16 /*
17 Purify will report a leak here. However, this mutex pool must be alive
18 until *everything* in Qt has been destructed. Unfortunately there is
19 no way to guarantee this, so we never destroy this mutex pool.
20 */
21 qt_global_mutexpool = new QMutexPool( TRUE );
22 }
23};
24QGlobalMutexPoolInitializer qt_global_mutexpool_initializer;
25
26/*!
27 \class QMutexPool qmutexpool_p.h
28 \brief The QMutexPool class provides a pool of QMutex objects.
29
30 \internal
31
32 \ingroup thread
33
34 QMutexPool is a convenience class that provides access to a fixed
35 number of QMutex objects.
36
37 Typical use of a QMutexPool is in situations where it is not
38 possible or feasible to use one QMutex for every protected object.
39 The mutex pool will return a mutex based on the address of the
40 object that needs protection.
41
42 For example, consider this simple class:
43
44 \code
45 class Number {
46 public:
47 Number( double n ) : num ( n ) { }
48
49 void setNumber( double n ) { num = n; }
50 double number() const { return num; }
51
52 private:
53 double num;
54 };
55 \endcode
56
57 Adding a QMutex member to the Number class does not make sense,
58 because it is so small. However, in order to ensure that access to
59 each Number is protected, you need to use a mutex. In this case, a
60 QMutexPool would be ideal.
61
62 Code to calculate the square of a number would then look something
63 like this:
64
65 \code
66 void calcSquare( Number *num )
67 {
68 QMutexLocker locker( mutexpool.get( num ) );
69 num.setNumber( num.number() * num.number() );
70 }
71 \endcode
72
73 This function will safely calculate the square of a number, since
74 it uses a mutex from a QMutexPool. The mutex is locked and
75 unlocked automatically by the QMutexLocker class. See the
76 QMutexLocker documentation for more details.
77*/
78
79/*!
80 Constructs a QMutexPool, reserving space for \a size QMutexes. If
81 \a recursive is TRUE, all QMutexes in the pool will be recursive
82 mutexes; otherwise they will all be non-recursive (the default).
83
84 The QMutexes are created when needed, and deleted when the
85 QMutexPool is destructed.
86*/
87QMutexPool::QMutexPool( bool recursive, int size )
88 : mutex( FALSE ), mutexes( size ), recurs( recursive )
89{
90 mutexes.fill( 0 );
91}
92
93/*!
94 Destructs a QMutexPool. All QMutexes that were created by the pool
95 are deleted.
96*/
97QMutexPool::~QMutexPool()
98{
99 QMutexLocker locker( &mutex );
100 QMutex **d = mutexes.data();
101 for ( int index = 0; (uint) index < mutexes.size(); index++ ) {
102 delete d[index];
103 d[index] = 0;
104 }
105}
106
107/*!
108 Returns a QMutex from the pool. QMutexPool uses the value \a
109 address to determine which mutex is retured from the pool.
110*/
111QMutex *QMutexPool::get( void *address )
112{
113 QMutex **d = mutexes.data();
114 int index = (int)( (ulong) address % mutexes.size() );
115
116 if ( ! d[index] ) {
117 // mutex not created, create one
118
119 QMutexLocker locker( &mutex );
120 // we need to check once again that the mutex hasn't been created, since
121 // 2 threads could be trying to create a mutex as the same index...
122 if ( ! d[index] ) {
123 d[index] = new QMutex( recurs );
124 }
125 }
126
127 return d[index];
128}
129
130#endif
diff --git a/qmake/tools/qptrcollection.cpp b/qmake/tools/qptrcollection.cpp
new file mode 100644
index 0000000..304ec1b
--- a/dev/null
+++ b/qmake/tools/qptrcollection.cpp
@@ -0,0 +1,180 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of base class for all pointer based collection classes
5**
6** Created : 920820
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qptrcollection.h"
39
40/*!
41 \class QPtrCollection qptrcollection.h
42 \reentrant
43 \brief The QPtrCollection class is the base class of most pointer-based Qt collections.
44
45 \ingroup collection
46 \ingroup tools
47
48 The QPtrCollection class is an abstract base class for the Qt
49 \link collection.html collection classes\endlink QDict, QPtrList,
50 etc. Qt also includes value based collections, e.g. QValueList,
51 QMap, etc.
52
53 A QPtrCollection only knows about the number of objects in the
54 collection and the deletion strategy (see setAutoDelete()).
55
56 A collection is implemented using the \c Item (generic collection
57 item) type, which is a \c void*. The template classes that create
58 the real collections cast the \c Item to the required type.
59*/
60
61
62/*!
63 \enum QPtrCollection::Item
64
65 This type is the generic "item" in a QPtrCollection.
66*/
67
68
69/*!
70 \fn QPtrCollection::QPtrCollection()
71
72 Constructs a collection. The constructor is protected because
73 QPtrCollection is an abstract class.
74*/
75
76/*!
77 \fn QPtrCollection::QPtrCollection( const QPtrCollection & source )
78
79 Constructs a copy of \a source with autoDelete() set to FALSE. The
80 constructor is protected because QPtrCollection is an abstract
81 class.
82
83 Note that if \a source has autoDelete turned on, copying it will
84 risk memory leaks, reading freed memory, or both.
85*/
86
87/*!
88 \fn QPtrCollection::~QPtrCollection()
89
90 Destroys the collection. The destructor is protected because
91 QPtrCollection is an abstract class.
92*/
93
94
95/*!
96 \fn bool QPtrCollection::autoDelete() const
97
98 Returns the setting of the auto-delete option. The default is FALSE.
99
100 \sa setAutoDelete()
101*/
102
103/*!
104 \fn void QPtrCollection::setAutoDelete( bool enable )
105
106 Sets the collection to auto-delete its contents if \a enable is
107 TRUE and to never delete them if \a enable is FALSE.
108
109 If auto-deleting is turned on, all the items in a collection are
110 deleted when the collection itself is deleted. This is convenient
111 if the collection has the only pointer to the items.
112
113 The default setting is FALSE, for safety. If you turn it on, be
114 careful about copying the collection - you might find yourself
115 with two collections deleting the same items.
116
117 Note that the auto-delete setting may also affect other functions
118 in subclasses. For example, a subclass that has a remove()
119 function will remove the item from its data structure, and if
120 auto-delete is enabled, will also delete the item.
121
122 \sa autoDelete()
123*/
124
125
126/*!
127 \fn virtual uint QPtrCollection::count() const
128
129 Returns the number of objects in the collection.
130*/
131
132/*!
133 \fn virtual void QPtrCollection::clear()
134
135 Removes all objects from the collection. The objects will be
136 deleted if auto-delete has been enabled.
137
138 \sa setAutoDelete()
139*/
140
141/*!
142 \fn void QPtrCollection::deleteItem( Item d )
143
144 Reimplement this function if you want to be able to delete items.
145
146 Deletes an item that is about to be removed from the collection.
147
148 This function has to reimplemented in the collection template
149 classes, and should \e only delete item \a d if auto-delete has
150 been enabled.
151
152 \warning If you reimplement this function you must also
153 reimplement the destructor and call the virtual function clear()
154 from your destructor. This is due to the way virtual functions and
155 destructors work in C++: Virtual functions in derived classes
156 cannot be called from a destructor. If you do not do this, your
157 deleteItem() function will not be called when the container is
158 destroyed.
159
160 \sa newItem(), setAutoDelete()
161*/
162
163/*!
164 Virtual function that creates a copy of an object that is about to
165 be inserted into the collection.
166
167 The default implementation returns the \a d pointer, i.e. no copy
168 is made.
169
170 This function is seldom reimplemented in the collection template
171 classes. It is not common practice to make a copy of something
172 that is being inserted.
173
174 \sa deleteItem()
175*/
176
177QPtrCollection::Item QPtrCollection::newItem( Item d )
178{
179 return d; // just return reference
180}
diff --git a/qmake/tools/qregexp.cpp b/qmake/tools/qregexp.cpp
new file mode 100644
index 0000000..500efed
--- a/dev/null
+++ b/qmake/tools/qregexp.cpp
@@ -0,0 +1,3935 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QRegExp class
5**
6** Created : 950126
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qregexp.h"
39
40#ifndef QT_NO_REGEXP
41
42#include "qmemarray.h"
43#include "qbitarray.h"
44#include "qcache.h"
45#include "qcleanuphandler.h"
46#include "qintdict.h"
47#include "qmap.h"
48#include "qptrvector.h"
49#include "qstring.h"
50#include "qtl.h"
51
52#ifdef QT_THREAD_SUPPORT
53#include "qmutexpool_p.h"
54#endif // QT_THREAD_SUPPORT
55
56#undef QT_TRANSLATE_NOOP
57#define QT_TRANSLATE_NOOP( context, sourceText ) sourceText
58
59#include <limits.h>
60
61// error strings for the regexp parser
62#define RXERR_OK QT_TRANSLATE_NOOP( "QRegExp", "no error occurred" )
63#define RXERR_DISABLED QT_TRANSLATE_NOOP( "QRegExp", "disabled feature used" )
64#define RXERR_CHARCLASS QT_TRANSLATE_NOOP( "QRegExp", "bad char class syntax" )
65#define RXERR_LOOKAHEAD QT_TRANSLATE_NOOP( "QRegExp", "bad lookahead syntax" )
66#define RXERR_REPETITION QT_TRANSLATE_NOOP( "QRegExp", "bad repetition syntax" )
67#define RXERR_OCTAL QT_TRANSLATE_NOOP( "QRegExp", "invalid octal value" )
68#define RXERR_LEFTDELIM QT_TRANSLATE_NOOP( "QRegExp", "missing left delim" )
69#define RXERR_END QT_TRANSLATE_NOOP( "QRegExp", "unexpected end" )
70#define RXERR_LIMIT QT_TRANSLATE_NOOP( "QRegExp", "met internal limit" )
71
72/*
73 WARNING! Be sure to read qregexp.tex before modifying this file.
74*/
75
76/*!
77 \class QRegExp qregexp.h
78 \reentrant
79 \brief The QRegExp class provides pattern matching using regular expressions.
80
81 \ingroup tools
82 \ingroup misc
83 \ingroup shared
84 \mainclass
85 \keyword regular expression
86
87 Regular expressions, or "regexps", provide a way to find patterns
88 within text. This is useful in many contexts, for example:
89
90 \table
91 \row \i Validation
92 \i A regexp can be used to check whether a piece of text
93 meets some criteria, e.g. is an integer or contains no
94 whitespace.
95 \row \i Searching
96 \i Regexps provide a much more powerful means of searching
97 text than simple string matching does. For example we can
98 create a regexp which says "find one of the words 'mail',
99 'letter' or 'correspondence' but not any of the words
100 'email', 'mailman' 'mailer', 'letterbox' etc."
101 \row \i Search and Replace
102 \i A regexp can be used to replace a pattern with a piece of
103 text, for example replace all occurrences of '&' with
104 '\&amp;' except where the '&' is already followed by 'amp;'.
105 \row \i String Splitting
106 \i A regexp can be used to identify where a string should be
107 split into its component fields, e.g. splitting tab-delimited
108 strings.
109 \endtable
110
111 We present a very brief introduction to regexps, a description of
112 Qt's regexp language, some code examples, and finally the function
113 documentation itself. QRegExp is modeled on Perl's regexp
114 language, and also fully supports Unicode. QRegExp can also be
115 used in the weaker 'wildcard' (globbing) mode which works in a
116 similar way to command shells. A good text on regexps is \e
117 {Mastering Regular Expressions: Powerful Techniques for Perl and
118 Other Tools} by Jeffrey E. Friedl, ISBN 1565922573.
119
120 Experienced regexp users may prefer to skip the introduction and
121 go directly to the relevant information.
122
123 \tableofcontents
124
125 \section1 Introduction
126
127 Regexps are built up from expressions, quantifiers, and assertions.
128 The simplest form of expression is simply a character, e.g.
129 <b>x</b> or <b>5</b>. An expression can also be a set of
130 characters. For example, <b>[ABCD]</b>, will match an <b>A</b> or
131 a <b>B</b> or a <b>C</b> or a <b>D</b>. As a shorthand we could
132 write this as <b>[A-D]</b>. If we want to match any of the
133 captital letters in the English alphabet we can write
134 <b>[A-Z]</b>. A quantifier tells the regexp engine how many
135 occurrences of the expression we want, e.g. <b>x{1,1}</b> means
136 match an <b>x</b> which occurs at least once and at most once.
137 We'll look at assertions and more complex expressions later.
138
139 Note that in general regexps cannot be used to check for balanced
140 brackets or tags. For example if you want to match an opening html
141 \c <b> and its closing \c </b> you can only use a regexp if you
142 know that these tags are not nested; the html fragment, \c{<b>bold
143 <b>bolder</b></b>} will not match as expected. If you know the
144 maximum level of nesting it is possible to create a regexp that
145 will match correctly, but for an unknown level of nesting, regexps
146 will fail.
147
148 We'll start by writing a regexp to match integers in the range 0
149 to 99. We will require at least one digit so we will start with
150 <b>[0-9]{1,1}</b> which means match a digit exactly once. This
151 regexp alone will match integers in the range 0 to 9. To match one
152 or two digits we can increase the maximum number of occurrences so
153 the regexp becomes <b>[0-9]{1,2}</b> meaning match a digit at
154 least once and at most twice. However, this regexp as it stands
155 will not match correctly. This regexp will match one or two digits
156 \e within a string. To ensure that we match against the whole
157 string we must use the anchor assertions. We need <b>^</b> (caret)
158 which when it is the first character in the regexp means that the
159 regexp must match from the beginning of the string. And we also
160 need <b>$</b> (dollar) which when it is the last character in the
161 regexp means that the regexp must match until the end of the
162 string. So now our regexp is <b>^[0-9]{1,2}$</b>. Note that
163 assertions, such as <b>^</b> and <b>$</b>, do not match any
164 characters.
165
166 If you've seen regexps elsewhere they may have looked different from
167 the ones above. This is because some sets of characters and some
168 quantifiers are so common that they have special symbols to
169 represent them. <b>[0-9]</b> can be replaced with the symbol
170 <b>\d</b>. The quantifier to match exactly one occurrence,
171 <b>{1,1}</b>, can be replaced with the expression itself. This means
172 that <b>x{1,1}</b> is exactly the same as <b>x</b> alone. So our 0
173 to 99 matcher could be written <b>^\d{1,2}$</b>. Another way of
174 writing it would be <b>^\d\d{0,1}$</b>, i.e. from the start of the
175 string match a digit followed by zero or one digits. In practice
176 most people would write it <b>^\d\d?$</b>. The <b>?</b> is a
177 shorthand for the quantifier <b>{0,1}</b>, i.e. a minimum of no
178 occurrences a maximum of one occurrence. This is used to make an
179 expression optional. The regexp <b>^\d\d?$</b> means "from the
180 beginning of the string match one digit followed by zero or one
181 digits and then the end of the string".
182
183 Our second example is matching the words 'mail', 'letter' or
184 'correspondence' but without matching 'email', 'mailman',
185 'mailer', 'letterbox' etc. We'll start by just matching 'mail'. In
186 full the regexp is, <b>m{1,1}a{1,1}i{1,1}l{1,1}</b>, but since
187 each expression itself is automatically quantified by <b>{1,1}</b>
188 we can simply write this as <b>mail</b>; an 'm' followed by an 'a'
189 followed by an 'i' followed by an 'l'. The symbol '|' (bar) is
190 used for \e alternation, so our regexp now becomes
191 <b>mail|letter|correspondence</b> which means match 'mail' \e or
192 'letter' \e or 'correspondence'. Whilst this regexp will find the
193 words we want it will also find words we don't want such as
194 'email'. We will start by putting our regexp in parentheses,
195 <b>(mail|letter|correspondence)</b>. Parentheses have two effects,
196 firstly they group expressions together and secondly they identify
197 parts of the regexp that we wish to \link #capturing-text capture
198 \endlink. Our regexp still matches any of the three words but now
199 they are grouped together as a unit. This is useful for building
200 up more complex regexps. It is also useful because it allows us to
201 examine which of the words actually matched. We need to use
202 another assertion, this time <b>\b</b> "word boundary":
203 <b>\b(mail|letter|correspondence)\b</b>. This regexp means "match
204 a word boundary followed by the expression in parentheses followed
205 by another word boundary". The <b>\b</b> assertion matches at a \e
206 position in the regexp not a \e character in the regexp. A word
207 boundary is any non-word character such as a space a newline or
208 the beginning or end of the string.
209
210 For our third example we want to replace ampersands with the HTML
211 entity '\&amp;'. The regexp to match is simple: <b>\&</b>, i.e.
212 match one ampersand. Unfortunately this will mess up our text if
213 some of the ampersands have already been turned into HTML
214 entities. So what we really want to say is replace an ampersand
215 providing it is not followed by 'amp;'. For this we need the
216 negative lookahead assertion and our regexp becomes:
217 <b>\&(?!amp;)</b>. The negative lookahead assertion is introduced
218 with '(?!' and finishes at the ')'. It means that the text it
219 contains, 'amp;' in our example, must \e not follow the expression
220 that preceeds it.
221
222 Regexps provide a rich language that can be used in a variety of
223 ways. For example suppose we want to count all the occurrences of
224 'Eric' and 'Eirik' in a string. Two valid regexps to match these
225 are <b>\\b(Eric|Eirik)\\b</b> and <b>\\bEi?ri[ck]\\b</b>. We need
226 the word boundary '\b' so we don't get 'Ericsson' etc. The second
227 regexp actually matches more than we want, 'Eric', 'Erik', 'Eiric'
228 and 'Eirik'.
229
230 We will implement some the examples above in the
231 \link #code-examples code examples \endlink section.
232
233 \target characters-and-abbreviations-for-sets-of-characters
234 \section1 Characters and Abbreviations for Sets of Characters
235
236 \table
237 \header \i Element \i Meaning
238 \row \i <b>c</b>
239 \i Any character represents itself unless it has a special
240 regexp meaning. Thus <b>c</b> matches the character \e c.
241 \row \i <b>\\c</b>
242 \i A character that follows a backslash matches the character
243 itself except where mentioned below. For example if you
244 wished to match a literal caret at the beginning of a string
245 you would write <b>\^</b>.
246 \row \i <b>\\a</b>
247 \i This matches the ASCII bell character (BEL, 0x07).
248 \row \i <b>\\f</b>
249 \i This matches the ASCII form feed character (FF, 0x0C).
250 \row \i <b>\\n</b>
251 \i This matches the ASCII line feed character (LF, 0x0A, Unix newline).
252 \row \i <b>\\r</b>
253 \i This matches the ASCII carriage return character (CR, 0x0D).
254 \row \i <b>\\t</b>
255 \i This matches the ASCII horizontal tab character (HT, 0x09).
256 \row \i <b>\\v</b>
257 \i This matches the ASCII vertical tab character (VT, 0x0B).
258 \row \i <b>\\xhhhh</b>
259 \i This matches the Unicode character corresponding to the
260 hexadecimal number hhhh (between 0x0000 and 0xFFFF). \0ooo
261 (i.e., \zero ooo) matches the ASCII/Latin-1 character
262 corresponding to the octal number ooo (between 0 and 0377).
263 \row \i <b>. (dot)</b>
264 \i This matches any character (including newline).
265 \row \i <b>\\d</b>
266 \i This matches a digit (see QChar::isDigit()).
267 \row \i <b>\\D</b>
268 \i This matches a non-digit.
269 \row \i <b>\\s</b>
270 \i This matches a whitespace (see QChar::isSpace()).
271 \row \i <b>\\S</b>
272 \i This matches a non-whitespace.
273 \row \i <b>\\w</b>
274 \i This matches a word character (see QChar::isLetterOrNumber()).
275 \row \i <b>\\W</b>
276 \i This matches a non-word character.
277 \row \i <b>\\n</b>
278 \i The n-th \link #capturing-text backreference \endlink,
279 e.g. \1, \2, etc.
280 \endtable
281
282 \e {Note that the C++ compiler transforms backslashes in strings
283 so to include a <b>\\</b> in a regexp you will need to enter it
284 twice, i.e. <b>\\\\</b>.}
285
286 \target sets-of-characters
287 \section1 Sets of Characters
288
289 Square brackets are used to match any character in the set of
290 characters contained within the square brackets. All the character
291 set abbreviations described above can be used within square
292 brackets. Apart from the character set abbreviations and the
293 following two exceptions no characters have special meanings in
294 square brackets.
295
296 \table
297 \row \i <b>^</b>
298 \i The caret negates the character set if it occurs as the
299 first character, i.e. immediately after the opening square
300 bracket. For example, <b>[abc]</b> matches 'a' or 'b' or 'c',
301 but <b>[^abc]</b> matches anything \e except 'a' or 'b' or
302 'c'.
303 \row \i <b>-</b>
304 \i The dash is used to indicate a range of characters, for
305 example <b>[W-Z]</b> matches 'W' or 'X' or 'Y' or 'Z'.
306 \endtable
307
308 Using the predefined character set abbreviations is more portable
309 than using character ranges across platforms and languages. For
310 example, <b>[0-9]</b> matches a digit in Western alphabets but
311 <b>\d</b> matches a digit in \e any alphabet.
312
313 Note that in most regexp literature sets of characters are called
314 "character classes".
315
316 \target quantifiers
317 \section1 Quantifiers
318
319 By default an expression is automatically quantified by
320 <b>{1,1}</b>, i.e. it should occur exactly once. In the following
321 list <b>\e {E}</b> stands for any expression. An expression is a
322 character or an abbreviation for a set of characters or a set of
323 characters in square brackets or any parenthesised expression.
324
325 \table
326 \row \i <b>\e {E}?</b>
327 \i Matches zero or one occurrence of \e E. This quantifier
328 means "the previous expression is optional" since it will
329 match whether or not the expression occurs in the string. It
330 is the same as <b>\e {E}{0,1}</b>. For example <b>dents?</b>
331 will match 'dent' and 'dents'.
332
333 \row \i <b>\e {E}+</b>
334 \i Matches one or more occurrences of \e E. This is the same
335 as <b>\e {E}{1,MAXINT}</b>. For example, <b>0+</b> will match
336 '0', '00', '000', etc.
337
338 \row \i <b>\e {E}*</b>
339 \i Matches zero or more occurrences of \e E. This is the same
340 as <b>\e {E}{0,MAXINT}</b>. The <b>*</b> quantifier is often
341 used by a mistake. Since it matches \e zero or more
342 occurrences it will match no occurrences at all. For example
343 if we want to match strings that end in whitespace and use
344 the regexp <b>\s*$</b> we would get a match on every string.
345 This is because we have said find zero or more whitespace
346 followed by the end of string, so even strings that don't end
347 in whitespace will match. The regexp we want in this case is
348 <b>\s+$</b> to match strings that have at least one
349 whitespace at the end.
350
351 \row \i <b>\e {E}{n}</b>
352 \i Matches exactly \e n occurrences of the expression. This
353 is the same as repeating the expression \e n times. For
354 example, <b>x{5}</b> is the same as <b>xxxxx</b>. It is also
355 the same as <b>\e {E}{n,n}</b>, e.g. <b>x{5,5}</b>.
356
357 \row \i <b>\e {E}{n,}</b>
358 \i Matches at least \e n occurrences of the expression. This
359 is the same as <b>\e {E}{n,MAXINT}</b>.
360
361 \row \i <b>\e {E}{,m}</b>
362 \i Matches at most \e m occurrences of the expression. This
363 is the same as <b>\e {E}{0,m}</b>.
364
365 \row \i <b>\e {E}{n,m}</b>
366 \i Matches at least \e n occurrences of the expression and at
367 most \e m occurrences of the expression.
368 \endtable
369
370 (MAXINT is implementation dependent but will not be smaller than
371 1024.)
372
373 If we wish to apply a quantifier to more than just the preceding
374 character we can use parentheses to group characters together in
375 an expression. For example, <b>tag+</b> matches a 't' followed by
376 an 'a' followed by at least one 'g', whereas <b>(tag)+</b> matches
377 at least one occurrence of 'tag'.
378
379 Note that quantifiers are "greedy". They will match as much text
380 as they can. For example, <b>0+</b> will match as many zeros as it
381 can from the first zero it finds, e.g. '2.<u>000</u>5'.
382 Quantifiers can be made non-greedy, see setMinimal().
383
384 \target capturing-text
385 \section1 Capturing Text
386
387 Parentheses allow us to group elements together so that we can
388 quantify and capture them. For example if we have the expression
389 <b>mail|letter|correspondence</b> that matches a string we know
390 that \e one of the words matched but not which one. Using
391 parentheses allows us to "capture" whatever is matched within
392 their bounds, so if we used <b>(mail|letter|correspondence)</b>
393 and matched this regexp against the string "I sent you some email"
394 we can use the cap() or capturedTexts() functions to extract the
395 matched characters, in this case 'mail'.
396
397 We can use captured text within the regexp itself. To refer to the
398 captured text we use \e backreferences which are indexed from 1,
399 the same as for cap(). For example we could search for duplicate
400 words in a string using <b>\b(\w+)\W+\1\b</b> which means match a
401 word boundary followed by one or more word characters followed by
402 one or more non-word characters followed by the same text as the
403 first parenthesised expression followed by a word boundary.
404
405 If we want to use parentheses purely for grouping and not for
406 capturing we can use the non-capturing syntax, e.g.
407 <b>(?:green|blue)</b>. Non-capturing parentheses begin '(?:' and
408 end ')'. In this example we match either 'green' or 'blue' but we
409 do not capture the match so we only know whether or not we matched
410 but not which color we actually found. Using non-capturing
411 parentheses is more efficient than using capturing parentheses
412 since the regexp engine has to do less book-keeping.
413
414 Both capturing and non-capturing parentheses may be nested.
415
416 \target assertions
417 \section1 Assertions
418
419 Assertions make some statement about the text at the point where
420 they occur in the regexp but they do not match any characters. In
421 the following list <b>\e {E}</b> stands for any expression.
422
423 \table
424 \row \i <b>^</b>
425 \i The caret signifies the beginning of the string. If you
426 wish to match a literal \c{^} you must escape it by
427 writing \c{\\^}. For example, <b>^#include</b> will only
428 match strings which \e begin with the characters '#include'.
429 (When the caret is the first character of a character set it
430 has a special meaning, see \link #sets-of-characters Sets of
431 Characters \endlink.)
432
433 \row \i <b>$</b>
434 \i The dollar signifies the end of the string. For example
435 <b>\d\s*$</b> will match strings which end with a digit
436 optionally followed by whitespace. If you wish to match a
437 literal \c{$} you must escape it by writing
438 \c{\\$}.
439
440 \row \i <b>\\b</b>
441 \i A word boundary. For example the regexp
442 <b>\\bOK\\b</b> means match immediately after a word
443 boundary (e.g. start of string or whitespace) the letter 'O'
444 then the letter 'K' immediately before another word boundary
445 (e.g. end of string or whitespace). But note that the
446 assertion does not actually match any whitespace so if we
447 write <b>(\\bOK\\b)</b> and we have a match it will only
448 contain 'OK' even if the string is "Its <u>OK</u> now".
449
450 \row \i <b>\\B</b>
451 \i A non-word boundary. This assertion is true wherever
452 <b>\\b</b> is false. For example if we searched for
453 <b>\\Bon\\B</b> in "Left on" the match would fail (space
454 and end of string aren't non-word boundaries), but it would
455 match in "t<u>on</u>ne".
456
457 \row \i <b>(?=\e E)</b>
458 \i Positive lookahead. This assertion is true if the
459 expression matches at this point in the regexp. For example,
460 <b>const(?=\\s+char)</b> matches 'const' whenever it is
461 followed by 'char', as in 'static <u>const</u> char *'.
462 (Compare with <b>const\\s+char</b>, which matches 'static
463 <u>const char</u> *'.)
464
465 \row \i <b>(?!\e E)</b>
466 \i Negative lookahead. This assertion is true if the
467 expression does not match at this point in the regexp. For
468 example, <b>const(?!\\s+char)</b> matches 'const' \e except
469 when it is followed by 'char'.
470 \endtable
471
472 \target wildcard-matching
473 \section1 Wildcard Matching (globbing)
474
475 Most command shells such as \e bash or \e cmd.exe support "file
476 globbing", the ability to identify a group of files by using
477 wildcards. The setWildcard() function is used to switch between
478 regexp and wildcard mode. Wildcard matching is much simpler than
479 full regexps and has only four features:
480
481 \table
482 \row \i <b>c</b>
483 \i Any character represents itself apart from those mentioned
484 below. Thus <b>c</b> matches the character \e c.
485 \row \i <b>?</b>
486 \i This matches any single character. It is the same as
487 <b>.</b> in full regexps.
488 \row \i <b>*</b>
489 \i This matches zero or more of any characters. It is the
490 same as <b>.*</b> in full regexps.
491 \row \i <b>[...]</b>
492 \i Sets of characters can be represented in square brackets,
493 similar to full regexps. Within the character class, like
494 outside, backslash has no special meaning.
495 \endtable
496
497 For example if we are in wildcard mode and have strings which
498 contain filenames we could identify HTML files with <b>*.html</b>.
499 This will match zero or more characters followed by a dot followed
500 by 'h', 't', 'm' and 'l'.
501
502 \target perl-users
503 \section1 Notes for Perl Users
504
505 Most of the character class abbreviations supported by Perl are
506 supported by QRegExp, see \link
507 #characters-and-abbreviations-for-sets-of-characters characters
508 and abbreviations for sets of characters \endlink.
509
510 In QRegExp, apart from within character classes, \c{^} always
511 signifies the start of the string, so carets must always be
512 escaped unless used for that purpose. In Perl the meaning of caret
513 varies automagically depending on where it occurs so escaping it
514 is rarely necessary. The same applies to \c{$} which in
515 QRegExp always signifies the end of the string.
516
517 QRegExp's quantifiers are the same as Perl's greedy quantifiers.
518 Non-greedy matching cannot be applied to individual quantifiers,
519 but can be applied to all the quantifiers in the pattern. For
520 example, to match the Perl regexp <b>ro+?m</b> requires:
521 \code
522 QRegExp rx( "ro+m" );
523 rx.setMinimal( TRUE );
524 \endcode
525
526 The equivalent of Perl's \c{/i} option is
527 setCaseSensitive(FALSE).
528
529 Perl's \c{/g} option can be emulated using a \link
530 #cap_in_a_loop loop \endlink.
531
532 In QRegExp <b>.</b> matches any character, therefore all QRegExp
533 regexps have the equivalent of Perl's \c{/s} option. QRegExp
534 does not have an equivalent to Perl's \c{/m} option, but this
535 can be emulated in various ways for example by splitting the input
536 into lines or by looping with a regexp that searches for newlines.
537
538 Because QRegExp is string oriented there are no \A, \Z or \z
539 assertions. The \G assertion is not supported but can be emulated
540 in a loop.
541
542 Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp
543 equivalents for $`, $' or $+. Perl's capturing variables, $1, $2,
544 ... correspond to cap(1) or capturedTexts()[1], cap(2) or
545 capturedTexts()[2], etc.
546
547 To substitute a pattern use QString::replace().
548
549 Perl's extended \c{/x} syntax is not supported, nor are
550 regexp comments (?#comment) or directives, e.g. (?i).
551
552 Both zero-width positive and zero-width negative lookahead
553 assertions (?=pattern) and (?!pattern) are supported with the same
554 syntax as Perl. Perl's lookbehind assertions, "independent"
555 subexpressions and conditional expressions are not supported.
556
557 Non-capturing parentheses are also supported, with the same
558 (?:pattern) syntax.
559
560 See QStringList::split() and QStringList::join() for equivalents
561 to Perl's split and join functions.
562
563 Note: because C++ transforms \\'s they must be written \e twice in
564 code, e.g. <b>\\b</b> must be written <b>\\\\b</b>.
565
566 \target code-examples
567 \section1 Code Examples
568
569 \code
570 QRegExp rx( "^\\d\\d?$" ); // match integers 0 to 99
571 rx.search( "123" ); // returns -1 (no match)
572 rx.search( "-6" ); // returns -1 (no match)
573 rx.search( "6" ); // returns 0 (matched as position 0)
574 \endcode
575
576 The third string matches '<u>6</u>'. This is a simple validation
577 regexp for integers in the range 0 to 99.
578
579 \code
580 QRegExp rx( "^\\S+$" ); // match strings without whitespace
581 rx.search( "Hello world" ); // returns -1 (no match)
582 rx.search( "This_is-OK" ); // returns 0 (matched at position 0)
583 \endcode
584
585 The second string matches '<u>This_is-OK</u>'. We've used the
586 character set abbreviation '\S' (non-whitespace) and the anchors
587 to match strings which contain no whitespace.
588
589 In the following example we match strings containing 'mail' or
590 'letter' or 'correspondence' but only match whole words i.e. not
591 'email'
592
593 \code
594 QRegExp rx( "\\b(mail|letter|correspondence)\\b" );
595 rx.search( "I sent you an email" ); // returns -1 (no match)
596 rx.search( "Please write the letter" ); // returns 17
597 \endcode
598
599 The second string matches "Please write the <u>letter</u>". The
600 word 'letter' is also captured (because of the parentheses). We
601 can see what text we've captured like this:
602
603 \code
604 QString captured = rx.cap( 1 ); // captured == "letter"
605 \endcode
606
607 This will capture the text from the first set of capturing
608 parentheses (counting capturing left parentheses from left to
609 right). The parentheses are counted from 1 since cap( 0 ) is the
610 whole matched regexp (equivalent to '&' in most regexp engines).
611
612 \code
613 QRegExp rx( "&(?!amp;)" ); // match ampersands but not &amp;
614 QString line1 = "This & that";
615 line1.replace( rx, "&amp;" );
616 // line1 == "This &amp; that"
617 QString line2 = "His &amp; hers & theirs";
618 line2.replace( rx, "&amp;" );
619 // line2 == "His &amp; hers &amp; theirs"
620 \endcode
621
622 Here we've passed the QRegExp to QString's replace() function to
623 replace the matched text with new text.
624
625 \code
626 QString str = "One Eric another Eirik, and an Ericsson."
627 " How many Eiriks, Eric?";
628 QRegExp rx( "\\b(Eric|Eirik)\\b" ); // match Eric or Eirik
629 int pos = 0; // where we are in the string
630 int count = 0; // how many Eric and Eirik's we've counted
631 while ( pos >= 0 ) {
632 pos = rx.search( str, pos );
633 if ( pos >= 0 ) {
634 pos++; // move along in str
635 count++; // count our Eric or Eirik
636 }
637 }
638 \endcode
639
640 We've used the search() function to repeatedly match the regexp in
641 the string. Note that instead of moving forward by one character
642 at a time \c pos++ we could have written \c {pos +=
643 rx.matchedLength()} to skip over the already matched string. The
644 count will equal 3, matching 'One <u>Eric</u> another
645 <u>Eirik</u>, and an Ericsson. How many Eiriks, <u>Eric</u>?'; it
646 doesn't match 'Ericsson' or 'Eiriks' because they are not bounded
647 by non-word boundaries.
648
649 One common use of regexps is to split lines of delimited data into
650 their component fields.
651
652 \code
653 str = "Trolltech AS\twww.trolltech.com\tNorway";
654 QString company, web, country;
655 rx.setPattern( "^([^\t]+)\t([^\t]+)\t([^\t]+)$" );
656 if ( rx.search( str ) != -1 ) {
657 company = rx.cap( 1 );
658 web = rx.cap( 2 );
659 country = rx.cap( 3 );
660 }
661 \endcode
662
663 In this example our input lines have the format company name, web
664 address and country. Unfortunately the regexp is rather long and
665 not very versatile -- the code will break if we add any more
666 fields. A simpler and better solution is to look for the
667 separator, '\t' in this case, and take the surrounding text. The
668 QStringList split() function can take a separator string or regexp
669 as an argument and split a string accordingly.
670
671 \code
672 QStringList field = QStringList::split( "\t", str );
673 \endcode
674
675 Here field[0] is the company, field[1] the web address and so on.
676
677 To imitate the matching of a shell we can use wildcard mode.
678
679 \code
680 QRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything
681 rx.setWildcard( TRUE ); // now it's a valid wildcard regexp
682 rx.search( "index.html" ); // returns 0 (matched at position 0)
683 rx.search( "default.htm" ); // returns -1 (no match)
684 rx.search( "readme.txt" ); // returns -1 (no match)
685 \endcode
686
687 Wildcard matching can be convenient because of its simplicity, but
688 any wildcard regexp can be defined using full regexps, e.g.
689 <b>.*\.html$</b>. Notice that we can't match both \c .html and \c
690 .htm files with a wildcard unless we use <b>*.htm*</b> which will
691 also match 'test.html.bak'. A full regexp gives us the precision
692 we need, <b>.*\\.html?$</b>.
693
694 QRegExp can match case insensitively using setCaseSensitive(), and
695 can use non-greedy matching, see setMinimal(). By default QRegExp
696 uses full regexps but this can be changed with setWildcard().
697 Searching can be forward with search() or backward with
698 searchRev(). Captured text can be accessed using capturedTexts()
699 which returns a string list of all captured strings, or using
700 cap() which returns the captured string for the given index. The
701 pos() function takes a match index and returns the position in the
702 string where the match was made (or -1 if there was no match).
703
704 \sa QRegExpValidator QString QStringList
705
706 \target member-function-documentation
707*/
708
709const int NumBadChars = 64;
710#define BadChar( ch ) ( (ch).unicode() % NumBadChars )
711
712const int NoOccurrence = INT_MAX;
713const int EmptyCapture = INT_MAX;
714const int InftyLen = INT_MAX;
715const int InftyRep = 1025;
716const int EOS = -1;
717
718/*
719 Merges two QMemArrays of ints and puts the result into the first one.
720*/
721static void mergeInto( QMemArray<int> *a, const QMemArray<int>& b )
722{
723 int asize = a->size();
724 int bsize = b.size();
725 if ( asize == 0 ) {
726 *a = b.copy();
727#ifndef QT_NO_REGEXP_OPTIM
728 } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) {
729 a->resize( asize + 1 );
730 (*a)[asize] = b[0];
731#endif
732 } else if ( bsize >= 1 ) {
733 int csize = asize + bsize;
734 QMemArray<int> c( csize );
735 int i = 0, j = 0, k = 0;
736 while ( i < asize ) {
737 if ( j < bsize ) {
738 if ( (*a)[i] == b[j] ) {
739 i++;
740 csize--;
741 } else if ( (*a)[i] < b[j] ) {
742 c[k++] = (*a)[i++];
743 } else {
744 c[k++] = b[j++];
745 }
746 } else {
747 memcpy( c.data() + k, (*a).data() + i,
748 (asize - i) * sizeof(int) );
749 break;
750 }
751 }
752 c.resize( csize );
753 if ( j < bsize )
754 memcpy( c.data() + k, b.data() + j, (bsize - j) * sizeof(int) );
755 *a = c;
756 }
757}
758
759/*
760 Merges two disjoint QMaps of (int, int) pairs and puts the result into the
761 first one.
762*/
763static void mergeInto( QMap<int, int> *a, const QMap<int, int>& b )
764{
765 QMap<int, int>::ConstIterator it;
766 for ( it = b.begin(); it != b.end(); ++it )
767 a->insert( it.key(), *it );
768}
769
770/*
771 Returns the value associated to key k in QMap m of (int, int) pairs, or 0 if
772 no such value is explicitly present.
773*/
774static int at( const QMap<int, int>& m, int k )
775{
776 QMap<int, int>::ConstIterator it = m.find( k );
777 if ( it == m.end() )
778 return 0;
779 else
780 return *it;
781}
782
783#ifndef QT_NO_REGEXP_WILDCARD
784/*
785 Translates a wildcard pattern to an equivalent regular expression pattern
786 (e.g., *.cpp to .*\.cpp).
787*/
788static QString wc2rx( const QString& wc_str )
789{
790 int wclen = wc_str.length();
791 QString rx = QString::fromLatin1( "" );
792 int i = 0;
793 const QChar *wc = wc_str.unicode();
794 while ( i < wclen ) {
795 QChar c = wc[i++];
796 switch ( c.unicode() ) {
797 case '*':
798 rx += QString::fromLatin1( ".*" );
799 break;
800 case '?':
801 rx += QChar( '.' );
802 break;
803 case '$':
804 case '(':
805 case ')':
806 case '+':
807 case '.':
808 case '\\':
809 case '^':
810 case '{':
811 case '|':
812 case '}':
813 rx += QChar( '\\' );
814 rx += c;
815 break;
816 case '[':
817 rx += c;
818 if ( wc[i] == QChar('^') )
819 rx += wc[i++];
820 if ( i < wclen ) {
821 if ( rx[i] == ']' )
822 rx += wc[i++];
823 while ( i < wclen && wc[i] != QChar(']') ) {
824 if ( wc[i] == '\\' )
825 rx += QChar( '\\' );
826 rx += wc[i++];
827 }
828 }
829 break;
830 default:
831 rx += c;
832 }
833 }
834 return rx;
835}
836#endif
837
838/*
839 The class QRegExpEngine encapsulates a modified nondeterministic
840 finite automaton (NFA).
841*/
842class QRegExpEngine : public QShared
843{
844public:
845#ifndef QT_NO_REGEXP_CCLASS
846 /*
847 The class CharClass represents a set of characters, such as can
848 be found in regular expressions (e.g., [a-z] denotes the set
849 {a, b, ..., z}).
850 */
851 class CharClass
852 {
853 public:
854 CharClass();
855 CharClass( const CharClass& cc ) { operator=( cc ); }
856
857 CharClass& operator=( const CharClass& cc );
858
859 void clear();
860 bool negative() const { return n; }
861 void setNegative( bool negative );
862 void addCategories( int cats );
863 void addRange( ushort from, ushort to );
864 void addSingleton( ushort ch ) { addRange( ch, ch ); }
865
866 bool in( QChar ch ) const;
867#ifndef QT_NO_REGEXP_OPTIM
868 const QMemArray<int>& firstOccurrence() const { return occ1; }
869#endif
870
871#if defined(QT_DEBUG)
872 void dump() const;
873#endif
874
875 private:
876 /*
877 The struct Range represents a range of characters (e.g.,
878 [0-9] denotes range 48 to 57).
879 */
880 struct Range
881 {
882 ushort from; // 48
883 ushort to; // 57
884 };
885
886 int c; // character classes
887 QMemArray<Range> r; // character ranges
888 bool n; // negative?
889#ifndef QT_NO_REGEXP_OPTIM
890 QMemArray<int> occ1; // first-occurrence array
891#endif
892 };
893#else
894 struct CharClass
895 {
896 int dummy;
897
898#ifndef QT_NO_REGEXP_OPTIM
899 CharClass() { occ1.fill( 0, NumBadChars ); }
900
901 const QMemArray<int>& firstOccurrence() const { return occ1; }
902 QMemArray<int> occ1;
903#endif
904 };
905#endif
906
907 QRegExpEngine( bool caseSensitive ) { setup( caseSensitive ); }
908 QRegExpEngine( const QString& rx, bool caseSensitive );
909#ifndef QT_NO_REGEXP_OPTIM
910 ~QRegExpEngine();
911#endif
912
913 bool isValid() const { return valid; }
914 const QString& errorString() const { return yyError; }
915 bool caseSensitive() const { return cs; }
916 int numCaptures() const { return officialncap; }
917 QMemArray<int> match( const QString& str, int pos, bool minimal,
918 bool oneTest, int caretIndex );
919 int matchedLength() const { return mmMatchedLen; }
920
921 int createState( QChar ch );
922 int createState( const CharClass& cc );
923#ifndef QT_NO_REGEXP_BACKREF
924 int createState( int bref );
925#endif
926
927 void addCatTransitions( const QMemArray<int>& from,
928 const QMemArray<int>& to );
929#ifndef QT_NO_REGEXP_CAPTURE
930 void addPlusTransitions( const QMemArray<int>& from,
931 const QMemArray<int>& to, int atom );
932#endif
933
934#ifndef QT_NO_REGEXP_ANCHOR_ALT
935 int anchorAlternation( int a, int b );
936 int anchorConcatenation( int a, int b );
937#else
938 int anchorAlternation( int a, int b ) { return a & b; }
939 int anchorConcatenation( int a, int b ) { return a | b; }
940#endif
941 void addAnchors( int from, int to, int a );
942
943#ifndef QT_NO_REGEXP_OPTIM
944 void setupGoodStringHeuristic( int earlyStart, int lateStart,
945 const QString& str );
946 void setupBadCharHeuristic( int minLen, const QMemArray<int>& firstOcc );
947 void heuristicallyChooseHeuristic();
948#endif
949
950#if defined(QT_DEBUG)
951 void dump() const;
952#endif
953
954private:
955 enum { CharClassBit = 0x10000, BackRefBit = 0x20000 };
956
957 /*
958 The struct State represents one state in a modified NFA. The
959 input characters matched are stored in the state instead of on
960 the transitions, something possible for an automaton
961 constructed from a regular expression.
962 */
963 struct State
964 {
965#ifndef QT_NO_REGEXP_CAPTURE
966 int atom; // which atom does this state belong to?
967#endif
968 int match; // what does it match? (see CharClassBit and BackRefBit)
969 QMemArray<int> outs; // out-transitions
970 QMap<int, int> *reenter; // atoms reentered when transiting out
971 QMap<int, int> *anchors; // anchors met when transiting out
972
973#ifndef QT_NO_REGEXP_CAPTURE
974 State( int a, int m )
975 : atom( a ), match( m ), reenter( 0 ), anchors( 0 ) { }
976#else
977 State( int m )
978 : match( m ), reenter( 0 ), anchors( 0 ) { }
979#endif
980 ~State() { delete reenter; delete anchors; }
981 };
982
983#ifndef QT_NO_REGEXP_LOOKAHEAD
984 /*
985 The struct Lookahead represents a lookahead a la Perl (e.g., (?=foo) and
986 (?!bar)).
987 */
988 struct Lookahead
989 {
990 QRegExpEngine *eng; // NFA representing the embedded regular expression
991 bool neg; // negative lookahead?
992
993 Lookahead( QRegExpEngine *eng0, bool neg0 )
994 : eng( eng0 ), neg( neg0 ) { }
995 ~Lookahead() { delete eng; }
996 };
997#endif
998
999#ifndef QT_NO_REGEXP_CAPTURE
1000 /*
1001 The struct Atom represents one node in the hierarchy of regular
1002 expression atoms.
1003 */
1004 struct Atom
1005 {
1006 int parent; // index of parent in array of atoms
1007 int capture; // index of capture, from 1 to ncap
1008 };
1009#endif
1010
1011#ifndef QT_NO_REGEXP_ANCHOR_ALT
1012 /*
1013 The struct AnchorAlternation represents a pair of anchors with
1014 OR semantics.
1015 */
1016 struct AnchorAlternation
1017 {
1018 int a; // this anchor...
1019 int b; // ...or this one
1020 };
1021#endif
1022
1023 enum { InitialState = 0, FinalState = 1 };
1024 void setup( bool caseSensitive );
1025 int setupState( int match );
1026
1027 /*
1028 Let's hope that 13 lookaheads and 14 back-references are
1029 enough.
1030 */
1031 enum { MaxLookaheads = 13, MaxBackRefs = 14 };
1032 enum { Anchor_Dollar = 0x00000001, Anchor_Caret = 0x00000002,
1033 Anchor_Word = 0x00000004, Anchor_NonWord = 0x00000008,
1034 Anchor_FirstLookahead = 0x00000010,
1035 Anchor_BackRef1Empty = Anchor_FirstLookahead << MaxLookaheads,
1036 Anchor_BackRef0Empty = Anchor_BackRef1Empty >> 1,
1037 Anchor_Alternation = Anchor_BackRef1Empty << MaxBackRefs,
1038
1039 Anchor_LookaheadMask = ( Anchor_FirstLookahead - 1 ) ^
1040 ( (Anchor_FirstLookahead << MaxLookaheads) - 1 ) };
1041#ifndef QT_NO_REGEXP_CAPTURE
1042 int startAtom( bool capture );
1043 void finishAtom( int atom ) { cf = f[atom].parent; }
1044#endif
1045
1046#ifndef QT_NO_REGEXP_LOOKAHEAD
1047 int addLookahead( QRegExpEngine *eng, bool negative );
1048#endif
1049
1050#ifndef QT_NO_REGEXP_CAPTURE
1051 bool isBetterCapture( const int *begin1, const int *end1, const int *begin2,
1052 const int *end2 );
1053#endif
1054 bool testAnchor( int i, int a, const int *capBegin );
1055
1056#ifndef QT_NO_REGEXP_OPTIM
1057 bool goodStringMatch();
1058 bool badCharMatch();
1059#else
1060 bool bruteMatch();
1061#endif
1062 bool matchHere();
1063
1064 QPtrVector<State> s; // array of states
1065 int ns; // number of states
1066#ifndef QT_NO_REGEXP_CAPTURE
1067 QMemArray<Atom> f; // atom hierarchy
1068 int nf; // number of atoms
1069 int cf; // current atom
1070#endif
1071 int officialncap; // number of captures, seen from the outside
1072 int ncap; // number of captures, seen from the inside
1073#ifndef QT_NO_REGEXP_CCLASS
1074 QPtrVector<CharClass> cl; // array of character classes
1075#endif
1076#ifndef QT_NO_REGEXP_LOOKAHEAD
1077 QPtrVector<Lookahead> ahead; // array of lookaheads
1078#endif
1079#ifndef QT_NO_REGEXP_ANCHOR_ALT
1080 QMemArray<AnchorAlternation> aa; // array of (a, b) pairs of anchors
1081#endif
1082#ifndef QT_NO_REGEXP_OPTIM
1083 bool caretAnchored; // does the regexp start with ^?
1084#endif
1085 bool valid; // is the regular expression valid?
1086 bool cs; // case sensitive?
1087#ifndef QT_NO_REGEXP_BACKREF
1088 int nbrefs; // number of back-references
1089#endif
1090
1091#ifndef QT_NO_REGEXP_OPTIM
1092 bool useGoodStringHeuristic; // use goodStringMatch? otherwise badCharMatch
1093
1094 int goodEarlyStart; // the index where goodStr can first occur in a match
1095 int goodLateStart; // the index where goodStr can last occur in a match
1096 QString goodStr; // the string that any match has to contain
1097
1098 int minl; // the minimum length of a match
1099 QMemArray<int> occ1; // first-occurrence array
1100#endif
1101
1102 /*
1103 The class Box is an abstraction for a regular expression
1104 fragment. It can also be seen as one node in the syntax tree of
1105 a regular expression with synthetized attributes.
1106
1107 It's interface is ugly for performance reasons.
1108 */
1109 class Box
1110 {
1111 public:
1112 Box( QRegExpEngine *engine );
1113 Box( const Box& b ) { operator=( b ); }
1114
1115 Box& operator=( const Box& b );
1116
1117 void clear() { operator=(Box(eng)); }
1118 void set( QChar ch );
1119 void set( const CharClass& cc );
1120#ifndef QT_NO_REGEXP_BACKREF
1121 void set( int bref );
1122#endif
1123
1124 void cat( const Box& b );
1125 void orx( const Box& b );
1126 void plus( int atom );
1127 void opt();
1128 void catAnchor( int a );
1129#ifndef QT_NO_REGEXP_OPTIM
1130 void setupHeuristics();
1131#endif
1132
1133#if defined(QT_DEBUG)
1134 void dump() const;
1135#endif
1136
1137 private:
1138 void addAnchorsToEngine( const Box& to ) const;
1139
1140 QRegExpEngine *eng; // the automaton under construction
1141 QMemArray<int> ls; // the left states (firstpos)
1142 QMemArray<int> rs; // the right states (lastpos)
1143 QMap<int, int> lanchors; // the left anchors
1144 QMap<int, int> ranchors; // the right anchors
1145 int skipanchors; // the anchors to match if the box is skipped
1146
1147#ifndef QT_NO_REGEXP_OPTIM
1148 int earlyStart; // the index where str can first occur
1149 int lateStart; // the index where str can last occur
1150 QString str; // a string that has to occur in any match
1151 QString leftStr; // a string occurring at the left of this box
1152 QString rightStr; // a string occurring at the right of this box
1153 int maxl; // the maximum length of this box (possibly InftyLen)
1154#endif
1155
1156 int minl; // the minimum length of this box
1157#ifndef QT_NO_REGEXP_OPTIM
1158 QMemArray<int> occ1; // first-occurrence array
1159#endif
1160 };
1161 friend class Box;
1162
1163 /*
1164 This is the lexical analyzer for regular expressions.
1165 */
1166 enum { Tok_Eos, Tok_Dollar, Tok_LeftParen, Tok_MagicLeftParen,
1167 Tok_PosLookahead, Tok_NegLookahead, Tok_RightParen, Tok_CharClass,
1168 Tok_Caret, Tok_Quantifier, Tok_Bar, Tok_Word, Tok_NonWord,
1169 Tok_Char = 0x10000, Tok_BackRef = 0x20000 };
1170 int getChar();
1171 int getEscape();
1172#ifndef QT_NO_REGEXP_INTERVAL
1173 int getRep( int def );
1174#endif
1175#ifndef QT_NO_REGEXP_LOOKAHEAD
1176 void skipChars( int n );
1177#endif
1178 void error( const char *msg );
1179 void startTokenizer( const QChar *rx, int len );
1180 int getToken();
1181
1182 const QChar *yyIn; // a pointer to the input regular expression pattern
1183 int yyPos0; // the position of yyTok in the input pattern
1184 int yyPos; // the position of the next character to read
1185 int yyLen; // the length of yyIn
1186 int yyCh; // the last character read
1187 CharClass *yyCharClass; // attribute for Tok_CharClass tokens
1188 int yyMinRep; // attribute for Tok_Quantifier
1189 int yyMaxRep; // ditto
1190 QString yyError; // syntax error or overflow during parsing?
1191
1192 /*
1193 This is the syntactic analyzer for regular expressions.
1194 */
1195 int parse( const QChar *rx, int len );
1196 void parseAtom( Box *box );
1197 void parseFactor( Box *box );
1198 void parseTerm( Box *box );
1199 void parseExpression( Box *box );
1200
1201 int yyTok; // the last token read
1202 bool yyMayCapture; // set this to FALSE to disable capturing
1203
1204 /*
1205 This is the engine state during matching.
1206 */
1207 const QString *mmStr; // a pointer to the input QString
1208 const QChar *mmIn; // a pointer to the input string data
1209 int mmPos; // the current position in the string
1210 int mmCaretPos;
1211 int mmLen; // the length of the input string
1212 bool mmMinimal; // minimal matching?
1213 QMemArray<int> mmCaptured; // an array of pairs (start, len)
1214 QMemArray<int> mmCapturedNoMatch; // an array of pairs (-1, -1)
1215 QMemArray<int> mmBigArray; // big QMemArray<int> array
1216 int *mmInNextStack; // is state is mmNextStack?
1217 int *mmCurStack; // stack of current states
1218 int *mmNextStack; // stack of next states
1219 int *mmCurCapBegin; // start of current states' captures
1220 int *mmNextCapBegin; // start of next states' captures
1221 int *mmCurCapEnd; // end of current states' captures
1222 int *mmNextCapEnd; // end of next states' captures
1223 int *mmTempCapBegin; // start of temporary captures
1224 int *mmTempCapEnd; // end of temporary captures
1225 int *mmCapBegin; // start of captures for a next state
1226 int *mmCapEnd; // end of captures for a next state
1227 int *mmSlideTab; // bump-along slide table for bad-character heuristic
1228 int mmSlideTabSize; // size of slide table
1229#ifndef QT_NO_REGEXP_BACKREF
1230 QIntDict<int> mmSleeping; // dictionary of back-reference sleepers
1231#endif
1232 int mmMatchLen; // length of match
1233 int mmMatchedLen; // length of partial match
1234};
1235
1236QRegExpEngine::QRegExpEngine( const QString& rx, bool caseSensitive )
1237#ifndef QT_NO_REGEXP_BACKREF
1238 : mmSleeping( 101 )
1239#endif
1240{
1241 setup( caseSensitive );
1242 valid = ( parse(rx.unicode(), rx.length()) == (int) rx.length() );
1243 if ( !valid )
1244 error( RXERR_LEFTDELIM );
1245}
1246
1247#ifndef QT_NO_REGEXP_OPTIM
1248QRegExpEngine::~QRegExpEngine()
1249{
1250}
1251#endif
1252
1253/*
1254 Tries to match in str and returns an array of (begin, length) pairs
1255 for captured text. If there is no match, all pairs are (-1, -1).
1256*/
1257QMemArray<int> QRegExpEngine::match( const QString& str, int pos, bool minimal,
1258 bool oneTest, int caretIndex )
1259{
1260 mmStr = &str;
1261 mmIn = str.unicode();
1262 if ( mmIn == 0 )
1263 mmIn = &QChar::null;
1264 mmPos = pos;
1265 mmCaretPos = caretIndex;
1266 mmLen = str.length();
1267 mmMinimal = minimal;
1268 mmMatchLen = 0;
1269 mmMatchedLen = 0;
1270
1271 bool matched = FALSE;
1272 if ( valid && mmPos >= 0 && mmPos <= mmLen ) {
1273#ifndef QT_NO_REGEXP_OPTIM
1274 if ( oneTest ) {
1275 matched = matchHere();
1276 } else {
1277 if ( mmPos <= mmLen - minl ) {
1278 if ( caretAnchored ) {
1279 matched = matchHere();
1280 } else if ( useGoodStringHeuristic ) {
1281 matched = goodStringMatch();
1282 } else {
1283 matched = badCharMatch();
1284 }
1285 }
1286 }
1287#else
1288 matched = oneTest ? matchHere() : bruteMatch();
1289#endif
1290 }
1291
1292 if ( matched ) {
1293 mmCaptured.detach();
1294 mmCaptured[0] = mmPos;
1295 mmCaptured[1] = mmMatchLen;
1296 for ( int j = 0; j < officialncap; j++ ) {
1297 int len = mmCapEnd[j] - mmCapBegin[j];
1298 mmCaptured[2 + 2 * j] = len > 0 ? mmPos + mmCapBegin[j] : 0;
1299 mmCaptured[2 + 2 * j + 1] = len;
1300 }
1301 return mmCaptured;
1302 } else {
1303 return mmCapturedNoMatch;
1304 }
1305}
1306
1307/*
1308 The three following functions add one state to the automaton and
1309 return the number of the state.
1310*/
1311
1312int QRegExpEngine::createState( QChar ch )
1313{
1314 return setupState( ch.unicode() );
1315}
1316
1317int QRegExpEngine::createState( const CharClass& cc )
1318{
1319#ifndef QT_NO_REGEXP_CCLASS
1320 int n = cl.size();
1321 cl.resize( n + 1 );
1322 cl.insert( n, new CharClass(cc) );
1323 return setupState( CharClassBit | n );
1324#else
1325 Q_UNUSED( cc );
1326 return setupState( CharClassBit );
1327#endif
1328}
1329
1330#ifndef QT_NO_REGEXP_BACKREF
1331int QRegExpEngine::createState( int bref )
1332{
1333 if ( bref > nbrefs ) {
1334 nbrefs = bref;
1335 if ( nbrefs > MaxBackRefs ) {
1336 error( RXERR_LIMIT );
1337 return 0;
1338 }
1339 }
1340 return setupState( BackRefBit | bref );
1341}
1342#endif
1343
1344/*
1345 The two following functions add a transition between all pairs of
1346 states (i, j) where i is fond in from, and j is found in to.
1347
1348 Cat-transitions are distinguished from plus-transitions for
1349 capturing.
1350*/
1351
1352void QRegExpEngine::addCatTransitions( const QMemArray<int>& from,
1353 const QMemArray<int>& to )
1354{
1355 for ( int i = 0; i < (int) from.size(); i++ ) {
1356 State *st = s[from[i]];
1357 mergeInto( &st->outs, to );
1358 }
1359}
1360
1361#ifndef QT_NO_REGEXP_CAPTURE
1362void QRegExpEngine::addPlusTransitions( const QMemArray<int>& from,
1363 const QMemArray<int>& to, int atom )
1364{
1365 for ( int i = 0; i < (int) from.size(); i++ ) {
1366 State *st = s[from[i]];
1367 QMemArray<int> oldOuts = st->outs.copy();
1368 mergeInto( &st->outs, to );
1369 if ( f[atom].capture >= 0 ) {
1370 if ( st->reenter == 0 )
1371 st->reenter = new QMap<int, int>;
1372 for ( int j = 0; j < (int) to.size(); j++ ) {
1373 if ( !st->reenter->contains(to[j]) &&
1374 oldOuts.bsearch(to[j]) < 0 )
1375 st->reenter->insert( to[j], atom );
1376 }
1377 }
1378 }
1379}
1380#endif
1381
1382#ifndef QT_NO_REGEXP_ANCHOR_ALT
1383/*
1384 Returns an anchor that means a OR b.
1385*/
1386int QRegExpEngine::anchorAlternation( int a, int b )
1387{
1388 if ( ((a & b) == a || (a & b) == b) && ((a | b) & Anchor_Alternation) == 0 )
1389 return a & b;
1390
1391 int n = aa.size();
1392#ifndef QT_NO_REGEXP_OPTIM
1393 if ( n > 0 && aa[n - 1].a == a && aa[n - 1].b == b )
1394 return Anchor_Alternation | ( n - 1 );
1395#endif
1396
1397 aa.resize( n + 1 );
1398 aa[n].a = a;
1399 aa[n].b = b;
1400 return Anchor_Alternation | n;
1401}
1402
1403/*
1404 Returns an anchor that means a AND b.
1405*/
1406int QRegExpEngine::anchorConcatenation( int a, int b )
1407{
1408 if ( ((a | b) & Anchor_Alternation) == 0 )
1409 return a | b;
1410 if ( (b & Anchor_Alternation) != 0 )
1411 qSwap( a, b );
1412
1413 int aprime = anchorConcatenation( aa[a ^ Anchor_Alternation].a, b );
1414 int bprime = anchorConcatenation( aa[a ^ Anchor_Alternation].b, b );
1415 return anchorAlternation( aprime, bprime );
1416}
1417#endif
1418
1419/*
1420 Adds anchor a on a transition caracterised by its from state and
1421 its to state.
1422*/
1423void QRegExpEngine::addAnchors( int from, int to, int a )
1424{
1425 State *st = s[from];
1426 if ( st->anchors == 0 )
1427 st->anchors = new QMap<int, int>;
1428 if ( st->anchors->contains(to) )
1429 a = anchorAlternation( (*st->anchors)[to], a );
1430 st->anchors->insert( to, a );
1431}
1432
1433#ifndef QT_NO_REGEXP_OPTIM
1434/*
1435 The two following functions provide the engine with the information
1436 needed by its matching heuristics.
1437*/
1438
1439void QRegExpEngine::setupGoodStringHeuristic( int earlyStart, int lateStart,
1440 const QString& str )
1441{
1442 goodEarlyStart = earlyStart;
1443 goodLateStart = lateStart;
1444 goodStr = cs ? str : str.lower();
1445}
1446
1447void QRegExpEngine::setupBadCharHeuristic( int minLen,
1448 const QMemArray<int>& firstOcc )
1449{
1450 minl = minLen;
1451 if ( cs ) {
1452 occ1 = firstOcc;
1453 } else {
1454 occ1.fill( 0, NumBadChars );
1455 }
1456}
1457
1458/*
1459 This function chooses between the good-string and the bad-character
1460 heuristics. It computes two scores and chooses the heuristic with
1461 the highest score.
1462
1463 Here are some common-sense constraints on the scores that should be
1464 respected if the formulas are ever modified: (1) If goodStr is
1465 empty, the good-string heuristic scores 0. (2) If the search is
1466 case insensitive, the good-string heuristic should be used, unless
1467 it scores 0. (Case insensitivity turns all entries of occ1 to 0.)
1468 (3) If (goodLateStart - goodEarlyStart) is big, the good-string
1469 heuristic should score less.
1470*/
1471void QRegExpEngine::heuristicallyChooseHeuristic()
1472{
1473 int i;
1474
1475 if ( minl == 0 )
1476 return;
1477
1478 /*
1479 Magic formula: The good string has to constitute a good
1480 proportion of the minimum-length string, and appear at a
1481 more-or-less known index.
1482 */
1483 int goodStringScore = ( 64 * goodStr.length() / minl ) -
1484 ( goodLateStart - goodEarlyStart );
1485
1486 /*
1487 Less magic formula: We pick a couple of characters at random,
1488 and check whether they are good or bad.
1489 */
1490 int badCharScore = 0;
1491 int step = QMAX( 1, NumBadChars / 32 );
1492 for ( i = 1; i < NumBadChars; i += step ) {
1493 if ( occ1[i] == NoOccurrence )
1494 badCharScore += minl;
1495 else
1496 badCharScore += occ1[i];
1497 }
1498 badCharScore /= minl;
1499
1500 useGoodStringHeuristic = ( goodStringScore > badCharScore );
1501}
1502#endif
1503
1504#if defined(QT_DEBUG)
1505void QRegExpEngine::dump() const
1506{
1507 int i, j;
1508 qDebug( "Case %ssensitive engine", cs ? "" : "in" );
1509 qDebug( " States" );
1510 for ( i = 0; i < ns; i++ ) {
1511 qDebug( " %d%s", i,
1512 i == InitialState ? " (initial)" :
1513 i == FinalState ? " (final)" : "" );
1514#ifndef QT_NO_REGEXP_CAPTURE
1515 qDebug( " in atom %d", s[i]->atom );
1516#endif
1517 int m = s[i]->match;
1518 if ( (m & CharClassBit) != 0 ) {
1519 qDebug( " match character class %d", m ^ CharClassBit );
1520#ifndef QT_NO_REGEXP_CCLASS
1521 cl[m ^ CharClassBit]->dump();
1522#else
1523 qDebug( " negative character class" );
1524#endif
1525 } else if ( (m & BackRefBit) != 0 ) {
1526 qDebug( " match back-reference %d", m ^ BackRefBit );
1527 } else if ( m >= 0x20 && m <= 0x7e ) {
1528 qDebug( " match 0x%.4x (%c)", m, m );
1529 } else {
1530 qDebug( " match 0x%.4x", m );
1531 }
1532 for ( j = 0; j < (int) s[i]->outs.size(); j++ ) {
1533 int next = s[i]->outs[j];
1534 qDebug( " -> %d", next );
1535 if ( s[i]->reenter != 0 && s[i]->reenter->contains(next) )
1536 qDebug( " [reenter %d]", (*s[i]->reenter)[next] );
1537 if ( s[i]->anchors != 0 && at(*s[i]->anchors, next) != 0 )
1538 qDebug( " [anchors 0x%.8x]", (*s[i]->anchors)[next] );
1539 }
1540 }
1541#ifndef QT_NO_REGEXP_CAPTURE
1542 if ( nf > 0 ) {
1543 qDebug( " Atom Parent Capture" );
1544 for ( i = 0; i < nf; i++ )
1545 qDebug( " %6d %6d %6d", i, f[i].parent, f[i].capture );
1546 }
1547#endif
1548#ifndef QT_NO_REGEXP_ANCHOR_ALT
1549 for ( i = 0; i < (int) aa.size(); i++ )
1550 qDebug( " Anchor alternation 0x%.8x: 0x%.8x 0x%.9x", i, aa[i].a,
1551 aa[i].b );
1552#endif
1553}
1554#endif
1555
1556void QRegExpEngine::setup( bool caseSensitive )
1557{
1558 s.setAutoDelete( TRUE );
1559 s.resize( 32 );
1560 ns = 0;
1561#ifndef QT_NO_REGEXP_CAPTURE
1562 f.resize( 32 );
1563 nf = 0;
1564 cf = -1;
1565#endif
1566 officialncap = 0;
1567 ncap = 0;
1568#ifndef QT_NO_REGEXP_CCLASS
1569 cl.setAutoDelete( TRUE );
1570#endif
1571#ifndef QT_NO_REGEXP_LOOKAHEAD
1572 ahead.setAutoDelete( TRUE );
1573#endif
1574#ifndef QT_NO_REGEXP_OPTIM
1575 caretAnchored = TRUE;
1576#endif
1577 valid = FALSE;
1578 cs = caseSensitive;
1579#ifndef QT_NO_REGEXP_BACKREF
1580 nbrefs = 0;
1581#endif
1582#ifndef QT_NO_REGEXP_OPTIM
1583 useGoodStringHeuristic = FALSE;
1584 minl = 0;
1585 occ1.fill( 0, NumBadChars );
1586#endif
1587 mmCapturedNoMatch.fill( -1, 2 );
1588}
1589
1590int QRegExpEngine::setupState( int match )
1591{
1592 if ( (ns & (ns + 1)) == 0 && ns + 1 >= (int) s.size() )
1593 s.resize( (ns + 1) << 1 );
1594#ifndef QT_NO_REGEXP_CAPTURE
1595 s.insert( ns, new State(cf, match) );
1596#else
1597 s.insert( ns, new State(match) );
1598#endif
1599 return ns++;
1600}
1601
1602#ifndef QT_NO_REGEXP_CAPTURE
1603/*
1604 Functions startAtom() and finishAtom() should be called to delimit
1605 atoms. When a state is created, it is assigned to the current atom.
1606 The information is later used for capturing.
1607*/
1608int QRegExpEngine::startAtom( bool capture )
1609{
1610 if ( (nf & (nf + 1)) == 0 && nf + 1 >= (int) f.size() )
1611 f.resize( (nf + 1) << 1 );
1612 f[nf].parent = cf;
1613 cf = nf++;
1614 f[cf].capture = capture ? ncap++ : -1;
1615 return cf;
1616}
1617#endif
1618
1619#ifndef QT_NO_REGEXP_LOOKAHEAD
1620/*
1621 Creates a lookahead anchor.
1622*/
1623int QRegExpEngine::addLookahead( QRegExpEngine *eng, bool negative )
1624{
1625 int n = ahead.size();
1626 if ( n == MaxLookaheads ) {
1627 error( RXERR_LIMIT );
1628 return 0;
1629 }
1630 ahead.resize( n + 1 );
1631 ahead.insert( n, new Lookahead(eng, negative) );
1632 return Anchor_FirstLookahead << n;
1633}
1634#endif
1635
1636#ifndef QT_NO_REGEXP_CAPTURE
1637/*
1638 We want the longest leftmost captures.
1639*/
1640bool QRegExpEngine::isBetterCapture( const int *begin1, const int *end1,
1641 const int *begin2, const int *end2 )
1642{
1643 for ( int i = 0; i < ncap; i++ ) {
1644 int delta = begin2[i] - begin1[i]; // it has to start early...
1645 if ( delta == 0 )
1646 delta = end1[i] - end2[i]; // ...and end late (like a party)
1647
1648 if ( delta != 0 )
1649 return delta > 0;
1650 }
1651 return FALSE;
1652}
1653#endif
1654
1655/*
1656 Returns TRUE if anchor a matches at position mmPos + i in the input
1657 string, otherwise FALSE.
1658*/
1659bool QRegExpEngine::testAnchor( int i, int a, const int *capBegin )
1660{
1661 int j;
1662
1663#ifndef QT_NO_REGEXP_ANCHOR_ALT
1664 if ( (a & Anchor_Alternation) != 0 ) {
1665 return testAnchor( i, aa[a ^ Anchor_Alternation].a, capBegin ) ||
1666 testAnchor( i, aa[a ^ Anchor_Alternation].b, capBegin );
1667 }
1668#endif
1669
1670 if ( (a & Anchor_Caret) != 0 ) {
1671 if ( mmPos + i != mmCaretPos )
1672 return FALSE;
1673 }
1674 if ( (a & Anchor_Dollar) != 0 ) {
1675 if ( mmPos + i != mmLen )
1676 return FALSE;
1677 }
1678#ifndef QT_NO_REGEXP_ESCAPE
1679 if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) {
1680 bool before = FALSE;
1681 bool after = FALSE;
1682 if ( mmPos + i != 0 )
1683 before = mmIn[mmPos + i - 1].isLetterOrNumber();
1684 if ( mmPos + i != mmLen )
1685 after = mmIn[mmPos + i].isLetterOrNumber();
1686 if ( (a & Anchor_Word) != 0 && (before == after) )
1687 return FALSE;
1688 if ( (a & Anchor_NonWord) != 0 && (before != after) )
1689 return FALSE;
1690 }
1691#endif
1692#ifndef QT_NO_REGEXP_LOOKAHEAD
1693 bool catchx = TRUE;
1694
1695 if ( (a & Anchor_LookaheadMask) != 0 ) {
1696 QConstString cstr = QConstString( (QChar *) mmIn + mmPos + i,
1697 mmLen - mmPos - i );
1698 for ( j = 0; j < (int) ahead.size(); j++ ) {
1699 if ( (a & (Anchor_FirstLookahead << j)) != 0 ) {
1700 catchx = ahead[j]->eng->match( cstr.string(), 0, TRUE, TRUE,
1701 mmCaretPos - mmPos - i )[0] == 0;
1702 if ( catchx == ahead[j]->neg )
1703 return FALSE;
1704 }
1705 }
1706 }
1707#endif
1708#ifndef QT_NO_REGEXP_CAPTURE
1709#ifndef QT_NO_REGEXP_BACKREF
1710 for ( j = 0; j < nbrefs; j++ ) {
1711 if ( (a & (Anchor_BackRef1Empty << j)) != 0 ) {
1712 if ( capBegin[j] != EmptyCapture )
1713 return FALSE;
1714 }
1715 }
1716#endif
1717#endif
1718 return TRUE;
1719}
1720
1721#ifndef QT_NO_REGEXP_OPTIM
1722/*
1723 The three following functions are what Jeffrey Friedl would call
1724 transmissions (or bump-alongs). Using one or the other should make
1725 no difference except in performance.
1726*/
1727
1728bool QRegExpEngine::goodStringMatch()
1729{
1730 int k = mmPos + goodEarlyStart;
1731
1732 while ( (k = mmStr->find(goodStr, k, cs)) != -1 ) {
1733 int from = k - goodLateStart;
1734 int to = k - goodEarlyStart;
1735 if ( from > mmPos )
1736 mmPos = from;
1737
1738 while ( mmPos <= to ) {
1739 if ( matchHere() )
1740 return TRUE;
1741 mmPos++;
1742 }
1743 k++;
1744 }
1745 return FALSE;
1746}
1747
1748bool QRegExpEngine::badCharMatch()
1749{
1750 int slideHead = 0;
1751 int slideNext = 0;
1752 int i;
1753 int lastPos = mmLen - minl;
1754 memset( mmSlideTab, 0, mmSlideTabSize * sizeof(int) );
1755
1756 /*
1757 Set up the slide table, used for the bad-character heuristic,
1758 using the table of first occurrence of each character.
1759 */
1760 for ( i = 0; i < minl; i++ ) {
1761 int sk = occ1[BadChar(mmIn[mmPos + i])];
1762 if ( sk == NoOccurrence )
1763 sk = i + 1;
1764 if ( sk > 0 ) {
1765 int k = i + 1 - sk;
1766 if ( k < 0 ) {
1767 sk = i + 1;
1768 k = 0;
1769 }
1770 if ( sk > mmSlideTab[k] )
1771 mmSlideTab[k] = sk;
1772 }
1773 }
1774
1775 if ( mmPos > lastPos )
1776 return FALSE;
1777
1778 for ( ;; ) {
1779 if ( ++slideNext >= mmSlideTabSize )
1780 slideNext = 0;
1781 if ( mmSlideTab[slideHead] > 0 ) {
1782 if ( mmSlideTab[slideHead] - 1 > mmSlideTab[slideNext] )
1783 mmSlideTab[slideNext] = mmSlideTab[slideHead] - 1;
1784 mmSlideTab[slideHead] = 0;
1785 } else {
1786 if ( matchHere() )
1787 return TRUE;
1788 }
1789
1790 if ( mmPos == lastPos )
1791 break;
1792
1793 /*
1794 Update the slide table. This code has much in common with
1795 the initialization code.
1796 */
1797 int sk = occ1[BadChar(mmIn[mmPos + minl])];
1798 if ( sk == NoOccurrence ) {
1799 mmSlideTab[slideNext] = minl;
1800 } else if ( sk > 0 ) {
1801 int k = slideNext + minl - sk;
1802 if ( k >= mmSlideTabSize )
1803 k -= mmSlideTabSize;
1804 if ( sk > mmSlideTab[k] )
1805 mmSlideTab[k] = sk;
1806 }
1807 slideHead = slideNext;
1808 mmPos++;
1809 }
1810 return FALSE;
1811}
1812#else
1813bool QRegExpEngine::bruteMatch()
1814{
1815 while ( mmPos <= mmLen ) {
1816 if ( matchHere() )
1817 return TRUE;
1818 mmPos++;
1819 }
1820 return FALSE;
1821}
1822#endif
1823
1824/*
1825 Here's the core of the engine. It tries to do a match here and now.
1826*/
1827bool QRegExpEngine::matchHere()
1828{
1829 int ncur = 1, nnext = 0;
1830 int i = 0, j, k, m;
1831 bool stop = FALSE;
1832
1833 mmMatchLen = -1;
1834 mmMatchedLen = -1;
1835 mmCurStack[0] = InitialState;
1836
1837#ifndef QT_NO_REGEXP_CAPTURE
1838 if ( ncap > 0 ) {
1839 for ( j = 0; j < ncap; j++ ) {
1840 mmCurCapBegin[j] = EmptyCapture;
1841 mmCurCapEnd[j] = EmptyCapture;
1842 }
1843 }
1844#endif
1845
1846#ifndef QT_NO_REGEXP_BACKREF
1847 int *zzZ = 0;
1848
1849 while ( (ncur > 0 || !mmSleeping.isEmpty()) && i <= mmLen - mmPos &&
1850 !stop )
1851#else
1852 while ( ncur > 0 && i <= mmLen - mmPos && !stop )
1853#endif
1854 {
1855 int ch = ( i < mmLen - mmPos ) ? mmIn[mmPos + i].unicode() : 0;
1856 for ( j = 0; j < ncur; j++ ) {
1857 int cur = mmCurStack[j];
1858 State *scur = s[cur];
1859 QMemArray<int>& outs = scur->outs;
1860 for ( k = 0; k < (int) outs.size(); k++ ) {
1861 int next = outs[k];
1862 State *snext = s[next];
1863 bool in = TRUE;
1864#ifndef QT_NO_REGEXP_BACKREF
1865 int needSomeSleep = 0;
1866#endif
1867
1868 /*
1869 First, check if the anchors are anchored properly.
1870 */
1871 if ( scur->anchors != 0 ) {
1872 int a = at( *scur->anchors, next );
1873 if ( a != 0 && !testAnchor(i, a, mmCurCapBegin + j * ncap) )
1874 in = FALSE;
1875 }
1876 /*
1877 If indeed they are, check if the input character is
1878 correct for this transition.
1879 */
1880 if ( in ) {
1881 m = snext->match;
1882 if ( (m & (CharClassBit | BackRefBit)) == 0 ) {
1883 if ( cs )
1884 in = ( m == ch );
1885 else
1886 in = ( QChar(m).lower() == QChar(ch).lower() );
1887 } else if ( next == FinalState ) {
1888 mmMatchLen = i;
1889 stop = mmMinimal;
1890 in = TRUE;
1891 } else if ( (m & CharClassBit) != 0 ) {
1892#ifndef QT_NO_REGEXP_CCLASS
1893 const CharClass *cc = cl[m ^ CharClassBit];
1894 if ( cs )
1895 in = cc->in( ch );
1896 else if ( cc->negative() )
1897 in = cc->in( QChar(ch).lower() ) &&
1898 cc->in( QChar(ch).upper() );
1899 else
1900 in = cc->in( QChar(ch).lower() ) ||
1901 cc->in( QChar(ch).upper() );
1902#endif
1903#ifndef QT_NO_REGEXP_BACKREF
1904 } else { /* ( (m & BackRefBit) != 0 ) */
1905 int bref = m ^ BackRefBit;
1906 int ell = j * ncap + ( bref - 1 );
1907
1908 in = bref <= ncap && mmCurCapBegin[ell] != EmptyCapture;
1909 if ( in ) {
1910 if ( cs )
1911 in = ( mmIn[mmPos + mmCurCapBegin[ell]]
1912 == QChar(ch) );
1913 else
1914 in = ( mmIn[mmPos + mmCurCapBegin[ell]].lower()
1915 == QChar(ch).lower() );
1916 }
1917
1918 if ( in ) {
1919 int delta;
1920 if ( mmCurCapEnd[ell] == EmptyCapture )
1921 delta = i - mmCurCapBegin[ell];
1922 else
1923 delta = mmCurCapEnd[ell] - mmCurCapBegin[ell];
1924
1925 in = ( delta <= mmLen - (mmPos + i) );
1926 if ( in && delta > 1 ) {
1927 int n = 1;
1928 if ( cs ) {
1929 while ( n < delta ) {
1930 if ( mmIn[mmPos +
1931 mmCurCapBegin[ell] + n] !=
1932 mmIn[mmPos + i + n] )
1933 break;
1934 n++;
1935 }
1936 } else {
1937 while ( n < delta ) {
1938 QChar a = mmIn[mmPos +
1939 mmCurCapBegin[ell] + n];
1940 QChar b = mmIn[mmPos + i + n];
1941 if ( a.lower() != b.lower() )
1942 break;
1943 n++;
1944 }
1945 }
1946 in = ( n == delta );
1947 if ( in )
1948 needSomeSleep = delta - 1;
1949 }
1950 }
1951#endif
1952 }
1953 }
1954
1955 /*
1956 We must now update our data structures.
1957 */
1958 if ( in ) {
1959#ifndef QT_NO_REGEXP_CAPTURE
1960 int *capBegin, *capEnd;
1961#endif
1962 /*
1963 If the next state was not encountered yet, all
1964 is fine.
1965 */
1966 if ( (m = mmInNextStack[next]) == -1 ) {
1967 m = nnext++;
1968 mmNextStack[m] = next;
1969 mmInNextStack[next] = m;
1970#ifndef QT_NO_REGEXP_CAPTURE
1971 capBegin = mmNextCapBegin + m * ncap;
1972 capEnd = mmNextCapEnd + m * ncap;
1973
1974 /*
1975 Otherwise, we'll first maintain captures in
1976 temporary arrays, and decide at the end whether
1977 it's best to keep the previous capture zones or
1978 the new ones.
1979 */
1980 } else {
1981 capBegin = mmTempCapBegin;
1982 capEnd = mmTempCapEnd;
1983#endif
1984 }
1985
1986#ifndef QT_NO_REGEXP_CAPTURE
1987 /*
1988 Updating the capture zones is much of a task.
1989 */
1990 if ( ncap > 0 ) {
1991 memcpy( capBegin, mmCurCapBegin + j * ncap,
1992 ncap * sizeof(int) );
1993 memcpy( capEnd, mmCurCapEnd + j * ncap,
1994 ncap * sizeof(int) );
1995 int c = scur->atom, n = snext->atom;
1996 int p = -1, q = -1;
1997 int cap;
1998
1999 /*
2000 Lemma 1. For any x in the range [0..nf), we
2001 have f[x].parent < x.
2002
2003 Proof. By looking at startAtom(), it is
2004 clear that cf < nf holds all the time, and
2005 thus that f[nf].parent < nf.
2006 */
2007
2008 /*
2009 If we are reentering an atom, we empty all
2010 capture zones inside it.
2011 */
2012 if ( scur->reenter != 0 &&
2013 (q = at(*scur->reenter, next)) != 0 ) {
2014 QBitArray b;
2015 b.fill( FALSE, nf );
2016 b.setBit( q, TRUE );
2017 for ( int ell = q + 1; ell < nf; ell++ ) {
2018 if ( b.testBit(f[ell].parent) ) {
2019 b.setBit( ell, TRUE );
2020 cap = f[ell].capture;
2021 if ( cap >= 0 ) {
2022 capBegin[cap] = EmptyCapture;
2023 capEnd[cap] = EmptyCapture;
2024 }
2025 }
2026 }
2027 p = f[q].parent;
2028
2029 /*
2030 Otherwise, close the capture zones we are
2031 leaving. We are leaving f[c].capture,
2032 f[f[c].parent].capture,
2033 f[f[f[c].parent].parent].capture, ...,
2034 until f[x].capture, with x such that
2035 f[x].parent is the youngest common ancestor
2036 for c and n.
2037
2038 We go up along c's and n's ancestry until
2039 we find x.
2040 */
2041 } else {
2042 p = c;
2043 q = n;
2044 while ( p != q ) {
2045 if ( p > q ) {
2046 cap = f[p].capture;
2047 if ( cap >= 0 ) {
2048 if ( capBegin[cap] == i ) {
2049 capBegin[cap] = EmptyCapture;
2050 capEnd[cap] = EmptyCapture;
2051 } else {
2052 capEnd[cap] = i;
2053 }
2054 }
2055 p = f[p].parent;
2056 } else {
2057 q = f[q].parent;
2058 }
2059 }
2060 }
2061
2062 /*
2063 In any case, we now open the capture zones
2064 we are entering. We work upwards from n
2065 until we reach p (the parent of the atom we
2066 reenter or the youngest common ancestor).
2067 */
2068 while ( n > p ) {
2069 cap = f[n].capture;
2070 if ( cap >= 0 ) {
2071 capBegin[cap] = i;
2072 capEnd[cap] = EmptyCapture;
2073 }
2074 n = f[n].parent;
2075 }
2076 /*
2077 If the next state was already in
2078 mmNextStack, we must choose carefully which
2079 capture zones we want to keep.
2080 */
2081 if ( capBegin == mmTempCapBegin &&
2082 isBetterCapture(capBegin, capEnd,
2083 mmNextCapBegin + m * ncap,
2084 mmNextCapEnd + m * ncap) ) {
2085 memcpy( mmNextCapBegin + m * ncap, capBegin,
2086 ncap * sizeof(int) );
2087 memcpy( mmNextCapEnd + m * ncap, capEnd,
2088 ncap * sizeof(int) );
2089 }
2090 }
2091#ifndef QT_NO_REGEXP_BACKREF
2092 /*
2093 We are done with updating the capture zones.
2094 It's now time to put the next state to sleep,
2095 if it needs to, and to remove it from
2096 mmNextStack.
2097 */
2098 if ( needSomeSleep > 0 ) {
2099 zzZ = new int[1 + 2 * ncap];
2100 zzZ[0] = next;
2101 if ( ncap > 0 ) {
2102 memcpy( zzZ + 1, capBegin, ncap * sizeof(int) );
2103 memcpy( zzZ + 1 + ncap, capEnd,
2104 ncap * sizeof(int) );
2105 }
2106 mmInNextStack[mmNextStack[--nnext]] = -1;
2107 mmSleeping.insert( i + needSomeSleep, zzZ );
2108 }
2109#endif
2110#endif
2111 }
2112 }
2113 }
2114#ifndef QT_NO_REGEXP_CAPTURE
2115 /*
2116 If we reached the final state, hurray! Copy the captured
2117 zone.
2118 */
2119 if ( ncap > 0 && (m = mmInNextStack[FinalState]) != -1 ) {
2120 memcpy( mmCapBegin, mmNextCapBegin + m * ncap, ncap * sizeof(int) );
2121 memcpy( mmCapEnd, mmNextCapEnd + m * ncap, ncap * sizeof(int) );
2122 }
2123#ifndef QT_NO_REGEXP_BACKREF
2124 /*
2125 It's time to wake up the sleepers.
2126 */
2127 if ( !mmSleeping.isEmpty() ) {
2128 while ( (zzZ = mmSleeping.take(i)) != 0 ) {
2129 int next = zzZ[0];
2130 int *capBegin = zzZ + 1;
2131 int *capEnd = zzZ + 1 + ncap;
2132 bool copyOver = TRUE;
2133
2134 if ( (m = mmInNextStack[zzZ[0]]) == -1 ) {
2135 m = nnext++;
2136 mmNextStack[m] = next;
2137 mmInNextStack[next] = m;
2138 } else {
2139 copyOver = isBetterCapture( mmNextCapBegin + m * ncap,
2140 mmNextCapEnd + m * ncap,
2141 capBegin, capEnd );
2142 }
2143 if ( copyOver ) {
2144 memcpy( mmNextCapBegin + m * ncap, capBegin,
2145 ncap * sizeof(int) );
2146 memcpy( mmNextCapEnd + m * ncap, capEnd,
2147 ncap * sizeof(int) );
2148 }
2149 delete[] zzZ;
2150 }
2151 }
2152#endif
2153#endif
2154 for ( j = 0; j < nnext; j++ )
2155 mmInNextStack[mmNextStack[j]] = -1;
2156
2157 // avoid needless iteration that confuses mmMatchedLen
2158 if ( nnext == 1 && mmNextStack[0] == FinalState
2159#ifndef QT_NO_REGEXP_BACKREF
2160 && mmSleeping.isEmpty()
2161#endif
2162 )
2163 stop = TRUE;
2164
2165 qSwap( mmCurStack, mmNextStack );
2166#ifndef QT_NO_REGEXP_CAPTURE
2167 qSwap( mmCurCapBegin, mmNextCapBegin );
2168 qSwap( mmCurCapEnd, mmNextCapEnd );
2169#endif
2170 ncur = nnext;
2171 nnext = 0;
2172 i++;
2173 }
2174
2175#ifndef QT_NO_REGEXP_BACKREF
2176 /*
2177 If minimal matching is enabled, we might have some sleepers
2178 left.
2179 */
2180 while ( !mmSleeping.isEmpty() ) {
2181 zzZ = mmSleeping.take( *QIntDictIterator<int>(mmSleeping) );
2182 delete[] zzZ;
2183 }
2184#endif
2185
2186 mmMatchedLen = i - 1;
2187 return ( mmMatchLen >= 0 );
2188}
2189
2190#ifndef QT_NO_REGEXP_CCLASS
2191
2192QRegExpEngine::CharClass::CharClass()
2193 : c( 0 ), n( FALSE )
2194{
2195#ifndef QT_NO_REGEXP_OPTIM
2196 occ1.fill( NoOccurrence, NumBadChars );
2197#endif
2198}
2199
2200QRegExpEngine::CharClass& QRegExpEngine::CharClass::operator=(
2201 const CharClass& cc )
2202{
2203 c = cc.c;
2204 r = cc.r.copy();
2205 n = cc.n;
2206#ifndef QT_NO_REGEXP_OPTIM
2207 occ1 = cc.occ1;
2208#endif
2209 return *this;
2210}
2211
2212void QRegExpEngine::CharClass::clear()
2213{
2214 c = 0;
2215 r.resize( 0 );
2216 n = FALSE;
2217}
2218
2219void QRegExpEngine::CharClass::setNegative( bool negative )
2220{
2221 n = negative;
2222#ifndef QT_NO_REGEXP_OPTIM
2223 occ1.fill( 0, NumBadChars );
2224#endif
2225}
2226
2227void QRegExpEngine::CharClass::addCategories( int cats )
2228{
2229 c |= cats;
2230#ifndef QT_NO_REGEXP_OPTIM
2231 occ1.fill( 0, NumBadChars );
2232#endif
2233}
2234
2235void QRegExpEngine::CharClass::addRange( ushort from, ushort to )
2236{
2237 if ( from > to )
2238 qSwap( from, to );
2239 int m = r.size();
2240 r.resize( m + 1 );
2241 r[m].from = from;
2242 r[m].to = to;
2243
2244#ifndef QT_NO_REGEXP_OPTIM
2245 int i;
2246
2247 if ( to - from < NumBadChars ) {
2248 occ1.detach();
2249 if ( from % NumBadChars <= to % NumBadChars ) {
2250 for ( i = from % NumBadChars; i <= to % NumBadChars; i++ )
2251 occ1[i] = 0;
2252 } else {
2253 for ( i = 0; i <= to % NumBadChars; i++ )
2254 occ1[i] = 0;
2255 for ( i = from % NumBadChars; i < NumBadChars; i++ )
2256 occ1[i] = 0;
2257 }
2258 } else {
2259 occ1.fill( 0, NumBadChars );
2260 }
2261#endif
2262}
2263
2264bool QRegExpEngine::CharClass::in( QChar ch ) const
2265{
2266#ifndef QT_NO_REGEXP_OPTIM
2267 if ( occ1[BadChar(ch)] == NoOccurrence )
2268 return n;
2269#endif
2270
2271 if ( c != 0 && (c & (1 << (int) ch.category())) != 0 )
2272 return !n;
2273 for ( int i = 0; i < (int) r.size(); i++ ) {
2274 if ( ch.unicode() >= r[i].from && ch.unicode() <= r[i].to )
2275 return !n;
2276 }
2277 return n;
2278}
2279
2280#if defined(QT_DEBUG)
2281void QRegExpEngine::CharClass::dump() const
2282{
2283 int i;
2284 qDebug( " %stive character class", n ? "nega" : "posi" );
2285#ifndef QT_NO_REGEXP_CCLASS
2286 if ( c != 0 )
2287 qDebug( " categories 0x%.8x", c );
2288#endif
2289 for ( i = 0; i < (int) r.size(); i++ )
2290 qDebug( " 0x%.4x through 0x%.4x", r[i].from, r[i].to );
2291}
2292#endif
2293#endif
2294
2295QRegExpEngine::Box::Box( QRegExpEngine *engine )
2296 : eng( engine ), skipanchors( 0 )
2297#ifndef QT_NO_REGEXP_OPTIM
2298 , earlyStart( 0 ), lateStart( 0 ), maxl( 0 )
2299#endif
2300{
2301#ifndef QT_NO_REGEXP_OPTIM
2302 occ1.fill( NoOccurrence, NumBadChars );
2303#endif
2304 minl = 0;
2305}
2306
2307QRegExpEngine::Box& QRegExpEngine::Box::operator=( const Box& b )
2308{
2309 eng = b.eng;
2310 ls = b.ls;
2311 rs = b.rs;
2312 lanchors = b.lanchors;
2313 ranchors = b.ranchors;
2314 skipanchors = b.skipanchors;
2315#ifndef QT_NO_REGEXP_OPTIM
2316 earlyStart = b.earlyStart;
2317 lateStart = b.lateStart;
2318 str = b.str;
2319 leftStr = b.leftStr;
2320 rightStr = b.rightStr;
2321 maxl = b.maxl;
2322 occ1 = b.occ1;
2323#endif
2324 minl = b.minl;
2325 return *this;
2326}
2327
2328void QRegExpEngine::Box::set( QChar ch )
2329{
2330 ls.resize( 1 );
2331 ls[0] = eng->createState( ch );
2332 rs = ls;
2333 rs.detach();
2334#ifndef QT_NO_REGEXP_OPTIM
2335 str = ch;
2336 leftStr = ch;
2337 rightStr = ch;
2338 maxl = 1;
2339 occ1.detach();
2340 occ1[BadChar(ch)] = 0;
2341#endif
2342 minl = 1;
2343}
2344
2345void QRegExpEngine::Box::set( const CharClass& cc )
2346{
2347 ls.resize( 1 );
2348 ls[0] = eng->createState( cc );
2349 rs = ls;
2350 rs.detach();
2351#ifndef QT_NO_REGEXP_OPTIM
2352 maxl = 1;
2353 occ1 = cc.firstOccurrence();
2354#endif
2355 minl = 1;
2356}
2357
2358#ifndef QT_NO_REGEXP_BACKREF
2359void QRegExpEngine::Box::set( int bref )
2360{
2361 ls.resize( 1 );
2362 ls[0] = eng->createState( bref );
2363 rs = ls;
2364 rs.detach();
2365 if ( bref >= 1 && bref <= MaxBackRefs )
2366 skipanchors = Anchor_BackRef0Empty << bref;
2367#ifndef QT_NO_REGEXP_OPTIM
2368 maxl = InftyLen;
2369#endif
2370 minl = 0;
2371}
2372#endif
2373
2374void QRegExpEngine::Box::cat( const Box& b )
2375{
2376 eng->addCatTransitions( rs, b.ls );
2377 addAnchorsToEngine( b );
2378 if ( minl == 0 ) {
2379 mergeInto( &lanchors, b.lanchors );
2380 if ( skipanchors != 0 ) {
2381 for ( int i = 0; i < (int) b.ls.size(); i++ ) {
2382 int a = eng->anchorConcatenation( at(lanchors, b.ls[i]),
2383 skipanchors );
2384 lanchors.insert( b.ls[i], a );
2385 }
2386 }
2387 mergeInto( &ls, b.ls );
2388 }
2389 if ( b.minl == 0 ) {
2390 mergeInto( &ranchors, b.ranchors );
2391 if ( b.skipanchors != 0 ) {
2392 for ( int i = 0; i < (int) rs.size(); i++ ) {
2393 int a = eng->anchorConcatenation( at(ranchors, rs[i]),
2394 b.skipanchors );
2395 ranchors.insert( rs[i], a );
2396 }
2397 }
2398 mergeInto( &rs, b.rs );
2399 } else {
2400 ranchors = b.ranchors;
2401 rs = b.rs;
2402 }
2403
2404#ifndef QT_NO_REGEXP_OPTIM
2405 if ( maxl != InftyLen ) {
2406 if ( rightStr.length() + b.leftStr.length() >
2407 QMAX(str.length(), b.str.length()) ) {
2408 earlyStart = minl - rightStr.length();
2409 lateStart = maxl - rightStr.length();
2410 str = rightStr + b.leftStr;
2411 } else if ( b.str.length() > str.length() ) {
2412 earlyStart = minl + b.earlyStart;
2413 lateStart = maxl + b.lateStart;
2414 str = b.str;
2415 }
2416 }
2417
2418 if ( (int) leftStr.length() == maxl )
2419 leftStr += b.leftStr;
2420 if ( (int) b.rightStr.length() == b.maxl )
2421 rightStr += b.rightStr;
2422 else
2423 rightStr = b.rightStr;
2424
2425 if ( maxl == InftyLen || b.maxl == InftyLen )
2426 maxl = InftyLen;
2427 else
2428 maxl += b.maxl;
2429
2430 occ1.detach();
2431 for ( int i = 0; i < NumBadChars; i++ ) {
2432 if ( b.occ1[i] != NoOccurrence && minl + b.occ1[i] < occ1[i] )
2433 occ1[i] = minl + b.occ1[i];
2434 }
2435#endif
2436
2437 minl += b.minl;
2438 if ( minl == 0 )
2439 skipanchors = eng->anchorConcatenation( skipanchors, b.skipanchors );
2440 else
2441 skipanchors = 0;
2442}
2443
2444void QRegExpEngine::Box::orx( const Box& b )
2445{
2446 mergeInto( &ls, b.ls );
2447 mergeInto( &lanchors, b.lanchors );
2448 mergeInto( &rs, b.rs );
2449 mergeInto( &ranchors, b.ranchors );
2450
2451 if ( b.minl == 0 ) {
2452 if ( minl == 0 )
2453 skipanchors = eng->anchorAlternation( skipanchors, b.skipanchors );
2454 else
2455 skipanchors = b.skipanchors;
2456 }
2457
2458#ifndef QT_NO_REGEXP_OPTIM
2459 occ1.detach();
2460 for ( int i = 0; i < NumBadChars; i++ ) {
2461 if ( occ1[i] > b.occ1[i] )
2462 occ1[i] = b.occ1[i];
2463 }
2464 earlyStart = 0;
2465 lateStart = 0;
2466 str = QString();
2467 leftStr = QString();
2468 rightStr = QString();
2469 if ( b.maxl > maxl )
2470 maxl = b.maxl;
2471#endif
2472 if ( b.minl < minl )
2473 minl = b.minl;
2474}
2475
2476void QRegExpEngine::Box::plus( int atom )
2477{
2478#ifndef QT_NO_REGEXP_CAPTURE
2479 eng->addPlusTransitions( rs, ls, atom );
2480#else
2481 Q_UNUSED( atom );
2482 eng->addCatTransitions( rs, ls );
2483#endif
2484 addAnchorsToEngine( *this );
2485#ifndef QT_NO_REGEXP_OPTIM
2486 maxl = InftyLen;
2487#endif
2488}
2489
2490void QRegExpEngine::Box::opt()
2491{
2492#ifndef QT_NO_REGEXP_OPTIM
2493 earlyStart = 0;
2494 lateStart = 0;
2495 str = QString();
2496 leftStr = QString();
2497 rightStr = QString();
2498#endif
2499 skipanchors = 0;
2500 minl = 0;
2501}
2502
2503void QRegExpEngine::Box::catAnchor( int a )
2504{
2505 if ( a != 0 ) {
2506 for ( int i = 0; i < (int) rs.size(); i++ ) {
2507 a = eng->anchorConcatenation( at(ranchors, rs[i]), a );
2508 ranchors.insert( rs[i], a );
2509 }
2510 if ( minl == 0 )
2511 skipanchors = eng->anchorConcatenation( skipanchors, a );
2512 }
2513}
2514
2515#ifndef QT_NO_REGEXP_OPTIM
2516void QRegExpEngine::Box::setupHeuristics()
2517{
2518 eng->setupGoodStringHeuristic( earlyStart, lateStart, str );
2519
2520 /*
2521 A regular expression such as 112|1 has occ1['2'] = 2 and minl =
2522 1 at this point. An entry of occ1 has to be at most minl or
2523 infinity for the rest of the algorithm to go well.
2524
2525 We waited until here before normalizing these cases (instead of
2526 doing it in Box::orx()) because sometimes things improve by
2527 themselves. Consider for example (112|1)34.
2528 */
2529 for ( int i = 0; i < NumBadChars; i++ ) {
2530 if ( occ1[i] != NoOccurrence && occ1[i] >= minl )
2531 occ1[i] = minl;
2532 }
2533 eng->setupBadCharHeuristic( minl, occ1 );
2534
2535 eng->heuristicallyChooseHeuristic();
2536}
2537#endif
2538
2539#if defined(QT_DEBUG)
2540void QRegExpEngine::Box::dump() const
2541{
2542 int i;
2543 qDebug( "Box of at least %d character%s", minl, minl == 1 ? "" : "s" );
2544 qDebug( " Left states:" );
2545 for ( i = 0; i < (int) ls.size(); i++ ) {
2546 if ( at(lanchors, ls[i]) == 0 )
2547 qDebug( " %d", ls[i] );
2548 else
2549 qDebug( " %d [anchors 0x%.8x]", ls[i], lanchors[ls[i]] );
2550 }
2551 qDebug( " Right states:" );
2552 for ( i = 0; i < (int) rs.size(); i++ ) {
2553 if ( at(ranchors, rs[i]) == 0 )
2554 qDebug( " %d", rs[i] );
2555 else
2556 qDebug( " %d [anchors 0x%.8x]", rs[i], ranchors[rs[i]] );
2557 }
2558 qDebug( " Skip anchors: 0x%.8x", skipanchors );
2559}
2560#endif
2561
2562void QRegExpEngine::Box::addAnchorsToEngine( const Box& to ) const
2563{
2564 for ( int i = 0; i < (int) to.ls.size(); i++ ) {
2565 for ( int j = 0; j < (int) rs.size(); j++ ) {
2566 int a = eng->anchorConcatenation( at(ranchors, rs[j]),
2567 at(to.lanchors, to.ls[i]) );
2568 eng->addAnchors( rs[j], to.ls[i], a );
2569 }
2570 }
2571}
2572
2573int QRegExpEngine::getChar()
2574{
2575 return ( yyPos == yyLen ) ? EOS : yyIn[yyPos++].unicode();
2576}
2577
2578int QRegExpEngine::getEscape()
2579{
2580#ifndef QT_NO_REGEXP_ESCAPE
2581 const char tab[] = "afnrtv"; // no b, as \b means word boundary
2582 const char backTab[] = "\a\f\n\r\t\v";
2583 ushort low;
2584 int i;
2585#endif
2586 ushort val;
2587 int prevCh = yyCh;
2588
2589 if ( prevCh == EOS ) {
2590 error( RXERR_END );
2591 return Tok_Char | '\\';
2592 }
2593 yyCh = getChar();
2594#ifndef QT_NO_REGEXP_ESCAPE
2595 if ( (prevCh & ~0xff) == 0 ) {
2596 const char *p = strchr( tab, prevCh );
2597 if ( p != 0 )
2598 return Tok_Char | backTab[p - tab];
2599 }
2600#endif
2601
2602 switch ( prevCh ) {
2603#ifndef QT_NO_REGEXP_ESCAPE
2604 case '0':
2605 val = 0;
2606 for ( i = 0; i < 3; i++ ) {
2607 if ( yyCh >= '0' && yyCh <= '7' )
2608 val = ( val << 3 ) | ( yyCh - '0' );
2609 else
2610 break;
2611 yyCh = getChar();
2612 }
2613 if ( (val & ~0377) != 0 )
2614 error( RXERR_OCTAL );
2615 return Tok_Char | val;
2616#endif
2617#ifndef QT_NO_REGEXP_ESCAPE
2618 case 'B':
2619 return Tok_NonWord;
2620#endif
2621#ifndef QT_NO_REGEXP_CCLASS
2622 case 'D':
2623 // see QChar::isDigit()
2624 yyCharClass->addCategories( 0x7fffffef );
2625 return Tok_CharClass;
2626 case 'S':
2627 // see QChar::isSpace()
2628 yyCharClass->addCategories( 0x7ffff87f );
2629 yyCharClass->addRange( 0x0000, 0x0008 );
2630 yyCharClass->addRange( 0x000e, 0x001f );
2631 yyCharClass->addRange( 0x007f, 0x009f );
2632 return Tok_CharClass;
2633 case 'W':
2634 // see QChar::isLetterOrNumber()
2635 yyCharClass->addCategories( 0x7ff07f8f );
2636 return Tok_CharClass;
2637#endif
2638#ifndef QT_NO_REGEXP_ESCAPE
2639 case 'b':
2640 return Tok_Word;
2641#endif
2642#ifndef QT_NO_REGEXP_CCLASS
2643 case 'd':
2644 // see QChar::isDigit()
2645 yyCharClass->addCategories( 0x00000010 );
2646 return Tok_CharClass;
2647 case 's':
2648 // see QChar::isSpace()
2649 yyCharClass->addCategories( 0x00000380 );
2650 yyCharClass->addRange( 0x0009, 0x000d );
2651 return Tok_CharClass;
2652 case 'w':
2653 // see QChar::isLetterOrNumber()
2654 yyCharClass->addCategories( 0x000f8070 );
2655 return Tok_CharClass;
2656#endif
2657#ifndef QT_NO_REGEXP_ESCAPE
2658 case 'x':
2659 val = 0;
2660 for ( i = 0; i < 4; i++ ) {
2661 low = QChar( yyCh ).lower();
2662 if ( low >= '0' && low <= '9' )
2663 val = ( val << 4 ) | ( low - '0' );
2664 else if ( low >= 'a' && low <= 'f' )
2665 val = ( val << 4 ) | ( low - 'a' + 10 );
2666 else
2667 break;
2668 yyCh = getChar();
2669 }
2670 return Tok_Char | val;
2671#endif
2672 default:
2673 if ( prevCh >= '1' && prevCh <= '9' ) {
2674#ifndef QT_NO_REGEXP_BACKREF
2675 val = prevCh - '0';
2676 while ( yyCh >= '0' && yyCh <= '9' ) {
2677 val = ( val *= 10 ) | ( yyCh - '0' );
2678 yyCh = getChar();
2679 }
2680 return Tok_BackRef | val;
2681#else
2682 error( RXERR_DISABLED );
2683#endif
2684 }
2685 return Tok_Char | prevCh;
2686 }
2687}
2688
2689#ifndef QT_NO_REGEXP_INTERVAL
2690int QRegExpEngine::getRep( int def )
2691{
2692 if ( yyCh >= '0' && yyCh <= '9' ) {
2693 int rep = 0;
2694 do {
2695 rep = 10 * rep + yyCh - '0';
2696 if ( rep >= InftyRep ) {
2697 error( RXERR_REPETITION );
2698 rep = def;
2699 }
2700 yyCh = getChar();
2701 } while ( yyCh >= '0' && yyCh <= '9' );
2702 return rep;
2703 } else {
2704 return def;
2705 }
2706}
2707#endif
2708
2709#ifndef QT_NO_REGEXP_LOOKAHEAD
2710void QRegExpEngine::skipChars( int n )
2711{
2712 if ( n > 0 ) {
2713 yyPos += n - 1;
2714 yyCh = getChar();
2715 }
2716}
2717#endif
2718
2719void QRegExpEngine::error( const char *msg )
2720{
2721 if ( yyError.isEmpty() )
2722 yyError = QString::fromLatin1( msg );
2723}
2724
2725void QRegExpEngine::startTokenizer( const QChar *rx, int len )
2726{
2727 yyIn = rx;
2728 yyPos0 = 0;
2729 yyPos = 0;
2730 yyLen = len;
2731 yyCh = getChar();
2732 yyCharClass = new CharClass;
2733 yyMinRep = 0;
2734 yyMaxRep = 0;
2735 yyError = QString();
2736}
2737
2738int QRegExpEngine::getToken()
2739{
2740#ifndef QT_NO_REGEXP_CCLASS
2741 ushort pendingCh = 0;
2742 bool charPending;
2743 bool rangePending;
2744 int tok;
2745#endif
2746 int prevCh = yyCh;
2747
2748 yyPos0 = yyPos - 1;
2749#ifndef QT_NO_REGEXP_CCLASS
2750 yyCharClass->clear();
2751#endif
2752 yyMinRep = 0;
2753 yyMaxRep = 0;
2754 yyCh = getChar();
2755 switch ( prevCh ) {
2756 case EOS:
2757 yyPos0 = yyPos;
2758 return Tok_Eos;
2759 case '$':
2760 return Tok_Dollar;
2761 case '(':
2762 if ( yyCh == '?' ) {
2763 prevCh = getChar();
2764 yyCh = getChar();
2765 switch ( prevCh ) {
2766#ifndef QT_NO_REGEXP_LOOKAHEAD
2767 case '!':
2768 return Tok_NegLookahead;
2769 case '=':
2770 return Tok_PosLookahead;
2771#endif
2772 case ':':
2773 return Tok_MagicLeftParen;
2774 default:
2775 error( RXERR_LOOKAHEAD );
2776 return Tok_MagicLeftParen;
2777 }
2778 } else {
2779 return Tok_LeftParen;
2780 }
2781 case ')':
2782 return Tok_RightParen;
2783 case '*':
2784 yyMinRep = 0;
2785 yyMaxRep = InftyRep;
2786 return Tok_Quantifier;
2787 case '+':
2788 yyMinRep = 1;
2789 yyMaxRep = InftyRep;
2790 return Tok_Quantifier;
2791 case '.':
2792#ifndef QT_NO_REGEXP_CCLASS
2793 yyCharClass->setNegative( TRUE );
2794#endif
2795 return Tok_CharClass;
2796 case '?':
2797 yyMinRep = 0;
2798 yyMaxRep = 1;
2799 return Tok_Quantifier;
2800 case '[':
2801#ifndef QT_NO_REGEXP_CCLASS
2802 if ( yyCh == '^' ) {
2803 yyCharClass->setNegative( TRUE );
2804 yyCh = getChar();
2805 }
2806 charPending = FALSE;
2807 rangePending = FALSE;
2808 do {
2809 if ( yyCh == '-' && charPending && !rangePending ) {
2810 rangePending = TRUE;
2811 yyCh = getChar();
2812 } else {
2813 if ( charPending && !rangePending ) {
2814 yyCharClass->addSingleton( pendingCh );
2815 charPending = FALSE;
2816 }
2817 if ( yyCh == '\\' ) {
2818 yyCh = getChar();
2819 tok = getEscape();
2820 if ( tok == Tok_Word )
2821 tok = '\b';
2822 } else {
2823 tok = Tok_Char | yyCh;
2824 yyCh = getChar();
2825 }
2826 if ( tok == Tok_CharClass ) {
2827 if ( rangePending ) {
2828 yyCharClass->addSingleton( '-' );
2829 yyCharClass->addSingleton( pendingCh );
2830 charPending = FALSE;
2831 rangePending = FALSE;
2832 }
2833 } else if ( (tok & Tok_Char) != 0 ) {
2834 if ( rangePending ) {
2835 yyCharClass->addRange( pendingCh, tok ^ Tok_Char );
2836 charPending = FALSE;
2837 rangePending = FALSE;
2838 } else {
2839 pendingCh = tok ^ Tok_Char;
2840 charPending = TRUE;
2841 }
2842 } else {
2843 error( RXERR_CHARCLASS );
2844 }
2845 }
2846 } while ( yyCh != ']' && yyCh != EOS );
2847 if ( rangePending )
2848 yyCharClass->addSingleton( '-' );
2849 if ( charPending )
2850 yyCharClass->addSingleton( pendingCh );
2851 if ( yyCh == EOS )
2852 error( RXERR_END );
2853 else
2854 yyCh = getChar();
2855 return Tok_CharClass;
2856#else
2857 error( RXERR_END );
2858 return Tok_Char | '[';
2859#endif
2860 case '\\':
2861 return getEscape();
2862 case ']':
2863 error( RXERR_LEFTDELIM );
2864 return Tok_Char | ']';
2865 case '^':
2866 return Tok_Caret;
2867 case '{':
2868#ifndef QT_NO_REGEXP_INTERVAL
2869 yyMinRep = getRep( 0 );
2870 yyMaxRep = yyMinRep;
2871 if ( yyCh == ',' ) {
2872 yyCh = getChar();
2873 yyMaxRep = getRep( InftyRep );
2874 }
2875 if ( yyMaxRep < yyMinRep )
2876 qSwap( yyMinRep, yyMaxRep );
2877 if ( yyCh != '}' )
2878 error( RXERR_REPETITION );
2879 yyCh = getChar();
2880 return Tok_Quantifier;
2881#else
2882 error( RXERR_DISABLED );
2883 return Tok_Char | '{';
2884#endif
2885 case '|':
2886 return Tok_Bar;
2887 case '}':
2888 error( RXERR_LEFTDELIM );
2889 return Tok_Char | '}';
2890 default:
2891 return Tok_Char | prevCh;
2892 }
2893}
2894
2895int QRegExpEngine::parse( const QChar *pattern, int len )
2896{
2897 valid = TRUE;
2898 startTokenizer( pattern, len );
2899 yyTok = getToken();
2900#ifndef QT_NO_REGEXP_CAPTURE
2901 yyMayCapture = TRUE;
2902#else
2903 yyMayCapture = FALSE;
2904#endif
2905
2906#ifndef QT_NO_REGEXP_CAPTURE
2907 int atom = startAtom( FALSE );
2908#endif
2909 CharClass anything;
2910 Box box( this ); // create InitialState
2911 box.set( anything );
2912 Box rightBox( this ); // create FinalState
2913 rightBox.set( anything );
2914
2915 Box middleBox( this );
2916 parseExpression( &middleBox );
2917#ifndef QT_NO_REGEXP_CAPTURE
2918 finishAtom( atom );
2919#endif
2920#ifndef QT_NO_REGEXP_OPTIM
2921 middleBox.setupHeuristics();
2922#endif
2923 box.cat( middleBox );
2924 box.cat( rightBox );
2925 delete yyCharClass;
2926 yyCharClass = 0;
2927
2928 officialncap = ncap;
2929#ifndef QT_NO_REGEXP_BACKREF
2930 if ( nbrefs > ncap )
2931 ncap = nbrefs;
2932#endif
2933
2934 mmCaptured.resize( 2 + 2 * officialncap );
2935 mmCapturedNoMatch.fill( -1, 2 + 2 * officialncap );
2936
2937 /*
2938 We use one QMemArray<int> for all the big data used a lot in
2939 matchHere() and friends.
2940 */
2941#ifndef QT_NO_REGEXP_OPTIM
2942 mmSlideTabSize = QMAX( minl + 1, 16 );
2943#else
2944 mmSlideTabSize = 0;
2945#endif
2946 mmBigArray.resize( (3 + 4 * ncap) * ns + 4 * ncap + mmSlideTabSize );
2947
2948 mmInNextStack = mmBigArray.data();
2949 memset( mmInNextStack, -1, ns * sizeof(int) );
2950 mmCurStack = mmInNextStack + ns;
2951 mmNextStack = mmInNextStack + 2 * ns;
2952
2953 mmCurCapBegin = mmInNextStack + 3 * ns;
2954 mmNextCapBegin = mmCurCapBegin + ncap * ns;
2955 mmCurCapEnd = mmCurCapBegin + 2 * ncap * ns;
2956 mmNextCapEnd = mmCurCapBegin + 3 * ncap * ns;
2957
2958 mmTempCapBegin = mmCurCapBegin + 4 * ncap * ns;
2959 mmTempCapEnd = mmTempCapBegin + ncap;
2960 mmCapBegin = mmTempCapBegin + 2 * ncap;
2961 mmCapEnd = mmTempCapBegin + 3 * ncap;
2962
2963 mmSlideTab = mmTempCapBegin + 4 * ncap;
2964
2965 if ( !yyError.isEmpty() )
2966 return -1;
2967
2968#ifndef QT_NO_REGEXP_OPTIM
2969 State *sinit = s[InitialState];
2970 caretAnchored = ( sinit->anchors != 0 );
2971 if ( caretAnchored ) {
2972 QMap<int, int>& anchors = *sinit->anchors;
2973 QMap<int, int>::ConstIterator a;
2974 for ( a = anchors.begin(); a != anchors.end(); ++a ) {
2975#ifndef QT_NO_REGEXP_ANCHOR_ALT
2976 if ( (*a & Anchor_Alternation) != 0 )
2977 break;
2978#endif
2979 if ( (*a & Anchor_Caret) == 0 ) {
2980 caretAnchored = FALSE;
2981 break;
2982 }
2983 }
2984 }
2985#endif
2986 return yyPos0;
2987}
2988
2989void QRegExpEngine::parseAtom( Box *box )
2990{
2991#ifndef QT_NO_REGEXP_LOOKAHEAD
2992 QRegExpEngine *eng = 0;
2993 bool neg;
2994 int len;
2995#endif
2996
2997 switch ( yyTok ) {
2998 case Tok_Dollar:
2999 box->catAnchor( Anchor_Dollar );
3000 break;
3001 case Tok_Caret:
3002 box->catAnchor( Anchor_Caret );
3003 break;
3004#ifndef QT_NO_REGEXP_LOOKAHEAD
3005 case Tok_PosLookahead:
3006 case Tok_NegLookahead:
3007 neg = ( yyTok == Tok_NegLookahead );
3008 eng = new QRegExpEngine( cs );
3009 len = eng->parse( yyIn + yyPos - 1, yyLen - yyPos + 1 );
3010 if ( len >= 0 )
3011 skipChars( len );
3012 else
3013 error( RXERR_LOOKAHEAD );
3014 box->catAnchor( addLookahead(eng, neg) );
3015 yyTok = getToken();
3016 if ( yyTok != Tok_RightParen )
3017 error( RXERR_LOOKAHEAD );
3018 break;
3019#endif
3020#ifndef QT_NO_REGEXP_ESCAPE
3021 case Tok_Word:
3022 box->catAnchor( Anchor_Word );
3023 break;
3024 case Tok_NonWord:
3025 box->catAnchor( Anchor_NonWord );
3026 break;
3027#endif
3028 case Tok_LeftParen:
3029 case Tok_MagicLeftParen:
3030 yyTok = getToken();
3031 parseExpression( box );
3032 if ( yyTok != Tok_RightParen )
3033 error( RXERR_END );
3034 break;
3035 case Tok_CharClass:
3036 box->set( *yyCharClass );
3037 break;
3038 case Tok_Quantifier:
3039 error( RXERR_REPETITION );
3040 break;
3041 default:
3042 if ( (yyTok & Tok_Char) != 0 )
3043 box->set( QChar(yyTok ^ Tok_Char) );
3044#ifndef QT_NO_REGEXP_BACKREF
3045 else if ( (yyTok & Tok_BackRef) != 0 )
3046 box->set( yyTok ^ Tok_BackRef );
3047#endif
3048 else
3049 error( RXERR_DISABLED );
3050 }
3051 yyTok = getToken();
3052}
3053
3054void QRegExpEngine::parseFactor( Box *box )
3055{
3056#ifndef QT_NO_REGEXP_CAPTURE
3057 int atom = startAtom( yyMayCapture && yyTok == Tok_LeftParen );
3058#else
3059 static const int atom = 0;
3060#endif
3061
3062#ifndef QT_NO_REGEXP_INTERVAL
3063#define YYREDO() \
3064 yyIn = in, yyPos0 = pos0, yyPos = pos, yyLen = len, yyCh = ch, \
3065 *yyCharClass = charClass, yyMinRep = 0, yyMaxRep = 0, yyTok = tok
3066
3067 const QChar *in = yyIn;
3068 int pos0 = yyPos0;
3069 int pos = yyPos;
3070 int len = yyLen;
3071 int ch = yyCh;
3072 CharClass charClass;
3073 if ( yyTok == Tok_CharClass )
3074 charClass = *yyCharClass;
3075 int tok = yyTok;
3076 bool mayCapture = yyMayCapture;
3077#endif
3078
3079 parseAtom( box );
3080#ifndef QT_NO_REGEXP_CAPTURE
3081 finishAtom( atom );
3082#endif
3083
3084 if ( yyTok == Tok_Quantifier ) {
3085 if ( yyMaxRep == InftyRep ) {
3086 box->plus( atom );
3087#ifndef QT_NO_REGEXP_INTERVAL
3088 } else if ( yyMaxRep == 0 ) {
3089 box->clear();
3090#endif
3091 }
3092 if ( yyMinRep == 0 )
3093 box->opt();
3094
3095#ifndef QT_NO_REGEXP_INTERVAL
3096 yyMayCapture = FALSE;
3097 int alpha = ( yyMinRep == 0 ) ? 0 : yyMinRep - 1;
3098 int beta = ( yyMaxRep == InftyRep ) ? 0 : yyMaxRep - ( alpha + 1 );
3099
3100 Box rightBox( this );
3101 int i;
3102
3103 for ( i = 0; i < beta; i++ ) {
3104 YYREDO();
3105 Box leftBox( this );
3106 parseAtom( &leftBox );
3107 leftBox.cat( rightBox );
3108 leftBox.opt();
3109 rightBox = leftBox;
3110 }
3111 for ( i = 0; i < alpha; i++ ) {
3112 YYREDO();
3113 Box leftBox( this );
3114 parseAtom( &leftBox );
3115 leftBox.cat( rightBox );
3116 rightBox = leftBox;
3117 }
3118 rightBox.cat( *box );
3119 *box = rightBox;
3120#endif
3121 yyTok = getToken();
3122#ifndef QT_NO_REGEXP_INTERVAL
3123 yyMayCapture = mayCapture;
3124#endif
3125 }
3126#undef YYREDO
3127}
3128
3129void QRegExpEngine::parseTerm( Box *box )
3130{
3131#ifndef QT_NO_REGEXP_OPTIM
3132 if ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar )
3133 parseFactor( box );
3134#endif
3135 while ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar ) {
3136 Box rightBox( this );
3137 parseFactor( &rightBox );
3138 box->cat( rightBox );
3139 }
3140}
3141
3142void QRegExpEngine::parseExpression( Box *box )
3143{
3144 parseTerm( box );
3145 while ( yyTok == Tok_Bar ) {
3146 Box rightBox( this );
3147 yyTok = getToken();
3148 parseTerm( &rightBox );
3149 box->orx( rightBox );
3150 }
3151}
3152
3153/*
3154 The struct QRegExpPrivate contains the private data of a regular
3155 expression other than the automaton. It makes it possible for many
3156 QRegExp objects to use the same QRegExpEngine object with different
3157 QRegExpPrivate objects.
3158*/
3159struct QRegExpPrivate
3160{
3161 QString pattern; // regular-expression or wildcard pattern
3162 QString rxpattern; // regular-expression pattern
3163#ifndef QT_NO_REGEXP_WILDCARD
3164 bool wc; // wildcard mode?
3165#endif
3166 bool min; // minimal matching? (instead of maximal)
3167#ifndef QT_NO_REGEXP_CAPTURE
3168 QString t; // last string passed to QRegExp::search() or searchRev()
3169 QStringList capturedCache; // what QRegExp::capturedTexts() returned last
3170#endif
3171 QMemArray<int> captured; // what QRegExpEngine::search() returned last
3172
3173 QRegExpPrivate() { captured.fill( -1, 2 ); }
3174};
3175
3176#ifndef QT_NO_REGEXP_OPTIM
3177static QCache<QRegExpEngine> *engineCache = 0;
3178static QSingleCleanupHandler<QCache<QRegExpEngine> > cleanup_cache;
3179#endif
3180
3181static QRegExpEngine *newEngine( const QString& pattern, bool caseSensitive )
3182{
3183#ifndef QT_NO_REGEXP_OPTIM
3184 if ( engineCache != 0 ) {
3185#ifdef QT_THREAD_SUPPORT
3186 QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) );
3187#endif
3188 QRegExpEngine *eng = engineCache->take( pattern );
3189 if ( eng == 0 || eng->caseSensitive() != caseSensitive ) {
3190 delete eng;
3191 } else {
3192 eng->ref();
3193 return eng;
3194 }
3195 }
3196#endif
3197 return new QRegExpEngine( pattern, caseSensitive );
3198}
3199
3200static void derefEngine( QRegExpEngine *eng, const QString& pattern )
3201{
3202 if ( eng != 0 && eng->deref() ) {
3203#ifndef QT_NO_REGEXP_OPTIM
3204#ifdef QT_THREAD_SUPPORT
3205 QMutexLocker locker( qt_global_mutexpool->get( &engineCache ) );
3206#endif
3207 if ( engineCache == 0 ) {
3208 engineCache = new QCache<QRegExpEngine>;
3209 engineCache->setAutoDelete( TRUE );
3210 cleanup_cache.set( &engineCache );
3211 }
3212 if ( !pattern.isNull() &&
3213 engineCache->insert(pattern, eng, 4 + pattern.length() / 4) )
3214 return;
3215#else
3216 Q_UNUSED( pattern );
3217#endif
3218 delete eng;
3219 }
3220}
3221
3222/*!
3223 \enum QRegExp::CaretMode
3224
3225 The CaretMode enum defines the different meanings of the caret
3226 (<b>^</b>) in a regular expression. The possible values are:
3227
3228 \value CaretAtZero
3229 The caret corresponds to index 0 in the searched string.
3230
3231 \value CaretAtOffset
3232 The caret corresponds to the start offset of the search.
3233
3234 \value CaretWontMatch
3235 The caret never matches.
3236*/
3237
3238/*!
3239 Constructs an empty regexp.
3240
3241 \sa isValid() errorString()
3242*/
3243QRegExp::QRegExp()
3244{
3245 eng = new QRegExpEngine( TRUE );
3246 priv = new QRegExpPrivate;
3247#ifndef QT_NO_REGEXP_WILDCARD
3248 priv->wc = FALSE;
3249#endif
3250 priv->min = FALSE;
3251 compile( TRUE );
3252}
3253
3254/*!
3255 Constructs a regular expression object for the given \a pattern
3256 string. The pattern must be given using wildcard notation if \a
3257 wildcard is TRUE (default is FALSE). The pattern is case
3258 sensitive, unless \a caseSensitive is FALSE. Matching is greedy
3259 (maximal), but can be changed by calling setMinimal().
3260
3261 \sa setPattern() setCaseSensitive() setWildcard() setMinimal()
3262*/
3263QRegExp::QRegExp( const QString& pattern, bool caseSensitive, bool wildcard )
3264{
3265 eng = 0;
3266 priv = new QRegExpPrivate;
3267 priv->pattern = pattern;
3268#ifndef QT_NO_REGEXP_WILDCARD
3269 priv->wc = wildcard;
3270#endif
3271 priv->min = FALSE;
3272 compile( caseSensitive );
3273}
3274
3275/*!
3276 Constructs a regular expression as a copy of \a rx.
3277
3278 \sa operator=()
3279*/
3280QRegExp::QRegExp( const QRegExp& rx )
3281{
3282 eng = 0;
3283 priv = new QRegExpPrivate;
3284 operator=( rx );
3285}
3286
3287/*!
3288 Destroys the regular expression and cleans up its internal data.
3289*/
3290QRegExp::~QRegExp()
3291{
3292 derefEngine( eng, priv->rxpattern );
3293 delete priv;
3294}
3295
3296/*!
3297 Copies the regular expression \a rx and returns a reference to the
3298 copy. The case sensitivity, wildcard and minimal matching options
3299 are also copied.
3300*/
3301QRegExp& QRegExp::operator=( const QRegExp& rx )
3302{
3303 rx.eng->ref();
3304 derefEngine( eng, priv->rxpattern );
3305 eng = rx.eng;
3306 priv->pattern = rx.priv->pattern;
3307 priv->rxpattern = rx.priv->rxpattern;
3308#ifndef QT_NO_REGEXP_WILDCARD
3309 priv->wc = rx.priv->wc;
3310#endif
3311 priv->min = rx.priv->min;
3312#ifndef QT_NO_REGEXP_CAPTURE
3313 priv->t = rx.priv->t;
3314 priv->capturedCache = rx.priv->capturedCache;
3315#endif
3316 priv->captured = rx.priv->captured;
3317 return *this;
3318}
3319
3320/*!
3321 Returns TRUE if this regular expression is equal to \a rx;
3322 otherwise returns FALSE.
3323
3324 Two QRegExp objects are equal if they have the same pattern
3325 strings and the same settings for case sensitivity, wildcard and
3326 minimal matching.
3327*/
3328bool QRegExp::operator==( const QRegExp& rx ) const
3329{
3330 return priv->pattern == rx.priv->pattern &&
3331 eng->caseSensitive() == rx.eng->caseSensitive() &&
3332#ifndef QT_NO_REGEXP_WILDCARD
3333 priv->wc == rx.priv->wc &&
3334#endif
3335 priv->min == rx.priv->min;
3336}
3337
3338/*!
3339 \fn bool QRegExp::operator!=( const QRegExp& rx ) const
3340
3341 Returns TRUE if this regular expression is not equal to \a rx;
3342 otherwise returns FALSE.
3343
3344 \sa operator==()
3345*/
3346
3347/*!
3348 Returns TRUE if the pattern string is empty; otherwise returns
3349 FALSE.
3350
3351 If you call exactMatch() with an empty pattern on an empty string
3352 it will return TRUE; otherwise it returns FALSE since it operates
3353 over the whole string. If you call search() with an empty pattern
3354 on \e any string it will return the start offset (0 by default)
3355 because the empty pattern matches the 'emptiness' at the start of
3356 the string. In this case the length of the match returned by
3357 matchedLength() will be 0.
3358
3359 See QString::isEmpty().
3360*/
3361
3362bool QRegExp::isEmpty() const
3363{
3364 return priv->pattern.isEmpty();
3365}
3366
3367/*!
3368 Returns TRUE if the regular expression is valid; otherwise returns
3369 FALSE. An invalid regular expression never matches.
3370
3371 The pattern <b>[a-z</b> is an example of an invalid pattern, since
3372 it lacks a closing square bracket.
3373
3374 Note that the validity of a regexp may also depend on the setting
3375 of the wildcard flag, for example <b>*.html</b> is a valid
3376 wildcard regexp but an invalid full regexp.
3377
3378 \sa errorString()
3379*/
3380bool QRegExp::isValid() const
3381{
3382 return eng->isValid();
3383}
3384
3385/*!
3386 Returns the pattern string of the regular expression. The pattern
3387 has either regular expression syntax or wildcard syntax, depending
3388 on wildcard().
3389
3390 \sa setPattern()
3391*/
3392QString QRegExp::pattern() const
3393{
3394 return priv->pattern;
3395}
3396
3397/*!
3398 Sets the pattern string to \a pattern. The case sensitivity,
3399 wildcard and minimal matching options are not changed.
3400
3401 \sa pattern()
3402*/
3403void QRegExp::setPattern( const QString& pattern )
3404{
3405 if ( priv->pattern != pattern ) {
3406 priv->pattern = pattern;
3407 compile( caseSensitive() );
3408 }
3409}
3410
3411/*!
3412 Returns TRUE if case sensitivity is enabled; otherwise returns
3413 FALSE. The default is TRUE.
3414
3415 \sa setCaseSensitive()
3416*/
3417bool QRegExp::caseSensitive() const
3418{
3419 return eng->caseSensitive();
3420}
3421
3422/*!
3423 Sets case sensitive matching to \a sensitive.
3424
3425 If \a sensitive is TRUE, <b>\\.txt$</b> matches \c{readme.txt} but
3426 not \c{README.TXT}.
3427
3428 \sa caseSensitive()
3429*/
3430void QRegExp::setCaseSensitive( bool sensitive )
3431{
3432 if ( sensitive != eng->caseSensitive() )
3433 compile( sensitive );
3434}
3435
3436#ifndef QT_NO_REGEXP_WILDCARD
3437/*!
3438 Returns TRUE if wildcard mode is enabled; otherwise returns FALSE.
3439 The default is FALSE.
3440
3441 \sa setWildcard()
3442*/
3443bool QRegExp::wildcard() const
3444{
3445 return priv->wc;
3446}
3447
3448/*!
3449 Sets the wildcard mode for the regular expression. The default is
3450 FALSE.
3451
3452 Setting \a wildcard to TRUE enables simple shell-like wildcard
3453 matching. (See \link #wildcard-matching wildcard matching
3454 (globbing) \endlink.)
3455
3456 For example, <b>r*.txt</b> matches the string \c{readme.txt} in
3457 wildcard mode, but does not match \c{readme}.
3458
3459 \sa wildcard()
3460*/
3461void QRegExp::setWildcard( bool wildcard )
3462{
3463 if ( wildcard != priv->wc ) {
3464 priv->wc = wildcard;
3465 compile( caseSensitive() );
3466 }
3467}
3468#endif
3469
3470/*!
3471 Returns TRUE if minimal (non-greedy) matching is enabled;
3472 otherwise returns FALSE.
3473
3474 \sa setMinimal()
3475*/
3476bool QRegExp::minimal() const
3477{
3478 return priv->min;
3479}
3480
3481/*!
3482 Enables or disables minimal matching. If \a minimal is FALSE,
3483 matching is greedy (maximal) which is the default.
3484
3485 For example, suppose we have the input string "We must be
3486 \<b>bold\</b>, very \<b>bold\</b>!" and the pattern
3487 <b>\<b>.*\</b></b>. With the default greedy (maximal) matching,
3488 the match is "We must be <u>\<b>bold\</b>, very
3489 \<b>bold\</b></u>!". But with minimal (non-greedy) matching the
3490 first match is: "We must be <u>\<b>bold\</b></u>, very
3491 \<b>bold\</b>!" and the second match is "We must be \<b>bold\</b>,
3492 very <u>\<b>bold\</b></u>!". In practice we might use the pattern
3493 <b>\<b>[^\<]+\</b></b> instead, although this will still fail for
3494 nested tags.
3495
3496 \sa minimal()
3497*/
3498void QRegExp::setMinimal( bool minimal )
3499{
3500 priv->min = minimal;
3501}
3502
3503/*!
3504 Returns TRUE if \a str is matched exactly by this regular
3505 expression; otherwise returns FALSE. You can determine how much of
3506 the string was matched by calling matchedLength().
3507
3508 For a given regexp string, R, exactMatch("R") is the equivalent of
3509 search("^R$") since exactMatch() effectively encloses the regexp
3510 in the start of string and end of string anchors, except that it
3511 sets matchedLength() differently.
3512
3513 For example, if the regular expression is <b>blue</b>, then
3514 exactMatch() returns TRUE only for input \c blue. For inputs \c
3515 bluebell, \c blutak and \c lightblue, exactMatch() returns FALSE
3516 and matchedLength() will return 4, 3 and 0 respectively.
3517
3518 Although const, this function sets matchedLength(),
3519 capturedTexts() and pos().
3520
3521 \sa search() searchRev() QRegExpValidator
3522*/
3523bool QRegExp::exactMatch( const QString& str ) const
3524{
3525#ifndef QT_NO_REGEXP_CAPTURE
3526 priv->t = str;
3527 priv->capturedCache.clear();
3528#endif
3529
3530 priv->captured = eng->match( str, 0, priv->min, TRUE, 0 );
3531 if ( priv->captured[1] == (int) str.length() ) {
3532 return TRUE;
3533 } else {
3534 priv->captured.detach();
3535 priv->captured[0] = 0;
3536 priv->captured[1] = eng->matchedLength();
3537 return FALSE;
3538 }
3539}
3540
3541#ifndef QT_NO_COMPAT
3542/*! \obsolete
3543
3544 Attempts to match in \a str, starting from position \a index.
3545 Returns the position of the match, or -1 if there was no match.
3546
3547 The length of the match is stored in \a *len, unless \a len is a
3548 null pointer.
3549
3550 If \a indexIsStart is TRUE (the default), the position \a index in
3551 the string will match the start of string anchor, <b>^</b>, in the
3552 regexp, if present. Otherwise, position 0 in \a str will match.
3553
3554 Use search() and matchedLength() instead of this function.
3555
3556 \sa QString::mid() QConstString
3557*/
3558int QRegExp::match( const QString& str, int index, int *len,
3559 bool indexIsStart ) const
3560{
3561 int pos = search( str, index, indexIsStart ? CaretAtOffset : CaretAtZero );
3562 if ( len != 0 )
3563 *len = matchedLength();
3564 return pos;
3565}
3566#endif // QT_NO_COMPAT
3567
3568/*!
3569 \overload
3570
3571 This convenience function searches with a \c CaretMode of \c
3572 CaretAtZero which is the most common usage.
3573*/
3574
3575int QRegExp::search( const QString& str, int offset ) const
3576{
3577 return search( str, offset, CaretAtZero );
3578}
3579
3580/*!
3581 Attempts to find a match in \a str from position \a offset (0 by
3582 default). If \a offset is -1, the search starts at the last
3583 character; if -2, at the next to last character; etc.
3584
3585 Returns the position of the first match, or -1 if there was no
3586 match.
3587
3588 The \a caretMode parameter can be used to instruct whether <b>^</b>
3589 should match at index 0 or at \a offset.
3590
3591 You might prefer to use QString::find(), QString::contains() or
3592 even QStringList::grep(). To replace matches use
3593 QString::replace().
3594
3595 Example:
3596 \code
3597 QString str = "offsets: 1.23 .50 71.00 6.00";
3598 QRegExp rx( "\\d*\\.\\d+" ); // primitive floating point matching
3599 int count = 0;
3600 int pos = 0;
3601 while ( (pos = rx.search(str, pos)) != -1 ) {
3602 count++;
3603 pos += rx.matchedLength();
3604 }
3605 // pos will be 9, 14, 18 and finally 24; count will end up as 4
3606 \endcode
3607
3608 Although const, this function sets matchedLength(),
3609 capturedTexts() and pos().
3610
3611 \sa searchRev() exactMatch()
3612*/
3613
3614int QRegExp::search( const QString& str, int offset, CaretMode caretMode ) const
3615{
3616 if ( offset < 0 )
3617 offset += str.length();
3618#ifndef QT_NO_REGEXP_CAPTURE
3619 priv->t = str;
3620 priv->capturedCache.clear();
3621#endif
3622 priv->captured = eng->match( str, offset, priv->min, FALSE,
3623 caretIndex(offset, caretMode) );
3624 return priv->captured[0];
3625}
3626
3627
3628/*!
3629 \overload
3630
3631 This convenience function searches with a \c CaretMode of \c
3632 CaretAtZero which is the most common usage.
3633*/
3634
3635int QRegExp::searchRev( const QString& str, int offset ) const
3636{
3637 return searchRev( str, offset, CaretAtZero );
3638}
3639
3640/*!
3641 Attempts to find a match backwards in \a str from position \a
3642 offset. If \a offset is -1 (the default), the search starts at the
3643 last character; if -2, at the next to last character; etc.
3644
3645 Returns the position of the first match, or -1 if there was no
3646 match.
3647
3648 The \a caretMode parameter can be used to instruct whether <b>^</b>
3649 should match at index 0 or at \a offset.
3650
3651 Although const, this function sets matchedLength(),
3652 capturedTexts() and pos().
3653
3654 \warning Searching backwards is much slower than searching
3655 forwards.
3656
3657 \sa search() exactMatch()
3658*/
3659
3660int QRegExp::searchRev( const QString& str, int offset,
3661 CaretMode caretMode ) const
3662{
3663 if ( offset < 0 )
3664 offset += str.length();
3665#ifndef QT_NO_REGEXP_CAPTURE
3666 priv->t = str;
3667 priv->capturedCache.clear();
3668#endif
3669 if ( offset < 0 || offset > (int) str.length() ) {
3670 priv->captured.detach();
3671 priv->captured.fill( -1 );
3672 return -1;
3673 }
3674
3675 while ( offset >= 0 ) {
3676 priv->captured = eng->match( str, offset, priv->min, TRUE,
3677 caretIndex(offset, caretMode) );
3678 if ( priv->captured[0] == offset )
3679 return offset;
3680 offset--;
3681 }
3682 return -1;
3683}
3684
3685/*!
3686 Returns the length of the last matched string, or -1 if there was
3687 no match.
3688
3689 \sa exactMatch() search() searchRev()
3690*/
3691int QRegExp::matchedLength() const
3692{
3693 return priv->captured[1];
3694}
3695
3696#ifndef QT_NO_REGEXP_CAPTURE
3697/*!
3698 Returns the number of captures contained in the regular expression.
3699 */
3700int QRegExp::numCaptures() const
3701{
3702 return eng->numCaptures();
3703}
3704
3705
3706
3707/*!
3708 Returns a list of the captured text strings.
3709
3710 The first string in the list is the entire matched string. Each
3711 subsequent list element contains a string that matched a
3712 (capturing) subexpression of the regexp.
3713
3714 For example:
3715 \code
3716 QRegExp rx( "(\\d+)(\\s*)(cm|inch(es)?)" );
3717 int pos = rx.search( "Length: 36 inches" );
3718 QStringList list = rx.capturedTexts();
3719 // list is now ( "36 inches", "36", " ", "inches", "es" )
3720 \endcode
3721
3722 The above example also captures elements that may be present but
3723 which we have no interest in. This problem can be solved by using
3724 non-capturing parentheses:
3725
3726 \code
3727 QRegExp rx( "(\\d+)(?:\\s*)(cm|inch(?:es)?)" );
3728 int pos = rx.search( "Length: 36 inches" );
3729 QStringList list = rx.capturedTexts();
3730 // list is now ( "36 inches", "36", "inches" )
3731 \endcode
3732
3733 Note that if you want to iterate over the list, you should iterate
3734 over a copy, e.g.
3735 \code
3736 QStringList list = rx.capturedTexts();
3737 QStringList::Iterator it = list.begin();
3738 while( it != list.end() ) {
3739 myProcessing( *it );
3740 ++it;
3741 }
3742 \endcode
3743
3744 Some regexps can match an indeterminate number of times. For
3745 example if the input string is "Offsets: 12 14 99 231 7" and the
3746 regexp, \c{rx}, is <b>(\\d+)+</b>, we would hope to get a list of
3747 all the numbers matched. However, after calling
3748 \c{rx.search(str)}, capturedTexts() will return the list ( "12",
3749 "12" ), i.e. the entire match was "12" and the first subexpression
3750 matched was "12". The correct approach is to use cap() in a \link
3751 #cap_in_a_loop loop \endlink.
3752
3753 The order of elements in the string list is as follows. The first
3754 element is the entire matching string. Each subsequent element
3755 corresponds to the next capturing open left parentheses. Thus
3756 capturedTexts()[1] is the text of the first capturing parentheses,
3757 capturedTexts()[2] is the text of the second and so on
3758 (corresponding to $1, $2, etc., in some other regexp languages).
3759
3760 \sa cap() pos() exactMatch() search() searchRev()
3761*/
3762QStringList QRegExp::capturedTexts()
3763{
3764 if ( priv->capturedCache.isEmpty() ) {
3765 for ( int i = 0; i < (int) priv->captured.size(); i += 2 ) {
3766 QString m;
3767 if ( priv->captured[i + 1] == 0 )
3768 m = QString::fromLatin1( "" );
3769 else if ( priv->captured[i] >= 0 )
3770 m = priv->t.mid( priv->captured[i],
3771 priv->captured[i + 1] );
3772 priv->capturedCache.append( m );
3773 }
3774 priv->t = QString::null;
3775 }
3776 return priv->capturedCache;
3777}
3778
3779/*!
3780 Returns the text captured by the \a nth subexpression. The entire
3781 match has index 0 and the parenthesized subexpressions have
3782 indices starting from 1 (excluding non-capturing parentheses).
3783
3784 \code
3785 QRegExp rxlen( "(\\d+)(?:\\s*)(cm|inch)" );
3786 int pos = rxlen.search( "Length: 189cm" );
3787 if ( pos > -1 ) {
3788 QString value = rxlen.cap( 1 ); // "189"
3789 QString unit = rxlen.cap( 2 ); // "cm"
3790 // ...
3791 }
3792 \endcode
3793
3794 The order of elements matched by cap() is as follows. The first
3795 element, cap(0), is the entire matching string. Each subsequent
3796 element corresponds to the next capturing open left parentheses.
3797 Thus cap(1) is the text of the first capturing parentheses, cap(2)
3798 is the text of the second, and so on.
3799
3800 \target cap_in_a_loop
3801 Some patterns may lead to a number of matches which cannot be
3802 determined in advance, for example:
3803
3804 \code
3805 QRegExp rx( "(\\d+)" );
3806 str = "Offsets: 12 14 99 231 7";
3807 QStringList list;
3808 pos = 0;
3809 while ( pos >= 0 ) {
3810 pos = rx.search( str, pos );
3811 if ( pos > -1 ) {
3812 list += rx.cap( 1 );
3813 pos += rx.matchedLength();
3814 }
3815 }
3816 // list contains "12", "14", "99", "231", "7"
3817 \endcode
3818
3819 \sa capturedTexts() pos() exactMatch() search() searchRev()
3820*/
3821QString QRegExp::cap( int nth )
3822{
3823 if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
3824 return QString::null;
3825 else
3826 return capturedTexts()[nth];
3827}
3828
3829/*!
3830 Returns the position of the \a nth captured text in the searched
3831 string. If \a nth is 0 (the default), pos() returns the position
3832 of the whole match.
3833
3834 Example:
3835 \code
3836 QRegExp rx( "/([a-z]+)/([a-z]+)" );
3837 rx.search( "Output /dev/null" ); // returns 7 (position of /dev/null)
3838 rx.pos( 0 ); // returns 7 (position of /dev/null)
3839 rx.pos( 1 ); // returns 8 (position of dev)
3840 rx.pos( 2 ); // returns 12 (position of null)
3841 \endcode
3842
3843 For zero-length matches, pos() always returns -1. (For example, if
3844 cap(4) would return an empty string, pos(4) returns -1.) This is
3845 due to an implementation tradeoff.
3846
3847 \sa capturedTexts() exactMatch() search() searchRev()
3848*/
3849int QRegExp::pos( int nth )
3850{
3851 if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
3852 return -1;
3853 else
3854 return priv->captured[2 * nth];
3855}
3856
3857/*!
3858 Returns a text string that explains why a regexp pattern is
3859 invalid the case being; otherwise returns "no error occurred".
3860
3861 \sa isValid()
3862*/
3863QString QRegExp::errorString()
3864{
3865 if ( isValid() ) {
3866 return QString( RXERR_OK );
3867 } else {
3868 return eng->errorString();
3869 }
3870}
3871#endif
3872
3873/*!
3874 Returns the string \a str with every regexp special character
3875 escaped with a backslash. The special characters are $, (, ), *, +,
3876 ., ?, [, \, ], ^, {, | and }.
3877
3878 Example:
3879 \code
3880 s1 = QRegExp::escape( "bingo" ); // s1 == "bingo"
3881 s2 = QRegExp::escape( "f(x)" ); // s2 == "f\\(x\\)"
3882 \endcode
3883
3884 This function is useful to construct regexp patterns dynamically:
3885
3886 \code
3887 QRegExp rx( "(" + QRegExp::escape(name) +
3888 "|" + QRegExp::escape(alias) + ")" );
3889 \endcode
3890*/
3891QString QRegExp::escape( const QString& str )
3892{
3893 static const char meta[] = "$()*+.?[\\]^{|}";
3894 QString quoted = str;
3895 int i = 0;
3896
3897 while ( i < (int) quoted.length() ) {
3898 if ( strchr(meta, quoted[i].latin1()) != 0 )
3899 quoted.insert( i++, "\\" );
3900 i++;
3901 }
3902 return quoted;
3903}
3904
3905void QRegExp::compile( bool caseSensitive )
3906{
3907 derefEngine( eng, priv->rxpattern );
3908#ifndef QT_NO_REGEXP_WILDCARD
3909 if ( priv->wc )
3910 priv->rxpattern = wc2rx( priv->pattern );
3911 else
3912#endif
3913 priv->rxpattern = priv->pattern.isNull() ? QString::fromLatin1( "" )
3914 : priv->pattern;
3915 eng = newEngine( priv->rxpattern, caseSensitive );
3916#ifndef QT_NO_REGEXP_CAPTURE
3917 priv->t = QString();
3918 priv->capturedCache.clear();
3919#endif
3920 priv->captured.detach();
3921 priv->captured.fill( -1, 2 + 2 * eng->numCaptures() );
3922}
3923
3924int QRegExp::caretIndex( int offset, CaretMode caretMode )
3925{
3926 if ( caretMode == CaretAtZero ) {
3927 return 0;
3928 } else if ( caretMode == CaretAtOffset ) {
3929 return offset;
3930 } else { // CaretWontMatch
3931 return -1;
3932 }
3933}
3934
3935#endif // QT_NO_REGEXP
diff --git a/qmake/tools/qsemaphore_unix.cpp b/qmake/tools/qsemaphore_unix.cpp
new file mode 100644
index 0000000..fcf28da
--- a/dev/null
+++ b/qmake/tools/qsemaphore_unix.cpp
@@ -0,0 +1,292 @@
1/****************************************************************************
2** $Id$
3**
4** QSemaphore class for Unix
5**
6** Created : 20010725
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#if defined(QT_THREAD_SUPPORT)
39
40#include "qsemaphore.h"
41#include "qmutex.h"
42#include "qwaitcondition.h"
43
44
45/*!
46 \class QSemaphore qsemaphore.h
47 \threadsafe
48 \brief The QSemaphore class provides a robust integer semaphore.
49
50 \ingroup thread
51 \ingroup environment
52
53 A QSemaphore can be used to serialize thread execution, in a
54 similar way to a QMutex. A semaphore differs from a mutex, in
55 that a semaphore can be accessed by more than one thread at a
56 time.
57
58 For example, suppose we have an application that stores data in a
59 large tree structure. The application creates 10 threads
60 (commonly called a thread pool) to perform searches on the tree.
61 When the application searches the tree for some piece of data, it
62 uses one thread per base node to do the searching. A semaphore
63 could be used to make sure that two threads don't try to search
64 the same branch of the tree at the same time.
65
66 A non-computing example of a semaphore would be dining at a
67 restuarant. A semaphore is initialized to have a maximum count
68 equal to the number of chairs in the restuarant. As people
69 arrive, they want a seat. As seats are filled, the semaphore is
70 accessed, once per person. As people leave, the access is
71 released, allowing more people to enter. If a party of 10 people
72 want to be seated, but there are only 9 seats, those 10 people
73 will wait, but a party of 4 people would be seated (taking the
74 available seats to 5, making the party of 10 people wait longer).
75
76 When a semaphore is created it is given a number which is the
77 maximum number of concurrent accesses it will permit. This amount
78 may be changed using operator++(), operator--(), operator+=() and
79 operator-=(). The number of accesses allowed is retrieved with
80 available(), and the total number with total(). Note that the
81 incrementing functions will block if there aren't enough available
82 accesses. Use tryAccess() if you want to acquire accesses without
83 blocking.
84*/
85
86
87class QSemaphorePrivate {
88public:
89 QSemaphorePrivate(int);
90
91 QMutex mutex;
92 QWaitCondition cond;
93
94 int value, max;
95};
96
97
98QSemaphorePrivate::QSemaphorePrivate(int m)
99 : mutex(FALSE), value(0), max(m)
100{
101}
102
103
104/*!
105 Creates a new semaphore. The semaphore can be concurrently
106 accessed at most \a maxcount times.
107*/
108QSemaphore::QSemaphore(int maxcount)
109{
110 d = new QSemaphorePrivate(maxcount);
111}
112
113
114/*!
115 Destroys the semaphore.
116
117 \warning If you destroy a semaphore that has accesses in use the
118 resultant behavior is undefined.
119*/
120QSemaphore::~QSemaphore()
121{
122 delete d;
123}
124
125
126/*!
127 Postfix ++ operator.
128
129 Try to get access to the semaphore. If \l available() == 0, this
130 call will block until it can get access, i.e. until available() \>
131 0.
132*/
133int QSemaphore::operator++(int)
134{
135 int ret;
136
137 d->mutex.lock();
138
139 while (d->value >= d->max)
140 d->cond.wait(&(d->mutex));
141
142 ++(d->value);
143 if (d->value > d->max) d->value = d->max;
144 ret = d->value;
145
146 d->mutex.unlock();
147
148 return ret;
149}
150
151
152/*!
153 Postfix -- operator.
154
155 Release access of the semaphore. This wakes all threads waiting
156 for access to the semaphore.
157*/
158int QSemaphore::operator--(int)
159{
160 int ret;
161
162 d->mutex.lock();
163
164 --(d->value);
165 if (d->value < 0) d->value = 0;
166 ret = d->value;
167
168 d->cond.wakeAll();
169 d->mutex.unlock();
170
171 return ret;
172}
173
174
175/*!
176 Try to get access to the semaphore. If \l available() \< \a n, this
177 call will block until it can get all the accesses it wants, i.e.
178 until available() \>= \a n.
179*/
180int QSemaphore::operator+=(int n)
181{
182 int ret;
183
184 d->mutex.lock();
185
186 while (d->value + n > d->max)
187 d->cond.wait(&(d->mutex));
188
189 d->value += n;
190
191#ifdef QT_CHECK_RANGE
192 if (d->value > d->max) {
193 qWarning("QSemaphore::operator+=: attempt to allocate more resources than available");
194 d->value = d->max;
195 }
196#endif
197
198 ret = d->value;
199
200 d->mutex.unlock();
201
202 return ret;
203}
204
205
206/*!
207 Release \a n accesses to the semaphore.
208*/
209int QSemaphore::operator-=(int n)
210{
211 int ret;
212
213 d->mutex.lock();
214
215 d->value -= n;
216
217#ifdef QT_CHECK_RANGE
218 if (d->value < 0) {
219 qWarning("QSemaphore::operator-=: attempt to deallocate more resources than taken");
220 d->value = 0;
221 }
222#endif
223
224 ret = d->value;
225
226 d->cond.wakeOne();
227 d->mutex.unlock();
228
229 return ret;
230}
231
232
233/*!
234 Returns the number of accesses currently available to the
235 semaphore.
236*/
237int QSemaphore::available() const {
238 int ret;
239
240 d->mutex.lock();
241 ret = d->max - d->value;
242 d->mutex.unlock();
243
244 return ret;
245}
246
247
248/*!
249 Returns the total number of accesses to the semaphore.
250*/
251int QSemaphore::total() const {
252 int ret;
253
254 d->mutex.lock();
255 ret = d->max;
256 d->mutex.unlock();
257
258 return ret;
259}
260
261
262/*!
263 Try to get access to the semaphore. If \l available() \< \a n, this
264 function will return FALSE immediately. If \l available() \>= \a n,
265 this function will take \a n accesses and return TRUE. This
266 function does \e not block.
267*/
268bool QSemaphore::tryAccess(int n)
269{
270 if (! d->mutex.tryLock())
271 return FALSE;
272
273 if (d->value + n > d->max) {
274 d->mutex.unlock();
275 return FALSE;
276 }
277
278 d->value += n;
279
280#ifdef QT_CHECK_RANGE
281 if (d->value > d->max) {
282 qWarning("QSemaphore::operator+=: attempt to allocate more resources than available");
283 d->value = d->max;
284 }
285#endif
286
287 d->mutex.unlock();
288
289 return TRUE;
290}
291
292#endif // QT_THREAD_SUPPORT
diff --git a/qmake/tools/qsettings.cpp b/qmake/tools/qsettings.cpp
new file mode 100644
index 0000000..5de105c
--- a/dev/null
+++ b/qmake/tools/qsettings.cpp
@@ -0,0 +1,1955 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QSettings class
5**
6** Created: 2000.06.26
7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40// POSIX Large File Support redefines open -> open64
41static inline int qt_open( const char *pathname, int flags, mode_t mode )
42{ return ::open( pathname, flags, mode ); }
43#if defined(open)
44# undef open
45#endif
46
47// POSIX Large File Support redefines truncate -> truncate64
48#if defined(truncate)
49# undef truncate
50#endif
51
52#include "qsettings.h"
53
54#ifndef QT_NO_SETTINGS
55
56#include "qdir.h"
57#include "qfile.h"
58#include "qfileinfo.h"
59#include "qmap.h"
60#include "qtextstream.h"
61#include "qregexp.h"
62#include <private/qsettings_p.h>
63#include <errno.h>
64
65/*!
66 \class QSettings
67 \brief The QSettings class provides persistent platform-independent application settings.
68
69 \ingroup io
70 \ingroup misc
71 \mainclass
72
73 On Unix systems, QSettings uses text files to store settings. On Windows
74 systems, QSettings uses the system registry. On Mac OS X, QSettings will
75 behave as on Unix, and store to text files.
76
77 Each setting comprises an identifying key and the data associated with
78 the key. A key is a unicode string which consists of \e two or more
79 subkeys. A subkey is a slash, '/', followed by one or more unicode
80 characters (excluding slashes, newlines, carriage returns and equals,
81 '=', signs). The associated data, called the entry or value, may be a
82 boolean, an integer, a double, a string or a list of strings. Entry
83 strings may contain any unicode characters.
84
85 If you want to save and restore the entire desktop's settings, i.e.
86 which applications are running, use QSettings to save the settings
87 for each individual application and QSessionManager to save the
88 desktop's session.
89
90 Example settings:
91 \code
92 /MyCompany/MyApplication/background color
93 /MyCompany/MyApplication/foreground color
94 /MyCompany/MyApplication/geometry/x
95 /MyCompany/MyApplication/geometry/y
96 /MyCompany/MyApplication/geometry/width
97 /MyCompany/MyApplication/geometry/height
98 /MyCompany/MyApplication/recent files/1
99 /MyCompany/MyApplication/recent files/2
100 /MyCompany/MyApplication/recent files/3
101 \endcode
102 Each line above is a complete key, made up of subkeys.
103
104 A typical usage pattern for application startup:
105 \code
106 QSettings settings;
107 settings.insertSearchPath( QSettings::Windows, "/MyCompany" );
108 // No search path needed for Unix; see notes further on.
109 // Use default values if the keys don't exist
110 QString bgColor = settings.readEntry( "/MyApplication/background color", "white" );
111 int width = settings.readNumEntry( "/MyApplication/geometry/width", 640 );
112 // ...
113 \endcode
114
115 A typical usage pattern for application exit or 'save preferences':
116 \code
117 QSettings settings;
118 settings.insertSearchPath( QSettings::Windows, "/MyCompany" );
119 // No search path needed for Unix; see notes further on.
120 settings.writeEntry( "/MyApplication/background color", bgColor );
121 settings.writeEntry( "/MyApplication/geometry/width", width );
122 // ...
123 \endcode
124
125 You can get a list of entry-holding keys by calling entryList(), and
126 a list of key-holding keys using subkeyList().
127
128 \code
129 QStringList keys = entryList( "/MyApplication" );
130 // keys contains 'background color' and 'foreground color'.
131
132 QStringList keys = entryList( "/MyApplication/recent files" );
133 // keys contains '1', '2' and '3'.
134
135 QStringList subkeys = subkeyList( "/MyApplication" );
136 // subkeys contains 'geometry' and 'recent files'
137
138 QStringList subkeys = subkeyList( "/MyApplication/recent files" );
139 // subkeys is empty.
140 \endcode
141
142 If you wish to use a different search path call insertSearchPath()
143 as often as necessary to add your preferred paths. Call
144 removeSearchPath() to remove any unwanted paths.
145
146 Since settings for Windows are stored in the registry there are size
147 limits as follows:
148 \list
149 \i A subkey may not exceed 255 characters.
150 \i An entry's value may not exceed 16,300 characters.
151 \i All the values of a key (for example, all the 'recent files'
152 subkeys values), may not exceed 65,535 characters.
153 \endlist
154
155 These limitations are not enforced on Unix.
156
157 \section1 Notes for Unix Applications
158
159 There is no universally accepted place for storing application
160 settings under Unix. In the examples the settings file will be
161 searched for in the following directories:
162 \list 1
163 \i INSTALL/etc/settings
164 \i /opt/MyCompany/share/etc
165 \i /opt/MyCompany/share/MyApplication/etc
166 \i $HOME/.qt
167 \endlist
168 When reading settings the files are searched in the order shown
169 above, with later settings overriding earlier settings. Files for
170 which the user doesn't have read permission are ignored. When saving
171 settings QSettings works in the order shown above, writing
172 to the first settings file for which the user has write permission.
173 (\c INSTALL is the directory where Qt was installed. This can be
174 modified by using the configure script's -prefix argument )
175
176 If you want to put the settings in a particular place in the
177 filesystem you could do this:
178 \code
179 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share" );
180 \endcode
181
182 But in practice you may prefer not to use a search path for Unix.
183 For example the following code:
184 \code
185 settings.writeEntry( "/MyApplication/geometry/width", width );
186 \endcode
187 will end up writing the "geometry/width" setting to the file
188 \c{$HOME/.qt/myapplicationrc} (assuming that the application is
189 being run by an ordinary user, i.e. not by root).
190
191 For cross-platform applications you should ensure that the Windows
192 size limitations are not exceeded.
193*/
194
195/*!
196 \enum QSettings::System
197
198 \value Mac Macintosh execution environments
199 \value Unix Mac OS X, Unix, Linux and Unix-like execution environments
200 \value Windows Windows execution environments
201*/
202
203/*!
204 \enum QSettings::Format
205
206 \value Native Store the settings in a platform dependent location
207 \value Ini Store the settings in a text file
208*/
209
210/*!
211 \enum QSettings::Scope
212
213 \value Global Save settings as global as possible
214 \value User Save settings in user space
215*/
216
217#if defined(Q_OS_UNIX)
218typedef int HANDLE;
219#define Q_LOCKREAD F_RDLCK
220#define Q_LOCKWRITE F_WRLCK
221/*
222 Locks the file specified by name. The lockfile is created as a
223 hidden file in the same directory as the target file, with .lock
224 appended to the name. For example, "/etc/settings/onerc" uses a
225 lockfile named "/etc/settings/.onerc.lock". The type argument
226 controls the type of the lock, it can be either F_RDLCK for a read
227 lock, or F_WRLCK for a write lock.
228
229 A file descriptor for the lock file is returned, and should be
230 closed with closelock() when the lock is no longer needed.
231 */
232static HANDLE openlock( const QString &name, int type )
233{
234 QFileInfo info( name );
235 // lockfile should be hidden, and never removed
236 QString lockfile = info.dirPath() + "/." + info.fileName() + ".lock";
237
238 // open the lockfile
239 HANDLE fd = qt_open( QFile::encodeName( lockfile ),
240 O_RDWR | O_CREAT, S_IRUSR | S_IWUSR );
241
242 if ( fd < 0 ) {
243 // failed to open the lock file, most likely because of permissions
244 return fd;
245 }
246
247 struct flock fl;
248 fl.l_type = type;
249 fl.l_whence = SEEK_SET;
250 fl.l_start = 0;
251 fl.l_len = 0;
252 if ( fcntl( fd, F_SETLKW, &fl ) == -1 ) {
253 // the lock failed, so we should fail silently, so that people
254 // using filesystems that do not support locking don't see
255 // numerous warnings about a failed lock
256 close( fd );
257 fd = -1;
258 }
259
260 return fd;
261}
262
263/*
264 Closes the lock file specified by fd. fd is the file descriptor
265 returned by the openlock() function.
266*/
267static void closelock( HANDLE fd )
268{
269 if ( fd < 0 ) {
270 // the lock file is not open
271 return;
272 }
273
274 struct flock fl;
275 fl.l_type = F_UNLCK;
276 fl.l_whence = SEEK_SET;
277 fl.l_start = 0;
278 fl.l_len = 0;
279 // ignore the return value, so that the unlock fails silently
280 (void) fcntl( fd, F_SETLKW, &fl );
281
282 close( fd );
283}
284#elif defined(Q_WS_WIN)
285#define Q_LOCKREAD 1
286#define Q_LOCKWRITE 2
287
288static HANDLE openlock( const QString &name, int /*type*/ )
289{
290 if ( !QFile::exists( name ) )
291 return 0;
292
293 return 0;
294
295 HANDLE fd = 0;
296
297 QT_WA( {
298 fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
299 } , {
300 fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
301 } );
302
303 if ( !LockFile( fd, 0, 0, -1, -1 ) ) {
304#ifdef QT_CHECK_STATE
305 qWarning( "QSettings: openlock failed!" );
306#endif
307 }
308 return fd;
309}
310
311void closelock( HANDLE fd )
312{
313 if ( !fd )
314 return;
315
316 if ( !UnlockFile( fd, 0, 0, -1, -1 ) ) {
317#ifdef QT_CHECK_STATE
318 qWarning( "QSettings: closelock failed!");
319#endif
320 }
321 CloseHandle( fd );
322}
323#endif
324
325
326QSettingsGroup::QSettingsGroup()
327 : modified(FALSE)
328{
329}
330
331
332
333
334void QSettingsHeading::read(const QString &filename)
335{
336 if (! QFileInfo(filename).exists())
337 return;
338
339 HANDLE lockfd = openlock( filename, Q_LOCKREAD );
340
341 QFile file(filename);
342 if (! file.open(IO_ReadOnly)) {
343#if defined(QT_CHECK_STATE)
344 qWarning("QSettings: failed to open file '%s'", filename.latin1());
345#endif
346 return;
347 }
348
349 git = end();
350
351 QTextStream stream(&file);
352 stream.setEncoding(QTextStream::UnicodeUTF8);
353 while (! stream.atEnd())
354 parseLine(stream);
355
356 git = end();
357
358 file.close();
359
360 closelock( lockfd );
361}
362
363
364void QSettingsHeading::parseLine(QTextStream &stream)
365{
366 QString line = stream.readLine();
367 if (line.isEmpty())
368 // empty line... we'll allow it
369 return;
370
371 if (line[0] == QChar('#'))
372 // commented line
373 return;
374
375 if (line[0] == QChar('[')) {
376 QString gname = line;
377
378 gname = gname.remove(0, 1);
379 if (gname[(int)gname.length() - 1] == QChar(']'))
380 gname = gname.remove(gname.length() - 1, 1);
381
382 git = find(gname);
383 if (git == end())
384 git = replace(gname, QSettingsGroup());
385 } else {
386 if (git == end()) {
387#if defined(QT_CHECK_STATE)
388 qWarning("QSettings: line '%s' out of group", line.latin1());
389#endif
390 return;
391 }
392
393 int i = line.find('=');
394 if (i == -1) {
395#if defined(QT_CHECK_STATE)
396 qWarning("QSettings: malformed line '%s' in group '%s'",
397 line.latin1(), git.key().latin1());
398#endif
399 return;
400 } else {
401 QString key, value;
402 key = line.left(i);
403 value = "";
404 bool esc=TRUE;
405 i++;
406 while (esc) {
407 esc = FALSE;
408 for ( ; i < (int)line.length(); i++ ) {
409 if ( esc ) {
410 if ( line[i] == 'n' )
411 value.append('\n'); // escaped newline
412 else if ( line[i] == '0' )
413 value = QString::null; // escaped empty string
414 else
415 value.append(line[i]);
416 esc = FALSE;
417 } else if ( line[i] == '\\' )
418 esc = TRUE;
419 else
420 value.append(line[i]);
421 }
422 if ( esc ) {
423 // Backwards-compatiblity...
424 // still escaped at EOL - manually escaped "newline"
425 if (stream.atEnd()) {
426#if defined(QT_CHECK_STATE)
427 qWarning("QSettings: reached end of file, expected continued line");
428#endif
429 break;
430 }
431 value.append('\n');
432 line = stream.readLine();
433 i = 0;
434 }
435 }
436
437 (*git).insert(key, value);
438 }
439 }
440}
441
442#ifdef Q_WS_WIN // for homedirpath reading from registry
443#include "qt_windows.h"
444#include "qlibrary.h"
445
446#ifndef CSIDL_APPDATA
447#define CSIDL_APPDATA 0x001a // <user name>\Application Data
448#endif
449#ifndef CSIDL_COMMON_APPDATA
450#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
451#endif
452
453#endif
454
455QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
456 : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE)
457{
458#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
459 if ( format != QSettings::Ini )
460 return;
461#endif
462
463 QString appSettings(QDir::homeDirPath() + "/.qt/");
464 QString defPath;
465#ifdef Q_WS_WIN
466#ifdef Q_OS_TEMP
467 TCHAR path[MAX_PATH];
468 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
469 appSettings = QString::fromUcs2( path );
470 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
471 defPath = QString::fromUcs2( path );
472#else
473 QLibrary library( "shell32" );
474 library.setAutoUnload( FALSE );
475 QT_WA( {
476 typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL);
477 GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathW" );
478 if ( SHGetSpecialFolderPath ) {
479 TCHAR path[MAX_PATH];
480 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
481 appSettings = QString::fromUcs2( (ushort*)path );
482 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
483 defPath = QString::fromUcs2( (ushort*)path );
484 }
485 } , {
486 typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL);
487 GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathA" );
488 if ( SHGetSpecialFolderPath ) {
489 char path[MAX_PATH];
490 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
491 appSettings = QString::fromLocal8Bit( path );
492 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
493 defPath = QString::fromLocal8Bit( path );
494 }
495 } );
496#endif // Q_OS_TEMP
497#else
498// for now
499#define QSETTINGS_DEFAULT_PATH_SUFFIX "/etc/settings"
500
501 defPath = qInstallPath();
502 defPath += QSETTINGS_DEFAULT_PATH_SUFFIX;
503#endif
504 QDir dir(appSettings);
505 if (! dir.exists()) {
506 if (! dir.mkdir(dir.path()))
507#if defined(QT_CHECK_STATE)
508 qWarning("QSettings: error creating %s", dir.path().latin1());
509#endif
510 }
511
512 if ( !!defPath )
513 searchPaths.append(defPath);
514 searchPaths.append(dir.path());
515}
516
517QSettingsPrivate::~QSettingsPrivate()
518{
519}
520
521QSettingsGroup QSettingsPrivate::readGroup()
522{
523 QSettingsHeading hd;
524 QSettingsGroup grp;
525
526 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
527 if (headingsit != headings.end())
528 hd = *headingsit;
529
530 QSettingsHeading::Iterator grpit = hd.find(group);
531 if (grpit == hd.end()) {
532 QStringList::Iterator it = searchPaths.begin();
533 while (it != searchPaths.end()) {
534 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
535 QString fn((*it++) + "/" + filebase + "rc");
536 if (! hd.contains(fn + "cached")) {
537 hd.read(fn);
538 hd.insert(fn + "cached", QSettingsGroup());
539 }
540 }
541
542 headings.replace(heading, hd);
543
544 grpit = hd.find(group);
545 if (grpit != hd.end())
546 grp = *grpit;
547 } else if (hd.count() != 0)
548 grp = *grpit;
549
550 return grp;
551}
552
553
554void QSettingsPrivate::removeGroup(const QString &key)
555{
556 QSettingsHeading hd;
557 QSettingsGroup grp;
558 bool found = FALSE;
559
560 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
561 if (headingsit != headings.end())
562 hd = *headingsit;
563
564 QSettingsHeading::Iterator grpit = hd.find(group);
565 if (grpit == hd.end()) {
566 QStringList::Iterator it = searchPaths.begin();
567 while (it != searchPaths.end()) {
568 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
569 QString fn((*it++) + "/" + filebase + "rc");
570 if (! hd.contains(fn + "cached")) {
571 hd.read(fn);
572 hd.insert(fn + "cached", QSettingsGroup());
573 }
574 }
575
576 headings.replace(heading, hd);
577
578 grpit = hd.find(group);
579 if (grpit != hd.end()) {
580 found = TRUE;
581 grp = *grpit;
582 }
583 } else if (hd.count() != 0) {
584 found = TRUE;
585 grp = *grpit;
586 }
587
588 if (found) {
589 grp.remove(key);
590
591 if (grp.count() > 0)
592 hd.replace(group, grp);
593 else
594 hd.remove(group);
595
596 if (hd.count() > 0)
597 headings.replace(heading, hd);
598 else
599 headings.remove(heading);
600
601 modified = TRUE;
602 }
603}
604
605
606void QSettingsPrivate::writeGroup(const QString &key, const QString &value)
607{
608 QSettingsHeading hd;
609 QSettingsGroup grp;
610
611 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
612 if (headingsit != headings.end())
613 hd = *headingsit;
614
615 QSettingsHeading::Iterator grpit = hd.find(group);
616 if (grpit == hd.end()) {
617 QStringList::Iterator it = searchPaths.begin();
618 while (it != searchPaths.end()) {
619 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
620 QString fn((*it++) + "/" + filebase + "rc");
621 if (! hd.contains(fn + "cached")) {
622 hd.read(fn);
623 hd.insert(fn + "cached", QSettingsGroup());
624 }
625 }
626
627 headings.replace(heading, hd);
628
629 grpit = hd.find(group);
630 if (grpit != hd.end())
631 grp = *grpit;
632 } else if (hd.count() != 0)
633 grp = *grpit;
634
635 grp.modified = TRUE;
636 grp.replace(key, value);
637 hd.replace(group, grp);
638 headings.replace(heading, hd);
639
640 modified = TRUE;
641}
642
643
644QDateTime QSettingsPrivate::modificationTime()
645{
646 QSettingsHeading hd = headings[heading];
647 QSettingsGroup grp = hd[group];
648
649 QDateTime datetime;
650
651 QStringList::Iterator it = searchPaths.begin();
652 while (it != searchPaths.end()) {
653 QFileInfo fi((*it++) + "/" + heading + "rc");
654 if (fi.exists() && fi.lastModified() > datetime)
655 datetime = fi.lastModified();
656 }
657
658 return datetime;
659}
660
661static bool verifyKey( const QString &key )
662{
663 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) )
664 return FALSE;
665 return TRUE;
666}
667
668static inline QString groupKey( const QString &group, const QString &key )
669{
670 if ( group.endsWith( "/" ) || key.startsWith( "/" ) )
671 return group + key;
672 return group + "/" + key;
673}
674
675/*!
676 Inserts \a path into the settings search path. The semantics of \a
677 path depends on the system \a s.
678
679 When \a s is \e Windows and the execution environment is \e not
680 Windows the function does nothing. Similarly when \a s is \e Unix and
681 the execution environment is \e not Unix the function does nothing.
682
683 When \a s is \e Windows, and the execution environment is Windows, the
684 search path list will be used as the first subfolder of the "Software"
685 folder in the registry.
686
687 When reading settings the folders are searched forwards from the
688 first folder (listed below) to the last, returning the first
689 settings found, and ignoring any folders for which the user doesn't
690 have read permission.
691 \list 1
692 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
693 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
694 \i HKEY_CURRENT_USER/Software/MyApplication
695 \i HKEY_LOCAL_MACHINE/Software/MyApplication
696 \endlist
697
698 \code
699 QSettings settings;
700 settings.insertSearchPath( QSettings::Windows, "/MyCompany" );
701 settings.writeEntry( "/MyApplication/Tip of the day", TRUE );
702 \endcode
703 The code above will write the subkey "Tip of the day" into the \e
704 first of the registry folders listed below that is found and for
705 which the user has write permission.
706 \list 1
707 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
708 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
709 \i HKEY_LOCAL_MACHINE/Software/MyApplication
710 \i HKEY_CURRENT_USER/Software/MyApplication
711 \endlist
712 If a setting is found in the HKEY_CURRENT_USER space, this setting
713 is overwritten independently of write permissions in the
714 HKEY_LOCAL_MACHINE space.
715
716 When \a s is \e Unix, and the execution environment is Unix, the
717 search path list will be used when trying to determine a suitable
718 filename for reading and writing settings files. By default, there are
719 two entries in the search path:
720
721 \list 1
722 \i INSTALL/etc - where \c INSTALL is the directory where Qt was installed.
723 \i $HOME/.qt/ - where \c $HOME is the user's home directory.
724 \endlist
725
726 All insertions into the search path will go before $HOME/.qt/.
727 For example:
728 \code
729 QSettings settings;
730 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/etc" );
731 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/MyApplication/etc" );
732 // ...
733 \endcode
734 Will result in a search path of:
735 \list 1
736 \i INSTALL/etc
737 \i /opt/MyCompany/share/etc
738 \i /opt/MyCompany/share/MyApplication/etc
739 \i $HOME/.qt
740 \endlist
741 When reading settings the files are searched in the order shown
742 above, with later settings overriding earlier settings. Files for
743 which the user doesn't have read permission are ignored. When saving
744 settings QSettings works in the order shown above, writing
745 to the first settings file for which the user has write permission.
746
747 Settings under Unix are stored in files whose names are based on the
748 first subkey of the key (not including the search path). The algorithm
749 for creating names is essentially: lowercase the first subkey, replace
750 spaces with underscores and add 'rc', e.g.
751 <tt>/MyCompany/MyApplication/background color</tt> will be stored in
752 <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of
753 the search path).
754
755 \sa removeSearchPath()
756
757*/
758void QSettings::insertSearchPath( System s, const QString &path)
759{
760#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
761 if ( d->sysd ) {
762 d->sysInsertSearchPath( s, path );
763 return;
764 }
765#endif
766
767 if ( !verifyKey( path ) ) {
768#if defined(QT_CHECK_STATE)
769 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
770#endif
771 return;
772 }
773
774#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
775 if ( d->sysd && s != Unix ) {
776#else
777 if ( s != Unix ) {
778#endif
779#ifdef Q_OS_MAC
780 if(s != Mac) //mac is respected on the mac as well
781#endif
782 return;
783 }
784
785 QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last());
786 if (it != d->searchPaths.end()) {
787 d->searchPaths.insert(it, path);
788 }
789}
790
791
792/*!
793 Removes all occurrences of \a path (using exact matching) from the
794 settings search path for system \a s. Note that the default search
795 paths cannot be removed.
796
797 \sa insertSearchPath()
798*/
799void QSettings::removeSearchPath( System s, const QString &path)
800{
801 if ( !verifyKey( path ) ) {
802#if defined(QT_CHECK_STATE)
803 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
804#endif
805 return;
806 }
807
808#ifdef Q_WS_WIN
809 if ( d->sysd ) {
810 d->sysRemoveSearchPath( s, path );
811 return;
812 }
813#endif
814#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
815 if ( d->sysd && s != Unix ) {
816#else
817 if ( s != Unix ) {
818#endif
819#ifdef Q_OS_MAC
820 if(s != Mac) //mac is respected on the mac as well
821#endif
822 return;
823 }
824
825 if (path == d->searchPaths.first() || path == d->searchPaths.last())
826 return;
827
828 d->searchPaths.remove(path);
829}
830
831
832/*!
833 Creates a settings object.
834*/
835QSettings::QSettings()
836{
837 d = new QSettingsPrivate( Native );
838 Q_CHECK_PTR(d);
839
840#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
841 d->sysd = 0;
842 d->sysInit();
843#endif
844}
845
846/*!
847 Creates a settings object. If \a format is 'Ini' the settings will
848 be stored in a text file, using the Unix strategy (see above). If \a format
849 is 'Native', the settings will be stored in a platform specific way
850 (ie. the Windows registry).
851*/
852QSettings::QSettings( Format format )
853{
854 d = new QSettingsPrivate( format );
855 Q_CHECK_PTR(d);
856
857#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
858 d->sysd = 0;
859 if ( format == Native )
860 d->sysInit();
861#else
862 Q_UNUSED(format);
863#endif
864}
865
866/*!
867 Destroys the settings object. All modifications made to the settings
868 will automatically be saved.
869
870*/
871QSettings::~QSettings()
872{
873 sync();
874
875#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
876 if ( d->sysd )
877 d->sysClear();
878#endif
879
880 delete d;
881}
882
883
884/*! \internal
885 Writes all modifications to the settings to disk. If any errors are
886 encountered, this function returns FALSE, otherwise it will return TRUE.
887*/
888bool QSettings::sync()
889{
890#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
891 if ( d->sysd )
892 return d->sysSync();
893#endif
894 if (! d->modified)
895 // fake success
896 return TRUE;
897
898 bool success = TRUE;
899 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
900
901 while (it != d->headings.end()) {
902 // determine filename
903 QSettingsHeading hd(*it);
904 QSettingsHeading::Iterator hdit = hd.begin();
905 QFile file;
906
907 QStringList::Iterator pit = d->searchPaths.begin();
908 while (pit != d->searchPaths.end()) {
909 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_");
910 QFileInfo di(*pit);
911 QFileInfo fi((*pit++) + "/" + filebase + "rc");
912
913 if ((fi.exists() && fi.isFile() && fi.isWritable()) ||
914 (! fi.exists() && di.isDir() && di.isWritable())) {
915 file.setName(fi.filePath());
916 break;
917 }
918 }
919
920 it++;
921
922 if (file.name().isNull() || file.name().isEmpty()) {
923
924#ifdef QT_CHECK_STATE
925 qWarning("QSettings::sync: filename is null/empty");
926#endif // QT_CHECK_STATE
927
928 success = FALSE;
929 continue;
930 }
931
932 HANDLE lockfd = openlock( file.name(), Q_LOCKWRITE );
933
934 if (! file.open(IO_WriteOnly)) {
935
936#ifdef QT_CHECK_STATE
937 qWarning("QSettings::sync: failed to open '%s' for writing",
938 file.name().latin1());
939#endif // QT_CHECK_STATE
940
941 success = FALSE;
942 continue;
943 }
944
945 // spew to file
946 QTextStream stream(&file);
947 stream.setEncoding(QTextStream::UnicodeUTF8);
948
949 while (hdit != hd.end()) {
950 if ((*hdit).count() > 0) {
951 stream << "[" << hdit.key() << "]" << endl;
952
953 QSettingsGroup grp(*hdit);
954 QSettingsGroup::Iterator grpit = grp.begin();
955
956 while (grpit != grp.end()) {
957 QString v = grpit.data();
958 if ( v.isNull() ) {
959 v = "\\0"; // escape null string
960 } else {
961 v.replace("\\", "\\\\"); // escape backslash
962 v.replace("\n", "\\n"); // escape newlines
963 }
964
965 stream << grpit.key() << "=" << v << endl;
966 grpit++;
967 }
968
969 stream << endl;
970 }
971
972 hdit++;
973 }
974
975 if (file.status() != IO_Ok) {
976
977#ifdef QT_CHECK_STATE
978 qWarning("QSettings::sync: error at end of write");
979#endif // QT_CHECK_STATE
980
981 success = FALSE;
982 }
983
984 file.close();
985
986 closelock( lockfd );
987 }
988
989 d->modified = FALSE;
990
991 return success;
992}
993
994
995/*!
996 \fn bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) const
997
998 Reads the entry specified by \a key, and returns a bool, or the
999 default value, \a def, if the entry couldn't be read.
1000 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1001 otherwise.
1002
1003 \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry()
1004*/
1005
1006/*!
1007 \internal
1008*/
1009bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1010{
1011 if ( !verifyKey( key ) ) {
1012#if defined(QT_CHECK_STATE)
1013 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1014#endif
1015 if ( ok )
1016 *ok = FALSE;
1017
1018 return def;
1019 }
1020
1021 QString theKey = groupKey( group(), key );
1022#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1023 if ( d->sysd )
1024 return d->sysReadBoolEntry( theKey, def, ok );
1025#endif
1026
1027 QString value = readEntry( theKey, ( def ? "true" : "false" ), ok );
1028
1029 if (value.lower() == "true")
1030 return TRUE;
1031 else if (value.lower() == "false")
1032 return FALSE;
1033 else if (value == "1")
1034 return TRUE;
1035 else if (value == "0")
1036 return FALSE;
1037
1038 if (! value.isEmpty())
1039 qWarning("QSettings::readBoolEntry: '%s' is not 'true' or 'false'",
1040 value.latin1());
1041 if ( ok )
1042 *ok = FALSE;
1043 return def;
1044}
1045
1046
1047/*!
1048 \fn double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) const
1049
1050 Reads the entry specified by \a key, and returns a double, or the
1051 default value, \a def, if the entry couldn't be read.
1052 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1053 otherwise.
1054
1055 \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry()
1056*/
1057
1058/*!
1059 \internal
1060*/
1061double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1062{
1063 if ( !verifyKey( key ) ) {
1064#if defined(QT_CHECK_STATE)
1065 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1066#endif
1067 if ( ok )
1068 *ok = FALSE;
1069
1070 return def;
1071 }
1072
1073 QString theKey = groupKey( group(), key );
1074#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1075 if ( d->sysd )
1076 return d->sysReadDoubleEntry( theKey, def, ok );
1077#endif
1078
1079 QString value = readEntry( theKey, QString::number(def), ok );
1080 bool conv_ok;
1081 double retval = value.toDouble( &conv_ok );
1082 if ( conv_ok )
1083 return retval;
1084 if ( ! value.isEmpty() )
1085 qWarning( "QSettings::readDoubleEntry: '%s' is not a number",
1086 value.latin1() );
1087 if ( ok )
1088 *ok = FALSE;
1089 return def;
1090}
1091
1092
1093/*!
1094 \fn int QSettings::readNumEntry(const QString &key, int def, bool *ok ) const
1095
1096 Reads the entry specified by \a key, and returns an integer, or the
1097 default value, \a def, if the entry couldn't be read.
1098 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1099 otherwise.
1100
1101 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
1102*/
1103
1104/*!
1105 \internal
1106*/
1107int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1108{
1109 if ( !verifyKey( key ) ) {
1110#if defined(QT_CHECK_STATE)
1111 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1112#endif
1113 if ( ok )
1114 *ok = FALSE;
1115 return def;
1116 }
1117
1118 QString theKey = groupKey( group(), key );
1119
1120#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1121 if ( d->sysd )
1122 return d->sysReadNumEntry( theKey, def, ok );
1123#endif
1124
1125 QString value = readEntry( theKey, QString::number( def ), ok );
1126 bool conv_ok;
1127 int retval = value.toInt( &conv_ok );
1128 if ( conv_ok )
1129 return retval;
1130 if ( ! value.isEmpty() )
1131 qWarning( "QSettings::readNumEntry: '%s' is not a number",
1132 value.latin1() );
1133 if ( ok )
1134 *ok = FALSE;
1135 return def;
1136}
1137
1138
1139/*!
1140 \fn QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) const
1141
1142 Reads the entry specified by \a key, and returns a QString, or the
1143 default value, \a def, if the entry couldn't be read.
1144 If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
1145 otherwise.
1146
1147 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
1148*/
1149
1150/*!
1151 \internal
1152*/
1153QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1154{
1155 if ( !verifyKey( key ) ) {
1156#if defined(QT_CHECK_STATE)
1157 qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1158#endif
1159 if ( ok )
1160 *ok = FALSE;
1161
1162 return def;
1163 }
1164
1165 QString theKey = groupKey( group(), key );
1166
1167#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1168 if ( d->sysd )
1169 return d->sysReadEntry( theKey, def, ok );
1170#endif
1171
1172 if ( ok ) // no, everything is not ok
1173 *ok = FALSE;
1174
1175 QString realkey;
1176
1177 if (theKey[0] == '/') {
1178 // parse our key
1179 QStringList list(QStringList::split('/', theKey));
1180
1181 if (list.count() < 2) {
1182#ifdef QT_CHECK_STATE
1183 qWarning("QSettings::readEntry: invalid key '%s'", theKey.latin1());
1184#endif // QT_CHECK_STATE
1185 if ( ok )
1186 *ok = FALSE;
1187 return def;
1188 }
1189
1190 if (list.count() == 2) {
1191 d->heading = list[0];
1192 d->group = "General";
1193 realkey = list[1];
1194 } else {
1195 d->heading = list[0];
1196 d->group = list[1];
1197
1198 // remove the group from the list
1199 list.remove(list.at(1));
1200 // remove the heading from the list
1201 list.remove(list.at(0));
1202
1203 realkey = list.join("/");
1204 }
1205 } else
1206 realkey = theKey;
1207
1208 QSettingsGroup grp = d->readGroup();
1209 QString retval = grp[realkey];
1210 if ( retval.isNull() )
1211 retval = def;
1212 else if ( ok ) // everything is ok
1213 *ok = TRUE;
1214 return retval;
1215}
1216
1217
1218#if !defined(Q_NO_BOOL_TYPE)
1219/*!
1220 Writes the boolean entry \a value into key \a key. The \a key is
1221 created if it doesn't exist. Any previous value is overwritten by \a
1222 value.
1223
1224 If an error occurs the settings are left unchanged and FALSE is
1225 returned; otherwise TRUE is returned.
1226
1227 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1228*/
1229bool QSettings::writeEntry(const QString &key, bool value)
1230{
1231 if ( !verifyKey( key ) ) {
1232#if defined(QT_CHECK_STATE)
1233 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1234#endif
1235 return FALSE;
1236 }
1237
1238 QString theKey = groupKey( group(), key );
1239
1240#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1241 if ( d->sysd )
1242 return d->sysWriteEntry( theKey, value );
1243#endif
1244 QString s(value ? "true" : "false");
1245 return writeEntry(theKey, s);
1246}
1247#endif
1248
1249
1250/*!
1251 \overload
1252 Writes the double entry \a value into key \a key. The \a key is
1253 created if it doesn't exist. Any previous value is overwritten by \a
1254 value.
1255
1256 If an error occurs the settings are left unchanged and FALSE is
1257 returned; otherwise TRUE is returned.
1258
1259 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1260*/
1261bool QSettings::writeEntry(const QString &key, double value)
1262{
1263 if ( !verifyKey( key ) ) {
1264#if defined(QT_CHECK_STATE)
1265 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1266#endif
1267 return FALSE;
1268 }
1269
1270 QString theKey = groupKey( group(), key );
1271
1272#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1273 if ( d->sysd )
1274 return d->sysWriteEntry( theKey, value );
1275#endif
1276 QString s(QString::number(value));
1277 return writeEntry(theKey, s);
1278}
1279
1280
1281/*!
1282 \overload
1283 Writes the integer entry \a value into key \a key. The \a key is
1284 created if it doesn't exist. Any previous value is overwritten by \a
1285 value.
1286
1287 If an error occurs the settings are left unchanged and FALSE is
1288 returned; otherwise TRUE is returned.
1289
1290 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1291*/
1292bool QSettings::writeEntry(const QString &key, int value)
1293{
1294 if ( !verifyKey( key ) ) {
1295#if defined(QT_CHECK_STATE)
1296 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1297#endif
1298 return FALSE;
1299 }
1300
1301 QString theKey = groupKey( group(), key );
1302
1303#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1304 if ( d->sysd )
1305 return d->sysWriteEntry( theKey, value );
1306#endif
1307 QString s(QString::number(value));
1308 return writeEntry(theKey, s);
1309}
1310
1311
1312/*!
1313 \internal
1314
1315 Writes the entry specified by \a key with the string-literal \a value,
1316 replacing any previous setting. If \a value is zero-length or null, the
1317 entry is replaced by an empty setting.
1318
1319 \e NOTE: This function is provided because some compilers use the
1320 writeEntry (const QString &, bool) overload for this code:
1321 writeEntry ("/foo/bar", "baz")
1322
1323 If an error occurs, this functions returns FALSE and the object is left
1324 unchanged.
1325
1326 \sa readEntry(), removeEntry()
1327*/
1328bool QSettings::writeEntry(const QString &key, const char *value)
1329{
1330 if ( !verifyKey( key ) ) {
1331#if defined(QT_CHECK_STATE)
1332 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1333#endif
1334 return FALSE;
1335 }
1336
1337 QString theKey = groupKey( group(), key );
1338
1339 return writeEntry(theKey, QString(value));
1340}
1341
1342
1343/*!
1344 \overload
1345 Writes the string entry \a value into key \a key. The \a key is
1346 created if it doesn't exist. Any previous value is overwritten by \a
1347 value. If \a value is an empty string or a null string the key's
1348 value will be an empty string.
1349
1350 If an error occurs the settings are left unchanged and FALSE is
1351 returned; otherwise TRUE is returned.
1352
1353 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1354*/
1355bool QSettings::writeEntry(const QString &key, const QString &value)
1356{
1357 if ( !verifyKey( key ) ) {
1358#if defined(QT_CHECK_STATE)
1359 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1360#endif
1361 return FALSE;
1362 }
1363
1364 QString theKey = groupKey( group(), key );
1365
1366#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1367 if ( d->sysd )
1368 return d->sysWriteEntry( theKey, value );
1369#endif
1370 // NOTE: we *do* allow value to be a null/empty string
1371
1372 QString realkey;
1373
1374 if (theKey[0] == '/') {
1375 // parse our key
1376 QStringList list(QStringList::split('/', theKey));
1377
1378 if (list.count() < 2) {
1379#ifdef QT_CHECK_STATE
1380 qWarning("QSettings::writeEntry: invalid key '%s'", theKey.latin1());
1381#endif // QT_CHECK_STATE
1382
1383 return FALSE;
1384 }
1385
1386 if (list.count() == 2) {
1387 d->heading = list[0];
1388 d->group = "General";
1389 realkey = list[1];
1390 } else {
1391 d->heading = list[0];
1392 d->group = list[1];
1393
1394 // remove the group from the list
1395 list.remove(list.at(1));
1396 // remove the heading from the list
1397 list.remove(list.at(0));
1398
1399 realkey = list.join("/");
1400 }
1401 } else
1402 realkey = theKey;
1403
1404 d->writeGroup(realkey, value);
1405 return TRUE;
1406}
1407
1408
1409/*!
1410 Removes the entry specified by \a key.
1411
1412 Returns TRUE if the entry existed and was removed; otherwise returns FALSE.
1413
1414 \sa readEntry(), writeEntry()
1415*/
1416bool QSettings::removeEntry(const QString &key)
1417{
1418 if ( !verifyKey( key ) ) {
1419#if defined(QT_CHECK_STATE)
1420 qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1421#endif
1422 return FALSE;
1423 }
1424
1425 QString theKey = groupKey( group(), key );
1426
1427#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1428 if ( d->sysd )
1429 return d->sysRemoveEntry( theKey );
1430#endif
1431
1432 QString realkey;
1433
1434 if (theKey[0] == '/') {
1435 // parse our key
1436 QStringList list(QStringList::split('/', theKey));
1437
1438 if (list.count() < 2) {
1439#ifdef QT_CHECK_STATE
1440 qWarning("QSettings::removeEntry: invalid key '%s'", theKey.latin1());
1441#endif // QT_CHECK_STATE
1442
1443 return FALSE;
1444 }
1445
1446 if (list.count() == 2) {
1447 d->heading = list[0];
1448 d->group = "General";
1449 realkey = list[1];
1450 } else {
1451 d->heading = list[0];
1452 d->group = list[1];
1453
1454 // remove the group from the list
1455 list.remove(list.at(1));
1456 // remove the heading from the list
1457 list.remove(list.at(0));
1458
1459 realkey = list.join("/");
1460 }
1461 } else
1462 realkey = theKey;
1463
1464 d->removeGroup(realkey);
1465 return TRUE;
1466}
1467
1468
1469/*!
1470 Returns a list of the keys which contain entries under \a key. Does \e
1471 not return any keys that contain keys.
1472
1473 Example settings:
1474 \code
1475 /MyCompany/MyApplication/background color
1476 /MyCompany/MyApplication/foreground color
1477 /MyCompany/MyApplication/geometry/x
1478 /MyCompany/MyApplication/geometry/y
1479 /MyCompany/MyApplication/geometry/width
1480 /MyCompany/MyApplication/geometry/height
1481 \endcode
1482 \code
1483 QStringList keys = entryList( "/MyCompany/MyApplication" );
1484 \endcode
1485 \c keys contains 'background color' and 'foreground color'. It does
1486 not contain 'geometry' because this key contains keys not entries.
1487
1488 To access the geometry values could either use subkeyList() to read
1489 the keys and then read each entry, or simply read each entry
1490 directly by specifying its full key, e.g.
1491 "/MyCompany/MyApplication/geometry/y".
1492
1493 \sa subkeyList()
1494*/
1495QStringList QSettings::entryList(const QString &key) const
1496{
1497 if ( !verifyKey( key ) ) {
1498#if defined(QT_CHECK_STATE)
1499 qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() );
1500#endif
1501 return QStringList();
1502 }
1503
1504 QString theKey = groupKey( group(), key );
1505
1506#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1507 if ( d->sysd )
1508 return d->sysEntryList( theKey );
1509#endif
1510
1511 QString realkey;
1512 if (theKey[0] == '/') {
1513 // parse our key
1514 QStringList list(QStringList::split('/', theKey));
1515
1516 if (list.count() < 1) {
1517#ifdef QT_CHECK_STATE
1518 qWarning("QSettings::listEntries: invalid key '%s'", theKey.latin1());
1519#endif // QT_CHECK_STATE
1520
1521 return QStringList();
1522 }
1523
1524 if (list.count() == 1) {
1525 d->heading = list[0];
1526 d->group = "General";
1527 } else {
1528 d->heading = list[0];
1529 d->group = list[1];
1530
1531 // remove the group from the list
1532 list.remove(list.at(1));
1533 // remove the heading from the list
1534 list.remove(list.at(0));
1535
1536 realkey = list.join("/");
1537 }
1538 } else
1539 realkey = theKey;
1540
1541 QSettingsGroup grp = d->readGroup();
1542 QSettingsGroup::Iterator it = grp.begin();
1543 QStringList ret;
1544 QString itkey;
1545 while (it != grp.end()) {
1546 itkey = it.key();
1547 it++;
1548
1549 if ( realkey.length() > 0 ) {
1550 if ( itkey.left( realkey.length() ) != realkey )
1551 continue;
1552 else
1553 itkey.remove( 0, realkey.length() + 1 );
1554 }
1555
1556 if ( itkey.find( '/' ) != -1 )
1557 continue;
1558
1559 ret << itkey;
1560 }
1561
1562 return ret;
1563}
1564
1565
1566/*!
1567 Returns a list of the keys which contain keys under \a key. Does \e
1568 not return any keys that contain entries.
1569
1570 Example settings:
1571 \code
1572 /MyCompany/MyApplication/background color
1573 /MyCompany/MyApplication/foreground color
1574 /MyCompany/MyApplication/geometry/x
1575 /MyCompany/MyApplication/geometry/y
1576 /MyCompany/MyApplication/geometry/width
1577 /MyCompany/MyApplication/geometry/height
1578 /MyCompany/MyApplication/recent files/1
1579 /MyCompany/MyApplication/recent files/2
1580 /MyCompany/MyApplication/recent files/3
1581 \endcode
1582 \code
1583 QStringList keys = subkeyList( "/MyCompany/MyApplication" );
1584 \endcode
1585 \c keys contains 'geometry' and 'recent files'. It does not contain
1586 'background color' or 'foreground color' because they are keys which
1587 contain entries not keys. To get a list of keys that have values
1588 rather than subkeys use entryList().
1589
1590 \sa entryList()
1591*/
1592QStringList QSettings::subkeyList(const QString &key) const
1593{
1594 if ( !verifyKey( key ) ) {
1595#if defined(QT_CHECK_STATE)
1596 qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() );
1597#endif
1598 return QStringList();
1599 }
1600
1601 QString theKey = groupKey( group(), key );
1602
1603#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1604 if ( d->sysd )
1605 return d->sysSubkeyList( theKey );
1606#endif
1607
1608 QString realkey;
1609 if (theKey[0] == '/') {
1610 // parse our key
1611 QStringList list(QStringList::split('/', theKey));
1612
1613 if (list.count() < 1) {
1614#ifdef QT_CHECK_STATE
1615 qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1());
1616#endif // QT_CHECK_STATE
1617
1618 return QStringList();
1619 }
1620
1621 if (list.count() == 1) {
1622 d->heading = list[0];
1623 d->group = "General";
1624 } else {
1625 d->heading = list[0];
1626 d->group = list[1];
1627
1628 // remove the group from the list
1629 list.remove(list.at(1));
1630 // remove the heading from the list
1631 list.remove(list.at(0));
1632
1633 realkey = list.join("/");
1634 }
1635 } else
1636 realkey = theKey;
1637
1638 QSettingsGroup grp = d->readGroup();
1639 QSettingsGroup::Iterator it = grp.begin();
1640 QStringList ret;
1641 QString itkey;
1642 while (it != grp.end()) {
1643 itkey = it.key();
1644 it++;
1645
1646 if ( realkey.length() > 0 ) {
1647 if ( itkey.left( realkey.length() ) != realkey )
1648 continue;
1649 else
1650 itkey.remove( 0, realkey.length() + 1 );
1651 }
1652
1653 int slash = itkey.find( '/' );
1654 if ( slash == -1 )
1655 continue;
1656 itkey.truncate( slash );
1657
1658 if ( ! ret.contains( itkey ) )
1659 ret << itkey;
1660 }
1661
1662 return ret;
1663}
1664
1665
1666/*!
1667 \internal
1668
1669 This function returns the time of last modification for \a key.
1670*/
1671QDateTime QSettings::lastModficationTime(const QString &key)
1672{
1673 if ( !verifyKey( key ) ) {
1674#if defined(QT_CHECK_STATE)
1675 qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1676#endif
1677 return QDateTime();
1678 }
1679
1680 QString theKey = groupKey( group(), key );
1681
1682#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1683 if ( d->sysd )
1684 return QDateTime();
1685#endif
1686
1687 if (theKey[0] == '/') {
1688 // parse our key
1689 QStringList list(QStringList::split('/', theKey));
1690
1691 if (list.count() < 2) {
1692#ifdef QT_CHECK_STATE
1693 qWarning("QSettings::lastModficationTime: invalid key '%s'", theKey.latin1());
1694#endif // QT_CHECK_STATE
1695
1696 return QDateTime();
1697 }
1698
1699 if (list.count() == 2) {
1700 d->heading = list[0];
1701 d->group = "General";
1702 } else {
1703 d->heading = list[0];
1704 d->group = list[1];
1705 }
1706 }
1707
1708 return d->modificationTime();
1709}
1710
1711
1712/*!
1713 \overload
1714
1715 Writes the string list entry \a value into key \a key. The \a key
1716 is created if it doesn't exist. Any previous value is overwritten
1717 by \a value. The list is stored as a sequence of strings separated
1718 by \a separator, so none of the strings in the list should contain
1719 the separator. If the list is empty or null the key's value will
1720 be an empty string.
1721
1722 If an error occurs the settings are left unchanged and FALSE is
1723 returned; otherwise returns TRUE.
1724
1725 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1726*/
1727bool QSettings::writeEntry(const QString &key, const QStringList &value,
1728 const QChar &separator)
1729{
1730 QString s(value.join(separator));
1731 return writeEntry(key, s);
1732}
1733
1734/*!
1735 \overload
1736
1737 Writes the string list entry \a value into key \a key. The \a key
1738 is created if it doesn't exist. Any previous value is overwritten
1739 by \a value.
1740
1741 If an error occurs the settings are left unchanged and FALSE is
1742 returned; otherwise returns TRUE.
1743
1744 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1745*/
1746bool QSettings::writeEntry(const QString &key, const QStringList &value)
1747{
1748 QString s;
1749 for (QStringList::ConstIterator it=value.begin(); it!=value.end(); ++it) {
1750 QString el = *it;
1751 if ( el.isNull() ) {
1752 el = "^0";
1753 } else {
1754 el.replace("^", "^^");
1755 }
1756 s+=el;
1757 s+="^e"; // end of element
1758 }
1759 return writeEntry(key, s);
1760}
1761
1762
1763/*!
1764 \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const
1765
1766 Reads the entry specified by \a key as a string. The \a separator
1767 is used to create a QStringList by calling QStringList::split(\a
1768 separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the
1769 key was read, otherwise \a *ok is set to FALSE.
1770
1771 Note that if you want to iterate over the list, you should iterate
1772 over a copy, e.g.
1773 \code
1774 QStringList list = mySettings.readListEntry( "size", " " );
1775 QStringList::Iterator it = list.begin();
1776 while( it != list.end() ) {
1777 myProcessing( *it );
1778 ++it;
1779 }
1780 \endcode
1781
1782 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), QStringList::split()
1783*/
1784
1785/*!
1786 \internal
1787*/
1788QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok )
1789{
1790 QString value = readEntry( key, QString::null, ok );
1791 if ( ok && !*ok )
1792 return QStringList();
1793
1794 return QStringList::split(separator, value);
1795}
1796
1797/*!
1798 \fn QStringList QSettings::readListEntry(const QString &key, bool *ok ) const
1799 Reads the entry specified by \a key as a string. If \a ok is not
1800 0, \a *ok is set to TRUE if the key was read, otherwise \a *ok is
1801 set to FALSE.
1802
1803 Note that if you want to iterate over the list, you should iterate
1804 over a copy, e.g.
1805 \code
1806 QStringList list = mySettings.readListEntry( "recentfiles" );
1807 QStringList::Iterator it = list.begin();
1808 while( it != list.end() ) {
1809 myProcessing( *it );
1810 ++it;
1811 }
1812 \endcode
1813
1814 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), QStringList::split()
1815*/
1816
1817/*!
1818 \internal
1819*/
1820QStringList QSettings::readListEntry(const QString &key, bool *ok )
1821{
1822 QString value = readEntry( key, QString::null, ok );
1823 if ( ok && !*ok )
1824 return QStringList();
1825 QStringList l;
1826 QString s;
1827 bool esc=FALSE;
1828 for (int i=0; i<(int)value.length(); i++) {
1829 if ( esc ) {
1830 if ( value[i] == 'e' ) { // end-of-string
1831 l.append(s);
1832 s="";
1833 } else if ( value[i] == '0' ) { // null string
1834 s=QString::null;
1835 } else {
1836 s.append(value[i]);
1837 }
1838 esc=FALSE;
1839 } else if ( value[i] == '^' ) {
1840 esc = TRUE;
1841 } else {
1842 s.append(value[i]);
1843 if ( i == (int)value.length()-1 )
1844 l.append(s);
1845 }
1846 }
1847 return l;
1848}
1849
1850/*!
1851 Insert platform-dependent paths from platform-independent information.
1852
1853 The \a domain should be an Internet domain name
1854 controlled by the producer of the software, eg. Trolltech products
1855 use "trolltech.com".
1856
1857 The \a product should be the official name of the product.
1858
1859 The \a scope should be
1860 QSettings::User for user-specific settings, or
1861 QSettings::Global for system-wide settings (generally
1862 these will be read-only to many users).
1863*/
1864
1865void QSettings::setPath( const QString &domain, const QString &product, Scope scope )
1866{
1867// On Windows, any trailing ".com(\..*)" is stripped from the domain. The
1868// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to
1869// HKEY_CURRENT_USER. Note that on some installations, not all users can
1870// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped
1871// from the domain. The Global scope corresponds to "/opt" (this would be
1872// configurable at library build time - eg. to "/usr/local" or "/usr"),
1873// while the User scope corresponds to $HOME/.*rc.
1874// Note that on most installations, not all users can write to the System
1875// scope.
1876//
1877// On MacOS X, if there is no "." in domain, append ".com", then reverse the
1878// order of the elements (Mac OS uses "com.apple.finder" as domain+product).
1879// The Global scope corresponds to /Library/Preferences/*.plist, while the
1880// User scope corresponds to ~/Library/Preferences/*.plist.
1881// Note that on most installations, not all users can write to the System
1882// scope.
1883 QString actualSearchPath;
1884 int lastDot = domain.findRev( '.' );
1885
1886#if defined(Q_WS_WIN)
1887 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1888 insertSearchPath( Windows, actualSearchPath );
1889#elif defined(Q_WS_MAC)
1890 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + ".";
1891 if ( topLevelDomain.isEmpty() )
1892 topLevelDomain = "com.";
1893 actualSearchPath = "/" + topLevelDomain + domain.left( lastDot ) + product;
1894 insertSearchPath( Mac, actualSearchPath );
1895#else
1896 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1897 insertSearchPath( Unix, actualSearchPath );
1898#endif
1899
1900 d->globalScope = scope == Global;
1901}
1902
1903/*!
1904 Appends \a group to the current key prefix.
1905*/
1906void QSettings::beginGroup( const QString &group )
1907{
1908 d->groupStack.push( group );
1909 d->groupDirty = TRUE;
1910}
1911
1912/*!
1913 Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone
1914 by a single call to endGroup().
1915*/
1916void QSettings::endGroup()
1917{
1918 d->groupStack.pop();
1919 d->groupDirty = TRUE;
1920}
1921
1922/*!
1923 Set the current key prefix to the empty string.
1924*/
1925void QSettings::resetGroup()
1926{
1927 d->groupStack.clear();
1928 d->groupDirty = FALSE;
1929 d->groupPrefix = QString::null;
1930}
1931
1932/*!
1933 Returns the current key prefix, or a null string if there is no key prefix set.
1934
1935 \sa beginGroup();
1936*/
1937QString QSettings::group() const
1938{
1939 if ( d->groupDirty ) {
1940 d->groupDirty = FALSE;
1941 d->groupPrefix = QString::null;
1942
1943 QValueStack<QString>::Iterator it = d->groupStack.begin();
1944 while ( it != d->groupStack.end() ) {
1945 QString group = *it;
1946 ++it;
1947 if ( group[0] != '/' )
1948 group = "/" + group;
1949 d->groupPrefix += group;
1950 }
1951 }
1952 return d->groupPrefix;
1953}
1954
1955#endif
diff --git a/qmake/tools/qstring.cpp b/qmake/tools/qstring.cpp
new file mode 100644
index 0000000..56df62b
--- a/dev/null
+++ b/qmake/tools/qstring.cpp
@@ -0,0 +1,17867 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of the QString class and related Unicode functions
5**
6** Created : 920722
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38// Don't define it while compiling this module, or USERS of Qt will
39// not be able to link.
40#ifdef QT_NO_CAST_ASCII
41#undef QT_NO_CAST_ASCII
42#endif
43
44#include "qstring.h"
45#include "qregexp.h"
46#include "qdatastream.h"
47#ifndef QT_NO_TEXTCODEC
48#include "qtextcodec.h"
49#endif
50#include <ctype.h>
51#include <limits.h>
52#include <stdarg.h>
53#include <stdio.h>
54#include <stdlib.h>
55#if defined(Q_WS_WIN)
56#include "qt_windows.h"
57#endif
58#if !defined( QT_NO_COMPONENT ) && !defined( QT_LITE_COMPONENT )
59#include "qcleanuphandler.h"
60#endif
61
62
63/* -------------------------------------------------------------------------
64 * unicode information
65 * these tables are generated from the unicode reference file
66 * ftp://ftp.unicode.org/Public/3.2-Update/UnicodeData.txt
67 *
68 * Lars
69 * -------------------------------------------------------------------------
70 */
71
72/* Perl script to generate (run perl -x tools/qstring.cpp)
73
74#!perl
75
76sub numberize
77{
78 my(%r, $n, $id);
79 for $id ( @_ ) {
80 $i = $id;
81 $i="" if $i eq "EMPTY";
82 $r{$i}=$n++;
83 }
84 return %r;
85}
86
87
88sub readUnicodeDataLine {
89 $code = shift @_;
90 for $n (qw{
91 name category combining_class bidi_category
92 character_decomposition decimal_digit_value digit_value
93 numeric_value mirrored oldname comment
94 uppercase lowercase titlecase})
95 {
96 $id = shift @_;
97 $codes = "${n}_code";
98 if ( defined %$codes && defined $$codes{$id} ) {
99 $id = $$codes{$id};
100 }
101 ${$n}{$code}=$id;
102 }
103 $decomp = $character_decomposition{$code};
104 if ( length $decomp == 0 ) {
105 $decomp = "<single>";
106 }
107 if (substr($decomp, 0, 1) ne '<') {
108 $decomp = "<canonical> " . $decomp;
109 }
110 @_ = split(" ", $decomp);
111 $tag = shift @_;
112 $tag = $character_decomposition_tag{$tag};
113 $decomp = join( ", 0x", @_ );
114 $decomp = "0x".$decomp;
115 $decomposition{$code} = $decomp;
116 $decomposition_tag{$code} = $tag;
117 $decomposition_pos{$code} = $position;
118 $len = scalar(@_);
119 $decomposition_len{$code} = $len;
120
121# we use canonical decompositions longer than 1 char
122# we exlude Arabic ligatures from the table
123 if($len > 1 and $tag == 1) {
124# ligature to add...
125 $start = shift @_;
126 $ligature{$start} = $ligature{$start}." ".$code;
127 }
128
129# adjust position
130 if($len != 0) {
131 $position += $len + 3;
132 }
133}
134
135
136# Code to integer mappings...
137#
138%category_code = numberize(qw{
139 EMPTY
140 Mn Mc Me
141 Nd Nl No
142 Zs Zl Zp
143 Cc Cf Cs Co Cn
144
145 Lu Ll Lt Lm Lo
146 Pc Pd Ps Pe Pi Pf Po
147 Sm Sc Sk So
148});
149%bidi_category_code = numberize(qw{
150 L R EN ES ET AN CS B S WS ON LRE LRO AL RLE RLO PDF NSM BN});
151%character_decomposition_tag = numberize(qw{
152 <single> <canonical> <font> <noBreak> <initial> <medial>
153 <final> <isolated> <circle> <super> <sub> <vertical>
154 <wide> <narrow> <small> <square> <compat> <fraction>
155});
156%mirrored_code = numberize(qw{N Y});
157
158%joining_code = numberize(qw{U D R C});
159
160# Read data into hashes...
161#
162open IN, "UnicodeData.txt";
163$position = 1;
164while (<IN>) {
165 @fields = split /;/;
166 if ( length($fields[0]) < 5 ) {
167 if ( $fields[1] =~ /, First>/ ) {
168 $codeRangeBegin = $fields[0];
169 } elsif ( $fields[1] =~ /, Last>/ ) {
170 for ( $i=hex($codeRangeBegin); $i<=hex($fields[0]); $i+=1 ) {
171 @fields2 = @fields;
172 $fields2[0] = sprintf "%lX", $i;
173 readUnicodeDataLine @fields2;
174 }
175 } else {
176 readUnicodeDataLine @fields;
177 }
178 }
179}
180
181open IN2, "ArabicShaping.txt";
182$position = 1;
183while (<IN2>) {
184 @fields = split /;/;
185 $code = shift @fields;
186 $dummy = shift @fields;
187 $join = shift @fields;
188 $join =~ s/ //g;
189 $join = $joining_code{$join};
190 $joining{$code}=$join;
191}
192
193# Build pages...
194#
195$rowtable_txt =
196 "static const Q_UINT8 * const unicode_info[256] = {";
197for $row ( 0..255 ) {
198 $nonzero=0;
199 $txt = "";
200 for $cell ( 0..255 ) {
201 $code = sprintf("%02X%02X",$row,$cell);
202 $info = $category{$code};
203 $info = 0 if !defined $info;
204 $txt .= "\n " if $cell%8 == 0;
205 $txt .= "$info, ";
206 }
207 $therow = $row{$txt};
208 if ( !defined $therow ) {
209 $size+=256;
210 $therow = "ui_".sprintf("%02X",$row);
211 $rowtext{$therow} =
212 "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
213 $row{$txt}=$therow;
214 }
215 $rowtable_txt .= "\n " if $row%8 == 0;
216 $rowtable_txt .= "$therow, ";
217}
218
219print "// START OF GENERATED DATA\n\n";
220print "#ifndef QT_NO_UNICODETABLES\n\n";
221
222# Print pages...
223#
224for $r ( sort keys %rowtext ) {
225 print $rowtext{$r};
226}
227print "$rowtable_txt\n};\n";
228$size += 256*4;
229print "// $size bytes\n\n";
230
231# Build decomposition tables
232#
233$rowtable_txt =
234 "static const Q_UINT16 * const decomposition_info[256] = {";
235$table_txt =
236 "static const Q_UINT16 decomposition_map[] = {\n 0,\n";
237for $row ( 0..255 ) {
238 $nonzero=0;
239 $txt = "";
240 for $cell ( 0..255 ) {
241 $code = sprintf("%02X%02X",$row,$cell);
242 $txt .= "\n " if $cell%8 == 0;
243 if( $decomposition_tag{$code} != 0 ) {
244 $txt .= " $decomposition_pos{$code},";
245 $table_txt .= " $decomposition_tag{$code},";
246 $table_txt .= " 0x$code,";
247 $table_txt .= " $decomposition{$code}, 0,\n";
248 $size += 2 * $decomposition_len{$code} + 6;
249 } else {
250 $txt .= " 0,";
251 }
252 }
253 $therow = $row{$txt};
254 if ( !defined $therow ) {
255 $size+=512;
256 $therow = "di_".sprintf("%02X",$row);
257 $dec_rowtext{$therow} =
258 "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
259 $row{$txt}=$therow;
260 }
261 $rowtable_txt .= "\n " if $row%8 == 0;
262 $rowtable_txt .= "$therow, ";
263}
264
265# Print decomposition tables
266#
267print "$table_txt\n};\n\n";
268for $r ( sort keys %dec_rowtext ) {
269 print $dec_rowtext{$r};
270}
271print "$rowtable_txt\n};\n";
272$size += 256*4;
273print "// $size bytes\n\n";
274
275
276# build ligature tables
277#
278$size = 0;
279$position = 1;
280$rowtable_txt =
281 "static const Q_UINT16 * const ligature_info[256] = {";
282$table_txt =
283 "static const Q_UINT16 ligature_map[] = {\n 0,\n";
284for $lig_row ( 0..255 ) {
285 $nonzero=0;
286 $txt = "";
287 for $cell ( 0..255 ) {
288 $code = sprintf("%02X%02X",$lig_row,$cell);
289 $txt .= "\n " if $cell%8 == 0;
290 if( defined $ligature{$code} ) {
291 $txt .= " $position,";
292 @ligature = split(" ", $ligature{$code});
293# we need to sort ligatures according to their length.
294# long ones have to come first!
295 @ligature_sort = sort { $decomposition_len{$b} <=> $decomposition_len{$a} } @ligature;
296# now replace each code by its position in
297# the decomposition map.
298 undef(@lig_pos);
299 for $n (@ligature_sort) {
300 push(@lig_pos, $decomposition_pos{$n});
301 }
302# debug info
303 if( 0 ) {
304 print "ligatures: $ligature{$code}\n";
305 $sort = join(" ", @ligature_sort);
306 print "sorted : $sort\n";
307 }
308 $lig = join(", ", @lig_pos);
309 $table_txt .= " $lig, 0,\n";
310 $size += 2 * scalar(@ligature) + 2;
311 $position += scalar(@ligature) + 1;
312 } else {
313 $txt .= " 0,";
314 }
315 }
316 $therow = $lig_row{$txt};
317 if ( !defined $therow ) {
318 $size+=512;
319 $therow = "li_".sprintf("%02X",$lig_row);
320 $lig_rowtext{$therow} =
321 "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
322 $lig_row{$txt}=$therow;
323 }
324 $rowtable_txt .= "\n " if $lig_row%8 == 0;
325 $rowtable_txt .= "$therow, ";
326}
327
328# Print ligature tables
329#
330print "$table_txt\n};\n\n";
331for $r ( sort keys %lig_rowtext ) {
332 print $lig_rowtext{$r};
333}
334print "$rowtable_txt\n};\n";
335$size += 256*4;
336print "// $size bytes\n\n";
337
338
339
340# Build direction/joining/mirrored pages...
341#
342$rowtable_txt =
343 "static const Q_UINT8 * const direction_info[256] = {";
344for $dir_row ( 0..255 ) {
345 $nonzero=0;
346 $txt = "";
347 for $cell ( 0..255 ) {
348 $code = sprintf("%02X%02X",$dir_row,$cell);
349 $dir = $bidi_category{$code};
350 $dir = 0 if !defined $dir;
351 $join = $joining{$code};
352 $join = 0 if !defined $join;
353 $mirr = $mirrored{$code};
354 $mirr = 0 if !defined $mirr;
355 $info = $dir + 32*$join + 128*$mirr;
356 $txt .= "\n " if $cell%8 == 0;
357 $txt .= "$info, ";
358 }
359 $therow = $dir_row{$txt};
360 if ( !defined $therow ) {
361 $size+=256;
362 $therow = "dir_".sprintf("%02X",$dir_row);
363 $dir_rowtext{$therow} =
364 "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
365 $dir_row{$txt}=$therow;
366 }
367 $rowtable_txt .= "\n " if $dir_row%8 == 0;
368 $rowtable_txt .= "$therow, ";
369}
370
371# Print pages...
372#
373for $r ( sort keys %dir_rowtext ) {
374 print $dir_rowtext{$r};
375}
376print "$rowtable_txt\n};\n";
377$size += 256*4;
378print "// $size bytes\n\n";
379
380# Build table of combining classes
381#
382$rowtable_txt =
383 "static const Q_UINT8 * const combining_info[256] = {";
384for $combining_row ( 0..255 ) {
385 $nonzero=0;
386 $txt = "";
387 for $cell ( 0..255 ) {
388 $code = sprintf("%02X%02X",$combining_row,$cell);
389 $info = $combining_class{$code};
390 $info = 0 if !defined $info;
391 $txt .= "\n " if $cell%8 == 0;
392 $txt .= "$info, ";
393 }
394 $therow = $combining_row{$txt};
395 if ( !defined $therow ) {
396 $size+=256;
397 $therow = "cmb_".sprintf("%02X",$combining_row);
398 $combining_rowtext{$therow} =
399 "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
400 $combining_row{$txt}=$therow;
401 }
402 $rowtable_txt .= "\n " if $combining_row%8 == 0;
403 $rowtable_txt .= "$therow, ";
404}
405
406# Print pages...
407#
408for $r ( sort keys %combining_rowtext ) {
409 print $combining_rowtext{$r};
410}
411print "$rowtable_txt\n};\n";
412$size += 256*4;
413print "// $size bytes\n\n";
414
415# Build case info
416#
417$rowtable_txt =
418 "static const Q_UINT16 * const case_info[256] = {";
419for $row ( 0..255 ) {
420 $nonzero=0;
421 $txt = "";
422 for $cell ( 0..255 ) {
423 $code = sprintf("%02X%02X",$row,$cell);
424 $info = $uppercase{$code};
425 if ( length( $info ) eq 0 ) {
426 $info = $lowercase{$code};
427 }
428 $info =~ s/^0+//;
429 if ( length( $info ) eq 0 ) {
430 $info = "0";
431 } else {
432 $info = "0x".lc($info);
433 }
434 if ( length( $info ) ne 1 ) {
435 $nonzero = 1;
436 }
437 $txt .= "\n " if $cell%8 == 0;
438 $txt .= "$info, ";
439 }
440 $therow = $case_row{$txt};
441 if ( !defined $therow && $nonzero ne 0 ) {
442 $size+=512;
443 $therow = "case_".sprintf("%02X",$row);
444 $case_rowtext{$therow} =
445 "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
446 $case_row{$txt}=$therow;
447 }
448 $rowtable_txt .= "\n " if $row%8 == 0;
449 if ( $nonzero ne 0 ) {
450 $rowtable_txt .= "$therow, ";
451 } else {
452 $rowtable_txt .= "0, ";
453 }
454}
455
456# Print pages...
457#
458for $r ( sort keys %case_rowtext ) {
459 print $case_rowtext{$r};
460}
461print "$rowtable_txt\n};\n";
462$size += 256*4;
463print "// $size bytes\n\n";
464
465# Build decimal info
466#
467$rowtable_txt =
468 "static const Q_INT8 * const decimal_info[256] = {";
469for $row ( 0..255 ) {
470 $nonzero=0;
471 $txt = "";
472 for $cell ( 0..255 ) {
473 $code = sprintf("%02X%02X",$row,$cell);
474 $info = $digit_value{$code};
475 if ( length( $info ) eq 0 ) {
476 $info = -1;
477 } else {
478 $nonzero = 1;
479 }
480 $txt .= "\n " if $cell%8 == 0;
481 $txt .= "$info, ";
482 }
483 $therow = $decimal_row{$txt};
484 if ( !defined $therow && $nonzero ne 0 ) {
485 $size+=512;
486 $therow = "num_".sprintf("%02X",$row);
487 $decimal_rowtext{$therow} =
488 "static const Q_INT8 ${therow}[] = {$txt\n};\n\n";
489 $decimal_row{$txt}=$therow;
490 }
491 $rowtable_txt .= "\n " if $row%8 == 0;
492 if ( $nonzero ne 0 ) {
493 $rowtable_txt .= "$therow, ";
494 } else {
495 $rowtable_txt .= "0, ";
496 }
497}
498
499# Print pages...
500#
501for $r ( sort keys %decimal_rowtext ) {
502 print $decimal_rowtext{$r};
503}
504print "$rowtable_txt\n};\n";
505$size += 256*4;
506print "// $size bytes\n\n";
507
508
509
510print "#endif\n\n";
511print "// END OF GENERATED DATA\n\n";
512
513
514
515__END__
516
517*/
518
519// START OF GENERATED DATA
520
521static const Q_UINT8 ui_00[] = {
522 10, 10, 10, 10, 10, 10, 10, 10,
523 10, 10, 10, 10, 10, 10, 10, 10,
524 10, 10, 10, 10, 10, 10, 10, 10,
525 10, 10, 10, 10, 10, 10, 10, 10,
526 7, 26, 26, 26, 28, 26, 26, 26,
527 22, 23, 26, 27, 26, 21, 26, 26,
528 4, 4, 4, 4, 4, 4, 4, 4,
529 4, 4, 26, 26, 27, 27, 27, 26,
530 26, 15, 15, 15, 15, 15, 15, 15,
531 15, 15, 15, 15, 15, 15, 15, 15,
532 15, 15, 15, 15, 15, 15, 15, 15,
533 15, 15, 15, 22, 26, 23, 29, 20,
534 29, 16, 16, 16, 16, 16, 16, 16,
535 16, 16, 16, 16, 16, 16, 16, 16,
536 16, 16, 16, 16, 16, 16, 16, 16,
537 16, 16, 16, 22, 27, 23, 27, 10,
538 10, 10, 10, 10, 10, 10, 10, 10,
539 10, 10, 10, 10, 10, 10, 10, 10,
540 10, 10, 10, 10, 10, 10, 10, 10,
541 10, 10, 10, 10, 10, 10, 10, 10,
542 7, 26, 28, 28, 28, 28, 30, 30,
543 29, 30, 16, 24, 27, 21, 30, 29,
544 30, 27, 6, 6, 29, 16, 30, 26,
545 29, 6, 16, 25, 6, 6, 6, 26,
546 15, 15, 15, 15, 15, 15, 15, 15,
547 15, 15, 15, 15, 15, 15, 15, 15,
548 15, 15, 15, 15, 15, 15, 15, 27,
549 15, 15, 15, 15, 15, 15, 15, 16,
550 16, 16, 16, 16, 16, 16, 16, 16,
551 16, 16, 16, 16, 16, 16, 16, 16,
552 16, 16, 16, 16, 16, 16, 16, 27,
553 16, 16, 16, 16, 16, 16, 16, 16,
554};
555
556#ifndef QT_NO_UNICODETABLES
557
558static const Q_UINT8 ui_01[] = {
559 15, 16, 15, 16, 15, 16, 15, 16,
560 15, 16, 15, 16, 15, 16, 15, 16,
561 15, 16, 15, 16, 15, 16, 15, 16,
562 15, 16, 15, 16, 15, 16, 15, 16,
563 15, 16, 15, 16, 15, 16, 15, 16,
564 15, 16, 15, 16, 15, 16, 15, 16,
565 15, 16, 15, 16, 15, 16, 15, 16,
566 16, 15, 16, 15, 16, 15, 16, 15,
567 16, 15, 16, 15, 16, 15, 16, 15,
568 16, 16, 15, 16, 15, 16, 15, 16,
569 15, 16, 15, 16, 15, 16, 15, 16,
570 15, 16, 15, 16, 15, 16, 15, 16,
571 15, 16, 15, 16, 15, 16, 15, 16,
572 15, 16, 15, 16, 15, 16, 15, 16,
573 15, 16, 15, 16, 15, 16, 15, 16,
574 15, 15, 16, 15, 16, 15, 16, 16,
575 16, 15, 15, 16, 15, 16, 15, 15,
576 16, 15, 15, 15, 16, 16, 15, 15,
577 15, 15, 16, 15, 15, 16, 15, 15,
578 15, 16, 16, 16, 15, 15, 16, 15,
579 15, 16, 15, 16, 15, 16, 15, 15,
580 16, 15, 16, 16, 15, 16, 15, 15,
581 16, 15, 15, 15, 16, 15, 16, 15,
582 15, 16, 16, 19, 15, 16, 16, 16,
583 19, 19, 19, 19, 15, 17, 16, 15,
584 17, 16, 15, 17, 16, 15, 16, 15,
585 16, 15, 16, 15, 16, 15, 16, 15,
586 16, 15, 16, 15, 16, 16, 15, 16,
587 15, 16, 15, 16, 15, 16, 15, 16,
588 15, 16, 15, 16, 15, 16, 15, 16,
589 16, 15, 17, 16, 15, 16, 15, 15,
590 15, 16, 15, 16, 15, 16, 15, 16,
591};
592
593static const Q_UINT8 ui_02[] = {
594 15, 16, 15, 16, 15, 16, 15, 16,
595 15, 16, 15, 16, 15, 16, 15, 16,
596 15, 16, 15, 16, 15, 16, 15, 16,
597 15, 16, 15, 16, 15, 16, 15, 16,
598 15, 0, 15, 16, 15, 16, 15, 16,
599 15, 16, 15, 16, 15, 16, 15, 16,
600 15, 16, 15, 16, 0, 0, 0, 0,
601 0, 0, 0, 0, 0, 0, 0, 0,
602 0, 0, 0, 0, 0, 0, 0, 0,
603 0, 0, 0, 0, 0, 0, 0, 0,
604 16, 16, 16, 16, 16, 16, 16, 16,
605 16, 16, 16, 16, 16, 16, 16, 16,
606 16, 16, 16, 16, 16, 16, 16, 16,
607 16, 16, 16, 16, 16, 16, 16, 16,
608 16, 16, 16, 16, 16, 16, 16, 16,
609 16, 16, 16, 16, 16, 16, 16, 16,
610 16, 16, 16, 16, 16, 16, 16, 16,
611 16, 16, 16, 16, 16, 16, 16, 16,
612 16, 16, 16, 16, 16, 16, 16, 16,
613 16, 16, 16, 16, 16, 16, 16, 16,
614 16, 16, 16, 16, 16, 16, 16, 16,
615 16, 16, 16, 16, 16, 16, 0, 0,
616 18, 18, 18, 18, 18, 18, 18, 18,
617 18, 29, 29, 18, 18, 18, 18, 18,
618 18, 18, 29, 29, 29, 29, 29, 29,
619 29, 29, 29, 29, 29, 29, 29, 29,
620 18, 18, 29, 29, 29, 29, 29, 29,
621 29, 29, 29, 29, 29, 29, 29, 29,
622 18, 18, 18, 18, 18, 29, 29, 29,
623 29, 29, 29, 29, 29, 29, 18, 0,
624 0, 0, 0, 0, 0, 0, 0, 0,
625 0, 0, 0, 0, 0, 0, 0, 0,
626};
627
628static const Q_UINT8 ui_03[] = {
629 1, 1, 1, 1, 1, 1, 1, 1,
630 1, 1, 1, 1, 1, 1, 1, 1,
631 1, 1, 1, 1, 1, 1, 1, 1,
632 1, 1, 1, 1, 1, 1, 1, 1,
633 1, 1, 1, 1, 1, 1, 1, 1,
634 1, 1, 1, 1, 1, 1, 1, 1,
635 1, 1, 1, 1, 1, 1, 1, 1,
636 1, 1, 1, 1, 1, 1, 1, 1,
637 1, 1, 1, 1, 1, 1, 1, 1,
638 1, 1, 1, 1, 1, 1, 1, 1,
639 0, 0, 0, 0, 0, 0, 0, 0,
640 0, 0, 0, 0, 0, 0, 0, 0,
641 1, 1, 1, 1, 1, 1, 1, 1,
642 1, 1, 1, 1, 1, 1, 1, 1,
643 0, 0, 0, 0, 29, 29, 0, 0,
644 0, 0, 18, 0, 0, 0, 26, 0,
645 0, 0, 0, 0, 29, 29, 15, 26,
646 15, 15, 15, 0, 15, 0, 15, 15,
647 16, 15, 15, 15, 15, 15, 15, 15,
648 15, 15, 15, 15, 15, 15, 15, 15,
649 15, 15, 0, 15, 15, 15, 15, 15,
650 15, 15, 15, 15, 16, 16, 16, 16,
651 16, 16, 16, 16, 16, 16, 16, 16,
652 16, 16, 16, 16, 16, 16, 16, 16,
653 16, 16, 16, 16, 16, 16, 16, 16,
654 16, 16, 16, 16, 16, 16, 16, 0,
655 16, 16, 15, 15, 15, 16, 16, 16,
656 15, 16, 15, 16, 15, 16, 15, 16,
657 15, 16, 15, 16, 15, 16, 15, 16,
658 15, 16, 15, 16, 15, 16, 15, 16,
659 16, 16, 16, 16, 15, 16, 27, 0,
660 0, 0, 0, 0, 0, 0, 0, 0,
661};
662
663static const Q_UINT8 ui_04[] = {
664 15, 15, 15, 15, 15, 15, 15, 15,
665 15, 15, 15, 15, 15, 15, 15, 15,
666 15, 15, 15, 15, 15, 15, 15, 15,
667 15, 15, 15, 15, 15, 15, 15, 15,
668 15, 15, 15, 15, 15, 15, 15, 15,
669 15, 15, 15, 15, 15, 15, 15, 15,
670 16, 16, 16, 16, 16, 16, 16, 16,
671 16, 16, 16, 16, 16, 16, 16, 16,
672 16, 16, 16, 16, 16, 16, 16, 16,
673 16, 16, 16, 16, 16, 16, 16, 16,
674 16, 16, 16, 16, 16, 16, 16, 16,
675 16, 16, 16, 16, 16, 16, 16, 16,
676 15, 16, 15, 16, 15, 16, 15, 16,
677 15, 16, 15, 16, 15, 16, 15, 16,
678 15, 16, 15, 16, 15, 16, 15, 16,
679 15, 16, 15, 16, 15, 16, 15, 16,
680 15, 16, 30, 1, 1, 1, 1, 0,
681 3, 3, 15, 16, 15, 16, 15, 16,
682 15, 16, 15, 16, 15, 16, 15, 16,
683 15, 16, 15, 16, 15, 16, 15, 16,
684 15, 16, 15, 16, 15, 16, 15, 16,
685 15, 16, 15, 16, 15, 16, 15, 16,
686 15, 16, 15, 16, 15, 16, 15, 16,
687 15, 16, 15, 16, 15, 16, 15, 16,
688 15, 15, 16, 15, 16, 15, 16, 15,
689 16, 15, 16, 15, 16, 15, 16, 0,
690 15, 16, 15, 16, 15, 16, 15, 16,
691 15, 16, 15, 16, 15, 16, 15, 16,
692 15, 16, 15, 16, 15, 16, 15, 16,
693 15, 16, 15, 16, 15, 16, 15, 16,
694 15, 16, 15, 16, 15, 16, 0, 0,
695 15, 16, 0, 0, 0, 0, 0, 0,
696};
697
698static const Q_UINT8 ui_05[] = {
699 15, 16, 15, 16, 15, 16, 15, 16,
700 15, 16, 15, 16, 15, 16, 15, 16,
701 0, 0, 0, 0, 0, 0, 0, 0,
702 0, 0, 0, 0, 0, 0, 0, 0,
703 0, 0, 0, 0, 0, 0, 0, 0,
704 0, 0, 0, 0, 0, 0, 0, 0,
705 0, 15, 15, 15, 15, 15, 15, 15,
706 15, 15, 15, 15, 15, 15, 15, 15,
707 15, 15, 15, 15, 15, 15, 15, 15,
708 15, 15, 15, 15, 15, 15, 15, 15,
709 15, 15, 15, 15, 15, 15, 15, 0,
710 0, 18, 26, 26, 26, 26, 26, 26,
711 0, 16, 16, 16, 16, 16, 16, 16,
712 16, 16, 16, 16, 16, 16, 16, 16,
713 16, 16, 16, 16, 16, 16, 16, 16,
714 16, 16, 16, 16, 16, 16, 16, 16,
715 16, 16, 16, 16, 16, 16, 16, 16,
716 0, 26, 21, 0, 0, 0, 0, 0,
717 0, 1, 1, 1, 1, 1, 1, 1,
718 1, 1, 1, 1, 1, 1, 1, 1,
719 1, 1, 0, 1, 1, 1, 1, 1,
720 1, 1, 1, 1, 1, 1, 1, 1,
721 1, 1, 1, 1, 1, 1, 1, 1,
722 1, 1, 0, 1, 1, 1, 26, 1,
723 26, 1, 1, 26, 1, 0, 0, 0,
724 0, 0, 0, 0, 0, 0, 0, 0,
725 19, 19, 19, 19, 19, 19, 19, 19,
726 19, 19, 19, 19, 19, 19, 19, 19,
727 19, 19, 19, 19, 19, 19, 19, 19,
728 19, 19, 19, 0, 0, 0, 0, 0,
729 19, 19, 19, 26, 26, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 0,
731};
732
733static const Q_UINT8 ui_06[] = {
734 0, 0, 0, 0, 0, 0, 0, 0,
735 0, 0, 0, 0, 26, 0, 0, 0,
736 0, 0, 0, 0, 0, 0, 0, 0,
737 0, 0, 0, 26, 0, 0, 0, 26,
738 0, 19, 19, 19, 19, 19, 19, 19,
739 19, 19, 19, 19, 19, 19, 19, 19,
740 19, 19, 19, 19, 19, 19, 19, 19,
741 19, 19, 19, 0, 0, 0, 0, 0,
742 18, 19, 19, 19, 19, 19, 19, 19,
743 19, 19, 19, 1, 1, 1, 1, 1,
744 1, 1, 1, 1, 1, 1, 0, 0,
745 0, 0, 0, 0, 0, 0, 0, 0,
746 4, 4, 4, 4, 4, 4, 4, 4,
747 4, 4, 26, 26, 26, 26, 19, 19,
748 1, 19, 19, 19, 19, 19, 19, 19,
749 19, 19, 19, 19, 19, 19, 19, 19,
750 19, 19, 19, 19, 19, 19, 19, 19,
751 19, 19, 19, 19, 19, 19, 19, 19,
752 19, 19, 19, 19, 19, 19, 19, 19,
753 19, 19, 19, 19, 19, 19, 19, 19,
754 19, 19, 19, 19, 19, 19, 19, 19,
755 19, 19, 19, 19, 19, 19, 19, 19,
756 19, 19, 19, 19, 19, 19, 19, 19,
757 19, 19, 19, 19, 19, 19, 19, 19,
758 19, 19, 19, 19, 19, 19, 19, 19,
759 19, 19, 19, 19, 19, 19, 19, 19,
760 19, 19, 19, 19, 26, 19, 1, 1,
761 1, 1, 1, 1, 1, 11, 3, 1,
762 1, 1, 1, 1, 1, 18, 18, 1,
763 1, 30, 1, 1, 1, 1, 0, 0,
764 4, 4, 4, 4, 4, 4, 4, 4,
765 4, 4, 19, 19, 19, 30, 30, 0,
766};
767
768static const Q_UINT8 ui_07[] = {
769 26, 26, 26, 26, 26, 26, 26, 26,
770 26, 26, 26, 26, 26, 26, 0, 11,
771 19, 1, 19, 19, 19, 19, 19, 19,
772 19, 19, 19, 19, 19, 19, 19, 19,
773 19, 19, 19, 19, 19, 19, 19, 19,
774 19, 19, 19, 19, 19, 0, 0, 0,
775 1, 1, 1, 1, 1, 1, 1, 1,
776 1, 1, 1, 1, 1, 1, 1, 1,
777 1, 1, 1, 1, 1, 1, 1, 1,
778 1, 1, 1, 0, 0, 0, 0, 0,
779 0, 0, 0, 0, 0, 0, 0, 0,
780 0, 0, 0, 0, 0, 0, 0, 0,
781 0, 0, 0, 0, 0, 0, 0, 0,
782 0, 0, 0, 0, 0, 0, 0, 0,
783 0, 0, 0, 0, 0, 0, 0, 0,
784 0, 0, 0, 0, 0, 0, 0, 0,
785 19, 19, 19, 19, 19, 19, 19, 19,
786 19, 19, 19, 19, 19, 19, 19, 19,
787 19, 19, 19, 19, 19, 19, 19, 19,
788 19, 19, 19, 19, 19, 19, 19, 19,
789 19, 19, 19, 19, 19, 19, 1, 1,
790 1, 1, 1, 1, 1, 1, 1, 1,
791 1, 19, 0, 0, 0, 0, 0, 0,
792 0, 0, 0, 0, 0, 0, 0, 0,
793 0, 0, 0, 0, 0, 0, 0, 0,
794 0, 0, 0, 0, 0, 0, 0, 0,
795 0, 0, 0, 0, 0, 0, 0, 0,
796 0, 0, 0, 0, 0, 0, 0, 0,
797 0, 0, 0, 0, 0, 0, 0, 0,
798 0, 0, 0, 0, 0, 0, 0, 0,
799 0, 0, 0, 0, 0, 0, 0, 0,
800 0, 0, 0, 0, 0, 0, 0, 0,
801};
802
803static const Q_UINT8 ui_08[] = {
804 0, 0, 0, 0, 0, 0, 0, 0,
805 0, 0, 0, 0, 0, 0, 0, 0,
806 0, 0, 0, 0, 0, 0, 0, 0,
807 0, 0, 0, 0, 0, 0, 0, 0,
808 0, 0, 0, 0, 0, 0, 0, 0,
809 0, 0, 0, 0, 0, 0, 0, 0,
810 0, 0, 0, 0, 0, 0, 0, 0,
811 0, 0, 0, 0, 0, 0, 0, 0,
812 0, 0, 0, 0, 0, 0, 0, 0,
813 0, 0, 0, 0, 0, 0, 0, 0,
814 0, 0, 0, 0, 0, 0, 0, 0,
815 0, 0, 0, 0, 0, 0, 0, 0,
816 0, 0, 0, 0, 0, 0, 0, 0,
817 0, 0, 0, 0, 0, 0, 0, 0,
818 0, 0, 0, 0, 0, 0, 0, 0,
819 0, 0, 0, 0, 0, 0, 0, 0,
820 0, 0, 0, 0, 0, 0, 0, 0,
821 0, 0, 0, 0, 0, 0, 0, 0,
822 0, 0, 0, 0, 0, 0, 0, 0,
823 0, 0, 0, 0, 0, 0, 0, 0,
824 0, 0, 0, 0, 0, 0, 0, 0,
825 0, 0, 0, 0, 0, 0, 0, 0,
826 0, 0, 0, 0, 0, 0, 0, 0,
827 0, 0, 0, 0, 0, 0, 0, 0,
828 0, 0, 0, 0, 0, 0, 0, 0,
829 0, 0, 0, 0, 0, 0, 0, 0,
830 0, 0, 0, 0, 0, 0, 0, 0,
831 0, 0, 0, 0, 0, 0, 0, 0,
832 0, 0, 0, 0, 0, 0, 0, 0,
833 0, 0, 0, 0, 0, 0, 0, 0,
834 0, 0, 0, 0, 0, 0, 0, 0,
835 0, 0, 0, 0, 0, 0, 0, 0,
836};
837
838static const Q_UINT8 ui_09[] = {
839 0, 1, 1, 2, 0, 19, 19, 19,
840 19, 19, 19, 19, 19, 19, 19, 19,
841 19, 19, 19, 19, 19, 19, 19, 19,
842 19, 19, 19, 19, 19, 19, 19, 19,
843 19, 19, 19, 19, 19, 19, 19, 19,
844 19, 19, 19, 19, 19, 19, 19, 19,
845 19, 19, 19, 19, 19, 19, 19, 19,
846 19, 19, 0, 0, 1, 19, 2, 2,
847 2, 1, 1, 1, 1, 1, 1, 1,
848 1, 2, 2, 2, 2, 1, 0, 0,
849 19, 1, 1, 1, 1, 0, 0, 0,
850 19, 19, 19, 19, 19, 19, 19, 19,
851 19, 19, 1, 1, 26, 26, 4, 4,
852 4, 4, 4, 4, 4, 4, 4, 4,
853 26, 0, 0, 0, 0, 0, 0, 0,
854 0, 0, 0, 0, 0, 0, 0, 0,
855 0, 1, 2, 2, 0, 19, 19, 19,
856 19, 19, 19, 19, 19, 0, 0, 19,
857 19, 0, 0, 19, 19, 19, 19, 19,
858 19, 19, 19, 19, 19, 19, 19, 19,
859 19, 19, 19, 19, 19, 19, 19, 19,
860 19, 0, 19, 19, 19, 19, 19, 19,
861 19, 0, 19, 0, 0, 0, 19, 19,
862 19, 19, 0, 0, 1, 0, 2, 2,
863 2, 1, 1, 1, 1, 0, 0, 2,
864 2, 0, 0, 2, 2, 1, 0, 0,
865 0, 0, 0, 0, 0, 0, 0, 2,
866 0, 0, 0, 0, 19, 19, 0, 19,
867 19, 19, 1, 1, 0, 0, 4, 4,
868 4, 4, 4, 4, 4, 4, 4, 4,
869 19, 19, 28, 28, 6, 6, 6, 6,
870 6, 6, 30, 0, 0, 0, 0, 0,
871};
872
873static const Q_UINT8 ui_0A[] = {
874 0, 0, 1, 0, 0, 19, 19, 19,
875 19, 19, 19, 0, 0, 0, 0, 19,
876 19, 0, 0, 19, 19, 19, 19, 19,
877 19, 19, 19, 19, 19, 19, 19, 19,
878 19, 19, 19, 19, 19, 19, 19, 19,
879 19, 0, 19, 19, 19, 19, 19, 19,
880 19, 0, 19, 19, 0, 19, 19, 0,
881 19, 19, 0, 0, 1, 0, 2, 2,
882 2, 1, 1, 0, 0, 0, 0, 1,
883 1, 0, 0, 1, 1, 1, 0, 0,
884 0, 0, 0, 0, 0, 0, 0, 0,
885 0, 19, 19, 19, 19, 0, 19, 0,
886 0, 0, 0, 0, 0, 0, 4, 4,
887 4, 4, 4, 4, 4, 4, 4, 4,
888 1, 1, 19, 19, 19, 0, 0, 0,
889 0, 0, 0, 0, 0, 0, 0, 0,
890 0, 1, 1, 2, 0, 19, 19, 19,
891 19, 19, 19, 19, 0, 19, 0, 19,
892 19, 19, 0, 19, 19, 19, 19, 19,
893 19, 19, 19, 19, 19, 19, 19, 19,
894 19, 19, 19, 19, 19, 19, 19, 19,
895 19, 0, 19, 19, 19, 19, 19, 19,
896 19, 0, 19, 19, 0, 19, 19, 19,
897 19, 19, 0, 0, 1, 19, 2, 2,
898 2, 1, 1, 1, 1, 1, 0, 1,
899 1, 2, 0, 2, 2, 1, 0, 0,
900 19, 0, 0, 0, 0, 0, 0, 0,
901 0, 0, 0, 0, 0, 0, 0, 0,
902 19, 0, 0, 0, 0, 0, 4, 4,
903 4, 4, 4, 4, 4, 4, 4, 4,
904 0, 0, 0, 0, 0, 0, 0, 0,
905 0, 0, 0, 0, 0, 0, 0, 0,
906};
907
908static const Q_UINT8 ui_0B[] = {
909 0, 1, 2, 2, 0, 19, 19, 19,
910 19, 19, 19, 19, 19, 0, 0, 19,
911 19, 0, 0, 19, 19, 19, 19, 19,
912 19, 19, 19, 19, 19, 19, 19, 19,
913 19, 19, 19, 19, 19, 19, 19, 19,
914 19, 0, 19, 19, 19, 19, 19, 19,
915 19, 0, 19, 19, 0, 0, 19, 19,
916 19, 19, 0, 0, 1, 19, 2, 1,
917 2, 1, 1, 1, 0, 0, 0, 2,
918 2, 0, 0, 2, 2, 1, 0, 0,
919 0, 0, 0, 0, 0, 0, 1, 2,
920 0, 0, 0, 0, 19, 19, 0, 19,
921 19, 19, 0, 0, 0, 0, 4, 4,
922 4, 4, 4, 4, 4, 4, 4, 4,
923 30, 0, 0, 0, 0, 0, 0, 0,
924 0, 0, 0, 0, 0, 0, 0, 0,
925 0, 0, 1, 19, 0, 19, 19, 19,
926 19, 19, 19, 0, 0, 0, 19, 19,
927 19, 0, 19, 19, 19, 19, 0, 0,
928 0, 19, 19, 0, 19, 0, 19, 19,
929 0, 0, 0, 19, 19, 0, 0, 0,
930 19, 19, 19, 0, 0, 0, 19, 19,
931 19, 19, 19, 19, 19, 19, 0, 19,
932 19, 19, 0, 0, 0, 0, 2, 2,
933 1, 2, 2, 0, 0, 0, 2, 2,
934 2, 0, 2, 2, 2, 1, 0, 0,
935 0, 0, 0, 0, 0, 0, 0, 2,
936 0, 0, 0, 0, 0, 0, 0, 0,
937 0, 0, 0, 0, 0, 0, 0, 4,
938 4, 4, 4, 4, 4, 4, 4, 4,
939 6, 6, 6, 0, 0, 0, 0, 0,
940 0, 0, 0, 0, 0, 0, 0, 0,
941};
942
943static const Q_UINT8 ui_0C[] = {
944 0, 2, 2, 2, 0, 19, 19, 19,
945 19, 19, 19, 19, 19, 0, 19, 19,
946 19, 0, 19, 19, 19, 19, 19, 19,
947 19, 19, 19, 19, 19, 19, 19, 19,
948 19, 19, 19, 19, 19, 19, 19, 19,
949 19, 0, 19, 19, 19, 19, 19, 19,
950 19, 19, 19, 19, 0, 19, 19, 19,
951 19, 19, 0, 0, 0, 0, 1, 1,
952 1, 2, 2, 2, 2, 0, 1, 1,
953 1, 0, 1, 1, 1, 1, 0, 0,
954 0, 0, 0, 0, 0, 1, 1, 0,
955 0, 0, 0, 0, 0, 0, 0, 0,
956 19, 19, 0, 0, 0, 0, 4, 4,
957 4, 4, 4, 4, 4, 4, 4, 4,
958 0, 0, 0, 0, 0, 0, 0, 0,
959 0, 0, 0, 0, 0, 0, 0, 0,
960 0, 0, 2, 2, 0, 19, 19, 19,
961 19, 19, 19, 19, 19, 0, 19, 19,
962 19, 0, 19, 19, 19, 19, 19, 19,
963 19, 19, 19, 19, 19, 19, 19, 19,
964 19, 19, 19, 19, 19, 19, 19, 19,
965 19, 0, 19, 19, 19, 19, 19, 19,
966 19, 19, 19, 19, 0, 19, 19, 19,
967 19, 19, 0, 0, 0, 0, 2, 1,
968 2, 2, 2, 2, 2, 0, 1, 2,
969 2, 0, 2, 2, 1, 1, 0, 0,
970 0, 0, 0, 0, 0, 2, 2, 0,
971 0, 0, 0, 0, 0, 0, 19, 0,
972 19, 19, 0, 0, 0, 0, 4, 4,
973 4, 4, 4, 4, 4, 4, 4, 4,
974 0, 0, 0, 0, 0, 0, 0, 0,
975 0, 0, 0, 0, 0, 0, 0, 0,
976};
977
978static const Q_UINT8 ui_0D[] = {
979 0, 0, 2, 2, 0, 19, 19, 19,
980 19, 19, 19, 19, 19, 0, 19, 19,
981 19, 0, 19, 19, 19, 19, 19, 19,
982 19, 19, 19, 19, 19, 19, 19, 19,
983 19, 19, 19, 19, 19, 19, 19, 19,
984 19, 0, 19, 19, 19, 19, 19, 19,
985 19, 19, 19, 19, 19, 19, 19, 19,
986 19, 19, 0, 0, 0, 0, 2, 2,
987 2, 1, 1, 1, 0, 0, 2, 2,
988 2, 0, 2, 2, 2, 1, 0, 0,
989 0, 0, 0, 0, 0, 0, 0, 2,
990 0, 0, 0, 0, 0, 0, 0, 0,
991 19, 19, 0, 0, 0, 0, 4, 4,
992 4, 4, 4, 4, 4, 4, 4, 4,
993 0, 0, 0, 0, 0, 0, 0, 0,
994 0, 0, 0, 0, 0, 0, 0, 0,
995 0, 0, 2, 2, 0, 19, 19, 19,
996 19, 19, 19, 19, 19, 19, 19, 19,
997 19, 19, 19, 19, 19, 19, 19, 0,
998 0, 0, 19, 19, 19, 19, 19, 19,
999 19, 19, 19, 19, 19, 19, 19, 19,
1000 19, 19, 19, 19, 19, 19, 19, 19,
1001 19, 19, 0, 19, 19, 19, 19, 19,
1002 19, 19, 19, 19, 0, 19, 0, 0,
1003 19, 19, 19, 19, 19, 19, 19, 0,
1004 0, 0, 1, 0, 0, 0, 0, 2,
1005 2, 2, 1, 1, 1, 0, 1, 0,
1006 2, 2, 2, 2, 2, 2, 2, 2,
1007 0, 0, 0, 0, 0, 0, 0, 0,
1008 0, 0, 0, 0, 0, 0, 0, 0,
1009 0, 0, 2, 2, 26, 0, 0, 0,
1010 0, 0, 0, 0, 0, 0, 0, 0,
1011};
1012
1013static const Q_UINT8 ui_0E[] = {
1014 0, 19, 19, 19, 19, 19, 19, 19,
1015 19, 19, 19, 19, 19, 19, 19, 19,
1016 19, 19, 19, 19, 19, 19, 19, 19,
1017 19, 19, 19, 19, 19, 19, 19, 19,
1018 19, 19, 19, 19, 19, 19, 19, 19,
1019 19, 19, 19, 19, 19, 19, 19, 19,
1020 19, 1, 19, 19, 1, 1, 1, 1,
1021 1, 1, 1, 0, 0, 0, 0, 28,
1022 19, 19, 19, 19, 19, 19, 18, 1,
1023 1, 1, 1, 1, 1, 1, 1, 26,
1024 4, 4, 4, 4, 4, 4, 4, 4,
1025 4, 4, 26, 26, 0, 0, 0, 0,
1026 0, 0, 0, 0, 0, 0, 0, 0,
1027 0, 0, 0, 0, 0, 0, 0, 0,
1028 0, 0, 0, 0, 0, 0, 0, 0,
1029 0, 0, 0, 0, 0, 0, 0, 0,
1030 0, 19, 19, 0, 19, 0, 0, 19,
1031 19, 0, 19, 0, 0, 19, 0, 0,
1032 0, 0, 0, 0, 19, 19, 19, 19,
1033 0, 19, 19, 19, 19, 19, 19, 19,
1034 0, 19, 19, 19, 0, 19, 0, 19,
1035 0, 0, 19, 19, 0, 19, 19, 19,
1036 19, 1, 19, 19, 1, 1, 1, 1,
1037 1, 1, 0, 1, 1, 19, 0, 0,
1038 19, 19, 19, 19, 19, 0, 18, 0,
1039 1, 1, 1, 1, 1, 1, 0, 0,
1040 4, 4, 4, 4, 4, 4, 4, 4,
1041 4, 4, 0, 0, 19, 19, 0, 0,
1042 0, 0, 0, 0, 0, 0, 0, 0,
1043 0, 0, 0, 0, 0, 0, 0, 0,
1044 0, 0, 0, 0, 0, 0, 0, 0,
1045 0, 0, 0, 0, 0, 0, 0, 0,
1046};
1047
1048static const Q_UINT8 ui_0F[] = {
1049 19, 30, 30, 30, 26, 26, 26, 26,
1050 26, 26, 26, 26, 26, 26, 26, 26,
1051 26, 26, 26, 30, 30, 30, 30, 30,
1052 1, 1, 30, 30, 30, 30, 30, 30,
1053 4, 4, 4, 4, 4, 4, 4, 4,
1054 4, 4, 6, 6, 6, 6, 6, 6,
1055 6, 6, 6, 6, 30, 1, 30, 1,
1056 30, 1, 22, 23, 22, 23, 2, 2,
1057 19, 19, 19, 19, 19, 19, 19, 19,
1058 0, 19, 19, 19, 19, 19, 19, 19,
1059 19, 19, 19, 19, 19, 19, 19, 19,
1060 19, 19, 19, 19, 19, 19, 19, 19,
1061 19, 19, 19, 19, 19, 19, 19, 19,
1062 19, 19, 19, 0, 0, 0, 0, 0,
1063 0, 1, 1, 1, 1, 1, 1, 1,
1064 1, 1, 1, 1, 1, 1, 1, 2,
1065 1, 1, 1, 1, 1, 26, 1, 1,
1066 19, 19, 19, 19, 0, 0, 0, 0,
1067 1, 1, 1, 1, 1, 1, 1, 1,
1068 0, 1, 1, 1, 1, 1, 1, 1,
1069 1, 1, 1, 1, 1, 1, 1, 1,
1070 1, 1, 1, 1, 1, 1, 1, 1,
1071 1, 1, 1, 1, 1, 1, 1, 1,
1072 1, 1, 1, 1, 1, 0, 30, 30,
1073 30, 30, 30, 30, 30, 30, 1, 30,
1074 30, 30, 30, 30, 30, 0, 0, 30,
1075 0, 0, 0, 0, 0, 0, 0, 0,
1076 0, 0, 0, 0, 0, 0, 0, 0,
1077 0, 0, 0, 0, 0, 0, 0, 0,
1078 0, 0, 0, 0, 0, 0, 0, 0,
1079 0, 0, 0, 0, 0, 0, 0, 0,
1080 0, 0, 0, 0, 0, 0, 0, 0,
1081};
1082
1083static const Q_UINT8 ui_10[] = {
1084 19, 19, 19, 19, 19, 19, 19, 19,
1085 19, 19, 19, 19, 19, 19, 19, 19,
1086 19, 19, 19, 19, 19, 19, 19, 19,
1087 19, 19, 19, 19, 19, 19, 19, 19,
1088 19, 19, 0, 19, 19, 19, 19, 19,
1089 0, 19, 19, 0, 2, 1, 1, 1,
1090 1, 2, 1, 0, 0, 0, 1, 1,
1091 2, 1, 0, 0, 0, 0, 0, 0,
1092 4, 4, 4, 4, 4, 4, 4, 4,
1093 4, 4, 26, 26, 26, 26, 26, 26,
1094 19, 19, 19, 19, 19, 19, 2, 2,
1095 1, 1, 0, 0, 0, 0, 0, 0,
1096 0, 0, 0, 0, 0, 0, 0, 0,
1097 0, 0, 0, 0, 0, 0, 0, 0,
1098 0, 0, 0, 0, 0, 0, 0, 0,
1099 0, 0, 0, 0, 0, 0, 0, 0,
1100 0, 0, 0, 0, 0, 0, 0, 0,
1101 0, 0, 0, 0, 0, 0, 0, 0,
1102 0, 0, 0, 0, 0, 0, 0, 0,
1103 0, 0, 0, 0, 0, 0, 0, 0,
1104 15, 15, 15, 15, 15, 15, 15, 15,
1105 15, 15, 15, 15, 15, 15, 15, 15,
1106 15, 15, 15, 15, 15, 15, 15, 15,
1107 15, 15, 15, 15, 15, 15, 15, 15,
1108 15, 15, 15, 15, 15, 15, 0, 0,
1109 0, 0, 0, 0, 0, 0, 0, 0,
1110 19, 19, 19, 19, 19, 19, 19, 19,
1111 19, 19, 19, 19, 19, 19, 19, 19,
1112 19, 19, 19, 19, 19, 19, 19, 19,
1113 19, 19, 19, 19, 19, 19, 19, 19,
1114 19, 19, 19, 19, 19, 19, 19, 19,
1115 19, 0, 0, 26, 0, 0, 0, 0,
1116};
1117
1118static const Q_UINT8 ui_11[] = {
1119 19, 19, 19, 19, 19, 19, 19, 19,
1120 19, 19, 19, 19, 19, 19, 19, 19,
1121 19, 19, 19, 19, 19, 19, 19, 19,
1122 19, 19, 19, 19, 19, 19, 19, 19,
1123 19, 19, 19, 19, 19, 19, 19, 19,
1124 19, 19, 19, 19, 19, 19, 19, 19,
1125 19, 19, 19, 19, 19, 19, 19, 19,
1126 19, 19, 19, 19, 19, 19, 19, 19,
1127 19, 19, 19, 19, 19, 19, 19, 19,
1128 19, 19, 19, 19, 19, 19, 19, 19,
1129 19, 19, 19, 19, 19, 19, 19, 19,
1130 19, 19, 0, 0, 0, 0, 0, 19,
1131 19, 19, 19, 19, 19, 19, 19, 19,
1132 19, 19, 19, 19, 19, 19, 19, 19,
1133 19, 19, 19, 19, 19, 19, 19, 19,
1134 19, 19, 19, 19, 19, 19, 19, 19,
1135 19, 19, 19, 19, 19, 19, 19, 19,
1136 19, 19, 19, 19, 19, 19, 19, 19,
1137 19, 19, 19, 19, 19, 19, 19, 19,
1138 19, 19, 19, 19, 19, 19, 19, 19,
1139 19, 19, 19, 0, 0, 0, 0, 0,
1140 19, 19, 19, 19, 19, 19, 19, 19,
1141 19, 19, 19, 19, 19, 19, 19, 19,
1142 19, 19, 19, 19, 19, 19, 19, 19,
1143 19, 19, 19, 19, 19, 19, 19, 19,
1144 19, 19, 19, 19, 19, 19, 19, 19,
1145 19, 19, 19, 19, 19, 19, 19, 19,
1146 19, 19, 19, 19, 19, 19, 19, 19,
1147 19, 19, 19, 19, 19, 19, 19, 19,
1148 19, 19, 19, 19, 19, 19, 19, 19,
1149 19, 19, 19, 19, 19, 19, 19, 19,
1150 19, 19, 0, 0, 0, 0, 0, 0,
1151};
1152
1153static const Q_UINT8 ui_12[] = {
1154 19, 19, 19, 19, 19, 19, 19, 0,
1155 19, 19, 19, 19, 19, 19, 19, 19,
1156 19, 19, 19, 19, 19, 19, 19, 19,
1157 19, 19, 19, 19, 19, 19, 19, 19,
1158 19, 19, 19, 19, 19, 19, 19, 19,
1159 19, 19, 19, 19, 19, 19, 19, 19,
1160 19, 19, 19, 19, 19, 19, 19, 19,
1161 19, 19, 19, 19, 19, 19, 19, 19,
1162 19, 19, 19, 19, 19, 19, 19, 0,
1163 19, 0, 19, 19, 19, 19, 0, 0,
1164 19, 19, 19, 19, 19, 19, 19, 0,
1165 19, 0, 19, 19, 19, 19, 0, 0,
1166 19, 19, 19, 19, 19, 19, 19, 19,
1167 19, 19, 19, 19, 19, 19, 19, 19,
1168 19, 19, 19, 19, 19, 19, 19, 19,
1169 19, 19, 19, 19, 19, 19, 19, 19,
1170 19, 19, 19, 19, 19, 19, 19, 0,
1171 19, 0, 19, 19, 19, 19, 0, 0,
1172 19, 19, 19, 19, 19, 19, 19, 19,
1173 19, 19, 19, 19, 19, 19, 19, 19,
1174 19, 19, 19, 19, 19, 19, 19, 19,
1175 19, 19, 19, 19, 19, 19, 19, 0,
1176 19, 0, 19, 19, 19, 19, 0, 0,
1177 19, 19, 19, 19, 19, 19, 19, 0,
1178 19, 0, 19, 19, 19, 19, 0, 0,
1179 19, 19, 19, 19, 19, 19, 19, 0,
1180 19, 19, 19, 19, 19, 19, 19, 0,
1181 19, 19, 19, 19, 19, 19, 19, 19,
1182 19, 19, 19, 19, 19, 19, 19, 19,
1183 19, 19, 19, 19, 19, 19, 19, 0,
1184 19, 19, 19, 19, 19, 19, 19, 19,
1185 19, 19, 19, 19, 19, 19, 19, 19,
1186};
1187
1188static const Q_UINT8 ui_13[] = {
1189 19, 19, 19, 19, 19, 19, 19, 19,
1190 19, 19, 19, 19, 19, 19, 19, 0,
1191 19, 0, 19, 19, 19, 19, 0, 0,
1192 19, 19, 19, 19, 19, 19, 19, 0,
1193 19, 19, 19, 19, 19, 19, 19, 19,
1194 19, 19, 19, 19, 19, 19, 19, 19,
1195 19, 19, 19, 19, 19, 19, 19, 19,
1196 19, 19, 19, 19, 19, 19, 19, 19,
1197 19, 19, 19, 19, 19, 19, 19, 0,
1198 19, 19, 19, 19, 19, 19, 19, 19,
1199 19, 19, 19, 19, 19, 19, 19, 19,
1200 19, 19, 19, 0, 0, 0, 0, 0,
1201 0, 26, 26, 26, 26, 26, 26, 26,
1202 26, 4, 4, 4, 4, 4, 4, 4,
1203 4, 4, 6, 6, 6, 6, 6, 6,
1204 6, 6, 6, 6, 6, 0, 0, 0,
1205 0, 0, 0, 0, 0, 0, 0, 0,
1206 0, 0, 0, 0, 0, 0, 0, 0,
1207 0, 0, 0, 0, 0, 0, 0, 0,
1208 0, 0, 0, 0, 0, 0, 0, 0,
1209 19, 19, 19, 19, 19, 19, 19, 19,
1210 19, 19, 19, 19, 19, 19, 19, 19,
1211 19, 19, 19, 19, 19, 19, 19, 19,
1212 19, 19, 19, 19, 19, 19, 19, 19,
1213 19, 19, 19, 19, 19, 19, 19, 19,
1214 19, 19, 19, 19, 19, 19, 19, 19,
1215 19, 19, 19, 19, 19, 19, 19, 19,
1216 19, 19, 19, 19, 19, 19, 19, 19,
1217 19, 19, 19, 19, 19, 19, 19, 19,
1218 19, 19, 19, 19, 19, 19, 19, 19,
1219 19, 19, 19, 19, 19, 0, 0, 0,
1220 0, 0, 0, 0, 0, 0, 0, 0,
1221};
1222
1223static const Q_UINT8 ui_14[] = {
1224 0, 19, 19, 19, 19, 19, 19, 19,
1225 19, 19, 19, 19, 19, 19, 19, 19,
1226 19, 19, 19, 19, 19, 19, 19, 19,
1227 19, 19, 19, 19, 19, 19, 19, 19,
1228 19, 19, 19, 19, 19, 19, 19, 19,
1229 19, 19, 19, 19, 19, 19, 19, 19,
1230 19, 19, 19, 19, 19, 19, 19, 19,
1231 19, 19, 19, 19, 19, 19, 19, 19,
1232 19, 19, 19, 19, 19, 19, 19, 19,
1233 19, 19, 19, 19, 19, 19, 19, 19,
1234 19, 19, 19, 19, 19, 19, 19, 19,
1235 19, 19, 19, 19, 19, 19, 19, 19,
1236 19, 19, 19, 19, 19, 19, 19, 19,
1237 19, 19, 19, 19, 19, 19, 19, 19,
1238 19, 19, 19, 19, 19, 19, 19, 19,
1239 19, 19, 19, 19, 19, 19, 19, 19,
1240 19, 19, 19, 19, 19, 19, 19, 19,
1241 19, 19, 19, 19, 19, 19, 19, 19,
1242 19, 19, 19, 19, 19, 19, 19, 19,
1243 19, 19, 19, 19, 19, 19, 19, 19,
1244 19, 19, 19, 19, 19, 19, 19, 19,
1245 19, 19, 19, 19, 19, 19, 19, 19,
1246 19, 19, 19, 19, 19, 19, 19, 19,
1247 19, 19, 19, 19, 19, 19, 19, 19,
1248 19, 19, 19, 19, 19, 19, 19, 19,
1249 19, 19, 19, 19, 19, 19, 19, 19,
1250 19, 19, 19, 19, 19, 19, 19, 19,
1251 19, 19, 19, 19, 19, 19, 19, 19,
1252 19, 19, 19, 19, 19, 19, 19, 19,
1253 19, 19, 19, 19, 19, 19, 19, 19,
1254 19, 19, 19, 19, 19, 19, 19, 19,
1255 19, 19, 19, 19, 19, 19, 19, 19,
1256};
1257
1258static const Q_UINT8 ui_15[] = {
1259 19, 19, 19, 19, 19, 19, 19, 19,
1260 19, 19, 19, 19, 19, 19, 19, 19,
1261 19, 19, 19, 19, 19, 19, 19, 19,
1262 19, 19, 19, 19, 19, 19, 19, 19,
1263 19, 19, 19, 19, 19, 19, 19, 19,
1264 19, 19, 19, 19, 19, 19, 19, 19,
1265 19, 19, 19, 19, 19, 19, 19, 19,
1266 19, 19, 19, 19, 19, 19, 19, 19,
1267 19, 19, 19, 19, 19, 19, 19, 19,
1268 19, 19, 19, 19, 19, 19, 19, 19,
1269 19, 19, 19, 19, 19, 19, 19, 19,
1270 19, 19, 19, 19, 19, 19, 19, 19,
1271 19, 19, 19, 19, 19, 19, 19, 19,
1272 19, 19, 19, 19, 19, 19, 19, 19,
1273 19, 19, 19, 19, 19, 19, 19, 19,
1274 19, 19, 19, 19, 19, 19, 19, 19,
1275 19, 19, 19, 19, 19, 19, 19, 19,
1276 19, 19, 19, 19, 19, 19, 19, 19,
1277 19, 19, 19, 19, 19, 19, 19, 19,
1278 19, 19, 19, 19, 19, 19, 19, 19,
1279 19, 19, 19, 19, 19, 19, 19, 19,
1280 19, 19, 19, 19, 19, 19, 19, 19,
1281 19, 19, 19, 19, 19, 19, 19, 19,
1282 19, 19, 19, 19, 19, 19, 19, 19,
1283 19, 19, 19, 19, 19, 19, 19, 19,
1284 19, 19, 19, 19, 19, 19, 19, 19,
1285 19, 19, 19, 19, 19, 19, 19, 19,
1286 19, 19, 19, 19, 19, 19, 19, 19,
1287 19, 19, 19, 19, 19, 19, 19, 19,
1288 19, 19, 19, 19, 19, 19, 19, 19,
1289 19, 19, 19, 19, 19, 19, 19, 19,
1290 19, 19, 19, 19, 19, 19, 19, 19,
1291};
1292
1293static const Q_UINT8 ui_16[] = {
1294 19, 19, 19, 19, 19, 19, 19, 19,
1295 19, 19, 19, 19, 19, 19, 19, 19,
1296 19, 19, 19, 19, 19, 19, 19, 19,
1297 19, 19, 19, 19, 19, 19, 19, 19,
1298 19, 19, 19, 19, 19, 19, 19, 19,
1299 19, 19, 19, 19, 19, 19, 19, 19,
1300 19, 19, 19, 19, 19, 19, 19, 19,
1301 19, 19, 19, 19, 19, 19, 19, 19,
1302 19, 19, 19, 19, 19, 19, 19, 19,
1303 19, 19, 19, 19, 19, 19, 19, 19,
1304 19, 19, 19, 19, 19, 19, 19, 19,
1305 19, 19, 19, 19, 19, 19, 19, 19,
1306 19, 19, 19, 19, 19, 19, 19, 19,
1307 19, 19, 19, 19, 19, 26, 26, 19,
1308 19, 19, 19, 19, 19, 19, 19, 0,
1309 0, 0, 0, 0, 0, 0, 0, 0,
1310 7, 19, 19, 19, 19, 19, 19, 19,
1311 19, 19, 19, 19, 19, 19, 19, 19,
1312 19, 19, 19, 19, 19, 19, 19, 19,
1313 19, 19, 19, 22, 23, 0, 0, 0,
1314 19, 19, 19, 19, 19, 19, 19, 19,
1315 19, 19, 19, 19, 19, 19, 19, 19,
1316 19, 19, 19, 19, 19, 19, 19, 19,
1317 19, 19, 19, 19, 19, 19, 19, 19,
1318 19, 19, 19, 19, 19, 19, 19, 19,
1319 19, 19, 19, 19, 19, 19, 19, 19,
1320 19, 19, 19, 19, 19, 19, 19, 19,
1321 19, 19, 19, 19, 19, 19, 19, 19,
1322 19, 19, 19, 19, 19, 19, 19, 19,
1323 19, 19, 19, 26, 26, 26, 5, 5,
1324 5, 0, 0, 0, 0, 0, 0, 0,
1325 0, 0, 0, 0, 0, 0, 0, 0,
1326};
1327
1328static const Q_UINT8 ui_17[] = {
1329 19, 19, 19, 19, 19, 19, 19, 19,
1330 19, 19, 19, 19, 19, 0, 19, 19,
1331 19, 19, 1, 1, 1, 0, 0, 0,
1332 0, 0, 0, 0, 0, 0, 0, 0,
1333 19, 19, 19, 19, 19, 19, 19, 19,
1334 19, 19, 19, 19, 19, 19, 19, 19,
1335 19, 19, 1, 1, 1, 26, 26, 0,
1336 0, 0, 0, 0, 0, 0, 0, 0,
1337 19, 19, 19, 19, 19, 19, 19, 19,
1338 19, 19, 19, 19, 19, 19, 19, 19,
1339 19, 19, 1, 1, 0, 0, 0, 0,
1340 0, 0, 0, 0, 0, 0, 0, 0,
1341 19, 19, 19, 19, 19, 19, 19, 19,
1342 19, 19, 19, 19, 19, 0, 19, 19,
1343 19, 0, 1, 1, 0, 0, 0, 0,
1344 0, 0, 0, 0, 0, 0, 0, 0,
1345 19, 19, 19, 19, 19, 19, 19, 19,
1346 19, 19, 19, 19, 19, 19, 19, 19,
1347 19, 19, 19, 19, 19, 19, 19, 19,
1348 19, 19, 19, 19, 19, 19, 19, 19,
1349 19, 19, 19, 19, 19, 19, 19, 19,
1350 19, 19, 19, 19, 19, 19, 19, 19,
1351 19, 19, 19, 19, 2, 2, 2, 1,
1352 1, 1, 1, 1, 1, 1, 2, 2,
1353 2, 2, 2, 2, 2, 2, 1, 2,
1354 2, 1, 1, 1, 1, 1, 1, 1,
1355 1, 1, 1, 1, 26, 26, 26, 18,
1356 26, 26, 26, 28, 19, 0, 0, 0,
1357 4, 4, 4, 4, 4, 4, 4, 4,
1358 4, 4, 0, 0, 0, 0, 0, 0,
1359 0, 0, 0, 0, 0, 0, 0, 0,
1360 0, 0, 0, 0, 0, 0, 0, 0,
1361};
1362
1363static const Q_UINT8 ui_18[] = {
1364 26, 26, 26, 26, 26, 26, 21, 26,
1365 26, 26, 26, 1, 1, 1, 11, 0,
1366 4, 4, 4, 4, 4, 4, 4, 4,
1367 4, 4, 0, 0, 0, 0, 0, 0,
1368 19, 19, 19, 19, 19, 19, 19, 19,
1369 19, 19, 19, 19, 19, 19, 19, 19,
1370 19, 19, 19, 19, 19, 19, 19, 19,
1371 19, 19, 19, 19, 19, 19, 19, 19,
1372 19, 19, 19, 18, 19, 19, 19, 19,
1373 19, 19, 19, 19, 19, 19, 19, 19,
1374 19, 19, 19, 19, 19, 19, 19, 19,
1375 19, 19, 19, 19, 19, 19, 19, 19,
1376 19, 19, 19, 19, 19, 19, 19, 19,
1377 19, 19, 19, 19, 19, 19, 19, 19,
1378 19, 19, 19, 19, 19, 19, 19, 19,
1379 0, 0, 0, 0, 0, 0, 0, 0,
1380 19, 19, 19, 19, 19, 19, 19, 19,
1381 19, 19, 19, 19, 19, 19, 19, 19,
1382 19, 19, 19, 19, 19, 19, 19, 19,
1383 19, 19, 19, 19, 19, 19, 19, 19,
1384 19, 19, 19, 19, 19, 19, 19, 19,
1385 19, 1, 0, 0, 0, 0, 0, 0,
1386 0, 0, 0, 0, 0, 0, 0, 0,
1387 0, 0, 0, 0, 0, 0, 0, 0,
1388 0, 0, 0, 0, 0, 0, 0, 0,
1389 0, 0, 0, 0, 0, 0, 0, 0,
1390 0, 0, 0, 0, 0, 0, 0, 0,
1391 0, 0, 0, 0, 0, 0, 0, 0,
1392 0, 0, 0, 0, 0, 0, 0, 0,
1393 0, 0, 0, 0, 0, 0, 0, 0,
1394 0, 0, 0, 0, 0, 0, 0, 0,
1395 0, 0, 0, 0, 0, 0, 0, 0,
1396};
1397
1398static const Q_UINT8 ui_1E[] = {
1399 15, 16, 15, 16, 15, 16, 15, 16,
1400 15, 16, 15, 16, 15, 16, 15, 16,
1401 15, 16, 15, 16, 15, 16, 15, 16,
1402 15, 16, 15, 16, 15, 16, 15, 16,
1403 15, 16, 15, 16, 15, 16, 15, 16,
1404 15, 16, 15, 16, 15, 16, 15, 16,
1405 15, 16, 15, 16, 15, 16, 15, 16,
1406 15, 16, 15, 16, 15, 16, 15, 16,
1407 15, 16, 15, 16, 15, 16, 15, 16,
1408 15, 16, 15, 16, 15, 16, 15, 16,
1409 15, 16, 15, 16, 15, 16, 15, 16,
1410 15, 16, 15, 16, 15, 16, 15, 16,
1411 15, 16, 15, 16, 15, 16, 15, 16,
1412 15, 16, 15, 16, 15, 16, 15, 16,
1413 15, 16, 15, 16, 15, 16, 15, 16,
1414 15, 16, 15, 16, 15, 16, 15, 16,
1415 15, 16, 15, 16, 15, 16, 15, 16,
1416 15, 16, 15, 16, 15, 16, 15, 16,
1417 15, 16, 15, 16, 15, 16, 16, 16,
1418 16, 16, 16, 16, 0, 0, 0, 0,
1419 15, 16, 15, 16, 15, 16, 15, 16,
1420 15, 16, 15, 16, 15, 16, 15, 16,
1421 15, 16, 15, 16, 15, 16, 15, 16,
1422 15, 16, 15, 16, 15, 16, 15, 16,
1423 15, 16, 15, 16, 15, 16, 15, 16,
1424 15, 16, 15, 16, 15, 16, 15, 16,
1425 15, 16, 15, 16, 15, 16, 15, 16,
1426 15, 16, 15, 16, 15, 16, 15, 16,
1427 15, 16, 15, 16, 15, 16, 15, 16,
1428 15, 16, 15, 16, 15, 16, 15, 16,
1429 15, 16, 15, 16, 15, 16, 15, 16,
1430 15, 16, 0, 0, 0, 0, 0, 0,
1431};
1432
1433static const Q_UINT8 ui_1F[] = {
1434 16, 16, 16, 16, 16, 16, 16, 16,
1435 15, 15, 15, 15, 15, 15, 15, 15,
1436 16, 16, 16, 16, 16, 16, 0, 0,
1437 15, 15, 15, 15, 15, 15, 0, 0,
1438 16, 16, 16, 16, 16, 16, 16, 16,
1439 15, 15, 15, 15, 15, 15, 15, 15,
1440 16, 16, 16, 16, 16, 16, 16, 16,
1441 15, 15, 15, 15, 15, 15, 15, 15,
1442 16, 16, 16, 16, 16, 16, 0, 0,
1443 15, 15, 15, 15, 15, 15, 0, 0,
1444 16, 16, 16, 16, 16, 16, 16, 16,
1445 0, 15, 0, 15, 0, 15, 0, 15,
1446 16, 16, 16, 16, 16, 16, 16, 16,
1447 15, 15, 15, 15, 15, 15, 15, 15,
1448 16, 16, 16, 16, 16, 16, 16, 16,
1449 16, 16, 16, 16, 16, 16, 0, 0,
1450 16, 16, 16, 16, 16, 16, 16, 16,
1451 17, 17, 17, 17, 17, 17, 17, 17,
1452 16, 16, 16, 16, 16, 16, 16, 16,
1453 17, 17, 17, 17, 17, 17, 17, 17,
1454 16, 16, 16, 16, 16, 16, 16, 16,
1455 17, 17, 17, 17, 17, 17, 17, 17,
1456 16, 16, 16, 16, 16, 0, 16, 16,
1457 15, 15, 15, 15, 17, 29, 16, 29,
1458 29, 29, 16, 16, 16, 0, 16, 16,
1459 15, 15, 15, 15, 17, 29, 29, 29,
1460 16, 16, 16, 16, 0, 0, 16, 16,
1461 15, 15, 15, 15, 0, 29, 29, 29,
1462 16, 16, 16, 16, 16, 16, 16, 16,
1463 15, 15, 15, 15, 15, 29, 29, 29,
1464 0, 0, 16, 16, 16, 0, 16, 16,
1465 15, 15, 15, 15, 17, 29, 29, 0,
1466};
1467
1468static const Q_UINT8 ui_20[] = {
1469 7, 7, 7, 7, 7, 7, 7, 7,
1470 7, 7, 7, 7, 11, 11, 11, 11,
1471 21, 21, 21, 21, 21, 21, 26, 26,
1472 24, 25, 22, 24, 24, 25, 22, 24,
1473 26, 26, 26, 26, 26, 26, 26, 26,
1474 8, 9, 11, 11, 11, 11, 11, 7,
1475 26, 26, 26, 26, 26, 26, 26, 26,
1476 26, 24, 25, 26, 26, 26, 26, 20,
1477 20, 26, 26, 26, 27, 22, 23, 26,
1478 26, 26, 26, 26, 26, 26, 26, 26,
1479 26, 26, 27, 0, 0, 0, 0, 26,
1480 0, 0, 0, 0, 0, 0, 0, 7,
1481 11, 11, 11, 11, 0, 0, 0, 0,
1482 0, 0, 11, 11, 11, 11, 11, 11,
1483 6, 16, 0, 0, 6, 6, 6, 6,
1484 6, 6, 27, 27, 27, 22, 23, 16,
1485 6, 6, 6, 6, 6, 6, 6, 6,
1486 6, 6, 27, 27, 27, 22, 23, 0,
1487 0, 0, 0, 0, 0, 0, 0, 0,
1488 0, 0, 0, 0, 0, 0, 0, 0,
1489 28, 28, 28, 28, 28, 28, 28, 28,
1490 28, 28, 28, 28, 28, 28, 28, 28,
1491 28, 28, 0, 0, 0, 0, 0, 0,
1492 0, 0, 0, 0, 0, 0, 0, 0,
1493 0, 0, 0, 0, 0, 0, 0, 0,
1494 0, 0, 0, 0, 0, 0, 0, 0,
1495 1, 1, 1, 1, 1, 1, 1, 1,
1496 1, 1, 1, 1, 1, 3, 3, 3,
1497 3, 1, 3, 3, 3, 1, 1, 1,
1498 1, 1, 1, 0, 0, 0, 0, 0,
1499 0, 0, 0, 0, 0, 0, 0, 0,
1500 0, 0, 0, 0, 0, 0, 0, 0,
1501};
1502
1503static const Q_UINT8 ui_21[] = {
1504 30, 30, 15, 30, 30, 30, 30, 15,
1505 30, 30, 16, 15, 15, 15, 16, 16,
1506 15, 15, 15, 16, 30, 15, 30, 30,
1507 30, 15, 15, 15, 15, 15, 30, 30,
1508 30, 30, 30, 30, 15, 30, 15, 30,
1509 15, 30, 15, 15, 15, 15, 30, 16,
1510 15, 15, 30, 15, 16, 19, 19, 19,
1511 19, 16, 30, 0, 0, 16, 15, 15,
1512 27, 27, 27, 27, 27, 15, 16, 16,
1513 16, 16, 30, 27, 0, 0, 0, 0,
1514 0, 0, 0, 6, 6, 6, 6, 6,
1515 6, 6, 6, 6, 6, 6, 6, 6,
1516 5, 5, 5, 5, 5, 5, 5, 5,
1517 5, 5, 5, 5, 5, 5, 5, 5,
1518 5, 5, 5, 5, 5, 5, 5, 5,
1519 5, 5, 5, 5, 5, 5, 5, 5,
1520 5, 5, 5, 5, 0, 0, 0, 0,
1521 0, 0, 0, 0, 0, 0, 0, 0,
1522 27, 27, 27, 27, 27, 30, 30, 30,
1523 30, 30, 27, 27, 30, 30, 30, 30,
1524 27, 30, 30, 27, 30, 30, 27, 30,
1525 30, 30, 30, 30, 30, 30, 27, 30,
1526 30, 30, 30, 30, 30, 30, 30, 30,
1527 30, 30, 30, 30, 30, 30, 30, 30,
1528 30, 30, 30, 30, 30, 30, 30, 30,
1529 30, 30, 30, 30, 30, 30, 27, 27,
1530 30, 30, 27, 30, 27, 30, 30, 30,
1531 30, 30, 30, 30, 30, 30, 30, 30,
1532 30, 30, 30, 30, 30, 30, 30, 30,
1533 30, 30, 30, 30, 30, 30, 30, 30,
1534 30, 30, 30, 30, 27, 27, 27, 27,
1535 27, 27, 27, 27, 27, 27, 27, 27,
1536};
1537
1538static const Q_UINT8 ui_22[] = {
1539 27, 27, 27, 27, 27, 27, 27, 27,
1540 27, 27, 27, 27, 27, 27, 27, 27,
1541 27, 27, 27, 27, 27, 27, 27, 27,
1542 27, 27, 27, 27, 27, 27, 27, 27,
1543 27, 27, 27, 27, 27, 27, 27, 27,
1544 27, 27, 27, 27, 27, 27, 27, 27,
1545 27, 27, 27, 27, 27, 27, 27, 27,
1546 27, 27, 27, 27, 27, 27, 27, 27,
1547 27, 27, 27, 27, 27, 27, 27, 27,
1548 27, 27, 27, 27, 27, 27, 27, 27,
1549 27, 27, 27, 27, 27, 27, 27, 27,
1550 27, 27, 27, 27, 27, 27, 27, 27,
1551 27, 27, 27, 27, 27, 27, 27, 27,
1552 27, 27, 27, 27, 27, 27, 27, 27,
1553 27, 27, 27, 27, 27, 27, 27, 27,
1554 27, 27, 27, 27, 27, 27, 27, 27,
1555 27, 27, 27, 27, 27, 27, 27, 27,
1556 27, 27, 27, 27, 27, 27, 27, 27,
1557 27, 27, 27, 27, 27, 27, 27, 27,
1558 27, 27, 27, 27, 27, 27, 27, 27,
1559 27, 27, 27, 27, 27, 27, 27, 27,
1560 27, 27, 27, 27, 27, 27, 27, 27,
1561 27, 27, 27, 27, 27, 27, 27, 27,
1562 27, 27, 27, 27, 27, 27, 27, 27,
1563 27, 27, 27, 27, 27, 27, 27, 27,
1564 27, 27, 27, 27, 27, 27, 27, 27,
1565 27, 27, 27, 27, 27, 27, 27, 27,
1566 27, 27, 27, 27, 27, 27, 27, 27,
1567 27, 27, 27, 27, 27, 27, 27, 27,
1568 27, 27, 27, 27, 27, 27, 27, 27,
1569 27, 27, 27, 27, 27, 27, 27, 27,
1570 27, 27, 27, 27, 27, 27, 27, 27,
1571};
1572
1573static const Q_UINT8 ui_23[] = {
1574 30, 30, 30, 30, 30, 30, 30, 30,
1575 27, 27, 27, 27, 30, 30, 30, 30,
1576 30, 30, 30, 30, 30, 30, 30, 30,
1577 30, 30, 30, 30, 30, 30, 30, 30,
1578 27, 27, 30, 30, 30, 30, 30, 30,
1579 30, 22, 23, 30, 30, 30, 30, 30,
1580 30, 30, 30, 30, 30, 30, 30, 30,
1581 30, 30, 30, 30, 30, 30, 30, 30,
1582 30, 30, 30, 30, 30, 30, 30, 30,
1583 30, 30, 30, 30, 30, 30, 30, 30,
1584 30, 30, 30, 30, 30, 30, 30, 30,
1585 30, 30, 30, 30, 30, 30, 30, 30,
1586 30, 30, 30, 30, 30, 30, 30, 30,
1587 30, 30, 30, 30, 30, 30, 30, 30,
1588 30, 30, 30, 30, 30, 30, 30, 30,
1589 30, 30, 30, 30, 27, 30, 30, 30,
1590 30, 30, 30, 30, 30, 30, 30, 30,
1591 30, 30, 30, 30, 30, 30, 30, 30,
1592 30, 30, 30, 30, 30, 30, 30, 30,
1593 30, 30, 30, 27, 27, 27, 27, 27,
1594 27, 27, 27, 27, 27, 27, 27, 27,
1595 27, 27, 27, 27, 27, 27, 27, 27,
1596 27, 27, 27, 27, 22, 23, 26, 30,
1597 30, 30, 30, 30, 30, 30, 30, 30,
1598 30, 30, 30, 30, 30, 30, 30, 30,
1599 30, 30, 30, 30, 30, 30, 30, 0,
1600 0, 0, 0, 0, 0, 0, 0, 0,
1601 0, 0, 0, 0, 0, 0, 0, 0,
1602 0, 0, 0, 0, 0, 0, 0, 0,
1603 0, 0, 0, 0, 0, 0, 0, 0,
1604 0, 0, 0, 0, 0, 0, 0, 0,
1605 0, 0, 0, 0, 0, 0, 0, 0,
1606};
1607
1608static const Q_UINT8 ui_24[] = {
1609 30, 30, 30, 30, 30, 30, 30, 30,
1610 30, 30, 30, 30, 30, 30, 30, 30,
1611 30, 30, 30, 30, 30, 30, 30, 30,
1612 30, 30, 30, 30, 30, 30, 30, 30,
1613 30, 30, 30, 30, 30, 30, 30, 0,
1614 0, 0, 0, 0, 0, 0, 0, 0,
1615 0, 0, 0, 0, 0, 0, 0, 0,
1616 0, 0, 0, 0, 0, 0, 0, 0,
1617 30, 30, 30, 30, 30, 30, 30, 30,
1618 30, 30, 30, 0, 0, 0, 0, 0,
1619 0, 0, 0, 0, 0, 0, 0, 0,
1620 0, 0, 0, 0, 0, 0, 0, 0,
1621 6, 6, 6, 6, 6, 6, 6, 6,
1622 6, 6, 6, 6, 6, 6, 6, 6,
1623 6, 6, 6, 6, 6, 6, 6, 6,
1624 6, 6, 6, 6, 6, 6, 6, 6,
1625 6, 6, 6, 6, 6, 6, 6, 6,
1626 6, 6, 6, 6, 6, 6, 6, 6,
1627 6, 6, 6, 6, 6, 6, 6, 6,
1628 6, 6, 6, 6, 30, 30, 30, 30,
1629 30, 30, 30, 30, 30, 30, 30, 30,
1630 30, 30, 30, 30, 30, 30, 30, 30,
1631 30, 30, 30, 30, 30, 30, 30, 30,
1632 30, 30, 30, 30, 30, 30, 30, 30,
1633 30, 30, 30, 30, 30, 30, 30, 30,
1634 30, 30, 30, 30, 30, 30, 30, 30,
1635 30, 30, 30, 30, 30, 30, 30, 30,
1636 30, 30, 30, 30, 30, 30, 30, 30,
1637 30, 30, 30, 30, 30, 30, 30, 30,
1638 30, 30, 6, 6, 6, 6, 6, 6,
1639 6, 6, 6, 6, 6, 6, 6, 6,
1640 6, 6, 6, 6, 6, 6, 6, 0,
1641};
1642
1643static const Q_UINT8 ui_25[] = {
1644 30, 30, 30, 30, 30, 30, 30, 30,
1645 30, 30, 30, 30, 30, 30, 30, 30,
1646 30, 30, 30, 30, 30, 30, 30, 30,
1647 30, 30, 30, 30, 30, 30, 30, 30,
1648 30, 30, 30, 30, 30, 30, 30, 30,
1649 30, 30, 30, 30, 30, 30, 30, 30,
1650 30, 30, 30, 30, 30, 30, 30, 30,
1651 30, 30, 30, 30, 30, 30, 30, 30,
1652 30, 30, 30, 30, 30, 30, 30, 30,
1653 30, 30, 30, 30, 30, 30, 30, 30,
1654 30, 30, 30, 30, 30, 30, 30, 30,
1655 30, 30, 30, 30, 30, 30, 30, 30,
1656 30, 30, 30, 30, 30, 30, 30, 30,
1657 30, 30, 30, 30, 30, 30, 30, 30,
1658 30, 30, 30, 30, 30, 30, 30, 30,
1659 30, 30, 30, 30, 30, 30, 30, 30,
1660 30, 30, 30, 30, 30, 30, 30, 30,
1661 30, 30, 30, 30, 30, 30, 30, 30,
1662 30, 30, 30, 30, 30, 30, 30, 30,
1663 30, 30, 30, 30, 30, 30, 30, 30,
1664 30, 30, 30, 30, 30, 30, 30, 30,
1665 30, 30, 30, 30, 30, 30, 30, 30,
1666 30, 30, 30, 30, 30, 30, 30, 27,
1667 30, 30, 30, 30, 30, 30, 30, 30,
1668 30, 27, 30, 30, 30, 30, 30, 30,
1669 30, 30, 30, 30, 30, 30, 30, 30,
1670 30, 30, 30, 30, 30, 30, 30, 30,
1671 30, 30, 30, 30, 30, 30, 30, 30,
1672 30, 30, 30, 30, 30, 30, 30, 30,
1673 30, 30, 30, 30, 30, 30, 30, 30,
1674 30, 30, 30, 30, 30, 30, 30, 30,
1675 27, 27, 27, 27, 27, 27, 27, 27,
1676};
1677
1678static const Q_UINT8 ui_26[] = {
1679 30, 30, 30, 30, 30, 30, 30, 30,
1680 30, 30, 30, 30, 30, 30, 30, 30,
1681 30, 30, 30, 30, 0, 0, 30, 30,
1682 0, 30, 30, 30, 30, 30, 30, 30,
1683 30, 30, 30, 30, 30, 30, 30, 30,
1684 30, 30, 30, 30, 30, 30, 30, 30,
1685 30, 30, 30, 30, 30, 30, 30, 30,
1686 30, 30, 30, 30, 30, 30, 30, 30,
1687 30, 30, 30, 30, 30, 30, 30, 30,
1688 30, 30, 30, 30, 30, 30, 30, 30,
1689 30, 30, 30, 30, 30, 30, 30, 30,
1690 30, 30, 30, 30, 30, 30, 30, 30,
1691 30, 30, 30, 30, 30, 30, 30, 30,
1692 30, 30, 30, 30, 30, 30, 30, 27,
1693 30, 30, 30, 30, 30, 30, 30, 30,
1694 30, 30, 30, 30, 30, 30, 0, 0,
1695 30, 30, 30, 30, 30, 30, 30, 30,
1696 30, 30, 0, 0, 0, 0, 0, 0,
1697 0, 0, 0, 0, 0, 0, 0, 0,
1698 0, 0, 0, 0, 0, 0, 0, 0,
1699 0, 0, 0, 0, 0, 0, 0, 0,
1700 0, 0, 0, 0, 0, 0, 0, 0,
1701 0, 0, 0, 0, 0, 0, 0, 0,
1702 0, 0, 0, 0, 0, 0, 0, 0,
1703 0, 0, 0, 0, 0, 0, 0, 0,
1704 0, 0, 0, 0, 0, 0, 0, 0,
1705 0, 0, 0, 0, 0, 0, 0, 0,
1706 0, 0, 0, 0, 0, 0, 0, 0,
1707 0, 0, 0, 0, 0, 0, 0, 0,
1708 0, 0, 0, 0, 0, 0, 0, 0,
1709 0, 0, 0, 0, 0, 0, 0, 0,
1710 0, 0, 0, 0, 0, 0, 0, 0,
1711};
1712
1713static const Q_UINT8 ui_27[] = {
1714 0, 30, 30, 30, 30, 0, 30, 30,
1715 30, 30, 0, 0, 30, 30, 30, 30,
1716 30, 30, 30, 30, 30, 30, 30, 30,
1717 30, 30, 30, 30, 30, 30, 30, 30,
1718 30, 30, 30, 30, 30, 30, 30, 30,
1719 0, 30, 30, 30, 30, 30, 30, 30,
1720 30, 30, 30, 30, 30, 30, 30, 30,
1721 30, 30, 30, 30, 30, 30, 30, 30,
1722 30, 30, 30, 30, 30, 30, 30, 30,
1723 30, 30, 30, 30, 0, 30, 0, 30,
1724 30, 30, 30, 0, 0, 0, 30, 0,
1725 30, 30, 30, 30, 30, 30, 30, 0,
1726 0, 30, 30, 30, 30, 30, 30, 30,
1727 22, 23, 22, 23, 22, 23, 22, 23,
1728 22, 23, 22, 23, 22, 23, 6, 6,
1729 6, 6, 6, 6, 6, 6, 6, 6,
1730 6, 6, 6, 6, 6, 6, 6, 6,
1731 6, 6, 6, 6, 6, 6, 6, 6,
1732 6, 6, 6, 6, 30, 0, 0, 0,
1733 30, 30, 30, 30, 30, 30, 30, 30,
1734 30, 30, 30, 30, 30, 30, 30, 30,
1735 30, 30, 30, 30, 30, 30, 30, 30,
1736 0, 30, 30, 30, 30, 30, 30, 30,
1737 30, 30, 30, 30, 30, 30, 30, 0,
1738 0, 0, 0, 0, 0, 0, 0, 0,
1739 0, 0, 0, 0, 0, 0, 0, 0,
1740 27, 27, 27, 27, 27, 27, 27, 27,
1741 27, 27, 27, 27, 27, 27, 27, 27,
1742 27, 27, 27, 27, 27, 27, 22, 23,
1743 22, 23, 22, 23, 0, 0, 0, 0,
1744 27, 27, 27, 27, 27, 27, 27, 27,
1745 27, 27, 27, 27, 27, 27, 27, 27,
1746};
1747
1748static const Q_UINT8 ui_28[] = {
1749 30, 30, 30, 30, 30, 30, 30, 30,
1750 30, 30, 30, 30, 30, 30, 30, 30,
1751 30, 30, 30, 30, 30, 30, 30, 30,
1752 30, 30, 30, 30, 30, 30, 30, 30,
1753 30, 30, 30, 30, 30, 30, 30, 30,
1754 30, 30, 30, 30, 30, 30, 30, 30,
1755 30, 30, 30, 30, 30, 30, 30, 30,
1756 30, 30, 30, 30, 30, 30, 30, 30,
1757 30, 30, 30, 30, 30, 30, 30, 30,
1758 30, 30, 30, 30, 30, 30, 30, 30,
1759 30, 30, 30, 30, 30, 30, 30, 30,
1760 30, 30, 30, 30, 30, 30, 30, 30,
1761 30, 30, 30, 30, 30, 30, 30, 30,
1762 30, 30, 30, 30, 30, 30, 30, 30,
1763 30, 30, 30, 30, 30, 30, 30, 30,
1764 30, 30, 30, 30, 30, 30, 30, 30,
1765 30, 30, 30, 30, 30, 30, 30, 30,
1766 30, 30, 30, 30, 30, 30, 30, 30,
1767 30, 30, 30, 30, 30, 30, 30, 30,
1768 30, 30, 30, 30, 30, 30, 30, 30,
1769 30, 30, 30, 30, 30, 30, 30, 30,
1770 30, 30, 30, 30, 30, 30, 30, 30,
1771 30, 30, 30, 30, 30, 30, 30, 30,
1772 30, 30, 30, 30, 30, 30, 30, 30,
1773 30, 30, 30, 30, 30, 30, 30, 30,
1774 30, 30, 30, 30, 30, 30, 30, 30,
1775 30, 30, 30, 30, 30, 30, 30, 30,
1776 30, 30, 30, 30, 30, 30, 30, 30,
1777 30, 30, 30, 30, 30, 30, 30, 30,
1778 30, 30, 30, 30, 30, 30, 30, 30,
1779 30, 30, 30, 30, 30, 30, 30, 30,
1780 30, 30, 30, 30, 30, 30, 30, 30,
1781};
1782
1783static const Q_UINT8 ui_29[] = {
1784 27, 27, 27, 27, 27, 27, 27, 27,
1785 27, 27, 27, 27, 27, 27, 27, 27,
1786 27, 27, 27, 27, 27, 27, 27, 27,
1787 27, 27, 27, 27, 27, 27, 27, 27,
1788 27, 27, 27, 27, 27, 27, 27, 27,
1789 27, 27, 27, 27, 27, 27, 27, 27,
1790 27, 27, 27, 27, 27, 27, 27, 27,
1791 27, 27, 27, 27, 27, 27, 27, 27,
1792 27, 27, 27, 27, 27, 27, 27, 27,
1793 27, 27, 27, 27, 27, 27, 27, 27,
1794 27, 27, 27, 27, 27, 27, 27, 27,
1795 27, 27, 27, 27, 27, 27, 27, 27,
1796 27, 27, 27, 27, 27, 27, 27, 27,
1797 27, 27, 27, 27, 27, 27, 27, 27,
1798 27, 27, 27, 27, 27, 27, 27, 27,
1799 27, 27, 27, 27, 27, 27, 27, 27,
1800 27, 27, 27, 22, 23, 22, 23, 22,
1801 23, 22, 23, 22, 23, 22, 23, 22,
1802 23, 22, 23, 22, 23, 22, 23, 22,
1803 23, 27, 27, 27, 27, 27, 27, 27,
1804 27, 27, 27, 27, 27, 27, 27, 27,
1805 27, 27, 27, 27, 27, 27, 27, 27,
1806 27, 27, 27, 27, 27, 27, 27, 27,
1807 27, 27, 27, 27, 27, 27, 27, 27,
1808 27, 27, 27, 27, 27, 27, 27, 27,
1809 27, 27, 27, 27, 27, 27, 27, 27,
1810 27, 27, 27, 27, 27, 27, 27, 27,
1811 22, 23, 22, 23, 27, 27, 27, 27,
1812 27, 27, 27, 27, 27, 27, 27, 27,
1813 27, 27, 27, 27, 27, 27, 27, 27,
1814 27, 27, 27, 27, 27, 27, 27, 27,
1815 27, 27, 27, 27, 22, 23, 27, 27,
1816};
1817
1818static const Q_UINT8 ui_2E[] = {
1819 0, 0, 0, 0, 0, 0, 0, 0,
1820 0, 0, 0, 0, 0, 0, 0, 0,
1821 0, 0, 0, 0, 0, 0, 0, 0,
1822 0, 0, 0, 0, 0, 0, 0, 0,
1823 0, 0, 0, 0, 0, 0, 0, 0,
1824 0, 0, 0, 0, 0, 0, 0, 0,
1825 0, 0, 0, 0, 0, 0, 0, 0,
1826 0, 0, 0, 0, 0, 0, 0, 0,
1827 0, 0, 0, 0, 0, 0, 0, 0,
1828 0, 0, 0, 0, 0, 0, 0, 0,
1829 0, 0, 0, 0, 0, 0, 0, 0,
1830 0, 0, 0, 0, 0, 0, 0, 0,
1831 0, 0, 0, 0, 0, 0, 0, 0,
1832 0, 0, 0, 0, 0, 0, 0, 0,
1833 0, 0, 0, 0, 0, 0, 0, 0,
1834 0, 0, 0, 0, 0, 0, 0, 0,
1835 30, 30, 30, 30, 30, 30, 30, 30,
1836 30, 30, 30, 30, 30, 30, 30, 30,
1837 30, 30, 30, 30, 30, 30, 30, 30,
1838 30, 30, 0, 30, 30, 30, 30, 30,
1839 30, 30, 30, 30, 30, 30, 30, 30,
1840 30, 30, 30, 30, 30, 30, 30, 30,
1841 30, 30, 30, 30, 30, 30, 30, 30,
1842 30, 30, 30, 30, 30, 30, 30, 30,
1843 30, 30, 30, 30, 30, 30, 30, 30,
1844 30, 30, 30, 30, 30, 30, 30, 30,
1845 30, 30, 30, 30, 30, 30, 30, 30,
1846 30, 30, 30, 30, 30, 30, 30, 30,
1847 30, 30, 30, 30, 30, 30, 30, 30,
1848 30, 30, 30, 30, 30, 30, 30, 30,
1849 30, 30, 30, 30, 0, 0, 0, 0,
1850 0, 0, 0, 0, 0, 0, 0, 0,
1851};
1852
1853static const Q_UINT8 ui_2F[] = {
1854 30, 30, 30, 30, 30, 30, 30, 30,
1855 30, 30, 30, 30, 30, 30, 30, 30,
1856 30, 30, 30, 30, 30, 30, 30, 30,
1857 30, 30, 30, 30, 30, 30, 30, 30,
1858 30, 30, 30, 30, 30, 30, 30, 30,
1859 30, 30, 30, 30, 30, 30, 30, 30,
1860 30, 30, 30, 30, 30, 30, 30, 30,
1861 30, 30, 30, 30, 30, 30, 30, 30,
1862 30, 30, 30, 30, 30, 30, 30, 30,
1863 30, 30, 30, 30, 30, 30, 30, 30,
1864 30, 30, 30, 30, 30, 30, 30, 30,
1865 30, 30, 30, 30, 30, 30, 30, 30,
1866 30, 30, 30, 30, 30, 30, 30, 30,
1867 30, 30, 30, 30, 30, 30, 30, 30,
1868 30, 30, 30, 30, 30, 30, 30, 30,
1869 30, 30, 30, 30, 30, 30, 30, 30,
1870 30, 30, 30, 30, 30, 30, 30, 30,
1871 30, 30, 30, 30, 30, 30, 30, 30,
1872 30, 30, 30, 30, 30, 30, 30, 30,
1873 30, 30, 30, 30, 30, 30, 30, 30,
1874 30, 30, 30, 30, 30, 30, 30, 30,
1875 30, 30, 30, 30, 30, 30, 30, 30,
1876 30, 30, 30, 30, 30, 30, 30, 30,
1877 30, 30, 30, 30, 30, 30, 30, 30,
1878 30, 30, 30, 30, 30, 30, 30, 30,
1879 30, 30, 30, 30, 30, 30, 30, 30,
1880 30, 30, 30, 30, 30, 30, 0, 0,
1881 0, 0, 0, 0, 0, 0, 0, 0,
1882 0, 0, 0, 0, 0, 0, 0, 0,
1883 0, 0, 0, 0, 0, 0, 0, 0,
1884 30, 30, 30, 30, 30, 30, 30, 30,
1885 30, 30, 30, 30, 0, 0, 0, 0,
1886};
1887
1888static const Q_UINT8 ui_30[] = {
1889 7, 26, 26, 26, 30, 18, 19, 5,
1890 22, 23, 22, 23, 22, 23, 22, 23,
1891 22, 23, 30, 30, 22, 23, 22, 23,
1892 22, 23, 22, 23, 21, 22, 23, 23,
1893 30, 5, 5, 5, 5, 5, 5, 5,
1894 5, 5, 1, 1, 1, 1, 1, 1,
1895 21, 18, 18, 18, 18, 18, 30, 30,
1896 5, 5, 5, 18, 19, 26, 30, 30,
1897 0, 19, 19, 19, 19, 19, 19, 19,
1898 19, 19, 19, 19, 19, 19, 19, 19,
1899 19, 19, 19, 19, 19, 19, 19, 19,
1900 19, 19, 19, 19, 19, 19, 19, 19,
1901 19, 19, 19, 19, 19, 19, 19, 19,
1902 19, 19, 19, 19, 19, 19, 19, 19,
1903 19, 19, 19, 19, 19, 19, 19, 19,
1904 19, 19, 19, 19, 19, 19, 19, 19,
1905 19, 19, 19, 19, 19, 19, 19, 19,
1906 19, 19, 19, 19, 19, 19, 19, 19,
1907 19, 19, 19, 19, 19, 19, 19, 0,
1908 0, 1, 1, 29, 29, 18, 18, 19,
1909 21, 19, 19, 19, 19, 19, 19, 19,
1910 19, 19, 19, 19, 19, 19, 19, 19,
1911 19, 19, 19, 19, 19, 19, 19, 19,
1912 19, 19, 19, 19, 19, 19, 19, 19,
1913 19, 19, 19, 19, 19, 19, 19, 19,
1914 19, 19, 19, 19, 19, 19, 19, 19,
1915 19, 19, 19, 19, 19, 19, 19, 19,
1916 19, 19, 19, 19, 19, 19, 19, 19,
1917 19, 19, 19, 19, 19, 19, 19, 19,
1918 19, 19, 19, 19, 19, 19, 19, 19,
1919 19, 19, 19, 19, 19, 19, 19, 19,
1920 19, 19, 19, 20, 18, 18, 18, 19,
1921};
1922
1923static const Q_UINT8 ui_31[] = {
1924 0, 0, 0, 0, 0, 19, 19, 19,
1925 19, 19, 19, 19, 19, 19, 19, 19,
1926 19, 19, 19, 19, 19, 19, 19, 19,
1927 19, 19, 19, 19, 19, 19, 19, 19,
1928 19, 19, 19, 19, 19, 19, 19, 19,
1929 19, 19, 19, 19, 19, 0, 0, 0,
1930 0, 19, 19, 19, 19, 19, 19, 19,
1931 19, 19, 19, 19, 19, 19, 19, 19,
1932 19, 19, 19, 19, 19, 19, 19, 19,
1933 19, 19, 19, 19, 19, 19, 19, 19,
1934 19, 19, 19, 19, 19, 19, 19, 19,
1935 19, 19, 19, 19, 19, 19, 19, 19,
1936 19, 19, 19, 19, 19, 19, 19, 19,
1937 19, 19, 19, 19, 19, 19, 19, 19,
1938 19, 19, 19, 19, 19, 19, 19, 19,
1939 19, 19, 19, 19, 19, 19, 19, 19,
1940 19, 19, 19, 19, 19, 19, 19, 19,
1941 19, 19, 19, 19, 19, 19, 19, 0,
1942 30, 30, 6, 6, 6, 6, 30, 30,
1943 30, 30, 30, 30, 30, 30, 30, 30,
1944 19, 19, 19, 19, 19, 19, 19, 19,
1945 19, 19, 19, 19, 19, 19, 19, 19,
1946 19, 19, 19, 19, 19, 19, 19, 19,
1947 0, 0, 0, 0, 0, 0, 0, 0,
1948 0, 0, 0, 0, 0, 0, 0, 0,
1949 0, 0, 0, 0, 0, 0, 0, 0,
1950 0, 0, 0, 0, 0, 0, 0, 0,
1951 0, 0, 0, 0, 0, 0, 0, 0,
1952 0, 0, 0, 0, 0, 0, 0, 0,
1953 0, 0, 0, 0, 0, 0, 0, 0,
1954 19, 19, 19, 19, 19, 19, 19, 19,
1955 19, 19, 19, 19, 19, 19, 19, 19,
1956};
1957
1958static const Q_UINT8 ui_32[] = {
1959 30, 30, 30, 30, 30, 30, 30, 30,
1960 30, 30, 30, 30, 30, 30, 30, 30,
1961 30, 30, 30, 30, 30, 30, 30, 30,
1962 30, 30, 30, 30, 30, 0, 0, 0,
1963 6, 6, 6, 6, 6, 6, 6, 6,
1964 6, 6, 30, 30, 30, 30, 30, 30,
1965 30, 30, 30, 30, 30, 30, 30, 30,
1966 30, 30, 30, 30, 30, 30, 30, 30,
1967 30, 30, 30, 30, 0, 0, 0, 0,
1968 0, 0, 0, 0, 0, 0, 0, 0,
1969 0, 6, 6, 6, 6, 6, 6, 6,
1970 6, 6, 6, 6, 6, 6, 6, 6,
1971 30, 30, 30, 30, 30, 30, 30, 30,
1972 30, 30, 30, 30, 30, 30, 30, 30,
1973 30, 30, 30, 30, 30, 30, 30, 30,
1974 30, 30, 30, 30, 0, 0, 0, 30,
1975 6, 6, 6, 6, 6, 6, 6, 6,
1976 6, 6, 30, 30, 30, 30, 30, 30,
1977 30, 30, 30, 30, 30, 30, 30, 30,
1978 30, 30, 30, 30, 30, 30, 30, 30,
1979 30, 30, 30, 30, 30, 30, 30, 30,
1980 30, 30, 30, 30, 30, 30, 30, 30,
1981 30, 6, 6, 6, 6, 6, 6, 6,
1982 6, 6, 6, 6, 6, 6, 6, 6,
1983 30, 30, 30, 30, 30, 30, 30, 30,
1984 30, 30, 30, 30, 0, 0, 0, 0,
1985 30, 30, 30, 30, 30, 30, 30, 30,
1986 30, 30, 30, 30, 30, 30, 30, 30,
1987 30, 30, 30, 30, 30, 30, 30, 30,
1988 30, 30, 30, 30, 30, 30, 30, 30,
1989 30, 30, 30, 30, 30, 30, 30, 30,
1990 30, 30, 30, 30, 30, 30, 30, 0,
1991};
1992
1993static const Q_UINT8 ui_33[] = {
1994 30, 30, 30, 30, 30, 30, 30, 30,
1995 30, 30, 30, 30, 30, 30, 30, 30,
1996 30, 30, 30, 30, 30, 30, 30, 30,
1997 30, 30, 30, 30, 30, 30, 30, 30,
1998 30, 30, 30, 30, 30, 30, 30, 30,
1999 30, 30, 30, 30, 30, 30, 30, 30,
2000 30, 30, 30, 30, 30, 30, 30, 30,
2001 30, 30, 30, 30, 30, 30, 30, 30,
2002 30, 30, 30, 30, 30, 30, 30, 30,
2003 30, 30, 30, 30, 30, 30, 30, 30,
2004 30, 30, 30, 30, 30, 30, 30, 30,
2005 30, 30, 30, 30, 30, 30, 30, 30,
2006 30, 30, 30, 30, 30, 30, 30, 30,
2007 30, 30, 30, 30, 30, 30, 30, 30,
2008 30, 30, 30, 30, 30, 30, 30, 0,
2009 0, 0, 0, 30, 30, 30, 30, 30,
2010 30, 30, 30, 30, 30, 30, 30, 30,
2011 30, 30, 30, 30, 30, 30, 30, 30,
2012 30, 30, 30, 30, 30, 30, 30, 30,
2013 30, 30, 30, 30, 30, 30, 30, 30,
2014 30, 30, 30, 30, 30, 30, 30, 30,
2015 30, 30, 30, 30, 30, 30, 30, 30,
2016 30, 30, 30, 30, 30, 30, 30, 30,
2017 30, 30, 30, 30, 30, 30, 30, 30,
2018 30, 30, 30, 30, 30, 30, 30, 30,
2019 30, 30, 30, 30, 30, 30, 30, 30,
2020 30, 30, 30, 30, 30, 30, 30, 30,
2021 30, 30, 30, 30, 30, 30, 0, 0,
2022 30, 30, 30, 30, 30, 30, 30, 30,
2023 30, 30, 30, 30, 30, 30, 30, 30,
2024 30, 30, 30, 30, 30, 30, 30, 30,
2025 30, 30, 30, 30, 30, 30, 30, 0,
2026};
2027
2028static const Q_UINT8 ui_4D[] = {
2029 19, 19, 19, 19, 19, 19, 19, 19,
2030 19, 19, 19, 19, 19, 19, 19, 19,
2031 19, 19, 19, 19, 19, 19, 19, 19,
2032 19, 19, 19, 19, 19, 19, 19, 19,
2033 19, 19, 19, 19, 19, 19, 19, 19,
2034 19, 19, 19, 19, 19, 19, 19, 19,
2035 19, 19, 19, 19, 19, 19, 19, 19,
2036 19, 19, 19, 19, 19, 19, 19, 19,
2037 19, 19, 19, 19, 19, 19, 19, 19,
2038 19, 19, 19, 19, 19, 19, 19, 19,
2039 19, 19, 19, 19, 19, 19, 19, 19,
2040 19, 19, 19, 19, 19, 19, 19, 19,
2041 19, 19, 19, 19, 19, 19, 19, 19,
2042 19, 19, 19, 19, 19, 19, 19, 19,
2043 19, 19, 19, 19, 19, 19, 19, 19,
2044 19, 19, 19, 19, 19, 19, 19, 19,
2045 19, 19, 19, 19, 19, 19, 19, 19,
2046 19, 19, 19, 19, 19, 19, 19, 19,
2047 19, 19, 19, 19, 19, 19, 19, 19,
2048 19, 19, 19, 19, 19, 19, 19, 19,
2049 19, 19, 19, 19, 19, 19, 19, 19,
2050 19, 19, 19, 19, 19, 19, 19, 19,
2051 19, 19, 19, 19, 19, 19, 0, 0,
2052 0, 0, 0, 0, 0, 0, 0, 0,
2053 0, 0, 0, 0, 0, 0, 0, 0,
2054 0, 0, 0, 0, 0, 0, 0, 0,
2055 0, 0, 0, 0, 0, 0, 0, 0,
2056 0, 0, 0, 0, 0, 0, 0, 0,
2057 0, 0, 0, 0, 0, 0, 0, 0,
2058 0, 0, 0, 0, 0, 0, 0, 0,
2059 0, 0, 0, 0, 0, 0, 0, 0,
2060 0, 0, 0, 0, 0, 0, 0, 0,
2061};
2062
2063static const Q_UINT8 ui_9F[] = {
2064 19, 19, 19, 19, 19, 19, 19, 19,
2065 19, 19, 19, 19, 19, 19, 19, 19,
2066 19, 19, 19, 19, 19, 19, 19, 19,
2067 19, 19, 19, 19, 19, 19, 19, 19,
2068 19, 19, 19, 19, 19, 19, 19, 19,
2069 19, 19, 19, 19, 19, 19, 19, 19,
2070 19, 19, 19, 19, 19, 19, 19, 19,
2071 19, 19, 19, 19, 19, 19, 19, 19,
2072 19, 19, 19, 19, 19, 19, 19, 19,
2073 19, 19, 19, 19, 19, 19, 19, 19,
2074 19, 19, 19, 19, 19, 19, 19, 19,
2075 19, 19, 19, 19, 19, 19, 19, 19,
2076 19, 19, 19, 19, 19, 19, 19, 19,
2077 19, 19, 19, 19, 19, 19, 19, 19,
2078 19, 19, 19, 19, 19, 19, 19, 19,
2079 19, 19, 19, 19, 19, 19, 19, 19,
2080 19, 19, 19, 19, 19, 19, 19, 19,
2081 19, 19, 19, 19, 19, 19, 19, 19,
2082 19, 19, 19, 19, 19, 19, 19, 19,
2083 19, 19, 19, 19, 19, 19, 19, 19,
2084 19, 19, 19, 19, 19, 19, 0, 0,
2085 0, 0, 0, 0, 0, 0, 0, 0,
2086 0, 0, 0, 0, 0, 0, 0, 0,
2087 0, 0, 0, 0, 0, 0, 0, 0,
2088 0, 0, 0, 0, 0, 0, 0, 0,
2089 0, 0, 0, 0, 0, 0, 0, 0,
2090 0, 0, 0, 0, 0, 0, 0, 0,
2091 0, 0, 0, 0, 0, 0, 0, 0,
2092 0, 0, 0, 0, 0, 0, 0, 0,
2093 0, 0, 0, 0, 0, 0, 0, 0,
2094 0, 0, 0, 0, 0, 0, 0, 0,
2095 0, 0, 0, 0, 0, 0, 0, 0,
2096};
2097
2098static const Q_UINT8 ui_A4[] = {
2099 19, 19, 19, 19, 19, 19, 19, 19,
2100 19, 19, 19, 19, 19, 19, 19, 19,
2101 19, 19, 19, 19, 19, 19, 19, 19,
2102 19, 19, 19, 19, 19, 19, 19, 19,
2103 19, 19, 19, 19, 19, 19, 19, 19,
2104 19, 19, 19, 19, 19, 19, 19, 19,
2105 19, 19, 19, 19, 19, 19, 19, 19,
2106 19, 19, 19, 19, 19, 19, 19, 19,
2107 19, 19, 19, 19, 19, 19, 19, 19,
2108 19, 19, 19, 19, 19, 19, 19, 19,
2109 19, 19, 19, 19, 19, 19, 19, 19,
2110 19, 19, 19, 19, 19, 19, 19, 19,
2111 19, 19, 19, 19, 19, 19, 19, 19,
2112 19, 19, 19, 19, 19, 19, 19, 19,
2113 19, 19, 19, 19, 19, 19, 19, 19,
2114 19, 19, 19, 19, 19, 19, 19, 19,
2115 19, 19, 19, 19, 19, 19, 19, 19,
2116 19, 19, 19, 19, 19, 0, 0, 0,
2117 30, 30, 30, 30, 30, 30, 30, 30,
2118 30, 30, 30, 30, 30, 30, 30, 30,
2119 30, 30, 30, 30, 30, 30, 30, 30,
2120 30, 30, 30, 30, 30, 30, 30, 30,
2121 30, 30, 30, 30, 30, 30, 30, 30,
2122 30, 30, 30, 30, 30, 30, 30, 30,
2123 30, 30, 30, 30, 30, 30, 30, 0,
2124 0, 0, 0, 0, 0, 0, 0, 0,
2125 0, 0, 0, 0, 0, 0, 0, 0,
2126 0, 0, 0, 0, 0, 0, 0, 0,
2127 0, 0, 0, 0, 0, 0, 0, 0,
2128 0, 0, 0, 0, 0, 0, 0, 0,
2129 0, 0, 0, 0, 0, 0, 0, 0,
2130 0, 0, 0, 0, 0, 0, 0, 0,
2131};
2132
2133static const Q_UINT8 ui_D7[] = {
2134 19, 19, 19, 19, 19, 19, 19, 19,
2135 19, 19, 19, 19, 19, 19, 19, 19,
2136 19, 19, 19, 19, 19, 19, 19, 19,
2137 19, 19, 19, 19, 19, 19, 19, 19,
2138 19, 19, 19, 19, 19, 19, 19, 19,
2139 19, 19, 19, 19, 19, 19, 19, 19,
2140 19, 19, 19, 19, 19, 19, 19, 19,
2141 19, 19, 19, 19, 19, 19, 19, 19,
2142 19, 19, 19, 19, 19, 19, 19, 19,
2143 19, 19, 19, 19, 19, 19, 19, 19,
2144 19, 19, 19, 19, 19, 19, 19, 19,
2145 19, 19, 19, 19, 19, 19, 19, 19,
2146 19, 19, 19, 19, 19, 19, 19, 19,
2147 19, 19, 19, 19, 19, 19, 19, 19,
2148 19, 19, 19, 19, 19, 19, 19, 19,
2149 19, 19, 19, 19, 19, 19, 19, 19,
2150 19, 19, 19, 19, 19, 19, 19, 19,
2151 19, 19, 19, 19, 19, 19, 19, 19,
2152 19, 19, 19, 19, 19, 19, 19, 19,
2153 19, 19, 19, 19, 19, 19, 19, 19,
2154 19, 19, 19, 19, 0, 0, 0, 0,
2155 0, 0, 0, 0, 0, 0, 0, 0,
2156 0, 0, 0, 0, 0, 0, 0, 0,
2157 0, 0, 0, 0, 0, 0, 0, 0,
2158 0, 0, 0, 0, 0, 0, 0, 0,
2159 0, 0, 0, 0, 0, 0, 0, 0,
2160 0, 0, 0, 0, 0, 0, 0, 0,
2161 0, 0, 0, 0, 0, 0, 0, 0,
2162 0, 0, 0, 0, 0, 0, 0, 0,
2163 0, 0, 0, 0, 0, 0, 0, 0,
2164 0, 0, 0, 0, 0, 0, 0, 0,
2165 0, 0, 0, 0, 0, 0, 0, 0,
2166};
2167
2168static const Q_UINT8 ui_D8[] = {
2169 12, 12, 12, 12, 12, 12, 12, 12,
2170 12, 12, 12, 12, 12, 12, 12, 12,
2171 12, 12, 12, 12, 12, 12, 12, 12,
2172 12, 12, 12, 12, 12, 12, 12, 12,
2173 12, 12, 12, 12, 12, 12, 12, 12,
2174 12, 12, 12, 12, 12, 12, 12, 12,
2175 12, 12, 12, 12, 12, 12, 12, 12,
2176 12, 12, 12, 12, 12, 12, 12, 12,
2177 12, 12, 12, 12, 12, 12, 12, 12,
2178 12, 12, 12, 12, 12, 12, 12, 12,
2179 12, 12, 12, 12, 12, 12, 12, 12,
2180 12, 12, 12, 12, 12, 12, 12, 12,
2181 12, 12, 12, 12, 12, 12, 12, 12,
2182 12, 12, 12, 12, 12, 12, 12, 12,
2183 12, 12, 12, 12, 12, 12, 12, 12,
2184 12, 12, 12, 12, 12, 12, 12, 12,
2185 12, 12, 12, 12, 12, 12, 12, 12,
2186 12, 12, 12, 12, 12, 12, 12, 12,
2187 12, 12, 12, 12, 12, 12, 12, 12,
2188 12, 12, 12, 12, 12, 12, 12, 12,
2189 12, 12, 12, 12, 12, 12, 12, 12,
2190 12, 12, 12, 12, 12, 12, 12, 12,
2191 12, 12, 12, 12, 12, 12, 12, 12,
2192 12, 12, 12, 12, 12, 12, 12, 12,
2193 12, 12, 12, 12, 12, 12, 12, 12,
2194 12, 12, 12, 12, 12, 12, 12, 12,
2195 12, 12, 12, 12, 12, 12, 12, 12,
2196 12, 12, 12, 12, 12, 12, 12, 12,
2197 12, 12, 12, 12, 12, 12, 12, 12,
2198 12, 12, 12, 12, 12, 12, 12, 12,
2199 12, 12, 12, 12, 12, 12, 12, 12,
2200 12, 12, 12, 12, 12, 12, 12, 12,
2201};
2202
2203static const Q_UINT8 ui_E0[] = {
2204 13, 13, 13, 13, 13, 13, 13, 13,
2205 13, 13, 13, 13, 13, 13, 13, 13,
2206 13, 13, 13, 13, 13, 13, 13, 13,
2207 13, 13, 13, 13, 13, 13, 13, 13,
2208 13, 13, 13, 13, 13, 13, 13, 13,
2209 13, 13, 13, 13, 13, 13, 13, 13,
2210 13, 13, 13, 13, 13, 13, 13, 13,
2211 13, 13, 13, 13, 13, 13, 13, 13,
2212 13, 13, 13, 13, 13, 13, 13, 13,
2213 13, 13, 13, 13, 13, 13, 13, 13,
2214 13, 13, 13, 13, 13, 13, 13, 13,
2215 13, 13, 13, 13, 13, 13, 13, 13,
2216 13, 13, 13, 13, 13, 13, 13, 13,
2217 13, 13, 13, 13, 13, 13, 13, 13,
2218 13, 13, 13, 13, 13, 13, 13, 13,
2219 13, 13, 13, 13, 13, 13, 13, 13,
2220 13, 13, 13, 13, 13, 13, 13, 13,
2221 13, 13, 13, 13, 13, 13, 13, 13,
2222 13, 13, 13, 13, 13, 13, 13, 13,
2223 13, 13, 13, 13, 13, 13, 13, 13,
2224 13, 13, 13, 13, 13, 13, 13, 13,
2225 13, 13, 13, 13, 13, 13, 13, 13,
2226 13, 13, 13, 13, 13, 13, 13, 13,
2227 13, 13, 13, 13, 13, 13, 13, 13,
2228 13, 13, 13, 13, 13, 13, 13, 13,
2229 13, 13, 13, 13, 13, 13, 13, 13,
2230 13, 13, 13, 13, 13, 13, 13, 13,
2231 13, 13, 13, 13, 13, 13, 13, 13,
2232 13, 13, 13, 13, 13, 13, 13, 13,
2233 13, 13, 13, 13, 13, 13, 13, 13,
2234 13, 13, 13, 13, 13, 13, 13, 13,
2235 13, 13, 13, 13, 13, 13, 13, 13,
2236};
2237
2238static const Q_UINT8 ui_FA[] = {
2239 19, 19, 19, 19, 19, 19, 19, 19,
2240 19, 19, 19, 19, 19, 19, 19, 19,
2241 19, 19, 19, 19, 19, 19, 19, 19,
2242 19, 19, 19, 19, 19, 19, 19, 19,
2243 19, 19, 19, 19, 19, 19, 19, 19,
2244 19, 19, 19, 19, 19, 19, 0, 0,
2245 19, 19, 19, 19, 19, 19, 19, 19,
2246 19, 19, 19, 19, 19, 19, 19, 19,
2247 19, 19, 19, 19, 19, 19, 19, 19,
2248 19, 19, 19, 19, 19, 19, 19, 19,
2249 19, 19, 19, 19, 19, 19, 19, 19,
2250 19, 19, 19, 19, 19, 19, 19, 19,
2251 19, 19, 19, 19, 19, 19, 19, 19,
2252 19, 19, 19, 0, 0, 0, 0, 0,
2253 0, 0, 0, 0, 0, 0, 0, 0,
2254 0, 0, 0, 0, 0, 0, 0, 0,
2255 0, 0, 0, 0, 0, 0, 0, 0,
2256 0, 0, 0, 0, 0, 0, 0, 0,
2257 0, 0, 0, 0, 0, 0, 0, 0,
2258 0, 0, 0, 0, 0, 0, 0, 0,
2259 0, 0, 0, 0, 0, 0, 0, 0,
2260 0, 0, 0, 0, 0, 0, 0, 0,
2261 0, 0, 0, 0, 0, 0, 0, 0,
2262 0, 0, 0, 0, 0, 0, 0, 0,
2263 0, 0, 0, 0, 0, 0, 0, 0,
2264 0, 0, 0, 0, 0, 0, 0, 0,
2265 0, 0, 0, 0, 0, 0, 0, 0,
2266 0, 0, 0, 0, 0, 0, 0, 0,
2267 0, 0, 0, 0, 0, 0, 0, 0,
2268 0, 0, 0, 0, 0, 0, 0, 0,
2269 0, 0, 0, 0, 0, 0, 0, 0,
2270 0, 0, 0, 0, 0, 0, 0, 0,
2271};
2272
2273static const Q_UINT8 ui_FB[] = {
2274 16, 16, 16, 16, 16, 16, 16, 0,
2275 0, 0, 0, 0, 0, 0, 0, 0,
2276 0, 0, 0, 16, 16, 16, 16, 16,
2277 0, 0, 0, 0, 0, 19, 1, 19,
2278 19, 19, 19, 19, 19, 19, 19, 19,
2279 19, 27, 19, 19, 19, 19, 19, 19,
2280 19, 19, 19, 19, 19, 19, 19, 0,
2281 19, 19, 19, 19, 19, 0, 19, 0,
2282 19, 19, 0, 19, 19, 0, 19, 19,
2283 19, 19, 19, 19, 19, 19, 19, 19,
2284 19, 19, 19, 19, 19, 19, 19, 19,
2285 19, 19, 19, 19, 19, 19, 19, 19,
2286 19, 19, 19, 19, 19, 19, 19, 19,
2287 19, 19, 19, 19, 19, 19, 19, 19,
2288 19, 19, 19, 19, 19, 19, 19, 19,
2289 19, 19, 19, 19, 19, 19, 19, 19,
2290 19, 19, 19, 19, 19, 19, 19, 19,
2291 19, 19, 19, 19, 19, 19, 19, 19,
2292 19, 19, 19, 19, 19, 19, 19, 19,
2293 19, 19, 19, 19, 19, 19, 19, 19,
2294 19, 19, 19, 19, 19, 19, 19, 19,
2295 19, 19, 19, 19, 19, 19, 19, 19,
2296 19, 19, 0, 0, 0, 0, 0, 0,
2297 0, 0, 0, 0, 0, 0, 0, 0,
2298 0, 0, 0, 0, 0, 0, 0, 0,
2299 0, 0, 0, 0, 0, 0, 0, 0,
2300 0, 0, 0, 19, 19, 19, 19, 19,
2301 19, 19, 19, 19, 19, 19, 19, 19,
2302 19, 19, 19, 19, 19, 19, 19, 19,
2303 19, 19, 19, 19, 19, 19, 19, 19,
2304 19, 19, 19, 19, 19, 19, 19, 19,
2305 19, 19, 19, 19, 19, 19, 19, 19,
2306};
2307
2308static const Q_UINT8 ui_FD[] = {
2309 19, 19, 19, 19, 19, 19, 19, 19,
2310 19, 19, 19, 19, 19, 19, 19, 19,
2311 19, 19, 19, 19, 19, 19, 19, 19,
2312 19, 19, 19, 19, 19, 19, 19, 19,
2313 19, 19, 19, 19, 19, 19, 19, 19,
2314 19, 19, 19, 19, 19, 19, 19, 19,
2315 19, 19, 19, 19, 19, 19, 19, 19,
2316 19, 19, 19, 19, 19, 19, 22, 23,
2317 0, 0, 0, 0, 0, 0, 0, 0,
2318 0, 0, 0, 0, 0, 0, 0, 0,
2319 19, 19, 19, 19, 19, 19, 19, 19,
2320 19, 19, 19, 19, 19, 19, 19, 19,
2321 19, 19, 19, 19, 19, 19, 19, 19,
2322 19, 19, 19, 19, 19, 19, 19, 19,
2323 19, 19, 19, 19, 19, 19, 19, 19,
2324 19, 19, 19, 19, 19, 19, 19, 19,
2325 19, 19, 19, 19, 19, 19, 19, 19,
2326 19, 19, 19, 19, 19, 19, 19, 19,
2327 0, 0, 19, 19, 19, 19, 19, 19,
2328 19, 19, 19, 19, 19, 19, 19, 19,
2329 19, 19, 19, 19, 19, 19, 19, 19,
2330 19, 19, 19, 19, 19, 19, 19, 19,
2331 19, 19, 19, 19, 19, 19, 19, 19,
2332 19, 19, 19, 19, 19, 19, 19, 19,
2333 19, 19, 19, 19, 19, 19, 19, 19,
2334 0, 0, 0, 0, 0, 0, 0, 0,
2335 0, 0, 0, 0, 0, 0, 0, 0,
2336 0, 0, 0, 0, 0, 0, 0, 0,
2337 0, 0, 0, 0, 0, 0, 0, 0,
2338 0, 0, 0, 0, 0, 0, 0, 0,
2339 19, 19, 19, 19, 19, 19, 19, 19,
2340 19, 19, 19, 19, 28, 0, 0, 0,
2341};
2342
2343static const Q_UINT8 ui_FE[] = {
2344 1, 1, 1, 1, 1, 1, 1, 1,
2345 1, 1, 1, 1, 1, 1, 1, 1,
2346 0, 0, 0, 0, 0, 0, 0, 0,
2347 0, 0, 0, 0, 0, 0, 0, 0,
2348 1, 1, 1, 1, 0, 0, 0, 0,
2349 0, 0, 0, 0, 0, 0, 0, 0,
2350 26, 21, 21, 20, 20, 22, 23, 22,
2351 23, 22, 23, 22, 23, 22, 23, 22,
2352 23, 22, 23, 22, 23, 26, 26, 0,
2353 0, 26, 26, 26, 26, 20, 20, 20,
2354 26, 26, 26, 0, 26, 26, 26, 26,
2355 21, 22, 23, 22, 23, 22, 23, 26,
2356 26, 26, 27, 21, 27, 27, 27, 0,
2357 26, 28, 26, 26, 0, 0, 0, 0,
2358 19, 19, 19, 19, 19, 0, 19, 19,
2359 19, 19, 19, 19, 19, 19, 19, 19,
2360 19, 19, 19, 19, 19, 19, 19, 19,
2361 19, 19, 19, 19, 19, 19, 19, 19,
2362 19, 19, 19, 19, 19, 19, 19, 19,
2363 19, 19, 19, 19, 19, 19, 19, 19,
2364 19, 19, 19, 19, 19, 19, 19, 19,
2365 19, 19, 19, 19, 19, 19, 19, 19,
2366 19, 19, 19, 19, 19, 19, 19, 19,
2367 19, 19, 19, 19, 19, 19, 19, 19,
2368 19, 19, 19, 19, 19, 19, 19, 19,
2369 19, 19, 19, 19, 19, 19, 19, 19,
2370 19, 19, 19, 19, 19, 19, 19, 19,
2371 19, 19, 19, 19, 19, 19, 19, 19,
2372 19, 19, 19, 19, 19, 19, 19, 19,
2373 19, 19, 19, 19, 19, 19, 19, 19,
2374 19, 19, 19, 19, 19, 19, 19, 19,
2375 19, 19, 19, 19, 19, 0, 0, 11,
2376};
2377
2378static const Q_UINT8 ui_FF[] = {
2379 0, 26, 26, 26, 28, 26, 26, 26,
2380 22, 23, 26, 27, 26, 21, 26, 26,
2381 4, 4, 4, 4, 4, 4, 4, 4,
2382 4, 4, 26, 26, 27, 27, 27, 26,
2383 26, 15, 15, 15, 15, 15, 15, 15,
2384 15, 15, 15, 15, 15, 15, 15, 15,
2385 15, 15, 15, 15, 15, 15, 15, 15,
2386 15, 15, 15, 22, 26, 23, 29, 20,
2387 29, 16, 16, 16, 16, 16, 16, 16,
2388 16, 16, 16, 16, 16, 16, 16, 16,
2389 16, 16, 16, 16, 16, 16, 16, 16,
2390 16, 16, 16, 22, 27, 23, 27, 22,
2391 23, 26, 22, 23, 26, 20, 19, 19,
2392 19, 19, 19, 19, 19, 19, 19, 19,
2393 18, 19, 19, 19, 19, 19, 19, 19,
2394 19, 19, 19, 19, 19, 19, 19, 19,
2395 19, 19, 19, 19, 19, 19, 19, 19,
2396 19, 19, 19, 19, 19, 19, 19, 19,
2397 19, 19, 19, 19, 19, 19, 19, 19,
2398 19, 19, 19, 19, 19, 19, 18, 18,
2399 19, 19, 19, 19, 19, 19, 19, 19,
2400 19, 19, 19, 19, 19, 19, 19, 19,
2401 19, 19, 19, 19, 19, 19, 19, 19,
2402 19, 19, 19, 19, 19, 19, 19, 0,
2403 0, 0, 19, 19, 19, 19, 19, 19,
2404 0, 0, 19, 19, 19, 19, 19, 19,
2405 0, 0, 19, 19, 19, 19, 19, 19,
2406 0, 0, 19, 19, 19, 0, 0, 0,
2407 28, 28, 27, 29, 30, 28, 28, 0,
2408 30, 27, 27, 27, 27, 30, 30, 0,
2409 0, 0, 0, 0, 0, 0, 0, 0,
2410 0, 11, 11, 11, 30, 30, 0, 0,
2411};
2412
2413static const Q_UINT8 * const unicode_info[256] = {
2414 ui_00, ui_01, ui_02, ui_03, ui_04, ui_05, ui_06, ui_07,
2415 ui_08, ui_09, ui_0A, ui_0B, ui_0C, ui_0D, ui_0E, ui_0F,
2416 ui_10, ui_11, ui_12, ui_13, ui_14, ui_15, ui_16, ui_17,
2417 ui_18, ui_08, ui_08, ui_08, ui_08, ui_08, ui_1E, ui_1F,
2418 ui_20, ui_21, ui_22, ui_23, ui_24, ui_25, ui_26, ui_27,
2419 ui_28, ui_29, ui_22, ui_08, ui_08, ui_08, ui_2E, ui_2F,
2420 ui_30, ui_31, ui_32, ui_33, ui_15, ui_15, ui_15, ui_15,
2421 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2422 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2423 ui_15, ui_15, ui_15, ui_15, ui_15, ui_4D, ui_15, ui_15,
2424 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2425 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2426 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2427 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2428 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2429 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2430 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2431 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2432 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2433 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_9F,
2434 ui_15, ui_15, ui_15, ui_15, ui_A4, ui_08, ui_08, ui_08,
2435 ui_08, ui_08, ui_08, ui_08, ui_15, ui_15, ui_15, ui_15,
2436 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2437 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2438 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2439 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15,
2440 ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_15, ui_D7,
2441 ui_D8, ui_D8, ui_D8, ui_D8, ui_D8, ui_D8, ui_D8, ui_D8,
2442 ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0,
2443 ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0,
2444 ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0, ui_E0,
2445 ui_E0, ui_15, ui_FA, ui_FB, ui_15, ui_FD, ui_FE, ui_FF,
2446};
2447// 14848 bytes
2448
2449static const Q_UINT16 decomposition_map[] = {
2450 0,
2451 3, 0x00A0, 0x0020, 0,
2452 16, 0x00A8, 0x0020, 0x0308, 0,
2453 9, 0x00AA, 0x0061, 0,
2454 16, 0x00AF, 0x0020, 0x0304, 0,
2455 9, 0x00B2, 0x0032, 0,
2456 9, 0x00B3, 0x0033, 0,
2457 16, 0x00B4, 0x0020, 0x0301, 0,
2458 16, 0x00B5, 0x03BC, 0,
2459 16, 0x00B8, 0x0020, 0x0327, 0,
2460 9, 0x00B9, 0x0031, 0,
2461 9, 0x00BA, 0x006F, 0,
2462 17, 0x00BC, 0x0031, 0x2044, 0x0034, 0,
2463 17, 0x00BD, 0x0031, 0x2044, 0x0032, 0,
2464 17, 0x00BE, 0x0033, 0x2044, 0x0034, 0,
2465 1, 0x00C0, 0x0041, 0x0300, 0,
2466 1, 0x00C1, 0x0041, 0x0301, 0,
2467 1, 0x00C2, 0x0041, 0x0302, 0,
2468 1, 0x00C3, 0x0041, 0x0303, 0,
2469 1, 0x00C4, 0x0041, 0x0308, 0,
2470 1, 0x00C5, 0x0041, 0x030A, 0,
2471 1, 0x00C7, 0x0043, 0x0327, 0,
2472 1, 0x00C8, 0x0045, 0x0300, 0,
2473 1, 0x00C9, 0x0045, 0x0301, 0,
2474 1, 0x00CA, 0x0045, 0x0302, 0,
2475 1, 0x00CB, 0x0045, 0x0308, 0,
2476 1, 0x00CC, 0x0049, 0x0300, 0,
2477 1, 0x00CD, 0x0049, 0x0301, 0,
2478 1, 0x00CE, 0x0049, 0x0302, 0,
2479 1, 0x00CF, 0x0049, 0x0308, 0,
2480 1, 0x00D1, 0x004E, 0x0303, 0,
2481 1, 0x00D2, 0x004F, 0x0300, 0,
2482 1, 0x00D3, 0x004F, 0x0301, 0,
2483 1, 0x00D4, 0x004F, 0x0302, 0,
2484 1, 0x00D5, 0x004F, 0x0303, 0,
2485 1, 0x00D6, 0x004F, 0x0308, 0,
2486 1, 0x00D9, 0x0055, 0x0300, 0,
2487 1, 0x00DA, 0x0055, 0x0301, 0,
2488 1, 0x00DB, 0x0055, 0x0302, 0,
2489 1, 0x00DC, 0x0055, 0x0308, 0,
2490 1, 0x00DD, 0x0059, 0x0301, 0,
2491 1, 0x00E0, 0x0061, 0x0300, 0,
2492 1, 0x00E1, 0x0061, 0x0301, 0,
2493 1, 0x00E2, 0x0061, 0x0302, 0,
2494 1, 0x00E3, 0x0061, 0x0303, 0,
2495 1, 0x00E4, 0x0061, 0x0308, 0,
2496 1, 0x00E5, 0x0061, 0x030A, 0,
2497 1, 0x00E7, 0x0063, 0x0327, 0,
2498 1, 0x00E8, 0x0065, 0x0300, 0,
2499 1, 0x00E9, 0x0065, 0x0301, 0,
2500 1, 0x00EA, 0x0065, 0x0302, 0,
2501 1, 0x00EB, 0x0065, 0x0308, 0,
2502 1, 0x00EC, 0x0069, 0x0300, 0,
2503 1, 0x00ED, 0x0069, 0x0301, 0,
2504 1, 0x00EE, 0x0069, 0x0302, 0,
2505 1, 0x00EF, 0x0069, 0x0308, 0,
2506 1, 0x00F1, 0x006E, 0x0303, 0,
2507 1, 0x00F2, 0x006F, 0x0300, 0,
2508 1, 0x00F3, 0x006F, 0x0301, 0,
2509 1, 0x00F4, 0x006F, 0x0302, 0,
2510 1, 0x00F5, 0x006F, 0x0303, 0,
2511 1, 0x00F6, 0x006F, 0x0308, 0,
2512 1, 0x00F9, 0x0075, 0x0300, 0,
2513 1, 0x00FA, 0x0075, 0x0301, 0,
2514 1, 0x00FB, 0x0075, 0x0302, 0,
2515 1, 0x00FC, 0x0075, 0x0308, 0,
2516 1, 0x00FD, 0x0079, 0x0301, 0,
2517 1, 0x00FF, 0x0079, 0x0308, 0,
2518 1, 0x0100, 0x0041, 0x0304, 0,
2519 1, 0x0101, 0x0061, 0x0304, 0,
2520 1, 0x0102, 0x0041, 0x0306, 0,
2521 1, 0x0103, 0x0061, 0x0306, 0,
2522 1, 0x0104, 0x0041, 0x0328, 0,
2523 1, 0x0105, 0x0061, 0x0328, 0,
2524 1, 0x0106, 0x0043, 0x0301, 0,
2525 1, 0x0107, 0x0063, 0x0301, 0,
2526 1, 0x0108, 0x0043, 0x0302, 0,
2527 1, 0x0109, 0x0063, 0x0302, 0,
2528 1, 0x010A, 0x0043, 0x0307, 0,
2529 1, 0x010B, 0x0063, 0x0307, 0,
2530 1, 0x010C, 0x0043, 0x030C, 0,
2531 1, 0x010D, 0x0063, 0x030C, 0,
2532 1, 0x010E, 0x0044, 0x030C, 0,
2533 1, 0x010F, 0x0064, 0x030C, 0,
2534 1, 0x0112, 0x0045, 0x0304, 0,
2535 1, 0x0113, 0x0065, 0x0304, 0,
2536 1, 0x0114, 0x0045, 0x0306, 0,
2537 1, 0x0115, 0x0065, 0x0306, 0,
2538 1, 0x0116, 0x0045, 0x0307, 0,
2539 1, 0x0117, 0x0065, 0x0307, 0,
2540 1, 0x0118, 0x0045, 0x0328, 0,
2541 1, 0x0119, 0x0065, 0x0328, 0,
2542 1, 0x011A, 0x0045, 0x030C, 0,
2543 1, 0x011B, 0x0065, 0x030C, 0,
2544 1, 0x011C, 0x0047, 0x0302, 0,
2545 1, 0x011D, 0x0067, 0x0302, 0,
2546 1, 0x011E, 0x0047, 0x0306, 0,
2547 1, 0x011F, 0x0067, 0x0306, 0,
2548 1, 0x0120, 0x0047, 0x0307, 0,
2549 1, 0x0121, 0x0067, 0x0307, 0,
2550 1, 0x0122, 0x0047, 0x0327, 0,
2551 1, 0x0123, 0x0067, 0x0327, 0,
2552 1, 0x0124, 0x0048, 0x0302, 0,
2553 1, 0x0125, 0x0068, 0x0302, 0,
2554 1, 0x0128, 0x0049, 0x0303, 0,
2555 1, 0x0129, 0x0069, 0x0303, 0,
2556 1, 0x012A, 0x0049, 0x0304, 0,
2557 1, 0x012B, 0x0069, 0x0304, 0,
2558 1, 0x012C, 0x0049, 0x0306, 0,
2559 1, 0x012D, 0x0069, 0x0306, 0,
2560 1, 0x012E, 0x0049, 0x0328, 0,
2561 1, 0x012F, 0x0069, 0x0328, 0,
2562 1, 0x0130, 0x0049, 0x0307, 0,
2563 16, 0x0132, 0x0049, 0x004A, 0,
2564 16, 0x0133, 0x0069, 0x006A, 0,
2565 1, 0x0134, 0x004A, 0x0302, 0,
2566 1, 0x0135, 0x006A, 0x0302, 0,
2567 1, 0x0136, 0x004B, 0x0327, 0,
2568 1, 0x0137, 0x006B, 0x0327, 0,
2569 1, 0x0139, 0x004C, 0x0301, 0,
2570 1, 0x013A, 0x006C, 0x0301, 0,
2571 1, 0x013B, 0x004C, 0x0327, 0,
2572 1, 0x013C, 0x006C, 0x0327, 0,
2573 1, 0x013D, 0x004C, 0x030C, 0,
2574 1, 0x013E, 0x006C, 0x030C, 0,
2575 16, 0x013F, 0x004C, 0x00B7, 0,
2576 16, 0x0140, 0x006C, 0x00B7, 0,
2577 1, 0x0143, 0x004E, 0x0301, 0,
2578 1, 0x0144, 0x006E, 0x0301, 0,
2579 1, 0x0145, 0x004E, 0x0327, 0,
2580 1, 0x0146, 0x006E, 0x0327, 0,
2581 1, 0x0147, 0x004E, 0x030C, 0,
2582 1, 0x0148, 0x006E, 0x030C, 0,
2583 16, 0x0149, 0x02BC, 0x006E, 0,
2584 1, 0x014C, 0x004F, 0x0304, 0,
2585 1, 0x014D, 0x006F, 0x0304, 0,
2586 1, 0x014E, 0x004F, 0x0306, 0,
2587 1, 0x014F, 0x006F, 0x0306, 0,
2588 1, 0x0150, 0x004F, 0x030B, 0,
2589 1, 0x0151, 0x006F, 0x030B, 0,
2590 1, 0x0154, 0x0052, 0x0301, 0,
2591 1, 0x0155, 0x0072, 0x0301, 0,
2592 1, 0x0156, 0x0052, 0x0327, 0,
2593 1, 0x0157, 0x0072, 0x0327, 0,
2594 1, 0x0158, 0x0052, 0x030C, 0,
2595 1, 0x0159, 0x0072, 0x030C, 0,
2596 1, 0x015A, 0x0053, 0x0301, 0,
2597 1, 0x015B, 0x0073, 0x0301, 0,
2598 1, 0x015C, 0x0053, 0x0302, 0,
2599 1, 0x015D, 0x0073, 0x0302, 0,
2600 1, 0x015E, 0x0053, 0x0327, 0,
2601 1, 0x015F, 0x0073, 0x0327, 0,
2602 1, 0x0160, 0x0053, 0x030C, 0,
2603 1, 0x0161, 0x0073, 0x030C, 0,
2604 1, 0x0162, 0x0054, 0x0327, 0,
2605 1, 0x0163, 0x0074, 0x0327, 0,
2606 1, 0x0164, 0x0054, 0x030C, 0,
2607 1, 0x0165, 0x0074, 0x030C, 0,
2608 1, 0x0168, 0x0055, 0x0303, 0,
2609 1, 0x0169, 0x0075, 0x0303, 0,
2610 1, 0x016A, 0x0055, 0x0304, 0,
2611 1, 0x016B, 0x0075, 0x0304, 0,
2612 1, 0x016C, 0x0055, 0x0306, 0,
2613 1, 0x016D, 0x0075, 0x0306, 0,
2614 1, 0x016E, 0x0055, 0x030A, 0,
2615 1, 0x016F, 0x0075, 0x030A, 0,
2616 1, 0x0170, 0x0055, 0x030B, 0,
2617 1, 0x0171, 0x0075, 0x030B, 0,
2618 1, 0x0172, 0x0055, 0x0328, 0,
2619 1, 0x0173, 0x0075, 0x0328, 0,
2620 1, 0x0174, 0x0057, 0x0302, 0,
2621 1, 0x0175, 0x0077, 0x0302, 0,
2622 1, 0x0176, 0x0059, 0x0302, 0,
2623 1, 0x0177, 0x0079, 0x0302, 0,
2624 1, 0x0178, 0x0059, 0x0308, 0,
2625 1, 0x0179, 0x005A, 0x0301, 0,
2626 1, 0x017A, 0x007A, 0x0301, 0,
2627 1, 0x017B, 0x005A, 0x0307, 0,
2628 1, 0x017C, 0x007A, 0x0307, 0,
2629 1, 0x017D, 0x005A, 0x030C, 0,
2630 1, 0x017E, 0x007A, 0x030C, 0,
2631 16, 0x017F, 0x0073, 0,
2632 1, 0x01A0, 0x004F, 0x031B, 0,
2633 1, 0x01A1, 0x006F, 0x031B, 0,
2634 1, 0x01AF, 0x0055, 0x031B, 0,
2635 1, 0x01B0, 0x0075, 0x031B, 0,
2636 16, 0x01C4, 0x0044, 0x017D, 0,
2637 16, 0x01C5, 0x0044, 0x017E, 0,
2638 16, 0x01C6, 0x0064, 0x017E, 0,
2639 16, 0x01C7, 0x004C, 0x004A, 0,
2640 16, 0x01C8, 0x004C, 0x006A, 0,
2641 16, 0x01C9, 0x006C, 0x006A, 0,
2642 16, 0x01CA, 0x004E, 0x004A, 0,
2643 16, 0x01CB, 0x004E, 0x006A, 0,
2644 16, 0x01CC, 0x006E, 0x006A, 0,
2645 1, 0x01CD, 0x0041, 0x030C, 0,
2646 1, 0x01CE, 0x0061, 0x030C, 0,
2647 1, 0x01CF, 0x0049, 0x030C, 0,
2648 1, 0x01D0, 0x0069, 0x030C, 0,
2649 1, 0x01D1, 0x004F, 0x030C, 0,
2650 1, 0x01D2, 0x006F, 0x030C, 0,
2651 1, 0x01D3, 0x0055, 0x030C, 0,
2652 1, 0x01D4, 0x0075, 0x030C, 0,
2653 1, 0x01D5, 0x00DC, 0x0304, 0,
2654 1, 0x01D6, 0x00FC, 0x0304, 0,
2655 1, 0x01D7, 0x00DC, 0x0301, 0,
2656 1, 0x01D8, 0x00FC, 0x0301, 0,
2657 1, 0x01D9, 0x00DC, 0x030C, 0,
2658 1, 0x01DA, 0x00FC, 0x030C, 0,
2659 1, 0x01DB, 0x00DC, 0x0300, 0,
2660 1, 0x01DC, 0x00FC, 0x0300, 0,
2661 1, 0x01DE, 0x00C4, 0x0304, 0,
2662 1, 0x01DF, 0x00E4, 0x0304, 0,
2663 1, 0x01E0, 0x0226, 0x0304, 0,
2664 1, 0x01E1, 0x0227, 0x0304, 0,
2665 1, 0x01E2, 0x00C6, 0x0304, 0,
2666 1, 0x01E3, 0x00E6, 0x0304, 0,
2667 1, 0x01E6, 0x0047, 0x030C, 0,
2668 1, 0x01E7, 0x0067, 0x030C, 0,
2669 1, 0x01E8, 0x004B, 0x030C, 0,
2670 1, 0x01E9, 0x006B, 0x030C, 0,
2671 1, 0x01EA, 0x004F, 0x0328, 0,
2672 1, 0x01EB, 0x006F, 0x0328, 0,
2673 1, 0x01EC, 0x01EA, 0x0304, 0,
2674 1, 0x01ED, 0x01EB, 0x0304, 0,
2675 1, 0x01EE, 0x01B7, 0x030C, 0,
2676 1, 0x01EF, 0x0292, 0x030C, 0,
2677 1, 0x01F0, 0x006A, 0x030C, 0,
2678 16, 0x01F1, 0x0044, 0x005A, 0,
2679 16, 0x01F2, 0x0044, 0x007A, 0,
2680 16, 0x01F3, 0x0064, 0x007A, 0,
2681 1, 0x01F4, 0x0047, 0x0301, 0,
2682 1, 0x01F5, 0x0067, 0x0301, 0,
2683 1, 0x01F8, 0x004E, 0x0300, 0,
2684 1, 0x01F9, 0x006E, 0x0300, 0,
2685 1, 0x01FA, 0x00C5, 0x0301, 0,
2686 1, 0x01FB, 0x00E5, 0x0301, 0,
2687 1, 0x01FC, 0x00C6, 0x0301, 0,
2688 1, 0x01FD, 0x00E6, 0x0301, 0,
2689 1, 0x01FE, 0x00D8, 0x0301, 0,
2690 1, 0x01FF, 0x00F8, 0x0301, 0,
2691 1, 0x0200, 0x0041, 0x030F, 0,
2692 1, 0x0201, 0x0061, 0x030F, 0,
2693 1, 0x0202, 0x0041, 0x0311, 0,
2694 1, 0x0203, 0x0061, 0x0311, 0,
2695 1, 0x0204, 0x0045, 0x030F, 0,
2696 1, 0x0205, 0x0065, 0x030F, 0,
2697 1, 0x0206, 0x0045, 0x0311, 0,
2698 1, 0x0207, 0x0065, 0x0311, 0,
2699 1, 0x0208, 0x0049, 0x030F, 0,
2700 1, 0x0209, 0x0069, 0x030F, 0,
2701 1, 0x020A, 0x0049, 0x0311, 0,
2702 1, 0x020B, 0x0069, 0x0311, 0,
2703 1, 0x020C, 0x004F, 0x030F, 0,
2704 1, 0x020D, 0x006F, 0x030F, 0,
2705 1, 0x020E, 0x004F, 0x0311, 0,
2706 1, 0x020F, 0x006F, 0x0311, 0,
2707 1, 0x0210, 0x0052, 0x030F, 0,
2708 1, 0x0211, 0x0072, 0x030F, 0,
2709 1, 0x0212, 0x0052, 0x0311, 0,
2710 1, 0x0213, 0x0072, 0x0311, 0,
2711 1, 0x0214, 0x0055, 0x030F, 0,
2712 1, 0x0215, 0x0075, 0x030F, 0,
2713 1, 0x0216, 0x0055, 0x0311, 0,
2714 1, 0x0217, 0x0075, 0x0311, 0,
2715 1, 0x0218, 0x0053, 0x0326, 0,
2716 1, 0x0219, 0x0073, 0x0326, 0,
2717 1, 0x021A, 0x0054, 0x0326, 0,
2718 1, 0x021B, 0x0074, 0x0326, 0,
2719 1, 0x021E, 0x0048, 0x030C, 0,
2720 1, 0x021F, 0x0068, 0x030C, 0,
2721 1, 0x0226, 0x0041, 0x0307, 0,
2722 1, 0x0227, 0x0061, 0x0307, 0,
2723 1, 0x0228, 0x0045, 0x0327, 0,
2724 1, 0x0229, 0x0065, 0x0327, 0,
2725 1, 0x022A, 0x00D6, 0x0304, 0,
2726 1, 0x022B, 0x00F6, 0x0304, 0,
2727 1, 0x022C, 0x00D5, 0x0304, 0,
2728 1, 0x022D, 0x00F5, 0x0304, 0,
2729 1, 0x022E, 0x004F, 0x0307, 0,
2730 1, 0x022F, 0x006F, 0x0307, 0,
2731 1, 0x0230, 0x022E, 0x0304, 0,
2732 1, 0x0231, 0x022F, 0x0304, 0,
2733 1, 0x0232, 0x0059, 0x0304, 0,
2734 1, 0x0233, 0x0079, 0x0304, 0,
2735 9, 0x02B0, 0x0068, 0,
2736 9, 0x02B1, 0x0266, 0,
2737 9, 0x02B2, 0x006A, 0,
2738 9, 0x02B3, 0x0072, 0,
2739 9, 0x02B4, 0x0279, 0,
2740 9, 0x02B5, 0x027B, 0,
2741 9, 0x02B6, 0x0281, 0,
2742 9, 0x02B7, 0x0077, 0,
2743 9, 0x02B8, 0x0079, 0,
2744 16, 0x02D8, 0x0020, 0x0306, 0,
2745 16, 0x02D9, 0x0020, 0x0307, 0,
2746 16, 0x02DA, 0x0020, 0x030A, 0,
2747 16, 0x02DB, 0x0020, 0x0328, 0,
2748 16, 0x02DC, 0x0020, 0x0303, 0,
2749 16, 0x02DD, 0x0020, 0x030B, 0,
2750 9, 0x02E0, 0x0263, 0,
2751 9, 0x02E1, 0x006C, 0,
2752 9, 0x02E2, 0x0073, 0,
2753 9, 0x02E3, 0x0078, 0,
2754 9, 0x02E4, 0x0295, 0,
2755 1, 0x0340, 0x0300, 0,
2756 1, 0x0341, 0x0301, 0,
2757 1, 0x0343, 0x0313, 0,
2758 1, 0x0344, 0x0308, 0x0301, 0,
2759 1, 0x0374, 0x02B9, 0,
2760 16, 0x037A, 0x0020, 0x0345, 0,
2761 1, 0x037E, 0x003B, 0,
2762 16, 0x0384, 0x0020, 0x0301, 0,
2763 1, 0x0385, 0x00A8, 0x0301, 0,
2764 1, 0x0386, 0x0391, 0x0301, 0,
2765 1, 0x0387, 0x00B7, 0,
2766 1, 0x0388, 0x0395, 0x0301, 0,
2767 1, 0x0389, 0x0397, 0x0301, 0,
2768 1, 0x038A, 0x0399, 0x0301, 0,
2769 1, 0x038C, 0x039F, 0x0301, 0,
2770 1, 0x038E, 0x03A5, 0x0301, 0,
2771 1, 0x038F, 0x03A9, 0x0301, 0,
2772 1, 0x0390, 0x03CA, 0x0301, 0,
2773 1, 0x03AA, 0x0399, 0x0308, 0,
2774 1, 0x03AB, 0x03A5, 0x0308, 0,
2775 1, 0x03AC, 0x03B1, 0x0301, 0,
2776 1, 0x03AD, 0x03B5, 0x0301, 0,
2777 1, 0x03AE, 0x03B7, 0x0301, 0,
2778 1, 0x03AF, 0x03B9, 0x0301, 0,
2779 1, 0x03B0, 0x03CB, 0x0301, 0,
2780 1, 0x03CA, 0x03B9, 0x0308, 0,
2781 1, 0x03CB, 0x03C5, 0x0308, 0,
2782 1, 0x03CC, 0x03BF, 0x0301, 0,
2783 1, 0x03CD, 0x03C5, 0x0301, 0,
2784 1, 0x03CE, 0x03C9, 0x0301, 0,
2785 16, 0x03D0, 0x03B2, 0,
2786 16, 0x03D1, 0x03B8, 0,
2787 16, 0x03D2, 0x03A5, 0,
2788 1, 0x03D3, 0x03D2, 0x0301, 0,
2789 1, 0x03D4, 0x03D2, 0x0308, 0,
2790 16, 0x03D5, 0x03C6, 0,
2791 16, 0x03D6, 0x03C0, 0,
2792 16, 0x03F0, 0x03BA, 0,
2793 16, 0x03F1, 0x03C1, 0,
2794 16, 0x03F2, 0x03C2, 0,
2795 16, 0x03F4, 0x0398, 0,
2796 16, 0x03F5, 0x03B5, 0,
2797 1, 0x0400, 0x0415, 0x0300, 0,
2798 1, 0x0401, 0x0415, 0x0308, 0,
2799 1, 0x0403, 0x0413, 0x0301, 0,
2800 1, 0x0407, 0x0406, 0x0308, 0,
2801 1, 0x040C, 0x041A, 0x0301, 0,
2802 1, 0x040D, 0x0418, 0x0300, 0,
2803 1, 0x040E, 0x0423, 0x0306, 0,
2804 1, 0x0419, 0x0418, 0x0306, 0,
2805 1, 0x0439, 0x0438, 0x0306, 0,
2806 1, 0x0450, 0x0435, 0x0300, 0,
2807 1, 0x0451, 0x0435, 0x0308, 0,
2808 1, 0x0453, 0x0433, 0x0301, 0,
2809 1, 0x0457, 0x0456, 0x0308, 0,
2810 1, 0x045C, 0x043A, 0x0301, 0,
2811 1, 0x045D, 0x0438, 0x0300, 0,
2812 1, 0x045E, 0x0443, 0x0306, 0,
2813 1, 0x0476, 0x0474, 0x030F, 0,
2814 1, 0x0477, 0x0475, 0x030F, 0,
2815 1, 0x04C1, 0x0416, 0x0306, 0,
2816 1, 0x04C2, 0x0436, 0x0306, 0,
2817 1, 0x04D0, 0x0410, 0x0306, 0,
2818 1, 0x04D1, 0x0430, 0x0306, 0,
2819 1, 0x04D2, 0x0410, 0x0308, 0,
2820 1, 0x04D3, 0x0430, 0x0308, 0,
2821 1, 0x04D6, 0x0415, 0x0306, 0,
2822 1, 0x04D7, 0x0435, 0x0306, 0,
2823 1, 0x04DA, 0x04D8, 0x0308, 0,
2824 1, 0x04DB, 0x04D9, 0x0308, 0,
2825 1, 0x04DC, 0x0416, 0x0308, 0,
2826 1, 0x04DD, 0x0436, 0x0308, 0,
2827 1, 0x04DE, 0x0417, 0x0308, 0,
2828 1, 0x04DF, 0x0437, 0x0308, 0,
2829 1, 0x04E2, 0x0418, 0x0304, 0,
2830 1, 0x04E3, 0x0438, 0x0304, 0,
2831 1, 0x04E4, 0x0418, 0x0308, 0,
2832 1, 0x04E5, 0x0438, 0x0308, 0,
2833 1, 0x04E6, 0x041E, 0x0308, 0,
2834 1, 0x04E7, 0x043E, 0x0308, 0,
2835 1, 0x04EA, 0x04E8, 0x0308, 0,
2836 1, 0x04EB, 0x04E9, 0x0308, 0,
2837 1, 0x04EC, 0x042D, 0x0308, 0,
2838 1, 0x04ED, 0x044D, 0x0308, 0,
2839 1, 0x04EE, 0x0423, 0x0304, 0,
2840 1, 0x04EF, 0x0443, 0x0304, 0,
2841 1, 0x04F0, 0x0423, 0x0308, 0,
2842 1, 0x04F1, 0x0443, 0x0308, 0,
2843 1, 0x04F2, 0x0423, 0x030B, 0,
2844 1, 0x04F3, 0x0443, 0x030B, 0,
2845 1, 0x04F4, 0x0427, 0x0308, 0,
2846 1, 0x04F5, 0x0447, 0x0308, 0,
2847 1, 0x04F8, 0x042B, 0x0308, 0,
2848 1, 0x04F9, 0x044B, 0x0308, 0,
2849 16, 0x0587, 0x0565, 0x0582, 0,
2850 1, 0x0622, 0x0627, 0x0653, 0,
2851 1, 0x0623, 0x0627, 0x0654, 0,
2852 1, 0x0624, 0x0648, 0x0654, 0,
2853 1, 0x0625, 0x0627, 0x0655, 0,
2854 1, 0x0626, 0x064A, 0x0654, 0,
2855 16, 0x0675, 0x0627, 0x0674, 0,
2856 16, 0x0676, 0x0648, 0x0674, 0,
2857 16, 0x0677, 0x06C7, 0x0674, 0,
2858 16, 0x0678, 0x064A, 0x0674, 0,
2859 1, 0x06C0, 0x06D5, 0x0654, 0,
2860 1, 0x06C2, 0x06C1, 0x0654, 0,
2861 1, 0x06D3, 0x06D2, 0x0654, 0,
2862 1, 0x0929, 0x0928, 0x093C, 0,
2863 1, 0x0931, 0x0930, 0x093C, 0,
2864 1, 0x0934, 0x0933, 0x093C, 0,
2865 1, 0x0958, 0x0915, 0x093C, 0,
2866 1, 0x0959, 0x0916, 0x093C, 0,
2867 1, 0x095A, 0x0917, 0x093C, 0,
2868 1, 0x095B, 0x091C, 0x093C, 0,
2869 1, 0x095C, 0x0921, 0x093C, 0,
2870 1, 0x095D, 0x0922, 0x093C, 0,
2871 1, 0x095E, 0x092B, 0x093C, 0,
2872 1, 0x095F, 0x092F, 0x093C, 0,
2873 1, 0x09CB, 0x09C7, 0x09BE, 0,
2874 1, 0x09CC, 0x09C7, 0x09D7, 0,
2875 1, 0x09DC, 0x09A1, 0x09BC, 0,
2876 1, 0x09DD, 0x09A2, 0x09BC, 0,
2877 1, 0x09DF, 0x09AF, 0x09BC, 0,
2878 1, 0x0A33, 0x0A32, 0x0A3C, 0,
2879 1, 0x0A36, 0x0A38, 0x0A3C, 0,
2880 1, 0x0A59, 0x0A16, 0x0A3C, 0,
2881 1, 0x0A5A, 0x0A17, 0x0A3C, 0,
2882 1, 0x0A5B, 0x0A1C, 0x0A3C, 0,
2883 1, 0x0A5E, 0x0A2B, 0x0A3C, 0,
2884 1, 0x0B48, 0x0B47, 0x0B56, 0,
2885 1, 0x0B4B, 0x0B47, 0x0B3E, 0,
2886 1, 0x0B4C, 0x0B47, 0x0B57, 0,
2887 1, 0x0B5C, 0x0B21, 0x0B3C, 0,
2888 1, 0x0B5D, 0x0B22, 0x0B3C, 0,
2889 1, 0x0B94, 0x0B92, 0x0BD7, 0,
2890 1, 0x0BCA, 0x0BC6, 0x0BBE, 0,
2891 1, 0x0BCB, 0x0BC7, 0x0BBE, 0,
2892 1, 0x0BCC, 0x0BC6, 0x0BD7, 0,
2893 1, 0x0C48, 0x0C46, 0x0C56, 0,
2894 1, 0x0CC0, 0x0CBF, 0x0CD5, 0,
2895 1, 0x0CC7, 0x0CC6, 0x0CD5, 0,
2896 1, 0x0CC8, 0x0CC6, 0x0CD6, 0,
2897 1, 0x0CCA, 0x0CC6, 0x0CC2, 0,
2898 1, 0x0CCB, 0x0CCA, 0x0CD5, 0,
2899 1, 0x0D4A, 0x0D46, 0x0D3E, 0,
2900 1, 0x0D4B, 0x0D47, 0x0D3E, 0,
2901 1, 0x0D4C, 0x0D46, 0x0D57, 0,
2902 1, 0x0DDA, 0x0DD9, 0x0DCA, 0,
2903 1, 0x0DDC, 0x0DD9, 0x0DCF, 0,
2904 1, 0x0DDD, 0x0DDC, 0x0DCA, 0,
2905 1, 0x0DDE, 0x0DD9, 0x0DDF, 0,
2906 16, 0x0E33, 0x0E4D, 0x0E32, 0,
2907 16, 0x0EB3, 0x0ECD, 0x0EB2, 0,
2908 16, 0x0EDC, 0x0EAB, 0x0E99, 0,
2909 16, 0x0EDD, 0x0EAB, 0x0EA1, 0,
2910 3, 0x0F0C, 0x0F0B, 0,
2911 1, 0x0F43, 0x0F42, 0x0FB7, 0,
2912 1, 0x0F4D, 0x0F4C, 0x0FB7, 0,
2913 1, 0x0F52, 0x0F51, 0x0FB7, 0,
2914 1, 0x0F57, 0x0F56, 0x0FB7, 0,
2915 1, 0x0F5C, 0x0F5B, 0x0FB7, 0,
2916 1, 0x0F69, 0x0F40, 0x0FB5, 0,
2917 1, 0x0F73, 0x0F71, 0x0F72, 0,
2918 1, 0x0F75, 0x0F71, 0x0F74, 0,
2919 1, 0x0F76, 0x0FB2, 0x0F80, 0,
2920 16, 0x0F77, 0x0FB2, 0x0F81, 0,
2921 1, 0x0F78, 0x0FB3, 0x0F80, 0,
2922 16, 0x0F79, 0x0FB3, 0x0F81, 0,
2923 1, 0x0F81, 0x0F71, 0x0F80, 0,
2924 1, 0x0F93, 0x0F92, 0x0FB7, 0,
2925 1, 0x0F9D, 0x0F9C, 0x0FB7, 0,
2926 1, 0x0FA2, 0x0FA1, 0x0FB7, 0,
2927 1, 0x0FA7, 0x0FA6, 0x0FB7, 0,
2928 1, 0x0FAC, 0x0FAB, 0x0FB7, 0,
2929 1, 0x0FB9, 0x0F90, 0x0FB5, 0,
2930 1, 0x1026, 0x1025, 0x102E, 0,
2931 1, 0x1E00, 0x0041, 0x0325, 0,
2932 1, 0x1E01, 0x0061, 0x0325, 0,
2933 1, 0x1E02, 0x0042, 0x0307, 0,
2934 1, 0x1E03, 0x0062, 0x0307, 0,
2935 1, 0x1E04, 0x0042, 0x0323, 0,
2936 1, 0x1E05, 0x0062, 0x0323, 0,
2937 1, 0x1E06, 0x0042, 0x0331, 0,
2938 1, 0x1E07, 0x0062, 0x0331, 0,
2939 1, 0x1E08, 0x00C7, 0x0301, 0,
2940 1, 0x1E09, 0x00E7, 0x0301, 0,
2941 1, 0x1E0A, 0x0044, 0x0307, 0,
2942 1, 0x1E0B, 0x0064, 0x0307, 0,
2943 1, 0x1E0C, 0x0044, 0x0323, 0,
2944 1, 0x1E0D, 0x0064, 0x0323, 0,
2945 1, 0x1E0E, 0x0044, 0x0331, 0,
2946 1, 0x1E0F, 0x0064, 0x0331, 0,
2947 1, 0x1E10, 0x0044, 0x0327, 0,
2948 1, 0x1E11, 0x0064, 0x0327, 0,
2949 1, 0x1E12, 0x0044, 0x032D, 0,
2950 1, 0x1E13, 0x0064, 0x032D, 0,
2951 1, 0x1E14, 0x0112, 0x0300, 0,
2952 1, 0x1E15, 0x0113, 0x0300, 0,
2953 1, 0x1E16, 0x0112, 0x0301, 0,
2954 1, 0x1E17, 0x0113, 0x0301, 0,
2955 1, 0x1E18, 0x0045, 0x032D, 0,
2956 1, 0x1E19, 0x0065, 0x032D, 0,
2957 1, 0x1E1A, 0x0045, 0x0330, 0,
2958 1, 0x1E1B, 0x0065, 0x0330, 0,
2959 1, 0x1E1C, 0x0228, 0x0306, 0,
2960 1, 0x1E1D, 0x0229, 0x0306, 0,
2961 1, 0x1E1E, 0x0046, 0x0307, 0,
2962 1, 0x1E1F, 0x0066, 0x0307, 0,
2963 1, 0x1E20, 0x0047, 0x0304, 0,
2964 1, 0x1E21, 0x0067, 0x0304, 0,
2965 1, 0x1E22, 0x0048, 0x0307, 0,
2966 1, 0x1E23, 0x0068, 0x0307, 0,
2967 1, 0x1E24, 0x0048, 0x0323, 0,
2968 1, 0x1E25, 0x0068, 0x0323, 0,
2969 1, 0x1E26, 0x0048, 0x0308, 0,
2970 1, 0x1E27, 0x0068, 0x0308, 0,
2971 1, 0x1E28, 0x0048, 0x0327, 0,
2972 1, 0x1E29, 0x0068, 0x0327, 0,
2973 1, 0x1E2A, 0x0048, 0x032E, 0,
2974 1, 0x1E2B, 0x0068, 0x032E, 0,
2975 1, 0x1E2C, 0x0049, 0x0330, 0,
2976 1, 0x1E2D, 0x0069, 0x0330, 0,
2977 1, 0x1E2E, 0x00CF, 0x0301, 0,
2978 1, 0x1E2F, 0x00EF, 0x0301, 0,
2979 1, 0x1E30, 0x004B, 0x0301, 0,
2980 1, 0x1E31, 0x006B, 0x0301, 0,
2981 1, 0x1E32, 0x004B, 0x0323, 0,
2982 1, 0x1E33, 0x006B, 0x0323, 0,
2983 1, 0x1E34, 0x004B, 0x0331, 0,
2984 1, 0x1E35, 0x006B, 0x0331, 0,
2985 1, 0x1E36, 0x004C, 0x0323, 0,
2986 1, 0x1E37, 0x006C, 0x0323, 0,
2987 1, 0x1E38, 0x1E36, 0x0304, 0,
2988 1, 0x1E39, 0x1E37, 0x0304, 0,
2989 1, 0x1E3A, 0x004C, 0x0331, 0,
2990 1, 0x1E3B, 0x006C, 0x0331, 0,
2991 1, 0x1E3C, 0x004C, 0x032D, 0,
2992 1, 0x1E3D, 0x006C, 0x032D, 0,
2993 1, 0x1E3E, 0x004D, 0x0301, 0,
2994 1, 0x1E3F, 0x006D, 0x0301, 0,
2995 1, 0x1E40, 0x004D, 0x0307, 0,
2996 1, 0x1E41, 0x006D, 0x0307, 0,
2997 1, 0x1E42, 0x004D, 0x0323, 0,
2998 1, 0x1E43, 0x006D, 0x0323, 0,
2999 1, 0x1E44, 0x004E, 0x0307, 0,
3000 1, 0x1E45, 0x006E, 0x0307, 0,
3001 1, 0x1E46, 0x004E, 0x0323, 0,
3002 1, 0x1E47, 0x006E, 0x0323, 0,
3003 1, 0x1E48, 0x004E, 0x0331, 0,
3004 1, 0x1E49, 0x006E, 0x0331, 0,
3005 1, 0x1E4A, 0x004E, 0x032D, 0,
3006 1, 0x1E4B, 0x006E, 0x032D, 0,
3007 1, 0x1E4C, 0x00D5, 0x0301, 0,
3008 1, 0x1E4D, 0x00F5, 0x0301, 0,
3009 1, 0x1E4E, 0x00D5, 0x0308, 0,
3010 1, 0x1E4F, 0x00F5, 0x0308, 0,
3011 1, 0x1E50, 0x014C, 0x0300, 0,
3012 1, 0x1E51, 0x014D, 0x0300, 0,
3013 1, 0x1E52, 0x014C, 0x0301, 0,
3014 1, 0x1E53, 0x014D, 0x0301, 0,
3015 1, 0x1E54, 0x0050, 0x0301, 0,
3016 1, 0x1E55, 0x0070, 0x0301, 0,
3017 1, 0x1E56, 0x0050, 0x0307, 0,
3018 1, 0x1E57, 0x0070, 0x0307, 0,
3019 1, 0x1E58, 0x0052, 0x0307, 0,
3020 1, 0x1E59, 0x0072, 0x0307, 0,
3021 1, 0x1E5A, 0x0052, 0x0323, 0,
3022 1, 0x1E5B, 0x0072, 0x0323, 0,
3023 1, 0x1E5C, 0x1E5A, 0x0304, 0,
3024 1, 0x1E5D, 0x1E5B, 0x0304, 0,
3025 1, 0x1E5E, 0x0052, 0x0331, 0,
3026 1, 0x1E5F, 0x0072, 0x0331, 0,
3027 1, 0x1E60, 0x0053, 0x0307, 0,
3028 1, 0x1E61, 0x0073, 0x0307, 0,
3029 1, 0x1E62, 0x0053, 0x0323, 0,
3030 1, 0x1E63, 0x0073, 0x0323, 0,
3031 1, 0x1E64, 0x015A, 0x0307, 0,
3032 1, 0x1E65, 0x015B, 0x0307, 0,
3033 1, 0x1E66, 0x0160, 0x0307, 0,
3034 1, 0x1E67, 0x0161, 0x0307, 0,
3035 1, 0x1E68, 0x1E62, 0x0307, 0,
3036 1, 0x1E69, 0x1E63, 0x0307, 0,
3037 1, 0x1E6A, 0x0054, 0x0307, 0,
3038 1, 0x1E6B, 0x0074, 0x0307, 0,
3039 1, 0x1E6C, 0x0054, 0x0323, 0,
3040 1, 0x1E6D, 0x0074, 0x0323, 0,
3041 1, 0x1E6E, 0x0054, 0x0331, 0,
3042 1, 0x1E6F, 0x0074, 0x0331, 0,
3043 1, 0x1E70, 0x0054, 0x032D, 0,
3044 1, 0x1E71, 0x0074, 0x032D, 0,
3045 1, 0x1E72, 0x0055, 0x0324, 0,
3046 1, 0x1E73, 0x0075, 0x0324, 0,
3047 1, 0x1E74, 0x0055, 0x0330, 0,
3048 1, 0x1E75, 0x0075, 0x0330, 0,
3049 1, 0x1E76, 0x0055, 0x032D, 0,
3050 1, 0x1E77, 0x0075, 0x032D, 0,
3051 1, 0x1E78, 0x0168, 0x0301, 0,
3052 1, 0x1E79, 0x0169, 0x0301, 0,
3053 1, 0x1E7A, 0x016A, 0x0308, 0,
3054 1, 0x1E7B, 0x016B, 0x0308, 0,
3055 1, 0x1E7C, 0x0056, 0x0303, 0,
3056 1, 0x1E7D, 0x0076, 0x0303, 0,
3057 1, 0x1E7E, 0x0056, 0x0323, 0,
3058 1, 0x1E7F, 0x0076, 0x0323, 0,
3059 1, 0x1E80, 0x0057, 0x0300, 0,
3060 1, 0x1E81, 0x0077, 0x0300, 0,
3061 1, 0x1E82, 0x0057, 0x0301, 0,
3062 1, 0x1E83, 0x0077, 0x0301, 0,
3063 1, 0x1E84, 0x0057, 0x0308, 0,
3064 1, 0x1E85, 0x0077, 0x0308, 0,
3065 1, 0x1E86, 0x0057, 0x0307, 0,
3066 1, 0x1E87, 0x0077, 0x0307, 0,
3067 1, 0x1E88, 0x0057, 0x0323, 0,
3068 1, 0x1E89, 0x0077, 0x0323, 0,
3069 1, 0x1E8A, 0x0058, 0x0307, 0,
3070 1, 0x1E8B, 0x0078, 0x0307, 0,
3071 1, 0x1E8C, 0x0058, 0x0308, 0,
3072 1, 0x1E8D, 0x0078, 0x0308, 0,
3073 1, 0x1E8E, 0x0059, 0x0307, 0,
3074 1, 0x1E8F, 0x0079, 0x0307, 0,
3075 1, 0x1E90, 0x005A, 0x0302, 0,
3076 1, 0x1E91, 0x007A, 0x0302, 0,
3077 1, 0x1E92, 0x005A, 0x0323, 0,
3078 1, 0x1E93, 0x007A, 0x0323, 0,
3079 1, 0x1E94, 0x005A, 0x0331, 0,
3080 1, 0x1E95, 0x007A, 0x0331, 0,
3081 1, 0x1E96, 0x0068, 0x0331, 0,
3082 1, 0x1E97, 0x0074, 0x0308, 0,
3083 1, 0x1E98, 0x0077, 0x030A, 0,
3084 1, 0x1E99, 0x0079, 0x030A, 0,
3085 16, 0x1E9A, 0x0061, 0x02BE, 0,
3086 1, 0x1E9B, 0x017F, 0x0307, 0,
3087 1, 0x1EA0, 0x0041, 0x0323, 0,
3088 1, 0x1EA1, 0x0061, 0x0323, 0,
3089 1, 0x1EA2, 0x0041, 0x0309, 0,
3090 1, 0x1EA3, 0x0061, 0x0309, 0,
3091 1, 0x1EA4, 0x00C2, 0x0301, 0,
3092 1, 0x1EA5, 0x00E2, 0x0301, 0,
3093 1, 0x1EA6, 0x00C2, 0x0300, 0,
3094 1, 0x1EA7, 0x00E2, 0x0300, 0,
3095 1, 0x1EA8, 0x00C2, 0x0309, 0,
3096 1, 0x1EA9, 0x00E2, 0x0309, 0,
3097 1, 0x1EAA, 0x00C2, 0x0303, 0,
3098 1, 0x1EAB, 0x00E2, 0x0303, 0,
3099 1, 0x1EAC, 0x1EA0, 0x0302, 0,
3100 1, 0x1EAD, 0x1EA1, 0x0302, 0,
3101 1, 0x1EAE, 0x0102, 0x0301, 0,
3102 1, 0x1EAF, 0x0103, 0x0301, 0,
3103 1, 0x1EB0, 0x0102, 0x0300, 0,
3104 1, 0x1EB1, 0x0103, 0x0300, 0,
3105 1, 0x1EB2, 0x0102, 0x0309, 0,
3106 1, 0x1EB3, 0x0103, 0x0309, 0,
3107 1, 0x1EB4, 0x0102, 0x0303, 0,
3108 1, 0x1EB5, 0x0103, 0x0303, 0,
3109 1, 0x1EB6, 0x1EA0, 0x0306, 0,
3110 1, 0x1EB7, 0x1EA1, 0x0306, 0,
3111 1, 0x1EB8, 0x0045, 0x0323, 0,
3112 1, 0x1EB9, 0x0065, 0x0323, 0,
3113 1, 0x1EBA, 0x0045, 0x0309, 0,
3114 1, 0x1EBB, 0x0065, 0x0309, 0,
3115 1, 0x1EBC, 0x0045, 0x0303, 0,
3116 1, 0x1EBD, 0x0065, 0x0303, 0,
3117 1, 0x1EBE, 0x00CA, 0x0301, 0,
3118 1, 0x1EBF, 0x00EA, 0x0301, 0,
3119 1, 0x1EC0, 0x00CA, 0x0300, 0,
3120 1, 0x1EC1, 0x00EA, 0x0300, 0,
3121 1, 0x1EC2, 0x00CA, 0x0309, 0,
3122 1, 0x1EC3, 0x00EA, 0x0309, 0,
3123 1, 0x1EC4, 0x00CA, 0x0303, 0,
3124 1, 0x1EC5, 0x00EA, 0x0303, 0,
3125 1, 0x1EC6, 0x1EB8, 0x0302, 0,
3126 1, 0x1EC7, 0x1EB9, 0x0302, 0,
3127 1, 0x1EC8, 0x0049, 0x0309, 0,
3128 1, 0x1EC9, 0x0069, 0x0309, 0,
3129 1, 0x1ECA, 0x0049, 0x0323, 0,
3130 1, 0x1ECB, 0x0069, 0x0323, 0,
3131 1, 0x1ECC, 0x004F, 0x0323, 0,
3132 1, 0x1ECD, 0x006F, 0x0323, 0,
3133 1, 0x1ECE, 0x004F, 0x0309, 0,
3134 1, 0x1ECF, 0x006F, 0x0309, 0,
3135 1, 0x1ED0, 0x00D4, 0x0301, 0,
3136 1, 0x1ED1, 0x00F4, 0x0301, 0,
3137 1, 0x1ED2, 0x00D4, 0x0300, 0,
3138 1, 0x1ED3, 0x00F4, 0x0300, 0,
3139 1, 0x1ED4, 0x00D4, 0x0309, 0,
3140 1, 0x1ED5, 0x00F4, 0x0309, 0,
3141 1, 0x1ED6, 0x00D4, 0x0303, 0,
3142 1, 0x1ED7, 0x00F4, 0x0303, 0,
3143 1, 0x1ED8, 0x1ECC, 0x0302, 0,
3144 1, 0x1ED9, 0x1ECD, 0x0302, 0,
3145 1, 0x1EDA, 0x01A0, 0x0301, 0,
3146 1, 0x1EDB, 0x01A1, 0x0301, 0,
3147 1, 0x1EDC, 0x01A0, 0x0300, 0,
3148 1, 0x1EDD, 0x01A1, 0x0300, 0,
3149 1, 0x1EDE, 0x01A0, 0x0309, 0,
3150 1, 0x1EDF, 0x01A1, 0x0309, 0,
3151 1, 0x1EE0, 0x01A0, 0x0303, 0,
3152 1, 0x1EE1, 0x01A1, 0x0303, 0,
3153 1, 0x1EE2, 0x01A0, 0x0323, 0,
3154 1, 0x1EE3, 0x01A1, 0x0323, 0,
3155 1, 0x1EE4, 0x0055, 0x0323, 0,
3156 1, 0x1EE5, 0x0075, 0x0323, 0,
3157 1, 0x1EE6, 0x0055, 0x0309, 0,
3158 1, 0x1EE7, 0x0075, 0x0309, 0,
3159 1, 0x1EE8, 0x01AF, 0x0301, 0,
3160 1, 0x1EE9, 0x01B0, 0x0301, 0,
3161 1, 0x1EEA, 0x01AF, 0x0300, 0,
3162 1, 0x1EEB, 0x01B0, 0x0300, 0,
3163 1, 0x1EEC, 0x01AF, 0x0309, 0,
3164 1, 0x1EED, 0x01B0, 0x0309, 0,
3165 1, 0x1EEE, 0x01AF, 0x0303, 0,
3166 1, 0x1EEF, 0x01B0, 0x0303, 0,
3167 1, 0x1EF0, 0x01AF, 0x0323, 0,
3168 1, 0x1EF1, 0x01B0, 0x0323, 0,
3169 1, 0x1EF2, 0x0059, 0x0300, 0,
3170 1, 0x1EF3, 0x0079, 0x0300, 0,
3171 1, 0x1EF4, 0x0059, 0x0323, 0,
3172 1, 0x1EF5, 0x0079, 0x0323, 0,
3173 1, 0x1EF6, 0x0059, 0x0309, 0,
3174 1, 0x1EF7, 0x0079, 0x0309, 0,
3175 1, 0x1EF8, 0x0059, 0x0303, 0,
3176 1, 0x1EF9, 0x0079, 0x0303, 0,
3177 1, 0x1F00, 0x03B1, 0x0313, 0,
3178 1, 0x1F01, 0x03B1, 0x0314, 0,
3179 1, 0x1F02, 0x1F00, 0x0300, 0,
3180 1, 0x1F03, 0x1F01, 0x0300, 0,
3181 1, 0x1F04, 0x1F00, 0x0301, 0,
3182 1, 0x1F05, 0x1F01, 0x0301, 0,
3183 1, 0x1F06, 0x1F00, 0x0342, 0,
3184 1, 0x1F07, 0x1F01, 0x0342, 0,
3185 1, 0x1F08, 0x0391, 0x0313, 0,
3186 1, 0x1F09, 0x0391, 0x0314, 0,
3187 1, 0x1F0A, 0x1F08, 0x0300, 0,
3188 1, 0x1F0B, 0x1F09, 0x0300, 0,
3189 1, 0x1F0C, 0x1F08, 0x0301, 0,
3190 1, 0x1F0D, 0x1F09, 0x0301, 0,
3191 1, 0x1F0E, 0x1F08, 0x0342, 0,
3192 1, 0x1F0F, 0x1F09, 0x0342, 0,
3193 1, 0x1F10, 0x03B5, 0x0313, 0,
3194 1, 0x1F11, 0x03B5, 0x0314, 0,
3195 1, 0x1F12, 0x1F10, 0x0300, 0,
3196 1, 0x1F13, 0x1F11, 0x0300, 0,
3197 1, 0x1F14, 0x1F10, 0x0301, 0,
3198 1, 0x1F15, 0x1F11, 0x0301, 0,
3199 1, 0x1F18, 0x0395, 0x0313, 0,
3200 1, 0x1F19, 0x0395, 0x0314, 0,
3201 1, 0x1F1A, 0x1F18, 0x0300, 0,
3202 1, 0x1F1B, 0x1F19, 0x0300, 0,
3203 1, 0x1F1C, 0x1F18, 0x0301, 0,
3204 1, 0x1F1D, 0x1F19, 0x0301, 0,
3205 1, 0x1F20, 0x03B7, 0x0313, 0,
3206 1, 0x1F21, 0x03B7, 0x0314, 0,
3207 1, 0x1F22, 0x1F20, 0x0300, 0,
3208 1, 0x1F23, 0x1F21, 0x0300, 0,
3209 1, 0x1F24, 0x1F20, 0x0301, 0,
3210 1, 0x1F25, 0x1F21, 0x0301, 0,
3211 1, 0x1F26, 0x1F20, 0x0342, 0,
3212 1, 0x1F27, 0x1F21, 0x0342, 0,
3213 1, 0x1F28, 0x0397, 0x0313, 0,
3214 1, 0x1F29, 0x0397, 0x0314, 0,
3215 1, 0x1F2A, 0x1F28, 0x0300, 0,
3216 1, 0x1F2B, 0x1F29, 0x0300, 0,
3217 1, 0x1F2C, 0x1F28, 0x0301, 0,
3218 1, 0x1F2D, 0x1F29, 0x0301, 0,
3219 1, 0x1F2E, 0x1F28, 0x0342, 0,
3220 1, 0x1F2F, 0x1F29, 0x0342, 0,
3221 1, 0x1F30, 0x03B9, 0x0313, 0,
3222 1, 0x1F31, 0x03B9, 0x0314, 0,
3223 1, 0x1F32, 0x1F30, 0x0300, 0,
3224 1, 0x1F33, 0x1F31, 0x0300, 0,
3225 1, 0x1F34, 0x1F30, 0x0301, 0,
3226 1, 0x1F35, 0x1F31, 0x0301, 0,
3227 1, 0x1F36, 0x1F30, 0x0342, 0,
3228 1, 0x1F37, 0x1F31, 0x0342, 0,
3229 1, 0x1F38, 0x0399, 0x0313, 0,
3230 1, 0x1F39, 0x0399, 0x0314, 0,
3231 1, 0x1F3A, 0x1F38, 0x0300, 0,
3232 1, 0x1F3B, 0x1F39, 0x0300, 0,
3233 1, 0x1F3C, 0x1F38, 0x0301, 0,
3234 1, 0x1F3D, 0x1F39, 0x0301, 0,
3235 1, 0x1F3E, 0x1F38, 0x0342, 0,
3236 1, 0x1F3F, 0x1F39, 0x0342, 0,
3237 1, 0x1F40, 0x03BF, 0x0313, 0,
3238 1, 0x1F41, 0x03BF, 0x0314, 0,
3239 1, 0x1F42, 0x1F40, 0x0300, 0,
3240 1, 0x1F43, 0x1F41, 0x0300, 0,
3241 1, 0x1F44, 0x1F40, 0x0301, 0,
3242 1, 0x1F45, 0x1F41, 0x0301, 0,
3243 1, 0x1F48, 0x039F, 0x0313, 0,
3244 1, 0x1F49, 0x039F, 0x0314, 0,
3245 1, 0x1F4A, 0x1F48, 0x0300, 0,
3246 1, 0x1F4B, 0x1F49, 0x0300, 0,
3247 1, 0x1F4C, 0x1F48, 0x0301, 0,
3248 1, 0x1F4D, 0x1F49, 0x0301, 0,
3249 1, 0x1F50, 0x03C5, 0x0313, 0,
3250 1, 0x1F51, 0x03C5, 0x0314, 0,
3251 1, 0x1F52, 0x1F50, 0x0300, 0,
3252 1, 0x1F53, 0x1F51, 0x0300, 0,
3253 1, 0x1F54, 0x1F50, 0x0301, 0,
3254 1, 0x1F55, 0x1F51, 0x0301, 0,
3255 1, 0x1F56, 0x1F50, 0x0342, 0,
3256 1, 0x1F57, 0x1F51, 0x0342, 0,
3257 1, 0x1F59, 0x03A5, 0x0314, 0,
3258 1, 0x1F5B, 0x1F59, 0x0300, 0,
3259 1, 0x1F5D, 0x1F59, 0x0301, 0,
3260 1, 0x1F5F, 0x1F59, 0x0342, 0,
3261 1, 0x1F60, 0x03C9, 0x0313, 0,
3262 1, 0x1F61, 0x03C9, 0x0314, 0,
3263 1, 0x1F62, 0x1F60, 0x0300, 0,
3264 1, 0x1F63, 0x1F61, 0x0300, 0,
3265 1, 0x1F64, 0x1F60, 0x0301, 0,
3266 1, 0x1F65, 0x1F61, 0x0301, 0,
3267 1, 0x1F66, 0x1F60, 0x0342, 0,
3268 1, 0x1F67, 0x1F61, 0x0342, 0,
3269 1, 0x1F68, 0x03A9, 0x0313, 0,
3270 1, 0x1F69, 0x03A9, 0x0314, 0,
3271 1, 0x1F6A, 0x1F68, 0x0300, 0,
3272 1, 0x1F6B, 0x1F69, 0x0300, 0,
3273 1, 0x1F6C, 0x1F68, 0x0301, 0,
3274 1, 0x1F6D, 0x1F69, 0x0301, 0,
3275 1, 0x1F6E, 0x1F68, 0x0342, 0,
3276 1, 0x1F6F, 0x1F69, 0x0342, 0,
3277 1, 0x1F70, 0x03B1, 0x0300, 0,
3278 1, 0x1F71, 0x03AC, 0,
3279 1, 0x1F72, 0x03B5, 0x0300, 0,
3280 1, 0x1F73, 0x03AD, 0,
3281 1, 0x1F74, 0x03B7, 0x0300, 0,
3282 1, 0x1F75, 0x03AE, 0,
3283 1, 0x1F76, 0x03B9, 0x0300, 0,
3284 1, 0x1F77, 0x03AF, 0,
3285 1, 0x1F78, 0x03BF, 0x0300, 0,
3286 1, 0x1F79, 0x03CC, 0,
3287 1, 0x1F7A, 0x03C5, 0x0300, 0,
3288 1, 0x1F7B, 0x03CD, 0,
3289 1, 0x1F7C, 0x03C9, 0x0300, 0,
3290 1, 0x1F7D, 0x03CE, 0,
3291 1, 0x1F80, 0x1F00, 0x0345, 0,
3292 1, 0x1F81, 0x1F01, 0x0345, 0,
3293 1, 0x1F82, 0x1F02, 0x0345, 0,
3294 1, 0x1F83, 0x1F03, 0x0345, 0,
3295 1, 0x1F84, 0x1F04, 0x0345, 0,
3296 1, 0x1F85, 0x1F05, 0x0345, 0,
3297 1, 0x1F86, 0x1F06, 0x0345, 0,
3298 1, 0x1F87, 0x1F07, 0x0345, 0,
3299 1, 0x1F88, 0x1F08, 0x0345, 0,
3300 1, 0x1F89, 0x1F09, 0x0345, 0,
3301 1, 0x1F8A, 0x1F0A, 0x0345, 0,
3302 1, 0x1F8B, 0x1F0B, 0x0345, 0,
3303 1, 0x1F8C, 0x1F0C, 0x0345, 0,
3304 1, 0x1F8D, 0x1F0D, 0x0345, 0,
3305 1, 0x1F8E, 0x1F0E, 0x0345, 0,
3306 1, 0x1F8F, 0x1F0F, 0x0345, 0,
3307 1, 0x1F90, 0x1F20, 0x0345, 0,
3308 1, 0x1F91, 0x1F21, 0x0345, 0,
3309 1, 0x1F92, 0x1F22, 0x0345, 0,
3310 1, 0x1F93, 0x1F23, 0x0345, 0,
3311 1, 0x1F94, 0x1F24, 0x0345, 0,
3312 1, 0x1F95, 0x1F25, 0x0345, 0,
3313 1, 0x1F96, 0x1F26, 0x0345, 0,
3314 1, 0x1F97, 0x1F27, 0x0345, 0,
3315 1, 0x1F98, 0x1F28, 0x0345, 0,
3316 1, 0x1F99, 0x1F29, 0x0345, 0,
3317 1, 0x1F9A, 0x1F2A, 0x0345, 0,
3318 1, 0x1F9B, 0x1F2B, 0x0345, 0,
3319 1, 0x1F9C, 0x1F2C, 0x0345, 0,
3320 1, 0x1F9D, 0x1F2D, 0x0345, 0,
3321 1, 0x1F9E, 0x1F2E, 0x0345, 0,
3322 1, 0x1F9F, 0x1F2F, 0x0345, 0,
3323 1, 0x1FA0, 0x1F60, 0x0345, 0,
3324 1, 0x1FA1, 0x1F61, 0x0345, 0,
3325 1, 0x1FA2, 0x1F62, 0x0345, 0,
3326 1, 0x1FA3, 0x1F63, 0x0345, 0,
3327 1, 0x1FA4, 0x1F64, 0x0345, 0,
3328 1, 0x1FA5, 0x1F65, 0x0345, 0,
3329 1, 0x1FA6, 0x1F66, 0x0345, 0,
3330 1, 0x1FA7, 0x1F67, 0x0345, 0,
3331 1, 0x1FA8, 0x1F68, 0x0345, 0,
3332 1, 0x1FA9, 0x1F69, 0x0345, 0,
3333 1, 0x1FAA, 0x1F6A, 0x0345, 0,
3334 1, 0x1FAB, 0x1F6B, 0x0345, 0,
3335 1, 0x1FAC, 0x1F6C, 0x0345, 0,
3336 1, 0x1FAD, 0x1F6D, 0x0345, 0,
3337 1, 0x1FAE, 0x1F6E, 0x0345, 0,
3338 1, 0x1FAF, 0x1F6F, 0x0345, 0,
3339 1, 0x1FB0, 0x03B1, 0x0306, 0,
3340 1, 0x1FB1, 0x03B1, 0x0304, 0,
3341 1, 0x1FB2, 0x1F70, 0x0345, 0,
3342 1, 0x1FB3, 0x03B1, 0x0345, 0,
3343 1, 0x1FB4, 0x03AC, 0x0345, 0,
3344 1, 0x1FB6, 0x03B1, 0x0342, 0,
3345 1, 0x1FB7, 0x1FB6, 0x0345, 0,
3346 1, 0x1FB8, 0x0391, 0x0306, 0,
3347 1, 0x1FB9, 0x0391, 0x0304, 0,
3348 1, 0x1FBA, 0x0391, 0x0300, 0,
3349 1, 0x1FBB, 0x0386, 0,
3350 1, 0x1FBC, 0x0391, 0x0345, 0,
3351 16, 0x1FBD, 0x0020, 0x0313, 0,
3352 1, 0x1FBE, 0x03B9, 0,
3353 16, 0x1FBF, 0x0020, 0x0313, 0,
3354 16, 0x1FC0, 0x0020, 0x0342, 0,
3355 1, 0x1FC1, 0x00A8, 0x0342, 0,
3356 1, 0x1FC2, 0x1F74, 0x0345, 0,
3357 1, 0x1FC3, 0x03B7, 0x0345, 0,
3358 1, 0x1FC4, 0x03AE, 0x0345, 0,
3359 1, 0x1FC6, 0x03B7, 0x0342, 0,
3360 1, 0x1FC7, 0x1FC6, 0x0345, 0,
3361 1, 0x1FC8, 0x0395, 0x0300, 0,
3362 1, 0x1FC9, 0x0388, 0,
3363 1, 0x1FCA, 0x0397, 0x0300, 0,
3364 1, 0x1FCB, 0x0389, 0,
3365 1, 0x1FCC, 0x0397, 0x0345, 0,
3366 1, 0x1FCD, 0x1FBF, 0x0300, 0,
3367 1, 0x1FCE, 0x1FBF, 0x0301, 0,
3368 1, 0x1FCF, 0x1FBF, 0x0342, 0,
3369 1, 0x1FD0, 0x03B9, 0x0306, 0,
3370 1, 0x1FD1, 0x03B9, 0x0304, 0,
3371 1, 0x1FD2, 0x03CA, 0x0300, 0,
3372 1, 0x1FD3, 0x0390, 0,
3373 1, 0x1FD6, 0x03B9, 0x0342, 0,
3374 1, 0x1FD7, 0x03CA, 0x0342, 0,
3375 1, 0x1FD8, 0x0399, 0x0306, 0,
3376 1, 0x1FD9, 0x0399, 0x0304, 0,
3377 1, 0x1FDA, 0x0399, 0x0300, 0,
3378 1, 0x1FDB, 0x038A, 0,
3379 1, 0x1FDD, 0x1FFE, 0x0300, 0,
3380 1, 0x1FDE, 0x1FFE, 0x0301, 0,
3381 1, 0x1FDF, 0x1FFE, 0x0342, 0,
3382 1, 0x1FE0, 0x03C5, 0x0306, 0,
3383 1, 0x1FE1, 0x03C5, 0x0304, 0,
3384 1, 0x1FE2, 0x03CB, 0x0300, 0,
3385 1, 0x1FE3, 0x03B0, 0,
3386 1, 0x1FE4, 0x03C1, 0x0313, 0,
3387 1, 0x1FE5, 0x03C1, 0x0314, 0,
3388 1, 0x1FE6, 0x03C5, 0x0342, 0,
3389 1, 0x1FE7, 0x03CB, 0x0342, 0,
3390 1, 0x1FE8, 0x03A5, 0x0306, 0,
3391 1, 0x1FE9, 0x03A5, 0x0304, 0,
3392 1, 0x1FEA, 0x03A5, 0x0300, 0,
3393 1, 0x1FEB, 0x038E, 0,
3394 1, 0x1FEC, 0x03A1, 0x0314, 0,
3395 1, 0x1FED, 0x00A8, 0x0300, 0,
3396 1, 0x1FEE, 0x0385, 0,
3397 1, 0x1FEF, 0x0060, 0,
3398 1, 0x1FF2, 0x1F7C, 0x0345, 0,
3399 1, 0x1FF3, 0x03C9, 0x0345, 0,
3400 1, 0x1FF4, 0x03CE, 0x0345, 0,
3401 1, 0x1FF6, 0x03C9, 0x0342, 0,
3402 1, 0x1FF7, 0x1FF6, 0x0345, 0,
3403 1, 0x1FF8, 0x039F, 0x0300, 0,
3404 1, 0x1FF9, 0x038C, 0,
3405 1, 0x1FFA, 0x03A9, 0x0300, 0,
3406 1, 0x1FFB, 0x038F, 0,
3407 1, 0x1FFC, 0x03A9, 0x0345, 0,
3408 1, 0x1FFD, 0x00B4, 0,
3409 16, 0x1FFE, 0x0020, 0x0314, 0,
3410 1, 0x2000, 0x2002, 0,
3411 1, 0x2001, 0x2003, 0,
3412 16, 0x2002, 0x0020, 0,
3413 16, 0x2003, 0x0020, 0,
3414 16, 0x2004, 0x0020, 0,
3415 16, 0x2005, 0x0020, 0,
3416 16, 0x2006, 0x0020, 0,
3417 3, 0x2007, 0x0020, 0,
3418 16, 0x2008, 0x0020, 0,
3419 16, 0x2009, 0x0020, 0,
3420 16, 0x200A, 0x0020, 0,
3421 3, 0x2011, 0x2010, 0,
3422 16, 0x2017, 0x0020, 0x0333, 0,
3423 16, 0x2024, 0x002E, 0,
3424 16, 0x2025, 0x002E, 0x002E, 0,
3425 16, 0x2026, 0x002E, 0x002E, 0x002E, 0,
3426 3, 0x202F, 0x0020, 0,
3427 16, 0x2033, 0x2032, 0x2032, 0,
3428 16, 0x2034, 0x2032, 0x2032, 0x2032, 0,
3429 16, 0x2036, 0x2035, 0x2035, 0,
3430 16, 0x2037, 0x2035, 0x2035, 0x2035, 0,
3431 16, 0x203C, 0x0021, 0x0021, 0,
3432 16, 0x203E, 0x0020, 0x0305, 0,
3433 16, 0x2047, 0x003F, 0x003F, 0,
3434 16, 0x2048, 0x003F, 0x0021, 0,
3435 16, 0x2049, 0x0021, 0x003F, 0,
3436 16, 0x2057, 0x2032, 0x2032, 0x2032, 0x2032, 0,
3437 16, 0x205F, 0x0020, 0,
3438 9, 0x2070, 0x0030, 0,
3439 9, 0x2071, 0x0069, 0,
3440 9, 0x2074, 0x0034, 0,
3441 9, 0x2075, 0x0035, 0,
3442 9, 0x2076, 0x0036, 0,
3443 9, 0x2077, 0x0037, 0,
3444 9, 0x2078, 0x0038, 0,
3445 9, 0x2079, 0x0039, 0,
3446 9, 0x207A, 0x002B, 0,
3447 9, 0x207B, 0x2212, 0,
3448 9, 0x207C, 0x003D, 0,
3449 9, 0x207D, 0x0028, 0,
3450 9, 0x207E, 0x0029, 0,
3451 9, 0x207F, 0x006E, 0,
3452 10, 0x2080, 0x0030, 0,
3453 10, 0x2081, 0x0031, 0,
3454 10, 0x2082, 0x0032, 0,
3455 10, 0x2083, 0x0033, 0,
3456 10, 0x2084, 0x0034, 0,
3457 10, 0x2085, 0x0035, 0,
3458 10, 0x2086, 0x0036, 0,
3459 10, 0x2087, 0x0037, 0,
3460 10, 0x2088, 0x0038, 0,
3461 10, 0x2089, 0x0039, 0,
3462 10, 0x208A, 0x002B, 0,
3463 10, 0x208B, 0x2212, 0,
3464 10, 0x208C, 0x003D, 0,
3465 10, 0x208D, 0x0028, 0,
3466 10, 0x208E, 0x0029, 0,
3467 16, 0x20A8, 0x0052, 0x0073, 0,
3468 16, 0x2100, 0x0061, 0x002F, 0x0063, 0,
3469 16, 0x2101, 0x0061, 0x002F, 0x0073, 0,
3470 2, 0x2102, 0x0043, 0,
3471 16, 0x2103, 0x00B0, 0x0043, 0,
3472 16, 0x2105, 0x0063, 0x002F, 0x006F, 0,
3473 16, 0x2106, 0x0063, 0x002F, 0x0075, 0,
3474 16, 0x2107, 0x0190, 0,
3475 16, 0x2109, 0x00B0, 0x0046, 0,
3476 2, 0x210A, 0x0067, 0,
3477 2, 0x210B, 0x0048, 0,
3478 2, 0x210C, 0x0048, 0,
3479 2, 0x210D, 0x0048, 0,
3480 2, 0x210E, 0x0068, 0,
3481 2, 0x210F, 0x0127, 0,
3482 2, 0x2110, 0x0049, 0,
3483 2, 0x2111, 0x0049, 0,
3484 2, 0x2112, 0x004C, 0,
3485 2, 0x2113, 0x006C, 0,
3486 2, 0x2115, 0x004E, 0,
3487 16, 0x2116, 0x004E, 0x006F, 0,
3488 2, 0x2119, 0x0050, 0,
3489 2, 0x211A, 0x0051, 0,
3490 2, 0x211B, 0x0052, 0,
3491 2, 0x211C, 0x0052, 0,
3492 2, 0x211D, 0x0052, 0,
3493 9, 0x2120, 0x0053, 0x004D, 0,
3494 16, 0x2121, 0x0054, 0x0045, 0x004C, 0,
3495 9, 0x2122, 0x0054, 0x004D, 0,
3496 2, 0x2124, 0x005A, 0,
3497 1, 0x2126, 0x03A9, 0,
3498 2, 0x2128, 0x005A, 0,
3499 1, 0x212A, 0x004B, 0,
3500 1, 0x212B, 0x00C5, 0,
3501 2, 0x212C, 0x0042, 0,
3502 2, 0x212D, 0x0043, 0,
3503 2, 0x212F, 0x0065, 0,
3504 2, 0x2130, 0x0045, 0,
3505 2, 0x2131, 0x0046, 0,
3506 2, 0x2133, 0x004D, 0,
3507 2, 0x2134, 0x006F, 0,
3508 16, 0x2135, 0x05D0, 0,
3509 16, 0x2136, 0x05D1, 0,
3510 16, 0x2137, 0x05D2, 0,
3511 16, 0x2138, 0x05D3, 0,
3512 2, 0x2139, 0x0069, 0,
3513 2, 0x213D, 0x03B3, 0,
3514 2, 0x213E, 0x0393, 0,
3515 2, 0x213F, 0x03A0, 0,
3516 2, 0x2140, 0x2211, 0,
3517 2, 0x2145, 0x0044, 0,
3518 2, 0x2146, 0x0064, 0,
3519 2, 0x2147, 0x0065, 0,
3520 2, 0x2148, 0x0069, 0,
3521 2, 0x2149, 0x006A, 0,
3522 17, 0x2153, 0x0031, 0x2044, 0x0033, 0,
3523 17, 0x2154, 0x0032, 0x2044, 0x0033, 0,
3524 17, 0x2155, 0x0031, 0x2044, 0x0035, 0,
3525 17, 0x2156, 0x0032, 0x2044, 0x0035, 0,
3526 17, 0x2157, 0x0033, 0x2044, 0x0035, 0,
3527 17, 0x2158, 0x0034, 0x2044, 0x0035, 0,
3528 17, 0x2159, 0x0031, 0x2044, 0x0036, 0,
3529 17, 0x215A, 0x0035, 0x2044, 0x0036, 0,
3530 17, 0x215B, 0x0031, 0x2044, 0x0038, 0,
3531 17, 0x215C, 0x0033, 0x2044, 0x0038, 0,
3532 17, 0x215D, 0x0035, 0x2044, 0x0038, 0,
3533 17, 0x215E, 0x0037, 0x2044, 0x0038, 0,
3534 17, 0x215F, 0x0031, 0x2044, 0,
3535 16, 0x2160, 0x0049, 0,
3536 16, 0x2161, 0x0049, 0x0049, 0,
3537 16, 0x2162, 0x0049, 0x0049, 0x0049, 0,
3538 16, 0x2163, 0x0049, 0x0056, 0,
3539 16, 0x2164, 0x0056, 0,
3540 16, 0x2165, 0x0056, 0x0049, 0,
3541 16, 0x2166, 0x0056, 0x0049, 0x0049, 0,
3542 16, 0x2167, 0x0056, 0x0049, 0x0049, 0x0049, 0,
3543 16, 0x2168, 0x0049, 0x0058, 0,
3544 16, 0x2169, 0x0058, 0,
3545 16, 0x216A, 0x0058, 0x0049, 0,
3546 16, 0x216B, 0x0058, 0x0049, 0x0049, 0,
3547 16, 0x216C, 0x004C, 0,
3548 16, 0x216D, 0x0043, 0,
3549 16, 0x216E, 0x0044, 0,
3550 16, 0x216F, 0x004D, 0,
3551 16, 0x2170, 0x0069, 0,
3552 16, 0x2171, 0x0069, 0x0069, 0,
3553 16, 0x2172, 0x0069, 0x0069, 0x0069, 0,
3554 16, 0x2173, 0x0069, 0x0076, 0,
3555 16, 0x2174, 0x0076, 0,
3556 16, 0x2175, 0x0076, 0x0069, 0,
3557 16, 0x2176, 0x0076, 0x0069, 0x0069, 0,
3558 16, 0x2177, 0x0076, 0x0069, 0x0069, 0x0069, 0,
3559 16, 0x2178, 0x0069, 0x0078, 0,
3560 16, 0x2179, 0x0078, 0,
3561 16, 0x217A, 0x0078, 0x0069, 0,
3562 16, 0x217B, 0x0078, 0x0069, 0x0069, 0,
3563 16, 0x217C, 0x006C, 0,
3564 16, 0x217D, 0x0063, 0,
3565 16, 0x217E, 0x0064, 0,
3566 16, 0x217F, 0x006D, 0,
3567 1, 0x219A, 0x2190, 0x0338, 0,
3568 1, 0x219B, 0x2192, 0x0338, 0,
3569 1, 0x21AE, 0x2194, 0x0338, 0,
3570 1, 0x21CD, 0x21D0, 0x0338, 0,
3571 1, 0x21CE, 0x21D4, 0x0338, 0,
3572 1, 0x21CF, 0x21D2, 0x0338, 0,
3573 1, 0x2204, 0x2203, 0x0338, 0,
3574 1, 0x2209, 0x2208, 0x0338, 0,
3575 1, 0x220C, 0x220B, 0x0338, 0,
3576 1, 0x2224, 0x2223, 0x0338, 0,
3577 1, 0x2226, 0x2225, 0x0338, 0,
3578 16, 0x222C, 0x222B, 0x222B, 0,
3579 16, 0x222D, 0x222B, 0x222B, 0x222B, 0,
3580 16, 0x222F, 0x222E, 0x222E, 0,
3581 16, 0x2230, 0x222E, 0x222E, 0x222E, 0,
3582 1, 0x2241, 0x223C, 0x0338, 0,
3583 1, 0x2244, 0x2243, 0x0338, 0,
3584 1, 0x2247, 0x2245, 0x0338, 0,
3585 1, 0x2249, 0x2248, 0x0338, 0,
3586 1, 0x2260, 0x003D, 0x0338, 0,
3587 1, 0x2262, 0x2261, 0x0338, 0,
3588 1, 0x226D, 0x224D, 0x0338, 0,
3589 1, 0x226E, 0x003C, 0x0338, 0,
3590 1, 0x226F, 0x003E, 0x0338, 0,
3591 1, 0x2270, 0x2264, 0x0338, 0,
3592 1, 0x2271, 0x2265, 0x0338, 0,
3593 1, 0x2274, 0x2272, 0x0338, 0,
3594 1, 0x2275, 0x2273, 0x0338, 0,
3595 1, 0x2278, 0x2276, 0x0338, 0,
3596 1, 0x2279, 0x2277, 0x0338, 0,
3597 1, 0x2280, 0x227A, 0x0338, 0,
3598 1, 0x2281, 0x227B, 0x0338, 0,
3599 1, 0x2284, 0x2282, 0x0338, 0,
3600 1, 0x2285, 0x2283, 0x0338, 0,
3601 1, 0x2288, 0x2286, 0x0338, 0,
3602 1, 0x2289, 0x2287, 0x0338, 0,
3603 1, 0x22AC, 0x22A2, 0x0338, 0,
3604 1, 0x22AD, 0x22A8, 0x0338, 0,
3605 1, 0x22AE, 0x22A9, 0x0338, 0,
3606 1, 0x22AF, 0x22AB, 0x0338, 0,
3607 1, 0x22E0, 0x227C, 0x0338, 0,
3608 1, 0x22E1, 0x227D, 0x0338, 0,
3609 1, 0x22E2, 0x2291, 0x0338, 0,
3610 1, 0x22E3, 0x2292, 0x0338, 0,
3611 1, 0x22EA, 0x22B2, 0x0338, 0,
3612 1, 0x22EB, 0x22B3, 0x0338, 0,
3613 1, 0x22EC, 0x22B4, 0x0338, 0,
3614 1, 0x22ED, 0x22B5, 0x0338, 0,
3615 1, 0x2329, 0x3008, 0,
3616 1, 0x232A, 0x3009, 0,
3617 8, 0x2460, 0x0031, 0,
3618 8, 0x2461, 0x0032, 0,
3619 8, 0x2462, 0x0033, 0,
3620 8, 0x2463, 0x0034, 0,
3621 8, 0x2464, 0x0035, 0,
3622 8, 0x2465, 0x0036, 0,
3623 8, 0x2466, 0x0037, 0,
3624 8, 0x2467, 0x0038, 0,
3625 8, 0x2468, 0x0039, 0,
3626 8, 0x2469, 0x0031, 0x0030, 0,
3627 8, 0x246A, 0x0031, 0x0031, 0,
3628 8, 0x246B, 0x0031, 0x0032, 0,
3629 8, 0x246C, 0x0031, 0x0033, 0,
3630 8, 0x246D, 0x0031, 0x0034, 0,
3631 8, 0x246E, 0x0031, 0x0035, 0,
3632 8, 0x246F, 0x0031, 0x0036, 0,
3633 8, 0x2470, 0x0031, 0x0037, 0,
3634 8, 0x2471, 0x0031, 0x0038, 0,
3635 8, 0x2472, 0x0031, 0x0039, 0,
3636 8, 0x2473, 0x0032, 0x0030, 0,
3637 16, 0x2474, 0x0028, 0x0031, 0x0029, 0,
3638 16, 0x2475, 0x0028, 0x0032, 0x0029, 0,
3639 16, 0x2476, 0x0028, 0x0033, 0x0029, 0,
3640 16, 0x2477, 0x0028, 0x0034, 0x0029, 0,
3641 16, 0x2478, 0x0028, 0x0035, 0x0029, 0,
3642 16, 0x2479, 0x0028, 0x0036, 0x0029, 0,
3643 16, 0x247A, 0x0028, 0x0037, 0x0029, 0,
3644 16, 0x247B, 0x0028, 0x0038, 0x0029, 0,
3645 16, 0x247C, 0x0028, 0x0039, 0x0029, 0,
3646 16, 0x247D, 0x0028, 0x0031, 0x0030, 0x0029, 0,
3647 16, 0x247E, 0x0028, 0x0031, 0x0031, 0x0029, 0,
3648 16, 0x247F, 0x0028, 0x0031, 0x0032, 0x0029, 0,
3649 16, 0x2480, 0x0028, 0x0031, 0x0033, 0x0029, 0,
3650 16, 0x2481, 0x0028, 0x0031, 0x0034, 0x0029, 0,
3651 16, 0x2482, 0x0028, 0x0031, 0x0035, 0x0029, 0,
3652 16, 0x2483, 0x0028, 0x0031, 0x0036, 0x0029, 0,
3653 16, 0x2484, 0x0028, 0x0031, 0x0037, 0x0029, 0,
3654 16, 0x2485, 0x0028, 0x0031, 0x0038, 0x0029, 0,
3655 16, 0x2486, 0x0028, 0x0031, 0x0039, 0x0029, 0,
3656 16, 0x2487, 0x0028, 0x0032, 0x0030, 0x0029, 0,
3657 16, 0x2488, 0x0031, 0x002E, 0,
3658 16, 0x2489, 0x0032, 0x002E, 0,
3659 16, 0x248A, 0x0033, 0x002E, 0,
3660 16, 0x248B, 0x0034, 0x002E, 0,
3661 16, 0x248C, 0x0035, 0x002E, 0,
3662 16, 0x248D, 0x0036, 0x002E, 0,
3663 16, 0x248E, 0x0037, 0x002E, 0,
3664 16, 0x248F, 0x0038, 0x002E, 0,
3665 16, 0x2490, 0x0039, 0x002E, 0,
3666 16, 0x2491, 0x0031, 0x0030, 0x002E, 0,
3667 16, 0x2492, 0x0031, 0x0031, 0x002E, 0,
3668 16, 0x2493, 0x0031, 0x0032, 0x002E, 0,
3669 16, 0x2494, 0x0031, 0x0033, 0x002E, 0,
3670 16, 0x2495, 0x0031, 0x0034, 0x002E, 0,
3671 16, 0x2496, 0x0031, 0x0035, 0x002E, 0,
3672 16, 0x2497, 0x0031, 0x0036, 0x002E, 0,
3673 16, 0x2498, 0x0031, 0x0037, 0x002E, 0,
3674 16, 0x2499, 0x0031, 0x0038, 0x002E, 0,
3675 16, 0x249A, 0x0031, 0x0039, 0x002E, 0,
3676 16, 0x249B, 0x0032, 0x0030, 0x002E, 0,
3677 16, 0x249C, 0x0028, 0x0061, 0x0029, 0,
3678 16, 0x249D, 0x0028, 0x0062, 0x0029, 0,
3679 16, 0x249E, 0x0028, 0x0063, 0x0029, 0,
3680 16, 0x249F, 0x0028, 0x0064, 0x0029, 0,
3681 16, 0x24A0, 0x0028, 0x0065, 0x0029, 0,
3682 16, 0x24A1, 0x0028, 0x0066, 0x0029, 0,
3683 16, 0x24A2, 0x0028, 0x0067, 0x0029, 0,
3684 16, 0x24A3, 0x0028, 0x0068, 0x0029, 0,
3685 16, 0x24A4, 0x0028, 0x0069, 0x0029, 0,
3686 16, 0x24A5, 0x0028, 0x006A, 0x0029, 0,
3687 16, 0x24A6, 0x0028, 0x006B, 0x0029, 0,
3688 16, 0x24A7, 0x0028, 0x006C, 0x0029, 0,
3689 16, 0x24A8, 0x0028, 0x006D, 0x0029, 0,
3690 16, 0x24A9, 0x0028, 0x006E, 0x0029, 0,
3691 16, 0x24AA, 0x0028, 0x006F, 0x0029, 0,
3692 16, 0x24AB, 0x0028, 0x0070, 0x0029, 0,
3693 16, 0x24AC, 0x0028, 0x0071, 0x0029, 0,
3694 16, 0x24AD, 0x0028, 0x0072, 0x0029, 0,
3695 16, 0x24AE, 0x0028, 0x0073, 0x0029, 0,
3696 16, 0x24AF, 0x0028, 0x0074, 0x0029, 0,
3697 16, 0x24B0, 0x0028, 0x0075, 0x0029, 0,
3698 16, 0x24B1, 0x0028, 0x0076, 0x0029, 0,
3699 16, 0x24B2, 0x0028, 0x0077, 0x0029, 0,
3700 16, 0x24B3, 0x0028, 0x0078, 0x0029, 0,
3701 16, 0x24B4, 0x0028, 0x0079, 0x0029, 0,
3702 16, 0x24B5, 0x0028, 0x007A, 0x0029, 0,
3703 8, 0x24B6, 0x0041, 0,
3704 8, 0x24B7, 0x0042, 0,
3705 8, 0x24B8, 0x0043, 0,
3706 8, 0x24B9, 0x0044, 0,
3707 8, 0x24BA, 0x0045, 0,
3708 8, 0x24BB, 0x0046, 0,
3709 8, 0x24BC, 0x0047, 0,
3710 8, 0x24BD, 0x0048, 0,
3711 8, 0x24BE, 0x0049, 0,
3712 8, 0x24BF, 0x004A, 0,
3713 8, 0x24C0, 0x004B, 0,
3714 8, 0x24C1, 0x004C, 0,
3715 8, 0x24C2, 0x004D, 0,
3716 8, 0x24C3, 0x004E, 0,
3717 8, 0x24C4, 0x004F, 0,
3718 8, 0x24C5, 0x0050, 0,
3719 8, 0x24C6, 0x0051, 0,
3720 8, 0x24C7, 0x0052, 0,
3721 8, 0x24C8, 0x0053, 0,
3722 8, 0x24C9, 0x0054, 0,
3723 8, 0x24CA, 0x0055, 0,
3724 8, 0x24CB, 0x0056, 0,
3725 8, 0x24CC, 0x0057, 0,
3726 8, 0x24CD, 0x0058, 0,
3727 8, 0x24CE, 0x0059, 0,
3728 8, 0x24CF, 0x005A, 0,
3729 8, 0x24D0, 0x0061, 0,
3730 8, 0x24D1, 0x0062, 0,
3731 8, 0x24D2, 0x0063, 0,
3732 8, 0x24D3, 0x0064, 0,
3733 8, 0x24D4, 0x0065, 0,
3734 8, 0x24D5, 0x0066, 0,
3735 8, 0x24D6, 0x0067, 0,
3736 8, 0x24D7, 0x0068, 0,
3737 8, 0x24D8, 0x0069, 0,
3738 8, 0x24D9, 0x006A, 0,
3739 8, 0x24DA, 0x006B, 0,
3740 8, 0x24DB, 0x006C, 0,
3741 8, 0x24DC, 0x006D, 0,
3742 8, 0x24DD, 0x006E, 0,
3743 8, 0x24DE, 0x006F, 0,
3744 8, 0x24DF, 0x0070, 0,
3745 8, 0x24E0, 0x0071, 0,
3746 8, 0x24E1, 0x0072, 0,
3747 8, 0x24E2, 0x0073, 0,
3748 8, 0x24E3, 0x0074, 0,
3749 8, 0x24E4, 0x0075, 0,
3750 8, 0x24E5, 0x0076, 0,
3751 8, 0x24E6, 0x0077, 0,
3752 8, 0x24E7, 0x0078, 0,
3753 8, 0x24E8, 0x0079, 0,
3754 8, 0x24E9, 0x007A, 0,
3755 8, 0x24EA, 0x0030, 0,
3756 16, 0x2A0C, 0x222B, 0x222B, 0x222B, 0x222B, 0,
3757 16, 0x2A74, 0x003A, 0x003A, 0x003D, 0,
3758 16, 0x2A75, 0x003D, 0x003D, 0,
3759 16, 0x2A76, 0x003D, 0x003D, 0x003D, 0,
3760 1, 0x2ADC, 0x2ADD, 0x0338, 0,
3761 16, 0x2E9F, 0x6BCD, 0,
3762 16, 0x2EF3, 0x9F9F, 0,
3763 16, 0x2F00, 0x4E00, 0,
3764 16, 0x2F01, 0x4E28, 0,
3765 16, 0x2F02, 0x4E36, 0,
3766 16, 0x2F03, 0x4E3F, 0,
3767 16, 0x2F04, 0x4E59, 0,
3768 16, 0x2F05, 0x4E85, 0,
3769 16, 0x2F06, 0x4E8C, 0,
3770 16, 0x2F07, 0x4EA0, 0,
3771 16, 0x2F08, 0x4EBA, 0,
3772 16, 0x2F09, 0x513F, 0,
3773 16, 0x2F0A, 0x5165, 0,
3774 16, 0x2F0B, 0x516B, 0,
3775 16, 0x2F0C, 0x5182, 0,
3776 16, 0x2F0D, 0x5196, 0,
3777 16, 0x2F0E, 0x51AB, 0,
3778 16, 0x2F0F, 0x51E0, 0,
3779 16, 0x2F10, 0x51F5, 0,
3780 16, 0x2F11, 0x5200, 0,
3781 16, 0x2F12, 0x529B, 0,
3782 16, 0x2F13, 0x52F9, 0,
3783 16, 0x2F14, 0x5315, 0,
3784 16, 0x2F15, 0x531A, 0,
3785 16, 0x2F16, 0x5338, 0,
3786 16, 0x2F17, 0x5341, 0,
3787 16, 0x2F18, 0x535C, 0,
3788 16, 0x2F19, 0x5369, 0,
3789 16, 0x2F1A, 0x5382, 0,
3790 16, 0x2F1B, 0x53B6, 0,
3791 16, 0x2F1C, 0x53C8, 0,
3792 16, 0x2F1D, 0x53E3, 0,
3793 16, 0x2F1E, 0x56D7, 0,
3794 16, 0x2F1F, 0x571F, 0,
3795 16, 0x2F20, 0x58EB, 0,
3796 16, 0x2F21, 0x5902, 0,
3797 16, 0x2F22, 0x590A, 0,
3798 16, 0x2F23, 0x5915, 0,
3799 16, 0x2F24, 0x5927, 0,
3800 16, 0x2F25, 0x5973, 0,
3801 16, 0x2F26, 0x5B50, 0,
3802 16, 0x2F27, 0x5B80, 0,
3803 16, 0x2F28, 0x5BF8, 0,
3804 16, 0x2F29, 0x5C0F, 0,
3805 16, 0x2F2A, 0x5C22, 0,
3806 16, 0x2F2B, 0x5C38, 0,
3807 16, 0x2F2C, 0x5C6E, 0,
3808 16, 0x2F2D, 0x5C71, 0,
3809 16, 0x2F2E, 0x5DDB, 0,
3810 16, 0x2F2F, 0x5DE5, 0,
3811 16, 0x2F30, 0x5DF1, 0,
3812 16, 0x2F31, 0x5DFE, 0,
3813 16, 0x2F32, 0x5E72, 0,
3814 16, 0x2F33, 0x5E7A, 0,
3815 16, 0x2F34, 0x5E7F, 0,
3816 16, 0x2F35, 0x5EF4, 0,
3817 16, 0x2F36, 0x5EFE, 0,
3818 16, 0x2F37, 0x5F0B, 0,
3819 16, 0x2F38, 0x5F13, 0,
3820 16, 0x2F39, 0x5F50, 0,
3821 16, 0x2F3A, 0x5F61, 0,
3822 16, 0x2F3B, 0x5F73, 0,
3823 16, 0x2F3C, 0x5FC3, 0,
3824 16, 0x2F3D, 0x6208, 0,
3825 16, 0x2F3E, 0x6236, 0,
3826 16, 0x2F3F, 0x624B, 0,
3827 16, 0x2F40, 0x652F, 0,
3828 16, 0x2F41, 0x6534, 0,
3829 16, 0x2F42, 0x6587, 0,
3830 16, 0x2F43, 0x6597, 0,
3831 16, 0x2F44, 0x65A4, 0,
3832 16, 0x2F45, 0x65B9, 0,
3833 16, 0x2F46, 0x65E0, 0,
3834 16, 0x2F47, 0x65E5, 0,
3835 16, 0x2F48, 0x66F0, 0,
3836 16, 0x2F49, 0x6708, 0,
3837 16, 0x2F4A, 0x6728, 0,
3838 16, 0x2F4B, 0x6B20, 0,
3839 16, 0x2F4C, 0x6B62, 0,
3840 16, 0x2F4D, 0x6B79, 0,
3841 16, 0x2F4E, 0x6BB3, 0,
3842 16, 0x2F4F, 0x6BCB, 0,
3843 16, 0x2F50, 0x6BD4, 0,
3844 16, 0x2F51, 0x6BDB, 0,
3845 16, 0x2F52, 0x6C0F, 0,
3846 16, 0x2F53, 0x6C14, 0,
3847 16, 0x2F54, 0x6C34, 0,
3848 16, 0x2F55, 0x706B, 0,
3849 16, 0x2F56, 0x722A, 0,
3850 16, 0x2F57, 0x7236, 0,
3851 16, 0x2F58, 0x723B, 0,
3852 16, 0x2F59, 0x723F, 0,
3853 16, 0x2F5A, 0x7247, 0,
3854 16, 0x2F5B, 0x7259, 0,
3855 16, 0x2F5C, 0x725B, 0,
3856 16, 0x2F5D, 0x72AC, 0,
3857 16, 0x2F5E, 0x7384, 0,
3858 16, 0x2F5F, 0x7389, 0,
3859 16, 0x2F60, 0x74DC, 0,
3860 16, 0x2F61, 0x74E6, 0,
3861 16, 0x2F62, 0x7518, 0,
3862 16, 0x2F63, 0x751F, 0,
3863 16, 0x2F64, 0x7528, 0,
3864 16, 0x2F65, 0x7530, 0,
3865 16, 0x2F66, 0x758B, 0,
3866 16, 0x2F67, 0x7592, 0,
3867 16, 0x2F68, 0x7676, 0,
3868 16, 0x2F69, 0x767D, 0,
3869 16, 0x2F6A, 0x76AE, 0,
3870 16, 0x2F6B, 0x76BF, 0,
3871 16, 0x2F6C, 0x76EE, 0,
3872 16, 0x2F6D, 0x77DB, 0,
3873 16, 0x2F6E, 0x77E2, 0,
3874 16, 0x2F6F, 0x77F3, 0,
3875 16, 0x2F70, 0x793A, 0,
3876 16, 0x2F71, 0x79B8, 0,
3877 16, 0x2F72, 0x79BE, 0,
3878 16, 0x2F73, 0x7A74, 0,
3879 16, 0x2F74, 0x7ACB, 0,
3880 16, 0x2F75, 0x7AF9, 0,
3881 16, 0x2F76, 0x7C73, 0,
3882 16, 0x2F77, 0x7CF8, 0,
3883 16, 0x2F78, 0x7F36, 0,
3884 16, 0x2F79, 0x7F51, 0,
3885 16, 0x2F7A, 0x7F8A, 0,
3886 16, 0x2F7B, 0x7FBD, 0,
3887 16, 0x2F7C, 0x8001, 0,
3888 16, 0x2F7D, 0x800C, 0,
3889 16, 0x2F7E, 0x8012, 0,
3890 16, 0x2F7F, 0x8033, 0,
3891 16, 0x2F80, 0x807F, 0,
3892 16, 0x2F81, 0x8089, 0,
3893 16, 0x2F82, 0x81E3, 0,
3894 16, 0x2F83, 0x81EA, 0,
3895 16, 0x2F84, 0x81F3, 0,
3896 16, 0x2F85, 0x81FC, 0,
3897 16, 0x2F86, 0x820C, 0,
3898 16, 0x2F87, 0x821B, 0,
3899 16, 0x2F88, 0x821F, 0,
3900 16, 0x2F89, 0x826E, 0,
3901 16, 0x2F8A, 0x8272, 0,
3902 16, 0x2F8B, 0x8278, 0,
3903 16, 0x2F8C, 0x864D, 0,
3904 16, 0x2F8D, 0x866B, 0,
3905 16, 0x2F8E, 0x8840, 0,
3906 16, 0x2F8F, 0x884C, 0,
3907 16, 0x2F90, 0x8863, 0,
3908 16, 0x2F91, 0x897E, 0,
3909 16, 0x2F92, 0x898B, 0,
3910 16, 0x2F93, 0x89D2, 0,
3911 16, 0x2F94, 0x8A00, 0,
3912 16, 0x2F95, 0x8C37, 0,
3913 16, 0x2F96, 0x8C46, 0,
3914 16, 0x2F97, 0x8C55, 0,
3915 16, 0x2F98, 0x8C78, 0,
3916 16, 0x2F99, 0x8C9D, 0,
3917 16, 0x2F9A, 0x8D64, 0,
3918 16, 0x2F9B, 0x8D70, 0,
3919 16, 0x2F9C, 0x8DB3, 0,
3920 16, 0x2F9D, 0x8EAB, 0,
3921 16, 0x2F9E, 0x8ECA, 0,
3922 16, 0x2F9F, 0x8F9B, 0,
3923 16, 0x2FA0, 0x8FB0, 0,
3924 16, 0x2FA1, 0x8FB5, 0,
3925 16, 0x2FA2, 0x9091, 0,
3926 16, 0x2FA3, 0x9149, 0,
3927 16, 0x2FA4, 0x91C6, 0,
3928 16, 0x2FA5, 0x91CC, 0,
3929 16, 0x2FA6, 0x91D1, 0,
3930 16, 0x2FA7, 0x9577, 0,
3931 16, 0x2FA8, 0x9580, 0,
3932 16, 0x2FA9, 0x961C, 0,
3933 16, 0x2FAA, 0x96B6, 0,
3934 16, 0x2FAB, 0x96B9, 0,
3935 16, 0x2FAC, 0x96E8, 0,
3936 16, 0x2FAD, 0x9751, 0,
3937 16, 0x2FAE, 0x975E, 0,
3938 16, 0x2FAF, 0x9762, 0,
3939 16, 0x2FB0, 0x9769, 0,
3940 16, 0x2FB1, 0x97CB, 0,
3941 16, 0x2FB2, 0x97ED, 0,
3942 16, 0x2FB3, 0x97F3, 0,
3943 16, 0x2FB4, 0x9801, 0,
3944 16, 0x2FB5, 0x98A8, 0,
3945 16, 0x2FB6, 0x98DB, 0,
3946 16, 0x2FB7, 0x98DF, 0,
3947 16, 0x2FB8, 0x9996, 0,
3948 16, 0x2FB9, 0x9999, 0,
3949 16, 0x2FBA, 0x99AC, 0,
3950 16, 0x2FBB, 0x9AA8, 0,
3951 16, 0x2FBC, 0x9AD8, 0,
3952 16, 0x2FBD, 0x9ADF, 0,
3953 16, 0x2FBE, 0x9B25, 0,
3954 16, 0x2FBF, 0x9B2F, 0,
3955 16, 0x2FC0, 0x9B32, 0,
3956 16, 0x2FC1, 0x9B3C, 0,
3957 16, 0x2FC2, 0x9B5A, 0,
3958 16, 0x2FC3, 0x9CE5, 0,
3959 16, 0x2FC4, 0x9E75, 0,
3960 16, 0x2FC5, 0x9E7F, 0,
3961 16, 0x2FC6, 0x9EA5, 0,
3962 16, 0x2FC7, 0x9EBB, 0,
3963 16, 0x2FC8, 0x9EC3, 0,
3964 16, 0x2FC9, 0x9ECD, 0,
3965 16, 0x2FCA, 0x9ED1, 0,
3966 16, 0x2FCB, 0x9EF9, 0,
3967 16, 0x2FCC, 0x9EFD, 0,
3968 16, 0x2FCD, 0x9F0E, 0,
3969 16, 0x2FCE, 0x9F13, 0,
3970 16, 0x2FCF, 0x9F20, 0,
3971 16, 0x2FD0, 0x9F3B, 0,
3972 16, 0x2FD1, 0x9F4A, 0,
3973 16, 0x2FD2, 0x9F52, 0,
3974 16, 0x2FD3, 0x9F8D, 0,
3975 16, 0x2FD4, 0x9F9C, 0,
3976 16, 0x2FD5, 0x9FA0, 0,
3977 12, 0x3000, 0x0020, 0,
3978 16, 0x3036, 0x3012, 0,
3979 16, 0x3038, 0x5341, 0,
3980 16, 0x3039, 0x5344, 0,
3981 16, 0x303A, 0x5345, 0,
3982 1, 0x304C, 0x304B, 0x3099, 0,
3983 1, 0x304E, 0x304D, 0x3099, 0,
3984 1, 0x3050, 0x304F, 0x3099, 0,
3985 1, 0x3052, 0x3051, 0x3099, 0,
3986 1, 0x3054, 0x3053, 0x3099, 0,
3987 1, 0x3056, 0x3055, 0x3099, 0,
3988 1, 0x3058, 0x3057, 0x3099, 0,
3989 1, 0x305A, 0x3059, 0x3099, 0,
3990 1, 0x305C, 0x305B, 0x3099, 0,
3991 1, 0x305E, 0x305D, 0x3099, 0,
3992 1, 0x3060, 0x305F, 0x3099, 0,
3993 1, 0x3062, 0x3061, 0x3099, 0,
3994 1, 0x3065, 0x3064, 0x3099, 0,
3995 1, 0x3067, 0x3066, 0x3099, 0,
3996 1, 0x3069, 0x3068, 0x3099, 0,
3997 1, 0x3070, 0x306F, 0x3099, 0,
3998 1, 0x3071, 0x306F, 0x309A, 0,
3999 1, 0x3073, 0x3072, 0x3099, 0,
4000 1, 0x3074, 0x3072, 0x309A, 0,
4001 1, 0x3076, 0x3075, 0x3099, 0,
4002 1, 0x3077, 0x3075, 0x309A, 0,
4003 1, 0x3079, 0x3078, 0x3099, 0,
4004 1, 0x307A, 0x3078, 0x309A, 0,
4005 1, 0x307C, 0x307B, 0x3099, 0,
4006 1, 0x307D, 0x307B, 0x309A, 0,
4007 1, 0x3094, 0x3046, 0x3099, 0,
4008 16, 0x309B, 0x0020, 0x3099, 0,
4009 16, 0x309C, 0x0020, 0x309A, 0,
4010 1, 0x309E, 0x309D, 0x3099, 0,
4011 11, 0x309F, 0x3088, 0x308A, 0,
4012 1, 0x30AC, 0x30AB, 0x3099, 0,
4013 1, 0x30AE, 0x30AD, 0x3099, 0,
4014 1, 0x30B0, 0x30AF, 0x3099, 0,
4015 1, 0x30B2, 0x30B1, 0x3099, 0,
4016 1, 0x30B4, 0x30B3, 0x3099, 0,
4017 1, 0x30B6, 0x30B5, 0x3099, 0,
4018 1, 0x30B8, 0x30B7, 0x3099, 0,
4019 1, 0x30BA, 0x30B9, 0x3099, 0,
4020 1, 0x30BC, 0x30BB, 0x3099, 0,
4021 1, 0x30BE, 0x30BD, 0x3099, 0,
4022 1, 0x30C0, 0x30BF, 0x3099, 0,
4023 1, 0x30C2, 0x30C1, 0x3099, 0,
4024 1, 0x30C5, 0x30C4, 0x3099, 0,
4025 1, 0x30C7, 0x30C6, 0x3099, 0,
4026 1, 0x30C9, 0x30C8, 0x3099, 0,
4027 1, 0x30D0, 0x30CF, 0x3099, 0,
4028 1, 0x30D1, 0x30CF, 0x309A, 0,
4029 1, 0x30D3, 0x30D2, 0x3099, 0,
4030 1, 0x30D4, 0x30D2, 0x309A, 0,
4031 1, 0x30D6, 0x30D5, 0x3099, 0,
4032 1, 0x30D7, 0x30D5, 0x309A, 0,
4033 1, 0x30D9, 0x30D8, 0x3099, 0,
4034 1, 0x30DA, 0x30D8, 0x309A, 0,
4035 1, 0x30DC, 0x30DB, 0x3099, 0,
4036 1, 0x30DD, 0x30DB, 0x309A, 0,
4037 1, 0x30F4, 0x30A6, 0x3099, 0,
4038 1, 0x30F7, 0x30EF, 0x3099, 0,
4039 1, 0x30F8, 0x30F0, 0x3099, 0,
4040 1, 0x30F9, 0x30F1, 0x3099, 0,
4041 1, 0x30FA, 0x30F2, 0x3099, 0,
4042 1, 0x30FE, 0x30FD, 0x3099, 0,
4043 11, 0x30FF, 0x30B3, 0x30C8, 0,
4044 16, 0x3131, 0x1100, 0,
4045 16, 0x3132, 0x1101, 0,
4046 16, 0x3133, 0x11AA, 0,
4047 16, 0x3134, 0x1102, 0,
4048 16, 0x3135, 0x11AC, 0,
4049 16, 0x3136, 0x11AD, 0,
4050 16, 0x3137, 0x1103, 0,
4051 16, 0x3138, 0x1104, 0,
4052 16, 0x3139, 0x1105, 0,
4053 16, 0x313A, 0x11B0, 0,
4054 16, 0x313B, 0x11B1, 0,
4055 16, 0x313C, 0x11B2, 0,
4056 16, 0x313D, 0x11B3, 0,
4057 16, 0x313E, 0x11B4, 0,
4058 16, 0x313F, 0x11B5, 0,
4059 16, 0x3140, 0x111A, 0,
4060 16, 0x3141, 0x1106, 0,
4061 16, 0x3142, 0x1107, 0,
4062 16, 0x3143, 0x1108, 0,
4063 16, 0x3144, 0x1121, 0,
4064 16, 0x3145, 0x1109, 0,
4065 16, 0x3146, 0x110A, 0,
4066 16, 0x3147, 0x110B, 0,
4067 16, 0x3148, 0x110C, 0,
4068 16, 0x3149, 0x110D, 0,
4069 16, 0x314A, 0x110E, 0,
4070 16, 0x314B, 0x110F, 0,
4071 16, 0x314C, 0x1110, 0,
4072 16, 0x314D, 0x1111, 0,
4073 16, 0x314E, 0x1112, 0,
4074 16, 0x314F, 0x1161, 0,
4075 16, 0x3150, 0x1162, 0,
4076 16, 0x3151, 0x1163, 0,
4077 16, 0x3152, 0x1164, 0,
4078 16, 0x3153, 0x1165, 0,
4079 16, 0x3154, 0x1166, 0,
4080 16, 0x3155, 0x1167, 0,
4081 16, 0x3156, 0x1168, 0,
4082 16, 0x3157, 0x1169, 0,
4083 16, 0x3158, 0x116A, 0,
4084 16, 0x3159, 0x116B, 0,
4085 16, 0x315A, 0x116C, 0,
4086 16, 0x315B, 0x116D, 0,
4087 16, 0x315C, 0x116E, 0,
4088 16, 0x315D, 0x116F, 0,
4089 16, 0x315E, 0x1170, 0,
4090 16, 0x315F, 0x1171, 0,
4091 16, 0x3160, 0x1172, 0,
4092 16, 0x3161, 0x1173, 0,
4093 16, 0x3162, 0x1174, 0,
4094 16, 0x3163, 0x1175, 0,
4095 16, 0x3164, 0x1160, 0,
4096 16, 0x3165, 0x1114, 0,
4097 16, 0x3166, 0x1115, 0,
4098 16, 0x3167, 0x11C7, 0,
4099 16, 0x3168, 0x11C8, 0,
4100 16, 0x3169, 0x11CC, 0,
4101 16, 0x316A, 0x11CE, 0,
4102 16, 0x316B, 0x11D3, 0,
4103 16, 0x316C, 0x11D7, 0,
4104 16, 0x316D, 0x11D9, 0,
4105 16, 0x316E, 0x111C, 0,
4106 16, 0x316F, 0x11DD, 0,
4107 16, 0x3170, 0x11DF, 0,
4108 16, 0x3171, 0x111D, 0,
4109 16, 0x3172, 0x111E, 0,
4110 16, 0x3173, 0x1120, 0,
4111 16, 0x3174, 0x1122, 0,
4112 16, 0x3175, 0x1123, 0,
4113 16, 0x3176, 0x1127, 0,
4114 16, 0x3177, 0x1129, 0,
4115 16, 0x3178, 0x112B, 0,
4116 16, 0x3179, 0x112C, 0,
4117 16, 0x317A, 0x112D, 0,
4118 16, 0x317B, 0x112E, 0,
4119 16, 0x317C, 0x112F, 0,
4120 16, 0x317D, 0x1132, 0,
4121 16, 0x317E, 0x1136, 0,
4122 16, 0x317F, 0x1140, 0,
4123 16, 0x3180, 0x1147, 0,
4124 16, 0x3181, 0x114C, 0,
4125 16, 0x3182, 0x11F1, 0,
4126 16, 0x3183, 0x11F2, 0,
4127 16, 0x3184, 0x1157, 0,
4128 16, 0x3185, 0x1158, 0,
4129 16, 0x3186, 0x1159, 0,
4130 16, 0x3187, 0x1184, 0,
4131 16, 0x3188, 0x1185, 0,
4132 16, 0x3189, 0x1188, 0,
4133 16, 0x318A, 0x1191, 0,
4134 16, 0x318B, 0x1192, 0,
4135 16, 0x318C, 0x1194, 0,
4136 16, 0x318D, 0x119E, 0,
4137 16, 0x318E, 0x11A1, 0,
4138 9, 0x3192, 0x4E00, 0,
4139 9, 0x3193, 0x4E8C, 0,
4140 9, 0x3194, 0x4E09, 0,
4141 9, 0x3195, 0x56DB, 0,
4142 9, 0x3196, 0x4E0A, 0,
4143 9, 0x3197, 0x4E2D, 0,
4144 9, 0x3198, 0x4E0B, 0,
4145 9, 0x3199, 0x7532, 0,
4146 9, 0x319A, 0x4E59, 0,
4147 9, 0x319B, 0x4E19, 0,
4148 9, 0x319C, 0x4E01, 0,
4149 9, 0x319D, 0x5929, 0,
4150 9, 0x319E, 0x5730, 0,
4151 9, 0x319F, 0x4EBA, 0,
4152 16, 0x3200, 0x0028, 0x1100, 0x0029, 0,
4153 16, 0x3201, 0x0028, 0x1102, 0x0029, 0,
4154 16, 0x3202, 0x0028, 0x1103, 0x0029, 0,
4155 16, 0x3203, 0x0028, 0x1105, 0x0029, 0,
4156 16, 0x3204, 0x0028, 0x1106, 0x0029, 0,
4157 16, 0x3205, 0x0028, 0x1107, 0x0029, 0,
4158 16, 0x3206, 0x0028, 0x1109, 0x0029, 0,
4159 16, 0x3207, 0x0028, 0x110B, 0x0029, 0,
4160 16, 0x3208, 0x0028, 0x110C, 0x0029, 0,
4161 16, 0x3209, 0x0028, 0x110E, 0x0029, 0,
4162 16, 0x320A, 0x0028, 0x110F, 0x0029, 0,
4163 16, 0x320B, 0x0028, 0x1110, 0x0029, 0,
4164 16, 0x320C, 0x0028, 0x1111, 0x0029, 0,
4165 16, 0x320D, 0x0028, 0x1112, 0x0029, 0,
4166 16, 0x320E, 0x0028, 0x1100, 0x1161, 0x0029, 0,
4167 16, 0x320F, 0x0028, 0x1102, 0x1161, 0x0029, 0,
4168 16, 0x3210, 0x0028, 0x1103, 0x1161, 0x0029, 0,
4169 16, 0x3211, 0x0028, 0x1105, 0x1161, 0x0029, 0,
4170 16, 0x3212, 0x0028, 0x1106, 0x1161, 0x0029, 0,
4171 16, 0x3213, 0x0028, 0x1107, 0x1161, 0x0029, 0,
4172 16, 0x3214, 0x0028, 0x1109, 0x1161, 0x0029, 0,
4173 16, 0x3215, 0x0028, 0x110B, 0x1161, 0x0029, 0,
4174 16, 0x3216, 0x0028, 0x110C, 0x1161, 0x0029, 0,
4175 16, 0x3217, 0x0028, 0x110E, 0x1161, 0x0029, 0,
4176 16, 0x3218, 0x0028, 0x110F, 0x1161, 0x0029, 0,
4177 16, 0x3219, 0x0028, 0x1110, 0x1161, 0x0029, 0,
4178 16, 0x321A, 0x0028, 0x1111, 0x1161, 0x0029, 0,
4179 16, 0x321B, 0x0028, 0x1112, 0x1161, 0x0029, 0,
4180 16, 0x321C, 0x0028, 0x110C, 0x116E, 0x0029, 0,
4181 16, 0x3220, 0x0028, 0x4E00, 0x0029, 0,
4182 16, 0x3221, 0x0028, 0x4E8C, 0x0029, 0,
4183 16, 0x3222, 0x0028, 0x4E09, 0x0029, 0,
4184 16, 0x3223, 0x0028, 0x56DB, 0x0029, 0,
4185 16, 0x3224, 0x0028, 0x4E94, 0x0029, 0,
4186 16, 0x3225, 0x0028, 0x516D, 0x0029, 0,
4187 16, 0x3226, 0x0028, 0x4E03, 0x0029, 0,
4188 16, 0x3227, 0x0028, 0x516B, 0x0029, 0,
4189 16, 0x3228, 0x0028, 0x4E5D, 0x0029, 0,
4190 16, 0x3229, 0x0028, 0x5341, 0x0029, 0,
4191 16, 0x322A, 0x0028, 0x6708, 0x0029, 0,
4192 16, 0x322B, 0x0028, 0x706B, 0x0029, 0,
4193 16, 0x322C, 0x0028, 0x6C34, 0x0029, 0,
4194 16, 0x322D, 0x0028, 0x6728, 0x0029, 0,
4195 16, 0x322E, 0x0028, 0x91D1, 0x0029, 0,
4196 16, 0x322F, 0x0028, 0x571F, 0x0029, 0,
4197 16, 0x3230, 0x0028, 0x65E5, 0x0029, 0,
4198 16, 0x3231, 0x0028, 0x682A, 0x0029, 0,
4199 16, 0x3232, 0x0028, 0x6709, 0x0029, 0,
4200 16, 0x3233, 0x0028, 0x793E, 0x0029, 0,
4201 16, 0x3234, 0x0028, 0x540D, 0x0029, 0,
4202 16, 0x3235, 0x0028, 0x7279, 0x0029, 0,
4203 16, 0x3236, 0x0028, 0x8CA1, 0x0029, 0,
4204 16, 0x3237, 0x0028, 0x795D, 0x0029, 0,
4205 16, 0x3238, 0x0028, 0x52B4, 0x0029, 0,
4206 16, 0x3239, 0x0028, 0x4EE3, 0x0029, 0,
4207 16, 0x323A, 0x0028, 0x547C, 0x0029, 0,
4208 16, 0x323B, 0x0028, 0x5B66, 0x0029, 0,
4209 16, 0x323C, 0x0028, 0x76E3, 0x0029, 0,
4210 16, 0x323D, 0x0028, 0x4F01, 0x0029, 0,
4211 16, 0x323E, 0x0028, 0x8CC7, 0x0029, 0,
4212 16, 0x323F, 0x0028, 0x5354, 0x0029, 0,
4213 16, 0x3240, 0x0028, 0x796D, 0x0029, 0,
4214 16, 0x3241, 0x0028, 0x4F11, 0x0029, 0,
4215 16, 0x3242, 0x0028, 0x81EA, 0x0029, 0,
4216 16, 0x3243, 0x0028, 0x81F3, 0x0029, 0,
4217 8, 0x3251, 0x0032, 0x0031, 0,
4218 8, 0x3252, 0x0032, 0x0032, 0,
4219 8, 0x3253, 0x0032, 0x0033, 0,
4220 8, 0x3254, 0x0032, 0x0034, 0,
4221 8, 0x3255, 0x0032, 0x0035, 0,
4222 8, 0x3256, 0x0032, 0x0036, 0,
4223 8, 0x3257, 0x0032, 0x0037, 0,
4224 8, 0x3258, 0x0032, 0x0038, 0,
4225 8, 0x3259, 0x0032, 0x0039, 0,
4226 8, 0x325A, 0x0033, 0x0030, 0,
4227 8, 0x325B, 0x0033, 0x0031, 0,
4228 8, 0x325C, 0x0033, 0x0032, 0,
4229 8, 0x325D, 0x0033, 0x0033, 0,
4230 8, 0x325E, 0x0033, 0x0034, 0,
4231 8, 0x325F, 0x0033, 0x0035, 0,
4232 8, 0x3260, 0x1100, 0,
4233 8, 0x3261, 0x1102, 0,
4234 8, 0x3262, 0x1103, 0,
4235 8, 0x3263, 0x1105, 0,
4236 8, 0x3264, 0x1106, 0,
4237 8, 0x3265, 0x1107, 0,
4238 8, 0x3266, 0x1109, 0,
4239 8, 0x3267, 0x110B, 0,
4240 8, 0x3268, 0x110C, 0,
4241 8, 0x3269, 0x110E, 0,
4242 8, 0x326A, 0x110F, 0,
4243 8, 0x326B, 0x1110, 0,
4244 8, 0x326C, 0x1111, 0,
4245 8, 0x326D, 0x1112, 0,
4246 8, 0x326E, 0x1100, 0x1161, 0,
4247 8, 0x326F, 0x1102, 0x1161, 0,
4248 8, 0x3270, 0x1103, 0x1161, 0,
4249 8, 0x3271, 0x1105, 0x1161, 0,
4250 8, 0x3272, 0x1106, 0x1161, 0,
4251 8, 0x3273, 0x1107, 0x1161, 0,
4252 8, 0x3274, 0x1109, 0x1161, 0,
4253 8, 0x3275, 0x110B, 0x1161, 0,
4254 8, 0x3276, 0x110C, 0x1161, 0,
4255 8, 0x3277, 0x110E, 0x1161, 0,
4256 8, 0x3278, 0x110F, 0x1161, 0,
4257 8, 0x3279, 0x1110, 0x1161, 0,
4258 8, 0x327A, 0x1111, 0x1161, 0,
4259 8, 0x327B, 0x1112, 0x1161, 0,
4260 8, 0x3280, 0x4E00, 0,
4261 8, 0x3281, 0x4E8C, 0,
4262 8, 0x3282, 0x4E09, 0,
4263 8, 0x3283, 0x56DB, 0,
4264 8, 0x3284, 0x4E94, 0,
4265 8, 0x3285, 0x516D, 0,
4266 8, 0x3286, 0x4E03, 0,
4267 8, 0x3287, 0x516B, 0,
4268 8, 0x3288, 0x4E5D, 0,
4269 8, 0x3289, 0x5341, 0,
4270 8, 0x328A, 0x6708, 0,
4271 8, 0x328B, 0x706B, 0,
4272 8, 0x328C, 0x6C34, 0,
4273 8, 0x328D, 0x6728, 0,
4274 8, 0x328E, 0x91D1, 0,
4275 8, 0x328F, 0x571F, 0,
4276 8, 0x3290, 0x65E5, 0,
4277 8, 0x3291, 0x682A, 0,
4278 8, 0x3292, 0x6709, 0,
4279 8, 0x3293, 0x793E, 0,
4280 8, 0x3294, 0x540D, 0,
4281 8, 0x3295, 0x7279, 0,
4282 8, 0x3296, 0x8CA1, 0,
4283 8, 0x3297, 0x795D, 0,
4284 8, 0x3298, 0x52B4, 0,
4285 8, 0x3299, 0x79D8, 0,
4286 8, 0x329A, 0x7537, 0,
4287 8, 0x329B, 0x5973, 0,
4288 8, 0x329C, 0x9069, 0,
4289 8, 0x329D, 0x512A, 0,
4290 8, 0x329E, 0x5370, 0,
4291 8, 0x329F, 0x6CE8, 0,
4292 8, 0x32A0, 0x9805, 0,
4293 8, 0x32A1, 0x4F11, 0,
4294 8, 0x32A2, 0x5199, 0,
4295 8, 0x32A3, 0x6B63, 0,
4296 8, 0x32A4, 0x4E0A, 0,
4297 8, 0x32A5, 0x4E2D, 0,
4298 8, 0x32A6, 0x4E0B, 0,
4299 8, 0x32A7, 0x5DE6, 0,
4300 8, 0x32A8, 0x53F3, 0,
4301 8, 0x32A9, 0x533B, 0,
4302 8, 0x32AA, 0x5B97, 0,
4303 8, 0x32AB, 0x5B66, 0,
4304 8, 0x32AC, 0x76E3, 0,
4305 8, 0x32AD, 0x4F01, 0,
4306 8, 0x32AE, 0x8CC7, 0,
4307 8, 0x32AF, 0x5354, 0,
4308 8, 0x32B0, 0x591C, 0,
4309 8, 0x32B1, 0x0033, 0x0036, 0,
4310 8, 0x32B2, 0x0033, 0x0037, 0,
4311 8, 0x32B3, 0x0033, 0x0038, 0,
4312 8, 0x32B4, 0x0033, 0x0039, 0,
4313 8, 0x32B5, 0x0034, 0x0030, 0,
4314 8, 0x32B6, 0x0034, 0x0031, 0,
4315 8, 0x32B7, 0x0034, 0x0032, 0,
4316 8, 0x32B8, 0x0034, 0x0033, 0,
4317 8, 0x32B9, 0x0034, 0x0034, 0,
4318 8, 0x32BA, 0x0034, 0x0035, 0,
4319 8, 0x32BB, 0x0034, 0x0036, 0,
4320 8, 0x32BC, 0x0034, 0x0037, 0,
4321 8, 0x32BD, 0x0034, 0x0038, 0,
4322 8, 0x32BE, 0x0034, 0x0039, 0,
4323 8, 0x32BF, 0x0035, 0x0030, 0,
4324 16, 0x32C0, 0x0031, 0x6708, 0,
4325 16, 0x32C1, 0x0032, 0x6708, 0,
4326 16, 0x32C2, 0x0033, 0x6708, 0,
4327 16, 0x32C3, 0x0034, 0x6708, 0,
4328 16, 0x32C4, 0x0035, 0x6708, 0,
4329 16, 0x32C5, 0x0036, 0x6708, 0,
4330 16, 0x32C6, 0x0037, 0x6708, 0,
4331 16, 0x32C7, 0x0038, 0x6708, 0,
4332 16, 0x32C8, 0x0039, 0x6708, 0,
4333 16, 0x32C9, 0x0031, 0x0030, 0x6708, 0,
4334 16, 0x32CA, 0x0031, 0x0031, 0x6708, 0,
4335 16, 0x32CB, 0x0031, 0x0032, 0x6708, 0,
4336 8, 0x32D0, 0x30A2, 0,
4337 8, 0x32D1, 0x30A4, 0,
4338 8, 0x32D2, 0x30A6, 0,
4339 8, 0x32D3, 0x30A8, 0,
4340 8, 0x32D4, 0x30AA, 0,
4341 8, 0x32D5, 0x30AB, 0,
4342 8, 0x32D6, 0x30AD, 0,
4343 8, 0x32D7, 0x30AF, 0,
4344 8, 0x32D8, 0x30B1, 0,
4345 8, 0x32D9, 0x30B3, 0,
4346 8, 0x32DA, 0x30B5, 0,
4347 8, 0x32DB, 0x30B7, 0,
4348 8, 0x32DC, 0x30B9, 0,
4349 8, 0x32DD, 0x30BB, 0,
4350 8, 0x32DE, 0x30BD, 0,
4351 8, 0x32DF, 0x30BF, 0,
4352 8, 0x32E0, 0x30C1, 0,
4353 8, 0x32E1, 0x30C4, 0,
4354 8, 0x32E2, 0x30C6, 0,
4355 8, 0x32E3, 0x30C8, 0,
4356 8, 0x32E4, 0x30CA, 0,
4357 8, 0x32E5, 0x30CB, 0,
4358 8, 0x32E6, 0x30CC, 0,
4359 8, 0x32E7, 0x30CD, 0,
4360 8, 0x32E8, 0x30CE, 0,
4361 8, 0x32E9, 0x30CF, 0,
4362 8, 0x32EA, 0x30D2, 0,
4363 8, 0x32EB, 0x30D5, 0,
4364 8, 0x32EC, 0x30D8, 0,
4365 8, 0x32ED, 0x30DB, 0,
4366 8, 0x32EE, 0x30DE, 0,
4367 8, 0x32EF, 0x30DF, 0,
4368 8, 0x32F0, 0x30E0, 0,
4369 8, 0x32F1, 0x30E1, 0,
4370 8, 0x32F2, 0x30E2, 0,
4371 8, 0x32F3, 0x30E4, 0,
4372 8, 0x32F4, 0x30E6, 0,
4373 8, 0x32F5, 0x30E8, 0,
4374 8, 0x32F6, 0x30E9, 0,
4375 8, 0x32F7, 0x30EA, 0,
4376 8, 0x32F8, 0x30EB, 0,
4377 8, 0x32F9, 0x30EC, 0,
4378 8, 0x32FA, 0x30ED, 0,
4379 8, 0x32FB, 0x30EF, 0,
4380 8, 0x32FC, 0x30F0, 0,
4381 8, 0x32FD, 0x30F1, 0,
4382 8, 0x32FE, 0x30F2, 0,
4383 15, 0x3300, 0x30A2, 0x30D1, 0x30FC, 0x30C8, 0,
4384 15, 0x3301, 0x30A2, 0x30EB, 0x30D5, 0x30A1, 0,
4385 15, 0x3302, 0x30A2, 0x30F3, 0x30DA, 0x30A2, 0,
4386 15, 0x3303, 0x30A2, 0x30FC, 0x30EB, 0,
4387 15, 0x3304, 0x30A4, 0x30CB, 0x30F3, 0x30B0, 0,
4388 15, 0x3305, 0x30A4, 0x30F3, 0x30C1, 0,
4389 15, 0x3306, 0x30A6, 0x30A9, 0x30F3, 0,
4390 15, 0x3307, 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, 0,
4391 15, 0x3308, 0x30A8, 0x30FC, 0x30AB, 0x30FC, 0,
4392 15, 0x3309, 0x30AA, 0x30F3, 0x30B9, 0,
4393 15, 0x330A, 0x30AA, 0x30FC, 0x30E0, 0,
4394 15, 0x330B, 0x30AB, 0x30A4, 0x30EA, 0,
4395 15, 0x330C, 0x30AB, 0x30E9, 0x30C3, 0x30C8, 0,
4396 15, 0x330D, 0x30AB, 0x30ED, 0x30EA, 0x30FC, 0,
4397 15, 0x330E, 0x30AC, 0x30ED, 0x30F3, 0,
4398 15, 0x330F, 0x30AC, 0x30F3, 0x30DE, 0,
4399 15, 0x3310, 0x30AE, 0x30AC, 0,
4400 15, 0x3311, 0x30AE, 0x30CB, 0x30FC, 0,
4401 15, 0x3312, 0x30AD, 0x30E5, 0x30EA, 0x30FC, 0,
4402 15, 0x3313, 0x30AE, 0x30EB, 0x30C0, 0x30FC, 0,
4403 15, 0x3314, 0x30AD, 0x30ED, 0,
4404 15, 0x3315, 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, 0,
4405 15, 0x3316, 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0,
4406 15, 0x3317, 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, 0,
4407 15, 0x3318, 0x30B0, 0x30E9, 0x30E0, 0,
4408 15, 0x3319, 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, 0,
4409 15, 0x331A, 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, 0,
4410 15, 0x331B, 0x30AF, 0x30ED, 0x30FC, 0x30CD, 0,
4411 15, 0x331C, 0x30B1, 0x30FC, 0x30B9, 0,
4412 15, 0x331D, 0x30B3, 0x30EB, 0x30CA, 0,
4413 15, 0x331E, 0x30B3, 0x30FC, 0x30DD, 0,
4414 15, 0x331F, 0x30B5, 0x30A4, 0x30AF, 0x30EB, 0,
4415 15, 0x3320, 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, 0,
4416 15, 0x3321, 0x30B7, 0x30EA, 0x30F3, 0x30B0, 0,
4417 15, 0x3322, 0x30BB, 0x30F3, 0x30C1, 0,
4418 15, 0x3323, 0x30BB, 0x30F3, 0x30C8, 0,
4419 15, 0x3324, 0x30C0, 0x30FC, 0x30B9, 0,
4420 15, 0x3325, 0x30C7, 0x30B7, 0,
4421 15, 0x3326, 0x30C9, 0x30EB, 0,
4422 15, 0x3327, 0x30C8, 0x30F3, 0,
4423 15, 0x3328, 0x30CA, 0x30CE, 0,
4424 15, 0x3329, 0x30CE, 0x30C3, 0x30C8, 0,
4425 15, 0x332A, 0x30CF, 0x30A4, 0x30C4, 0,
4426 15, 0x332B, 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, 0,
4427 15, 0x332C, 0x30D1, 0x30FC, 0x30C4, 0,
4428 15, 0x332D, 0x30D0, 0x30FC, 0x30EC, 0x30EB, 0,
4429 15, 0x332E, 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, 0,
4430 15, 0x332F, 0x30D4, 0x30AF, 0x30EB, 0,
4431 15, 0x3330, 0x30D4, 0x30B3, 0,
4432 15, 0x3331, 0x30D3, 0x30EB, 0,
4433 15, 0x3332, 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, 0,
4434 15, 0x3333, 0x30D5, 0x30A3, 0x30FC, 0x30C8, 0,
4435 15, 0x3334, 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, 0,
4436 15, 0x3335, 0x30D5, 0x30E9, 0x30F3, 0,
4437 15, 0x3336, 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, 0,
4438 15, 0x3337, 0x30DA, 0x30BD, 0,
4439 15, 0x3338, 0x30DA, 0x30CB, 0x30D2, 0,
4440 15, 0x3339, 0x30D8, 0x30EB, 0x30C4, 0,
4441 15, 0x333A, 0x30DA, 0x30F3, 0x30B9, 0,
4442 15, 0x333B, 0x30DA, 0x30FC, 0x30B8, 0,
4443 15, 0x333C, 0x30D9, 0x30FC, 0x30BF, 0,
4444 15, 0x333D, 0x30DD, 0x30A4, 0x30F3, 0x30C8, 0,
4445 15, 0x333E, 0x30DC, 0x30EB, 0x30C8, 0,
4446 15, 0x333F, 0x30DB, 0x30F3, 0,
4447 15, 0x3340, 0x30DD, 0x30F3, 0x30C9, 0,
4448 15, 0x3341, 0x30DB, 0x30FC, 0x30EB, 0,
4449 15, 0x3342, 0x30DB, 0x30FC, 0x30F3, 0,
4450 15, 0x3343, 0x30DE, 0x30A4, 0x30AF, 0x30ED, 0,
4451 15, 0x3344, 0x30DE, 0x30A4, 0x30EB, 0,
4452 15, 0x3345, 0x30DE, 0x30C3, 0x30CF, 0,
4453 15, 0x3346, 0x30DE, 0x30EB, 0x30AF, 0,
4454 15, 0x3347, 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, 0,
4455 15, 0x3348, 0x30DF, 0x30AF, 0x30ED, 0x30F3, 0,
4456 15, 0x3349, 0x30DF, 0x30EA, 0,
4457 15, 0x334A, 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, 0,
4458 15, 0x334B, 0x30E1, 0x30AC, 0,
4459 15, 0x334C, 0x30E1, 0x30AC, 0x30C8, 0x30F3, 0,
4460 15, 0x334D, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0,
4461 15, 0x334E, 0x30E4, 0x30FC, 0x30C9, 0,
4462 15, 0x334F, 0x30E4, 0x30FC, 0x30EB, 0,
4463 15, 0x3350, 0x30E6, 0x30A2, 0x30F3, 0,
4464 15, 0x3351, 0x30EA, 0x30C3, 0x30C8, 0x30EB, 0,
4465 15, 0x3352, 0x30EA, 0x30E9, 0,
4466 15, 0x3353, 0x30EB, 0x30D4, 0x30FC, 0,
4467 15, 0x3354, 0x30EB, 0x30FC, 0x30D6, 0x30EB, 0,
4468 15, 0x3355, 0x30EC, 0x30E0, 0,
4469 15, 0x3356, 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, 0,
4470 15, 0x3357, 0x30EF, 0x30C3, 0x30C8, 0,
4471 16, 0x3358, 0x0030, 0x70B9, 0,
4472 16, 0x3359, 0x0031, 0x70B9, 0,
4473 16, 0x335A, 0x0032, 0x70B9, 0,
4474 16, 0x335B, 0x0033, 0x70B9, 0,
4475 16, 0x335C, 0x0034, 0x70B9, 0,
4476 16, 0x335D, 0x0035, 0x70B9, 0,
4477 16, 0x335E, 0x0036, 0x70B9, 0,
4478 16, 0x335F, 0x0037, 0x70B9, 0,
4479 16, 0x3360, 0x0038, 0x70B9, 0,
4480 16, 0x3361, 0x0039, 0x70B9, 0,
4481 16, 0x3362, 0x0031, 0x0030, 0x70B9, 0,
4482 16, 0x3363, 0x0031, 0x0031, 0x70B9, 0,
4483 16, 0x3364, 0x0031, 0x0032, 0x70B9, 0,
4484 16, 0x3365, 0x0031, 0x0033, 0x70B9, 0,
4485 16, 0x3366, 0x0031, 0x0034, 0x70B9, 0,
4486 16, 0x3367, 0x0031, 0x0035, 0x70B9, 0,
4487 16, 0x3368, 0x0031, 0x0036, 0x70B9, 0,
4488 16, 0x3369, 0x0031, 0x0037, 0x70B9, 0,
4489 16, 0x336A, 0x0031, 0x0038, 0x70B9, 0,
4490 16, 0x336B, 0x0031, 0x0039, 0x70B9, 0,
4491 16, 0x336C, 0x0032, 0x0030, 0x70B9, 0,
4492 16, 0x336D, 0x0032, 0x0031, 0x70B9, 0,
4493 16, 0x336E, 0x0032, 0x0032, 0x70B9, 0,
4494 16, 0x336F, 0x0032, 0x0033, 0x70B9, 0,
4495 16, 0x3370, 0x0032, 0x0034, 0x70B9, 0,
4496 15, 0x3371, 0x0068, 0x0050, 0x0061, 0,
4497 15, 0x3372, 0x0064, 0x0061, 0,
4498 15, 0x3373, 0x0041, 0x0055, 0,
4499 15, 0x3374, 0x0062, 0x0061, 0x0072, 0,
4500 15, 0x3375, 0x006F, 0x0056, 0,
4501 15, 0x3376, 0x0070, 0x0063, 0,
4502 15, 0x337B, 0x5E73, 0x6210, 0,
4503 15, 0x337C, 0x662D, 0x548C, 0,
4504 15, 0x337D, 0x5927, 0x6B63, 0,
4505 15, 0x337E, 0x660E, 0x6CBB, 0,
4506 15, 0x337F, 0x682A, 0x5F0F, 0x4F1A, 0x793E, 0,
4507 15, 0x3380, 0x0070, 0x0041, 0,
4508 15, 0x3381, 0x006E, 0x0041, 0,
4509 15, 0x3382, 0x03BC, 0x0041, 0,
4510 15, 0x3383, 0x006D, 0x0041, 0,
4511 15, 0x3384, 0x006B, 0x0041, 0,
4512 15, 0x3385, 0x004B, 0x0042, 0,
4513 15, 0x3386, 0x004D, 0x0042, 0,
4514 15, 0x3387, 0x0047, 0x0042, 0,
4515 15, 0x3388, 0x0063, 0x0061, 0x006C, 0,
4516 15, 0x3389, 0x006B, 0x0063, 0x0061, 0x006C, 0,
4517 15, 0x338A, 0x0070, 0x0046, 0,
4518 15, 0x338B, 0x006E, 0x0046, 0,
4519 15, 0x338C, 0x03BC, 0x0046, 0,
4520 15, 0x338D, 0x03BC, 0x0067, 0,
4521 15, 0x338E, 0x006D, 0x0067, 0,
4522 15, 0x338F, 0x006B, 0x0067, 0,
4523 15, 0x3390, 0x0048, 0x007A, 0,
4524 15, 0x3391, 0x006B, 0x0048, 0x007A, 0,
4525 15, 0x3392, 0x004D, 0x0048, 0x007A, 0,
4526 15, 0x3393, 0x0047, 0x0048, 0x007A, 0,
4527 15, 0x3394, 0x0054, 0x0048, 0x007A, 0,
4528 15, 0x3395, 0x03BC, 0x2113, 0,
4529 15, 0x3396, 0x006D, 0x2113, 0,
4530 15, 0x3397, 0x0064, 0x2113, 0,
4531 15, 0x3398, 0x006B, 0x2113, 0,
4532 15, 0x3399, 0x0066, 0x006D, 0,
4533 15, 0x339A, 0x006E, 0x006D, 0,
4534 15, 0x339B, 0x03BC, 0x006D, 0,
4535 15, 0x339C, 0x006D, 0x006D, 0,
4536 15, 0x339D, 0x0063, 0x006D, 0,
4537 15, 0x339E, 0x006B, 0x006D, 0,
4538 15, 0x339F, 0x006D, 0x006D, 0x00B2, 0,
4539 15, 0x33A0, 0x0063, 0x006D, 0x00B2, 0,
4540 15, 0x33A1, 0x006D, 0x00B2, 0,
4541 15, 0x33A2, 0x006B, 0x006D, 0x00B2, 0,
4542 15, 0x33A3, 0x006D, 0x006D, 0x00B3, 0,
4543 15, 0x33A4, 0x0063, 0x006D, 0x00B3, 0,
4544 15, 0x33A5, 0x006D, 0x00B3, 0,
4545 15, 0x33A6, 0x006B, 0x006D, 0x00B3, 0,
4546 15, 0x33A7, 0x006D, 0x2215, 0x0073, 0,
4547 15, 0x33A8, 0x006D, 0x2215, 0x0073, 0x00B2, 0,
4548 15, 0x33A9, 0x0050, 0x0061, 0,
4549 15, 0x33AA, 0x006B, 0x0050, 0x0061, 0,
4550 15, 0x33AB, 0x004D, 0x0050, 0x0061, 0,
4551 15, 0x33AC, 0x0047, 0x0050, 0x0061, 0,
4552 15, 0x33AD, 0x0072, 0x0061, 0x0064, 0,
4553 15, 0x33AE, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0,
4554 15, 0x33AF, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, 0,
4555 15, 0x33B0, 0x0070, 0x0073, 0,
4556 15, 0x33B1, 0x006E, 0x0073, 0,
4557 15, 0x33B2, 0x03BC, 0x0073, 0,
4558 15, 0x33B3, 0x006D, 0x0073, 0,
4559 15, 0x33B4, 0x0070, 0x0056, 0,
4560 15, 0x33B5, 0x006E, 0x0056, 0,
4561 15, 0x33B6, 0x03BC, 0x0056, 0,
4562 15, 0x33B7, 0x006D, 0x0056, 0,
4563 15, 0x33B8, 0x006B, 0x0056, 0,
4564 15, 0x33B9, 0x004D, 0x0056, 0,
4565 15, 0x33BA, 0x0070, 0x0057, 0,
4566 15, 0x33BB, 0x006E, 0x0057, 0,
4567 15, 0x33BC, 0x03BC, 0x0057, 0,
4568 15, 0x33BD, 0x006D, 0x0057, 0,
4569 15, 0x33BE, 0x006B, 0x0057, 0,
4570 15, 0x33BF, 0x004D, 0x0057, 0,
4571 15, 0x33C0, 0x006B, 0x03A9, 0,
4572 15, 0x33C1, 0x004D, 0x03A9, 0,
4573 15, 0x33C2, 0x0061, 0x002E, 0x006D, 0x002E, 0,
4574 15, 0x33C3, 0x0042, 0x0071, 0,
4575 15, 0x33C4, 0x0063, 0x0063, 0,
4576 15, 0x33C5, 0x0063, 0x0064, 0,
4577 15, 0x33C6, 0x0043, 0x2215, 0x006B, 0x0067, 0,
4578 15, 0x33C7, 0x0043, 0x006F, 0x002E, 0,
4579 15, 0x33C8, 0x0064, 0x0042, 0,
4580 15, 0x33C9, 0x0047, 0x0079, 0,
4581 15, 0x33CA, 0x0068, 0x0061, 0,
4582 15, 0x33CB, 0x0048, 0x0050, 0,
4583 15, 0x33CC, 0x0069, 0x006E, 0,
4584 15, 0x33CD, 0x004B, 0x004B, 0,
4585 15, 0x33CE, 0x004B, 0x004D, 0,
4586 15, 0x33CF, 0x006B, 0x0074, 0,
4587 15, 0x33D0, 0x006C, 0x006D, 0,
4588 15, 0x33D1, 0x006C, 0x006E, 0,
4589 15, 0x33D2, 0x006C, 0x006F, 0x0067, 0,
4590 15, 0x33D3, 0x006C, 0x0078, 0,
4591 15, 0x33D4, 0x006D, 0x0062, 0,
4592 15, 0x33D5, 0x006D, 0x0069, 0x006C, 0,
4593 15, 0x33D6, 0x006D, 0x006F, 0x006C, 0,
4594 15, 0x33D7, 0x0050, 0x0048, 0,
4595 15, 0x33D8, 0x0070, 0x002E, 0x006D, 0x002E, 0,
4596 15, 0x33D9, 0x0050, 0x0050, 0x004D, 0,
4597 15, 0x33DA, 0x0050, 0x0052, 0,
4598 15, 0x33DB, 0x0073, 0x0072, 0,
4599 15, 0x33DC, 0x0053, 0x0076, 0,
4600 15, 0x33DD, 0x0057, 0x0062, 0,
4601 16, 0x33E0, 0x0031, 0x65E5, 0,
4602 16, 0x33E1, 0x0032, 0x65E5, 0,
4603 16, 0x33E2, 0x0033, 0x65E5, 0,
4604 16, 0x33E3, 0x0034, 0x65E5, 0,
4605 16, 0x33E4, 0x0035, 0x65E5, 0,
4606 16, 0x33E5, 0x0036, 0x65E5, 0,
4607 16, 0x33E6, 0x0037, 0x65E5, 0,
4608 16, 0x33E7, 0x0038, 0x65E5, 0,
4609 16, 0x33E8, 0x0039, 0x65E5, 0,
4610 16, 0x33E9, 0x0031, 0x0030, 0x65E5, 0,
4611 16, 0x33EA, 0x0031, 0x0031, 0x65E5, 0,
4612 16, 0x33EB, 0x0031, 0x0032, 0x65E5, 0,
4613 16, 0x33EC, 0x0031, 0x0033, 0x65E5, 0,
4614 16, 0x33ED, 0x0031, 0x0034, 0x65E5, 0,
4615 16, 0x33EE, 0x0031, 0x0035, 0x65E5, 0,
4616 16, 0x33EF, 0x0031, 0x0036, 0x65E5, 0,
4617 16, 0x33F0, 0x0031, 0x0037, 0x65E5, 0,
4618 16, 0x33F1, 0x0031, 0x0038, 0x65E5, 0,
4619 16, 0x33F2, 0x0031, 0x0039, 0x65E5, 0,
4620 16, 0x33F3, 0x0032, 0x0030, 0x65E5, 0,
4621 16, 0x33F4, 0x0032, 0x0031, 0x65E5, 0,
4622 16, 0x33F5, 0x0032, 0x0032, 0x65E5, 0,
4623 16, 0x33F6, 0x0032, 0x0033, 0x65E5, 0,
4624 16, 0x33F7, 0x0032, 0x0034, 0x65E5, 0,
4625 16, 0x33F8, 0x0032, 0x0035, 0x65E5, 0,
4626 16, 0x33F9, 0x0032, 0x0036, 0x65E5, 0,
4627 16, 0x33FA, 0x0032, 0x0037, 0x65E5, 0,
4628 16, 0x33FB, 0x0032, 0x0038, 0x65E5, 0,
4629 16, 0x33FC, 0x0032, 0x0039, 0x65E5, 0,
4630 16, 0x33FD, 0x0033, 0x0030, 0x65E5, 0,
4631 16, 0x33FE, 0x0033, 0x0031, 0x65E5, 0,
4632 1, 0xF900, 0x8C48, 0,
4633 1, 0xF901, 0x66F4, 0,
4634 1, 0xF902, 0x8ECA, 0,
4635 1, 0xF903, 0x8CC8, 0,
4636 1, 0xF904, 0x6ED1, 0,
4637 1, 0xF905, 0x4E32, 0,
4638 1, 0xF906, 0x53E5, 0,
4639 1, 0xF907, 0x9F9C, 0,
4640 1, 0xF908, 0x9F9C, 0,
4641 1, 0xF909, 0x5951, 0,
4642 1, 0xF90A, 0x91D1, 0,
4643 1, 0xF90B, 0x5587, 0,
4644 1, 0xF90C, 0x5948, 0,
4645 1, 0xF90D, 0x61F6, 0,
4646 1, 0xF90E, 0x7669, 0,
4647 1, 0xF90F, 0x7F85, 0,
4648 1, 0xF910, 0x863F, 0,
4649 1, 0xF911, 0x87BA, 0,
4650 1, 0xF912, 0x88F8, 0,
4651 1, 0xF913, 0x908F, 0,
4652 1, 0xF914, 0x6A02, 0,
4653 1, 0xF915, 0x6D1B, 0,
4654 1, 0xF916, 0x70D9, 0,
4655 1, 0xF917, 0x73DE, 0,
4656 1, 0xF918, 0x843D, 0,
4657 1, 0xF919, 0x916A, 0,
4658 1, 0xF91A, 0x99F1, 0,
4659 1, 0xF91B, 0x4E82, 0,
4660 1, 0xF91C, 0x5375, 0,
4661 1, 0xF91D, 0x6B04, 0,
4662 1, 0xF91E, 0x721B, 0,
4663 1, 0xF91F, 0x862D, 0,
4664 1, 0xF920, 0x9E1E, 0,
4665 1, 0xF921, 0x5D50, 0,
4666 1, 0xF922, 0x6FEB, 0,
4667 1, 0xF923, 0x85CD, 0,
4668 1, 0xF924, 0x8964, 0,
4669 1, 0xF925, 0x62C9, 0,
4670 1, 0xF926, 0x81D8, 0,
4671 1, 0xF927, 0x881F, 0,
4672 1, 0xF928, 0x5ECA, 0,
4673 1, 0xF929, 0x6717, 0,
4674 1, 0xF92A, 0x6D6A, 0,
4675 1, 0xF92B, 0x72FC, 0,
4676 1, 0xF92C, 0x90CE, 0,
4677 1, 0xF92D, 0x4F86, 0,
4678 1, 0xF92E, 0x51B7, 0,
4679 1, 0xF92F, 0x52DE, 0,
4680 1, 0xF930, 0x64C4, 0,
4681 1, 0xF931, 0x6AD3, 0,
4682 1, 0xF932, 0x7210, 0,
4683 1, 0xF933, 0x76E7, 0,
4684 1, 0xF934, 0x8001, 0,
4685 1, 0xF935, 0x8606, 0,
4686 1, 0xF936, 0x865C, 0,
4687 1, 0xF937, 0x8DEF, 0,
4688 1, 0xF938, 0x9732, 0,
4689 1, 0xF939, 0x9B6F, 0,
4690 1, 0xF93A, 0x9DFA, 0,
4691 1, 0xF93B, 0x788C, 0,
4692 1, 0xF93C, 0x797F, 0,
4693 1, 0xF93D, 0x7DA0, 0,
4694 1, 0xF93E, 0x83C9, 0,
4695 1, 0xF93F, 0x9304, 0,
4696 1, 0xF940, 0x9E7F, 0,
4697 1, 0xF941, 0x8AD6, 0,
4698 1, 0xF942, 0x58DF, 0,
4699 1, 0xF943, 0x5F04, 0,
4700 1, 0xF944, 0x7C60, 0,
4701 1, 0xF945, 0x807E, 0,
4702 1, 0xF946, 0x7262, 0,
4703 1, 0xF947, 0x78CA, 0,
4704 1, 0xF948, 0x8CC2, 0,
4705 1, 0xF949, 0x96F7, 0,
4706 1, 0xF94A, 0x58D8, 0,
4707 1, 0xF94B, 0x5C62, 0,
4708 1, 0xF94C, 0x6A13, 0,
4709 1, 0xF94D, 0x6DDA, 0,
4710 1, 0xF94E, 0x6F0F, 0,
4711 1, 0xF94F, 0x7D2F, 0,
4712 1, 0xF950, 0x7E37, 0,
4713 1, 0xF951, 0x964B, 0,
4714 1, 0xF952, 0x52D2, 0,
4715 1, 0xF953, 0x808B, 0,
4716 1, 0xF954, 0x51DC, 0,
4717 1, 0xF955, 0x51CC, 0,
4718 1, 0xF956, 0x7A1C, 0,
4719 1, 0xF957, 0x7DBE, 0,
4720 1, 0xF958, 0x83F1, 0,
4721 1, 0xF959, 0x9675, 0,
4722 1, 0xF95A, 0x8B80, 0,
4723 1, 0xF95B, 0x62CF, 0,
4724 1, 0xF95C, 0x6A02, 0,
4725 1, 0xF95D, 0x8AFE, 0,
4726 1, 0xF95E, 0x4E39, 0,
4727 1, 0xF95F, 0x5BE7, 0,
4728 1, 0xF960, 0x6012, 0,
4729 1, 0xF961, 0x7387, 0,
4730 1, 0xF962, 0x7570, 0,
4731 1, 0xF963, 0x5317, 0,
4732 1, 0xF964, 0x78FB, 0,
4733 1, 0xF965, 0x4FBF, 0,
4734 1, 0xF966, 0x5FA9, 0,
4735 1, 0xF967, 0x4E0D, 0,
4736 1, 0xF968, 0x6CCC, 0,
4737 1, 0xF969, 0x6578, 0,
4738 1, 0xF96A, 0x7D22, 0,
4739 1, 0xF96B, 0x53C3, 0,
4740 1, 0xF96C, 0x585E, 0,
4741 1, 0xF96D, 0x7701, 0,
4742 1, 0xF96E, 0x8449, 0,
4743 1, 0xF96F, 0x8AAA, 0,
4744 1, 0xF970, 0x6BBA, 0,
4745 1, 0xF971, 0x8FB0, 0,
4746 1, 0xF972, 0x6C88, 0,
4747 1, 0xF973, 0x62FE, 0,
4748 1, 0xF974, 0x82E5, 0,
4749 1, 0xF975, 0x63A0, 0,
4750 1, 0xF976, 0x7565, 0,
4751 1, 0xF977, 0x4EAE, 0,
4752 1, 0xF978, 0x5169, 0,
4753 1, 0xF979, 0x51C9, 0,
4754 1, 0xF97A, 0x6881, 0,
4755 1, 0xF97B, 0x7CE7, 0,
4756 1, 0xF97C, 0x826F, 0,
4757 1, 0xF97D, 0x8AD2, 0,
4758 1, 0xF97E, 0x91CF, 0,
4759 1, 0xF97F, 0x52F5, 0,
4760 1, 0xF980, 0x5442, 0,
4761 1, 0xF981, 0x5973, 0,
4762 1, 0xF982, 0x5EEC, 0,
4763 1, 0xF983, 0x65C5, 0,
4764 1, 0xF984, 0x6FFE, 0,
4765 1, 0xF985, 0x792A, 0,
4766 1, 0xF986, 0x95AD, 0,
4767 1, 0xF987, 0x9A6A, 0,
4768 1, 0xF988, 0x9E97, 0,
4769 1, 0xF989, 0x9ECE, 0,
4770 1, 0xF98A, 0x529B, 0,
4771 1, 0xF98B, 0x66C6, 0,
4772 1, 0xF98C, 0x6B77, 0,
4773 1, 0xF98D, 0x8F62, 0,
4774 1, 0xF98E, 0x5E74, 0,
4775 1, 0xF98F, 0x6190, 0,
4776 1, 0xF990, 0x6200, 0,
4777 1, 0xF991, 0x649A, 0,
4778 1, 0xF992, 0x6F23, 0,
4779 1, 0xF993, 0x7149, 0,
4780 1, 0xF994, 0x7489, 0,
4781 1, 0xF995, 0x79CA, 0,
4782 1, 0xF996, 0x7DF4, 0,
4783 1, 0xF997, 0x806F, 0,
4784 1, 0xF998, 0x8F26, 0,
4785 1, 0xF999, 0x84EE, 0,
4786 1, 0xF99A, 0x9023, 0,
4787 1, 0xF99B, 0x934A, 0,
4788 1, 0xF99C, 0x5217, 0,
4789 1, 0xF99D, 0x52A3, 0,
4790 1, 0xF99E, 0x54BD, 0,
4791 1, 0xF99F, 0x70C8, 0,
4792 1, 0xF9A0, 0x88C2, 0,
4793 1, 0xF9A1, 0x8AAA, 0,
4794 1, 0xF9A2, 0x5EC9, 0,
4795 1, 0xF9A3, 0x5FF5, 0,
4796 1, 0xF9A4, 0x637B, 0,
4797 1, 0xF9A5, 0x6BAE, 0,
4798 1, 0xF9A6, 0x7C3E, 0,
4799 1, 0xF9A7, 0x7375, 0,
4800 1, 0xF9A8, 0x4EE4, 0,
4801 1, 0xF9A9, 0x56F9, 0,
4802 1, 0xF9AA, 0x5BE7, 0,
4803 1, 0xF9AB, 0x5DBA, 0,
4804 1, 0xF9AC, 0x601C, 0,
4805 1, 0xF9AD, 0x73B2, 0,
4806 1, 0xF9AE, 0x7469, 0,
4807 1, 0xF9AF, 0x7F9A, 0,
4808 1, 0xF9B0, 0x8046, 0,
4809 1, 0xF9B1, 0x9234, 0,
4810 1, 0xF9B2, 0x96F6, 0,
4811 1, 0xF9B3, 0x9748, 0,
4812 1, 0xF9B4, 0x9818, 0,
4813 1, 0xF9B5, 0x4F8B, 0,
4814 1, 0xF9B6, 0x79AE, 0,
4815 1, 0xF9B7, 0x91B4, 0,
4816 1, 0xF9B8, 0x96B8, 0,
4817 1, 0xF9B9, 0x60E1, 0,
4818 1, 0xF9BA, 0x4E86, 0,
4819 1, 0xF9BB, 0x50DA, 0,
4820 1, 0xF9BC, 0x5BEE, 0,
4821 1, 0xF9BD, 0x5C3F, 0,
4822 1, 0xF9BE, 0x6599, 0,
4823 1, 0xF9BF, 0x6A02, 0,
4824 1, 0xF9C0, 0x71CE, 0,
4825 1, 0xF9C1, 0x7642, 0,
4826 1, 0xF9C2, 0x84FC, 0,
4827 1, 0xF9C3, 0x907C, 0,
4828 1, 0xF9C4, 0x9F8D, 0,
4829 1, 0xF9C5, 0x6688, 0,
4830 1, 0xF9C6, 0x962E, 0,
4831 1, 0xF9C7, 0x5289, 0,
4832 1, 0xF9C8, 0x677B, 0,
4833 1, 0xF9C9, 0x67F3, 0,
4834 1, 0xF9CA, 0x6D41, 0,
4835 1, 0xF9CB, 0x6E9C, 0,
4836 1, 0xF9CC, 0x7409, 0,
4837 1, 0xF9CD, 0x7559, 0,
4838 1, 0xF9CE, 0x786B, 0,
4839 1, 0xF9CF, 0x7D10, 0,
4840 1, 0xF9D0, 0x985E, 0,
4841 1, 0xF9D1, 0x516D, 0,
4842 1, 0xF9D2, 0x622E, 0,
4843 1, 0xF9D3, 0x9678, 0,
4844 1, 0xF9D4, 0x502B, 0,
4845 1, 0xF9D5, 0x5D19, 0,
4846 1, 0xF9D6, 0x6DEA, 0,
4847 1, 0xF9D7, 0x8F2A, 0,
4848 1, 0xF9D8, 0x5F8B, 0,
4849 1, 0xF9D9, 0x6144, 0,
4850 1, 0xF9DA, 0x6817, 0,
4851 1, 0xF9DB, 0x7387, 0,
4852 1, 0xF9DC, 0x9686, 0,
4853 1, 0xF9DD, 0x5229, 0,
4854 1, 0xF9DE, 0x540F, 0,
4855 1, 0xF9DF, 0x5C65, 0,
4856 1, 0xF9E0, 0x6613, 0,
4857 1, 0xF9E1, 0x674E, 0,
4858 1, 0xF9E2, 0x68A8, 0,
4859 1, 0xF9E3, 0x6CE5, 0,
4860 1, 0xF9E4, 0x7406, 0,
4861 1, 0xF9E5, 0x75E2, 0,
4862 1, 0xF9E6, 0x7F79, 0,
4863 1, 0xF9E7, 0x88CF, 0,
4864 1, 0xF9E8, 0x88E1, 0,
4865 1, 0xF9E9, 0x91CC, 0,
4866 1, 0xF9EA, 0x96E2, 0,
4867 1, 0xF9EB, 0x533F, 0,
4868 1, 0xF9EC, 0x6EBA, 0,
4869 1, 0xF9ED, 0x541D, 0,
4870 1, 0xF9EE, 0x71D0, 0,
4871 1, 0xF9EF, 0x7498, 0,
4872 1, 0xF9F0, 0x85FA, 0,
4873 1, 0xF9F1, 0x96A3, 0,
4874 1, 0xF9F2, 0x9C57, 0,
4875 1, 0xF9F3, 0x9E9F, 0,
4876 1, 0xF9F4, 0x6797, 0,
4877 1, 0xF9F5, 0x6DCB, 0,
4878 1, 0xF9F6, 0x81E8, 0,
4879 1, 0xF9F7, 0x7ACB, 0,
4880 1, 0xF9F8, 0x7B20, 0,
4881 1, 0xF9F9, 0x7C92, 0,
4882 1, 0xF9FA, 0x72C0, 0,
4883 1, 0xF9FB, 0x7099, 0,
4884 1, 0xF9FC, 0x8B58, 0,
4885 1, 0xF9FD, 0x4EC0, 0,
4886 1, 0xF9FE, 0x8336, 0,
4887 1, 0xF9FF, 0x523A, 0,
4888 1, 0xFA00, 0x5207, 0,
4889 1, 0xFA01, 0x5EA6, 0,
4890 1, 0xFA02, 0x62D3, 0,
4891 1, 0xFA03, 0x7CD6, 0,
4892 1, 0xFA04, 0x5B85, 0,
4893 1, 0xFA05, 0x6D1E, 0,
4894 1, 0xFA06, 0x66B4, 0,
4895 1, 0xFA07, 0x8F3B, 0,
4896 1, 0xFA08, 0x884C, 0,
4897 1, 0xFA09, 0x964D, 0,
4898 1, 0xFA0A, 0x898B, 0,
4899 1, 0xFA0B, 0x5ED3, 0,
4900 1, 0xFA0C, 0x5140, 0,
4901 1, 0xFA0D, 0x55C0, 0,
4902 1, 0xFA10, 0x585A, 0,
4903 1, 0xFA12, 0x6674, 0,
4904 1, 0xFA15, 0x51DE, 0,
4905 1, 0xFA16, 0x732A, 0,
4906 1, 0xFA17, 0x76CA, 0,
4907 1, 0xFA18, 0x793C, 0,
4908 1, 0xFA19, 0x795E, 0,
4909 1, 0xFA1A, 0x7965, 0,
4910 1, 0xFA1B, 0x798F, 0,
4911 1, 0xFA1C, 0x9756, 0,
4912 1, 0xFA1D, 0x7CBE, 0,
4913 1, 0xFA1E, 0x7FBD, 0,
4914 1, 0xFA20, 0x8612, 0,
4915 1, 0xFA22, 0x8AF8, 0,
4916 1, 0xFA25, 0x9038, 0,
4917 1, 0xFA26, 0x90FD, 0,
4918 1, 0xFA2A, 0x98EF, 0,
4919 1, 0xFA2B, 0x98FC, 0,
4920 1, 0xFA2C, 0x9928, 0,
4921 1, 0xFA2D, 0x9DB4, 0,
4922 1, 0xFA30, 0x4FAE, 0,
4923 1, 0xFA31, 0x50E7, 0,
4924 1, 0xFA32, 0x514D, 0,
4925 1, 0xFA33, 0x52C9, 0,
4926 1, 0xFA34, 0x52E4, 0,
4927 1, 0xFA35, 0x5351, 0,
4928 1, 0xFA36, 0x559D, 0,
4929 1, 0xFA37, 0x5606, 0,
4930 1, 0xFA38, 0x5668, 0,
4931 1, 0xFA39, 0x5840, 0,
4932 1, 0xFA3A, 0x58A8, 0,
4933 1, 0xFA3B, 0x5C64, 0,
4934 1, 0xFA3C, 0x5C6E, 0,
4935 1, 0xFA3D, 0x6094, 0,
4936 1, 0xFA3E, 0x6168, 0,
4937 1, 0xFA3F, 0x618E, 0,
4938 1, 0xFA40, 0x61F2, 0,
4939 1, 0xFA41, 0x654F, 0,
4940 1, 0xFA42, 0x65E2, 0,
4941 1, 0xFA43, 0x6691, 0,
4942 1, 0xFA44, 0x6885, 0,
4943 1, 0xFA45, 0x6D77, 0,
4944 1, 0xFA46, 0x6E1A, 0,
4945 1, 0xFA47, 0x6F22, 0,
4946 1, 0xFA48, 0x716E, 0,
4947 1, 0xFA49, 0x722B, 0,
4948 1, 0xFA4A, 0x7422, 0,
4949 1, 0xFA4B, 0x7891, 0,
4950 1, 0xFA4C, 0x793E, 0,
4951 1, 0xFA4D, 0x7949, 0,
4952 1, 0xFA4E, 0x7948, 0,
4953 1, 0xFA4F, 0x7950, 0,
4954 1, 0xFA50, 0x7956, 0,
4955 1, 0xFA51, 0x795D, 0,
4956 1, 0xFA52, 0x798D, 0,
4957 1, 0xFA53, 0x798E, 0,
4958 1, 0xFA54, 0x7A40, 0,
4959 1, 0xFA55, 0x7A81, 0,
4960 1, 0xFA56, 0x7BC0, 0,
4961 1, 0xFA57, 0x7DF4, 0,
4962 1, 0xFA58, 0x7E09, 0,
4963 1, 0xFA59, 0x7E41, 0,
4964 1, 0xFA5A, 0x7F72, 0,
4965 1, 0xFA5B, 0x8005, 0,
4966 1, 0xFA5C, 0x81ED, 0,
4967 1, 0xFA5D, 0x8279, 0,
4968 1, 0xFA5E, 0x8279, 0,
4969 1, 0xFA5F, 0x8457, 0,
4970 1, 0xFA60, 0x8910, 0,
4971 1, 0xFA61, 0x8996, 0,
4972 1, 0xFA62, 0x8B01, 0,
4973 1, 0xFA63, 0x8B39, 0,
4974 1, 0xFA64, 0x8CD3, 0,
4975 1, 0xFA65, 0x8D08, 0,
4976 1, 0xFA66, 0x8FB6, 0,
4977 1, 0xFA67, 0x9038, 0,
4978 1, 0xFA68, 0x96E3, 0,
4979 1, 0xFA69, 0x97FF, 0,
4980 1, 0xFA6A, 0x983B, 0,
4981 16, 0xFB00, 0x0066, 0x0066, 0,
4982 16, 0xFB01, 0x0066, 0x0069, 0,
4983 16, 0xFB02, 0x0066, 0x006C, 0,
4984 16, 0xFB03, 0x0066, 0x0066, 0x0069, 0,
4985 16, 0xFB04, 0x0066, 0x0066, 0x006C, 0,
4986 16, 0xFB05, 0x017F, 0x0074, 0,
4987 16, 0xFB06, 0x0073, 0x0074, 0,
4988 16, 0xFB13, 0x0574, 0x0576, 0,
4989 16, 0xFB14, 0x0574, 0x0565, 0,
4990 16, 0xFB15, 0x0574, 0x056B, 0,
4991 16, 0xFB16, 0x057E, 0x0576, 0,
4992 16, 0xFB17, 0x0574, 0x056D, 0,
4993 1, 0xFB1D, 0x05D9, 0x05B4, 0,
4994 1, 0xFB1F, 0x05F2, 0x05B7, 0,
4995 2, 0xFB20, 0x05E2, 0,
4996 2, 0xFB21, 0x05D0, 0,
4997 2, 0xFB22, 0x05D3, 0,
4998 2, 0xFB23, 0x05D4, 0,
4999 2, 0xFB24, 0x05DB, 0,
5000 2, 0xFB25, 0x05DC, 0,
5001 2, 0xFB26, 0x05DD, 0,
5002 2, 0xFB27, 0x05E8, 0,
5003 2, 0xFB28, 0x05EA, 0,
5004 2, 0xFB29, 0x002B, 0,
5005 1, 0xFB2A, 0x05E9, 0x05C1, 0,
5006 1, 0xFB2B, 0x05E9, 0x05C2, 0,
5007 1, 0xFB2C, 0xFB49, 0x05C1, 0,
5008 1, 0xFB2D, 0xFB49, 0x05C2, 0,
5009 1, 0xFB2E, 0x05D0, 0x05B7, 0,
5010 1, 0xFB2F, 0x05D0, 0x05B8, 0,
5011 1, 0xFB30, 0x05D0, 0x05BC, 0,
5012 1, 0xFB31, 0x05D1, 0x05BC, 0,
5013 1, 0xFB32, 0x05D2, 0x05BC, 0,
5014 1, 0xFB33, 0x05D3, 0x05BC, 0,
5015 1, 0xFB34, 0x05D4, 0x05BC, 0,
5016 1, 0xFB35, 0x05D5, 0x05BC, 0,
5017 1, 0xFB36, 0x05D6, 0x05BC, 0,
5018 1, 0xFB38, 0x05D8, 0x05BC, 0,
5019 1, 0xFB39, 0x05D9, 0x05BC, 0,
5020 1, 0xFB3A, 0x05DA, 0x05BC, 0,
5021 1, 0xFB3B, 0x05DB, 0x05BC, 0,
5022 1, 0xFB3C, 0x05DC, 0x05BC, 0,
5023 1, 0xFB3E, 0x05DE, 0x05BC, 0,
5024 1, 0xFB40, 0x05E0, 0x05BC, 0,
5025 1, 0xFB41, 0x05E1, 0x05BC, 0,
5026 1, 0xFB43, 0x05E3, 0x05BC, 0,
5027 1, 0xFB44, 0x05E4, 0x05BC, 0,
5028 1, 0xFB46, 0x05E6, 0x05BC, 0,
5029 1, 0xFB47, 0x05E7, 0x05BC, 0,
5030 1, 0xFB48, 0x05E8, 0x05BC, 0,
5031 1, 0xFB49, 0x05E9, 0x05BC, 0,
5032 1, 0xFB4A, 0x05EA, 0x05BC, 0,
5033 1, 0xFB4B, 0x05D5, 0x05B9, 0,
5034 1, 0xFB4C, 0x05D1, 0x05BF, 0,
5035 1, 0xFB4D, 0x05DB, 0x05BF, 0,
5036 1, 0xFB4E, 0x05E4, 0x05BF, 0,
5037 16, 0xFB4F, 0x05D0, 0x05DC, 0,
5038 7, 0xFB50, 0x0671, 0,
5039 6, 0xFB51, 0x0671, 0,
5040 7, 0xFB52, 0x067B, 0,
5041 6, 0xFB53, 0x067B, 0,
5042 4, 0xFB54, 0x067B, 0,
5043 5, 0xFB55, 0x067B, 0,
5044 7, 0xFB56, 0x067E, 0,
5045 6, 0xFB57, 0x067E, 0,
5046 4, 0xFB58, 0x067E, 0,
5047 5, 0xFB59, 0x067E, 0,
5048 7, 0xFB5A, 0x0680, 0,
5049 6, 0xFB5B, 0x0680, 0,
5050 4, 0xFB5C, 0x0680, 0,
5051 5, 0xFB5D, 0x0680, 0,
5052 7, 0xFB5E, 0x067A, 0,
5053 6, 0xFB5F, 0x067A, 0,
5054 4, 0xFB60, 0x067A, 0,
5055 5, 0xFB61, 0x067A, 0,
5056 7, 0xFB62, 0x067F, 0,
5057 6, 0xFB63, 0x067F, 0,
5058 4, 0xFB64, 0x067F, 0,
5059 5, 0xFB65, 0x067F, 0,
5060 7, 0xFB66, 0x0679, 0,
5061 6, 0xFB67, 0x0679, 0,
5062 4, 0xFB68, 0x0679, 0,
5063 5, 0xFB69, 0x0679, 0,
5064 7, 0xFB6A, 0x06A4, 0,
5065 6, 0xFB6B, 0x06A4, 0,
5066 4, 0xFB6C, 0x06A4, 0,
5067 5, 0xFB6D, 0x06A4, 0,
5068 7, 0xFB6E, 0x06A6, 0,
5069 6, 0xFB6F, 0x06A6, 0,
5070 4, 0xFB70, 0x06A6, 0,
5071 5, 0xFB71, 0x06A6, 0,
5072 7, 0xFB72, 0x0684, 0,
5073 6, 0xFB73, 0x0684, 0,
5074 4, 0xFB74, 0x0684, 0,
5075 5, 0xFB75, 0x0684, 0,
5076 7, 0xFB76, 0x0683, 0,
5077 6, 0xFB77, 0x0683, 0,
5078 4, 0xFB78, 0x0683, 0,
5079 5, 0xFB79, 0x0683, 0,
5080 7, 0xFB7A, 0x0686, 0,
5081 6, 0xFB7B, 0x0686, 0,
5082 4, 0xFB7C, 0x0686, 0,
5083 5, 0xFB7D, 0x0686, 0,
5084 7, 0xFB7E, 0x0687, 0,
5085 6, 0xFB7F, 0x0687, 0,
5086 4, 0xFB80, 0x0687, 0,
5087 5, 0xFB81, 0x0687, 0,
5088 7, 0xFB82, 0x068D, 0,
5089 6, 0xFB83, 0x068D, 0,
5090 7, 0xFB84, 0x068C, 0,
5091 6, 0xFB85, 0x068C, 0,
5092 7, 0xFB86, 0x068E, 0,
5093 6, 0xFB87, 0x068E, 0,
5094 7, 0xFB88, 0x0688, 0,
5095 6, 0xFB89, 0x0688, 0,
5096 7, 0xFB8A, 0x0698, 0,
5097 6, 0xFB8B, 0x0698, 0,
5098 7, 0xFB8C, 0x0691, 0,
5099 6, 0xFB8D, 0x0691, 0,
5100 7, 0xFB8E, 0x06A9, 0,
5101 6, 0xFB8F, 0x06A9, 0,
5102 4, 0xFB90, 0x06A9, 0,
5103 5, 0xFB91, 0x06A9, 0,
5104 7, 0xFB92, 0x06AF, 0,
5105 6, 0xFB93, 0x06AF, 0,
5106 4, 0xFB94, 0x06AF, 0,
5107 5, 0xFB95, 0x06AF, 0,
5108 7, 0xFB96, 0x06B3, 0,
5109 6, 0xFB97, 0x06B3, 0,
5110 4, 0xFB98, 0x06B3, 0,
5111 5, 0xFB99, 0x06B3, 0,
5112 7, 0xFB9A, 0x06B1, 0,
5113 6, 0xFB9B, 0x06B1, 0,
5114 4, 0xFB9C, 0x06B1, 0,
5115 5, 0xFB9D, 0x06B1, 0,
5116 7, 0xFB9E, 0x06BA, 0,
5117 6, 0xFB9F, 0x06BA, 0,
5118 7, 0xFBA0, 0x06BB, 0,
5119 6, 0xFBA1, 0x06BB, 0,
5120 4, 0xFBA2, 0x06BB, 0,
5121 5, 0xFBA3, 0x06BB, 0,
5122 7, 0xFBA4, 0x06C0, 0,
5123 6, 0xFBA5, 0x06C0, 0,
5124 7, 0xFBA6, 0x06C1, 0,
5125 6, 0xFBA7, 0x06C1, 0,
5126 4, 0xFBA8, 0x06C1, 0,
5127 5, 0xFBA9, 0x06C1, 0,
5128 7, 0xFBAA, 0x06BE, 0,
5129 6, 0xFBAB, 0x06BE, 0,
5130 4, 0xFBAC, 0x06BE, 0,
5131 5, 0xFBAD, 0x06BE, 0,
5132 7, 0xFBAE, 0x06D2, 0,
5133 6, 0xFBAF, 0x06D2, 0,
5134 7, 0xFBB0, 0x06D3, 0,
5135 6, 0xFBB1, 0x06D3, 0,
5136 7, 0xFBD3, 0x06AD, 0,
5137 6, 0xFBD4, 0x06AD, 0,
5138 4, 0xFBD5, 0x06AD, 0,
5139 5, 0xFBD6, 0x06AD, 0,
5140 7, 0xFBD7, 0x06C7, 0,
5141 6, 0xFBD8, 0x06C7, 0,
5142 7, 0xFBD9, 0x06C6, 0,
5143 6, 0xFBDA, 0x06C6, 0,
5144 7, 0xFBDB, 0x06C8, 0,
5145 6, 0xFBDC, 0x06C8, 0,
5146 7, 0xFBDD, 0x0677, 0,
5147 7, 0xFBDE, 0x06CB, 0,
5148 6, 0xFBDF, 0x06CB, 0,
5149 7, 0xFBE0, 0x06C5, 0,
5150 6, 0xFBE1, 0x06C5, 0,
5151 7, 0xFBE2, 0x06C9, 0,
5152 6, 0xFBE3, 0x06C9, 0,
5153 7, 0xFBE4, 0x06D0, 0,
5154 6, 0xFBE5, 0x06D0, 0,
5155 4, 0xFBE6, 0x06D0, 0,
5156 5, 0xFBE7, 0x06D0, 0,
5157 4, 0xFBE8, 0x0649, 0,
5158 5, 0xFBE9, 0x0649, 0,
5159 7, 0xFBEA, 0x0626, 0x0627, 0,
5160 6, 0xFBEB, 0x0626, 0x0627, 0,
5161 7, 0xFBEC, 0x0626, 0x06D5, 0,
5162 6, 0xFBED, 0x0626, 0x06D5, 0,
5163 7, 0xFBEE, 0x0626, 0x0648, 0,
5164 6, 0xFBEF, 0x0626, 0x0648, 0,
5165 7, 0xFBF0, 0x0626, 0x06C7, 0,
5166 6, 0xFBF1, 0x0626, 0x06C7, 0,
5167 7, 0xFBF2, 0x0626, 0x06C6, 0,
5168 6, 0xFBF3, 0x0626, 0x06C6, 0,
5169 7, 0xFBF4, 0x0626, 0x06C8, 0,
5170 6, 0xFBF5, 0x0626, 0x06C8, 0,
5171 7, 0xFBF6, 0x0626, 0x06D0, 0,
5172 6, 0xFBF7, 0x0626, 0x06D0, 0,
5173 4, 0xFBF8, 0x0626, 0x06D0, 0,
5174 7, 0xFBF9, 0x0626, 0x0649, 0,
5175 6, 0xFBFA, 0x0626, 0x0649, 0,
5176 4, 0xFBFB, 0x0626, 0x0649, 0,
5177 7, 0xFBFC, 0x06CC, 0,
5178 6, 0xFBFD, 0x06CC, 0,
5179 4, 0xFBFE, 0x06CC, 0,
5180 5, 0xFBFF, 0x06CC, 0,
5181 7, 0xFC00, 0x0626, 0x062C, 0,
5182 7, 0xFC01, 0x0626, 0x062D, 0,
5183 7, 0xFC02, 0x0626, 0x0645, 0,
5184 7, 0xFC03, 0x0626, 0x0649, 0,
5185 7, 0xFC04, 0x0626, 0x064A, 0,
5186 7, 0xFC05, 0x0628, 0x062C, 0,
5187 7, 0xFC06, 0x0628, 0x062D, 0,
5188 7, 0xFC07, 0x0628, 0x062E, 0,
5189 7, 0xFC08, 0x0628, 0x0645, 0,
5190 7, 0xFC09, 0x0628, 0x0649, 0,
5191 7, 0xFC0A, 0x0628, 0x064A, 0,
5192 7, 0xFC0B, 0x062A, 0x062C, 0,
5193 7, 0xFC0C, 0x062A, 0x062D, 0,
5194 7, 0xFC0D, 0x062A, 0x062E, 0,
5195 7, 0xFC0E, 0x062A, 0x0645, 0,
5196 7, 0xFC0F, 0x062A, 0x0649, 0,
5197 7, 0xFC10, 0x062A, 0x064A, 0,
5198 7, 0xFC11, 0x062B, 0x062C, 0,
5199 7, 0xFC12, 0x062B, 0x0645, 0,
5200 7, 0xFC13, 0x062B, 0x0649, 0,
5201 7, 0xFC14, 0x062B, 0x064A, 0,
5202 7, 0xFC15, 0x062C, 0x062D, 0,
5203 7, 0xFC16, 0x062C, 0x0645, 0,
5204 7, 0xFC17, 0x062D, 0x062C, 0,
5205 7, 0xFC18, 0x062D, 0x0645, 0,
5206 7, 0xFC19, 0x062E, 0x062C, 0,
5207 7, 0xFC1A, 0x062E, 0x062D, 0,
5208 7, 0xFC1B, 0x062E, 0x0645, 0,
5209 7, 0xFC1C, 0x0633, 0x062C, 0,
5210 7, 0xFC1D, 0x0633, 0x062D, 0,
5211 7, 0xFC1E, 0x0633, 0x062E, 0,
5212 7, 0xFC1F, 0x0633, 0x0645, 0,
5213 7, 0xFC20, 0x0635, 0x062D, 0,
5214 7, 0xFC21, 0x0635, 0x0645, 0,
5215 7, 0xFC22, 0x0636, 0x062C, 0,
5216 7, 0xFC23, 0x0636, 0x062D, 0,
5217 7, 0xFC24, 0x0636, 0x062E, 0,
5218 7, 0xFC25, 0x0636, 0x0645, 0,
5219 7, 0xFC26, 0x0637, 0x062D, 0,
5220 7, 0xFC27, 0x0637, 0x0645, 0,
5221 7, 0xFC28, 0x0638, 0x0645, 0,
5222 7, 0xFC29, 0x0639, 0x062C, 0,
5223 7, 0xFC2A, 0x0639, 0x0645, 0,
5224 7, 0xFC2B, 0x063A, 0x062C, 0,
5225 7, 0xFC2C, 0x063A, 0x0645, 0,
5226 7, 0xFC2D, 0x0641, 0x062C, 0,
5227 7, 0xFC2E, 0x0641, 0x062D, 0,
5228 7, 0xFC2F, 0x0641, 0x062E, 0,
5229 7, 0xFC30, 0x0641, 0x0645, 0,
5230 7, 0xFC31, 0x0641, 0x0649, 0,
5231 7, 0xFC32, 0x0641, 0x064A, 0,
5232 7, 0xFC33, 0x0642, 0x062D, 0,
5233 7, 0xFC34, 0x0642, 0x0645, 0,
5234 7, 0xFC35, 0x0642, 0x0649, 0,
5235 7, 0xFC36, 0x0642, 0x064A, 0,
5236 7, 0xFC37, 0x0643, 0x0627, 0,
5237 7, 0xFC38, 0x0643, 0x062C, 0,
5238 7, 0xFC39, 0x0643, 0x062D, 0,
5239 7, 0xFC3A, 0x0643, 0x062E, 0,
5240 7, 0xFC3B, 0x0643, 0x0644, 0,
5241 7, 0xFC3C, 0x0643, 0x0645, 0,
5242 7, 0xFC3D, 0x0643, 0x0649, 0,
5243 7, 0xFC3E, 0x0643, 0x064A, 0,
5244 7, 0xFC3F, 0x0644, 0x062C, 0,
5245 7, 0xFC40, 0x0644, 0x062D, 0,
5246 7, 0xFC41, 0x0644, 0x062E, 0,
5247 7, 0xFC42, 0x0644, 0x0645, 0,
5248 7, 0xFC43, 0x0644, 0x0649, 0,
5249 7, 0xFC44, 0x0644, 0x064A, 0,
5250 7, 0xFC45, 0x0645, 0x062C, 0,
5251 7, 0xFC46, 0x0645, 0x062D, 0,
5252 7, 0xFC47, 0x0645, 0x062E, 0,
5253 7, 0xFC48, 0x0645, 0x0645, 0,
5254 7, 0xFC49, 0x0645, 0x0649, 0,
5255 7, 0xFC4A, 0x0645, 0x064A, 0,
5256 7, 0xFC4B, 0x0646, 0x062C, 0,
5257 7, 0xFC4C, 0x0646, 0x062D, 0,
5258 7, 0xFC4D, 0x0646, 0x062E, 0,
5259 7, 0xFC4E, 0x0646, 0x0645, 0,
5260 7, 0xFC4F, 0x0646, 0x0649, 0,
5261 7, 0xFC50, 0x0646, 0x064A, 0,
5262 7, 0xFC51, 0x0647, 0x062C, 0,
5263 7, 0xFC52, 0x0647, 0x0645, 0,
5264 7, 0xFC53, 0x0647, 0x0649, 0,
5265 7, 0xFC54, 0x0647, 0x064A, 0,
5266 7, 0xFC55, 0x064A, 0x062C, 0,
5267 7, 0xFC56, 0x064A, 0x062D, 0,
5268 7, 0xFC57, 0x064A, 0x062E, 0,
5269 7, 0xFC58, 0x064A, 0x0645, 0,
5270 7, 0xFC59, 0x064A, 0x0649, 0,
5271 7, 0xFC5A, 0x064A, 0x064A, 0,
5272 7, 0xFC5B, 0x0630, 0x0670, 0,
5273 7, 0xFC5C, 0x0631, 0x0670, 0,
5274 7, 0xFC5D, 0x0649, 0x0670, 0,
5275 7, 0xFC5E, 0x0020, 0x064C, 0x0651, 0,
5276 7, 0xFC5F, 0x0020, 0x064D, 0x0651, 0,
5277 7, 0xFC60, 0x0020, 0x064E, 0x0651, 0,
5278 7, 0xFC61, 0x0020, 0x064F, 0x0651, 0,
5279 7, 0xFC62, 0x0020, 0x0650, 0x0651, 0,
5280 7, 0xFC63, 0x0020, 0x0651, 0x0670, 0,
5281 6, 0xFC64, 0x0626, 0x0631, 0,
5282 6, 0xFC65, 0x0626, 0x0632, 0,
5283 6, 0xFC66, 0x0626, 0x0645, 0,
5284 6, 0xFC67, 0x0626, 0x0646, 0,
5285 6, 0xFC68, 0x0626, 0x0649, 0,
5286 6, 0xFC69, 0x0626, 0x064A, 0,
5287 6, 0xFC6A, 0x0628, 0x0631, 0,
5288 6, 0xFC6B, 0x0628, 0x0632, 0,
5289 6, 0xFC6C, 0x0628, 0x0645, 0,
5290 6, 0xFC6D, 0x0628, 0x0646, 0,
5291 6, 0xFC6E, 0x0628, 0x0649, 0,
5292 6, 0xFC6F, 0x0628, 0x064A, 0,
5293 6, 0xFC70, 0x062A, 0x0631, 0,
5294 6, 0xFC71, 0x062A, 0x0632, 0,
5295 6, 0xFC72, 0x062A, 0x0645, 0,
5296 6, 0xFC73, 0x062A, 0x0646, 0,
5297 6, 0xFC74, 0x062A, 0x0649, 0,
5298 6, 0xFC75, 0x062A, 0x064A, 0,
5299 6, 0xFC76, 0x062B, 0x0631, 0,
5300 6, 0xFC77, 0x062B, 0x0632, 0,
5301 6, 0xFC78, 0x062B, 0x0645, 0,
5302 6, 0xFC79, 0x062B, 0x0646, 0,
5303 6, 0xFC7A, 0x062B, 0x0649, 0,
5304 6, 0xFC7B, 0x062B, 0x064A, 0,
5305 6, 0xFC7C, 0x0641, 0x0649, 0,
5306 6, 0xFC7D, 0x0641, 0x064A, 0,
5307 6, 0xFC7E, 0x0642, 0x0649, 0,
5308 6, 0xFC7F, 0x0642, 0x064A, 0,
5309 6, 0xFC80, 0x0643, 0x0627, 0,
5310 6, 0xFC81, 0x0643, 0x0644, 0,
5311 6, 0xFC82, 0x0643, 0x0645, 0,
5312 6, 0xFC83, 0x0643, 0x0649, 0,
5313 6, 0xFC84, 0x0643, 0x064A, 0,
5314 6, 0xFC85, 0x0644, 0x0645, 0,
5315 6, 0xFC86, 0x0644, 0x0649, 0,
5316 6, 0xFC87, 0x0644, 0x064A, 0,
5317 6, 0xFC88, 0x0645, 0x0627, 0,
5318 6, 0xFC89, 0x0645, 0x0645, 0,
5319 6, 0xFC8A, 0x0646, 0x0631, 0,
5320 6, 0xFC8B, 0x0646, 0x0632, 0,
5321 6, 0xFC8C, 0x0646, 0x0645, 0,
5322 6, 0xFC8D, 0x0646, 0x0646, 0,
5323 6, 0xFC8E, 0x0646, 0x0649, 0,
5324 6, 0xFC8F, 0x0646, 0x064A, 0,
5325 6, 0xFC90, 0x0649, 0x0670, 0,
5326 6, 0xFC91, 0x064A, 0x0631, 0,
5327 6, 0xFC92, 0x064A, 0x0632, 0,
5328 6, 0xFC93, 0x064A, 0x0645, 0,
5329 6, 0xFC94, 0x064A, 0x0646, 0,
5330 6, 0xFC95, 0x064A, 0x0649, 0,
5331 6, 0xFC96, 0x064A, 0x064A, 0,
5332 4, 0xFC97, 0x0626, 0x062C, 0,
5333 4, 0xFC98, 0x0626, 0x062D, 0,
5334 4, 0xFC99, 0x0626, 0x062E, 0,
5335 4, 0xFC9A, 0x0626, 0x0645, 0,
5336 4, 0xFC9B, 0x0626, 0x0647, 0,
5337 4, 0xFC9C, 0x0628, 0x062C, 0,
5338 4, 0xFC9D, 0x0628, 0x062D, 0,
5339 4, 0xFC9E, 0x0628, 0x062E, 0,
5340 4, 0xFC9F, 0x0628, 0x0645, 0,
5341 4, 0xFCA0, 0x0628, 0x0647, 0,
5342 4, 0xFCA1, 0x062A, 0x062C, 0,
5343 4, 0xFCA2, 0x062A, 0x062D, 0,
5344 4, 0xFCA3, 0x062A, 0x062E, 0,
5345 4, 0xFCA4, 0x062A, 0x0645, 0,
5346 4, 0xFCA5, 0x062A, 0x0647, 0,
5347 4, 0xFCA6, 0x062B, 0x0645, 0,
5348 4, 0xFCA7, 0x062C, 0x062D, 0,
5349 4, 0xFCA8, 0x062C, 0x0645, 0,
5350 4, 0xFCA9, 0x062D, 0x062C, 0,
5351 4, 0xFCAA, 0x062D, 0x0645, 0,
5352 4, 0xFCAB, 0x062E, 0x062C, 0,
5353 4, 0xFCAC, 0x062E, 0x0645, 0,
5354 4, 0xFCAD, 0x0633, 0x062C, 0,
5355 4, 0xFCAE, 0x0633, 0x062D, 0,
5356 4, 0xFCAF, 0x0633, 0x062E, 0,
5357 4, 0xFCB0, 0x0633, 0x0645, 0,
5358 4, 0xFCB1, 0x0635, 0x062D, 0,
5359 4, 0xFCB2, 0x0635, 0x062E, 0,
5360 4, 0xFCB3, 0x0635, 0x0645, 0,
5361 4, 0xFCB4, 0x0636, 0x062C, 0,
5362 4, 0xFCB5, 0x0636, 0x062D, 0,
5363 4, 0xFCB6, 0x0636, 0x062E, 0,
5364 4, 0xFCB7, 0x0636, 0x0645, 0,
5365 4, 0xFCB8, 0x0637, 0x062D, 0,
5366 4, 0xFCB9, 0x0638, 0x0645, 0,
5367 4, 0xFCBA, 0x0639, 0x062C, 0,
5368 4, 0xFCBB, 0x0639, 0x0645, 0,
5369 4, 0xFCBC, 0x063A, 0x062C, 0,
5370 4, 0xFCBD, 0x063A, 0x0645, 0,
5371 4, 0xFCBE, 0x0641, 0x062C, 0,
5372 4, 0xFCBF, 0x0641, 0x062D, 0,
5373 4, 0xFCC0, 0x0641, 0x062E, 0,
5374 4, 0xFCC1, 0x0641, 0x0645, 0,
5375 4, 0xFCC2, 0x0642, 0x062D, 0,
5376 4, 0xFCC3, 0x0642, 0x0645, 0,
5377 4, 0xFCC4, 0x0643, 0x062C, 0,
5378 4, 0xFCC5, 0x0643, 0x062D, 0,
5379 4, 0xFCC6, 0x0643, 0x062E, 0,
5380 4, 0xFCC7, 0x0643, 0x0644, 0,
5381 4, 0xFCC8, 0x0643, 0x0645, 0,
5382 4, 0xFCC9, 0x0644, 0x062C, 0,
5383 4, 0xFCCA, 0x0644, 0x062D, 0,
5384 4, 0xFCCB, 0x0644, 0x062E, 0,
5385 4, 0xFCCC, 0x0644, 0x0645, 0,
5386 4, 0xFCCD, 0x0644, 0x0647, 0,
5387 4, 0xFCCE, 0x0645, 0x062C, 0,
5388 4, 0xFCCF, 0x0645, 0x062D, 0,
5389 4, 0xFCD0, 0x0645, 0x062E, 0,
5390 4, 0xFCD1, 0x0645, 0x0645, 0,
5391 4, 0xFCD2, 0x0646, 0x062C, 0,
5392 4, 0xFCD3, 0x0646, 0x062D, 0,
5393 4, 0xFCD4, 0x0646, 0x062E, 0,
5394 4, 0xFCD5, 0x0646, 0x0645, 0,
5395 4, 0xFCD6, 0x0646, 0x0647, 0,
5396 4, 0xFCD7, 0x0647, 0x062C, 0,
5397 4, 0xFCD8, 0x0647, 0x0645, 0,
5398 4, 0xFCD9, 0x0647, 0x0670, 0,
5399 4, 0xFCDA, 0x064A, 0x062C, 0,
5400 4, 0xFCDB, 0x064A, 0x062D, 0,
5401 4, 0xFCDC, 0x064A, 0x062E, 0,
5402 4, 0xFCDD, 0x064A, 0x0645, 0,
5403 4, 0xFCDE, 0x064A, 0x0647, 0,
5404 5, 0xFCDF, 0x0626, 0x0645, 0,
5405 5, 0xFCE0, 0x0626, 0x0647, 0,
5406 5, 0xFCE1, 0x0628, 0x0645, 0,
5407 5, 0xFCE2, 0x0628, 0x0647, 0,
5408 5, 0xFCE3, 0x062A, 0x0645, 0,
5409 5, 0xFCE4, 0x062A, 0x0647, 0,
5410 5, 0xFCE5, 0x062B, 0x0645, 0,
5411 5, 0xFCE6, 0x062B, 0x0647, 0,
5412 5, 0xFCE7, 0x0633, 0x0645, 0,
5413 5, 0xFCE8, 0x0633, 0x0647, 0,
5414 5, 0xFCE9, 0x0634, 0x0645, 0,
5415 5, 0xFCEA, 0x0634, 0x0647, 0,
5416 5, 0xFCEB, 0x0643, 0x0644, 0,
5417 5, 0xFCEC, 0x0643, 0x0645, 0,
5418 5, 0xFCED, 0x0644, 0x0645, 0,
5419 5, 0xFCEE, 0x0646, 0x0645, 0,
5420 5, 0xFCEF, 0x0646, 0x0647, 0,
5421 5, 0xFCF0, 0x064A, 0x0645, 0,
5422 5, 0xFCF1, 0x064A, 0x0647, 0,
5423 5, 0xFCF2, 0x0640, 0x064E, 0x0651, 0,
5424 5, 0xFCF3, 0x0640, 0x064F, 0x0651, 0,
5425 5, 0xFCF4, 0x0640, 0x0650, 0x0651, 0,
5426 7, 0xFCF5, 0x0637, 0x0649, 0,
5427 7, 0xFCF6, 0x0637, 0x064A, 0,
5428 7, 0xFCF7, 0x0639, 0x0649, 0,
5429 7, 0xFCF8, 0x0639, 0x064A, 0,
5430 7, 0xFCF9, 0x063A, 0x0649, 0,
5431 7, 0xFCFA, 0x063A, 0x064A, 0,
5432 7, 0xFCFB, 0x0633, 0x0649, 0,
5433 7, 0xFCFC, 0x0633, 0x064A, 0,
5434 7, 0xFCFD, 0x0634, 0x0649, 0,
5435 7, 0xFCFE, 0x0634, 0x064A, 0,
5436 7, 0xFCFF, 0x062D, 0x0649, 0,
5437 7, 0xFD00, 0x062D, 0x064A, 0,
5438 7, 0xFD01, 0x062C, 0x0649, 0,
5439 7, 0xFD02, 0x062C, 0x064A, 0,
5440 7, 0xFD03, 0x062E, 0x0649, 0,
5441 7, 0xFD04, 0x062E, 0x064A, 0,
5442 7, 0xFD05, 0x0635, 0x0649, 0,
5443 7, 0xFD06, 0x0635, 0x064A, 0,
5444 7, 0xFD07, 0x0636, 0x0649, 0,
5445 7, 0xFD08, 0x0636, 0x064A, 0,
5446 7, 0xFD09, 0x0634, 0x062C, 0,
5447 7, 0xFD0A, 0x0634, 0x062D, 0,
5448 7, 0xFD0B, 0x0634, 0x062E, 0,
5449 7, 0xFD0C, 0x0634, 0x0645, 0,
5450 7, 0xFD0D, 0x0634, 0x0631, 0,
5451 7, 0xFD0E, 0x0633, 0x0631, 0,
5452 7, 0xFD0F, 0x0635, 0x0631, 0,
5453 7, 0xFD10, 0x0636, 0x0631, 0,
5454 6, 0xFD11, 0x0637, 0x0649, 0,
5455 6, 0xFD12, 0x0637, 0x064A, 0,
5456 6, 0xFD13, 0x0639, 0x0649, 0,
5457 6, 0xFD14, 0x0639, 0x064A, 0,
5458 6, 0xFD15, 0x063A, 0x0649, 0,
5459 6, 0xFD16, 0x063A, 0x064A, 0,
5460 6, 0xFD17, 0x0633, 0x0649, 0,
5461 6, 0xFD18, 0x0633, 0x064A, 0,
5462 6, 0xFD19, 0x0634, 0x0649, 0,
5463 6, 0xFD1A, 0x0634, 0x064A, 0,
5464 6, 0xFD1B, 0x062D, 0x0649, 0,
5465 6, 0xFD1C, 0x062D, 0x064A, 0,
5466 6, 0xFD1D, 0x062C, 0x0649, 0,
5467 6, 0xFD1E, 0x062C, 0x064A, 0,
5468 6, 0xFD1F, 0x062E, 0x0649, 0,
5469 6, 0xFD20, 0x062E, 0x064A, 0,
5470 6, 0xFD21, 0x0635, 0x0649, 0,
5471 6, 0xFD22, 0x0635, 0x064A, 0,
5472 6, 0xFD23, 0x0636, 0x0649, 0,
5473 6, 0xFD24, 0x0636, 0x064A, 0,
5474 6, 0xFD25, 0x0634, 0x062C, 0,
5475 6, 0xFD26, 0x0634, 0x062D, 0,
5476 6, 0xFD27, 0x0634, 0x062E, 0,
5477 6, 0xFD28, 0x0634, 0x0645, 0,
5478 6, 0xFD29, 0x0634, 0x0631, 0,
5479 6, 0xFD2A, 0x0633, 0x0631, 0,
5480 6, 0xFD2B, 0x0635, 0x0631, 0,
5481 6, 0xFD2C, 0x0636, 0x0631, 0,
5482 4, 0xFD2D, 0x0634, 0x062C, 0,
5483 4, 0xFD2E, 0x0634, 0x062D, 0,
5484 4, 0xFD2F, 0x0634, 0x062E, 0,
5485 4, 0xFD30, 0x0634, 0x0645, 0,
5486 4, 0xFD31, 0x0633, 0x0647, 0,
5487 4, 0xFD32, 0x0634, 0x0647, 0,
5488 4, 0xFD33, 0x0637, 0x0645, 0,
5489 5, 0xFD34, 0x0633, 0x062C, 0,
5490 5, 0xFD35, 0x0633, 0x062D, 0,
5491 5, 0xFD36, 0x0633, 0x062E, 0,
5492 5, 0xFD37, 0x0634, 0x062C, 0,
5493 5, 0xFD38, 0x0634, 0x062D, 0,
5494 5, 0xFD39, 0x0634, 0x062E, 0,
5495 5, 0xFD3A, 0x0637, 0x0645, 0,
5496 5, 0xFD3B, 0x0638, 0x0645, 0,
5497 6, 0xFD3C, 0x0627, 0x064B, 0,
5498 7, 0xFD3D, 0x0627, 0x064B, 0,
5499 4, 0xFD50, 0x062A, 0x062C, 0x0645, 0,
5500 6, 0xFD51, 0x062A, 0x062D, 0x062C, 0,
5501 4, 0xFD52, 0x062A, 0x062D, 0x062C, 0,
5502 4, 0xFD53, 0x062A, 0x062D, 0x0645, 0,
5503 4, 0xFD54, 0x062A, 0x062E, 0x0645, 0,
5504 4, 0xFD55, 0x062A, 0x0645, 0x062C, 0,
5505 4, 0xFD56, 0x062A, 0x0645, 0x062D, 0,
5506 4, 0xFD57, 0x062A, 0x0645, 0x062E, 0,
5507 6, 0xFD58, 0x062C, 0x0645, 0x062D, 0,
5508 4, 0xFD59, 0x062C, 0x0645, 0x062D, 0,
5509 6, 0xFD5A, 0x062D, 0x0645, 0x064A, 0,
5510 6, 0xFD5B, 0x062D, 0x0645, 0x0649, 0,
5511 4, 0xFD5C, 0x0633, 0x062D, 0x062C, 0,
5512 4, 0xFD5D, 0x0633, 0x062C, 0x062D, 0,
5513 6, 0xFD5E, 0x0633, 0x062C, 0x0649, 0,
5514 6, 0xFD5F, 0x0633, 0x0645, 0x062D, 0,
5515 4, 0xFD60, 0x0633, 0x0645, 0x062D, 0,
5516 4, 0xFD61, 0x0633, 0x0645, 0x062C, 0,
5517 6, 0xFD62, 0x0633, 0x0645, 0x0645, 0,
5518 4, 0xFD63, 0x0633, 0x0645, 0x0645, 0,
5519 6, 0xFD64, 0x0635, 0x062D, 0x062D, 0,
5520 4, 0xFD65, 0x0635, 0x062D, 0x062D, 0,
5521 6, 0xFD66, 0x0635, 0x0645, 0x0645, 0,
5522 6, 0xFD67, 0x0634, 0x062D, 0x0645, 0,
5523 4, 0xFD68, 0x0634, 0x062D, 0x0645, 0,
5524 6, 0xFD69, 0x0634, 0x062C, 0x064A, 0,
5525 6, 0xFD6A, 0x0634, 0x0645, 0x062E, 0,
5526 4, 0xFD6B, 0x0634, 0x0645, 0x062E, 0,
5527 6, 0xFD6C, 0x0634, 0x0645, 0x0645, 0,
5528 4, 0xFD6D, 0x0634, 0x0645, 0x0645, 0,
5529 6, 0xFD6E, 0x0636, 0x062D, 0x0649, 0,
5530 6, 0xFD6F, 0x0636, 0x062E, 0x0645, 0,
5531 4, 0xFD70, 0x0636, 0x062E, 0x0645, 0,
5532 6, 0xFD71, 0x0637, 0x0645, 0x062D, 0,
5533 4, 0xFD72, 0x0637, 0x0645, 0x062D, 0,
5534 4, 0xFD73, 0x0637, 0x0645, 0x0645, 0,
5535 6, 0xFD74, 0x0637, 0x0645, 0x064A, 0,
5536 6, 0xFD75, 0x0639, 0x062C, 0x0645, 0,
5537 6, 0xFD76, 0x0639, 0x0645, 0x0645, 0,
5538 4, 0xFD77, 0x0639, 0x0645, 0x0645, 0,
5539 6, 0xFD78, 0x0639, 0x0645, 0x0649, 0,
5540 6, 0xFD79, 0x063A, 0x0645, 0x0645, 0,
5541 6, 0xFD7A, 0x063A, 0x0645, 0x064A, 0,
5542 6, 0xFD7B, 0x063A, 0x0645, 0x0649, 0,
5543 6, 0xFD7C, 0x0641, 0x062E, 0x0645, 0,
5544 4, 0xFD7D, 0x0641, 0x062E, 0x0645, 0,
5545 6, 0xFD7E, 0x0642, 0x0645, 0x062D, 0,
5546 6, 0xFD7F, 0x0642, 0x0645, 0x0645, 0,
5547 6, 0xFD80, 0x0644, 0x062D, 0x0645, 0,
5548 6, 0xFD81, 0x0644, 0x062D, 0x064A, 0,
5549 6, 0xFD82, 0x0644, 0x062D, 0x0649, 0,
5550 4, 0xFD83, 0x0644, 0x062C, 0x062C, 0,
5551 6, 0xFD84, 0x0644, 0x062C, 0x062C, 0,
5552 6, 0xFD85, 0x0644, 0x062E, 0x0645, 0,
5553 4, 0xFD86, 0x0644, 0x062E, 0x0645, 0,
5554 6, 0xFD87, 0x0644, 0x0645, 0x062D, 0,
5555 4, 0xFD88, 0x0644, 0x0645, 0x062D, 0,
5556 4, 0xFD89, 0x0645, 0x062D, 0x062C, 0,
5557 4, 0xFD8A, 0x0645, 0x062D, 0x0645, 0,
5558 6, 0xFD8B, 0x0645, 0x062D, 0x064A, 0,
5559 4, 0xFD8C, 0x0645, 0x062C, 0x062D, 0,
5560 4, 0xFD8D, 0x0645, 0x062C, 0x0645, 0,
5561 4, 0xFD8E, 0x0645, 0x062E, 0x062C, 0,
5562 4, 0xFD8F, 0x0645, 0x062E, 0x0645, 0,
5563 4, 0xFD92, 0x0645, 0x062C, 0x062E, 0,
5564 4, 0xFD93, 0x0647, 0x0645, 0x062C, 0,
5565 4, 0xFD94, 0x0647, 0x0645, 0x0645, 0,
5566 4, 0xFD95, 0x0646, 0x062D, 0x0645, 0,
5567 6, 0xFD96, 0x0646, 0x062D, 0x0649, 0,
5568 6, 0xFD97, 0x0646, 0x062C, 0x0645, 0,
5569 4, 0xFD98, 0x0646, 0x062C, 0x0645, 0,
5570 6, 0xFD99, 0x0646, 0x062C, 0x0649, 0,
5571 6, 0xFD9A, 0x0646, 0x0645, 0x064A, 0,
5572 6, 0xFD9B, 0x0646, 0x0645, 0x0649, 0,
5573 6, 0xFD9C, 0x064A, 0x0645, 0x0645, 0,
5574 4, 0xFD9D, 0x064A, 0x0645, 0x0645, 0,
5575 6, 0xFD9E, 0x0628, 0x062E, 0x064A, 0,
5576 6, 0xFD9F, 0x062A, 0x062C, 0x064A, 0,
5577 6, 0xFDA0, 0x062A, 0x062C, 0x0649, 0,
5578 6, 0xFDA1, 0x062A, 0x062E, 0x064A, 0,
5579 6, 0xFDA2, 0x062A, 0x062E, 0x0649, 0,
5580 6, 0xFDA3, 0x062A, 0x0645, 0x064A, 0,
5581 6, 0xFDA4, 0x062A, 0x0645, 0x0649, 0,
5582 6, 0xFDA5, 0x062C, 0x0645, 0x064A, 0,
5583 6, 0xFDA6, 0x062C, 0x062D, 0x0649, 0,
5584 6, 0xFDA7, 0x062C, 0x0645, 0x0649, 0,
5585 6, 0xFDA8, 0x0633, 0x062E, 0x0649, 0,
5586 6, 0xFDA9, 0x0635, 0x062D, 0x064A, 0,
5587 6, 0xFDAA, 0x0634, 0x062D, 0x064A, 0,
5588 6, 0xFDAB, 0x0636, 0x062D, 0x064A, 0,
5589 6, 0xFDAC, 0x0644, 0x062C, 0x064A, 0,
5590 6, 0xFDAD, 0x0644, 0x0645, 0x064A, 0,
5591 6, 0xFDAE, 0x064A, 0x062D, 0x064A, 0,
5592 6, 0xFDAF, 0x064A, 0x062C, 0x064A, 0,
5593 6, 0xFDB0, 0x064A, 0x0645, 0x064A, 0,
5594 6, 0xFDB1, 0x0645, 0x0645, 0x064A, 0,
5595 6, 0xFDB2, 0x0642, 0x0645, 0x064A, 0,
5596 6, 0xFDB3, 0x0646, 0x062D, 0x064A, 0,
5597 4, 0xFDB4, 0x0642, 0x0645, 0x062D, 0,
5598 4, 0xFDB5, 0x0644, 0x062D, 0x0645, 0,
5599 6, 0xFDB6, 0x0639, 0x0645, 0x064A, 0,
5600 6, 0xFDB7, 0x0643, 0x0645, 0x064A, 0,
5601 4, 0xFDB8, 0x0646, 0x062C, 0x062D, 0,
5602 6, 0xFDB9, 0x0645, 0x062E, 0x064A, 0,
5603 4, 0xFDBA, 0x0644, 0x062C, 0x0645, 0,
5604 6, 0xFDBB, 0x0643, 0x0645, 0x0645, 0,
5605 6, 0xFDBC, 0x0644, 0x062C, 0x0645, 0,
5606 6, 0xFDBD, 0x0646, 0x062C, 0x062D, 0,
5607 6, 0xFDBE, 0x062C, 0x062D, 0x064A, 0,
5608 6, 0xFDBF, 0x062D, 0x062C, 0x064A, 0,
5609 6, 0xFDC0, 0x0645, 0x062C, 0x064A, 0,
5610 6, 0xFDC1, 0x0641, 0x0645, 0x064A, 0,
5611 6, 0xFDC2, 0x0628, 0x062D, 0x064A, 0,
5612 4, 0xFDC3, 0x0643, 0x0645, 0x0645, 0,
5613 4, 0xFDC4, 0x0639, 0x062C, 0x0645, 0,
5614 4, 0xFDC5, 0x0635, 0x0645, 0x0645, 0,
5615 6, 0xFDC6, 0x0633, 0x062E, 0x064A, 0,
5616 6, 0xFDC7, 0x0646, 0x062C, 0x064A, 0,
5617 7, 0xFDF0, 0x0635, 0x0644, 0x06D2, 0,
5618 7, 0xFDF1, 0x0642, 0x0644, 0x06D2, 0,
5619 7, 0xFDF2, 0x0627, 0x0644, 0x0644, 0x0647, 0,
5620 7, 0xFDF3, 0x0627, 0x0643, 0x0628, 0x0631, 0,
5621 7, 0xFDF4, 0x0645, 0x062D, 0x0645, 0x062F, 0,
5622 7, 0xFDF5, 0x0635, 0x0644, 0x0639, 0x0645, 0,
5623 7, 0xFDF6, 0x0631, 0x0633, 0x0648, 0x0644, 0,
5624 7, 0xFDF7, 0x0639, 0x0644, 0x064A, 0x0647, 0,
5625 7, 0xFDF8, 0x0648, 0x0633, 0x0644, 0x0645, 0,
5626 7, 0xFDF9, 0x0635, 0x0644, 0x0649, 0,
5627 7, 0xFDFA, 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, 0,
5628 7, 0xFDFB, 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, 0,
5629 7, 0xFDFC, 0x0631, 0x06CC, 0x0627, 0x0644, 0,
5630 11, 0xFE30, 0x2025, 0,
5631 11, 0xFE31, 0x2014, 0,
5632 11, 0xFE32, 0x2013, 0,
5633 11, 0xFE33, 0x005F, 0,
5634 11, 0xFE34, 0x005F, 0,
5635 11, 0xFE35, 0x0028, 0,
5636 11, 0xFE36, 0x0029, 0,
5637 11, 0xFE37, 0x007B, 0,
5638 11, 0xFE38, 0x007D, 0,
5639 11, 0xFE39, 0x3014, 0,
5640 11, 0xFE3A, 0x3015, 0,
5641 11, 0xFE3B, 0x3010, 0,
5642 11, 0xFE3C, 0x3011, 0,
5643 11, 0xFE3D, 0x300A, 0,
5644 11, 0xFE3E, 0x300B, 0,
5645 11, 0xFE3F, 0x3008, 0,
5646 11, 0xFE40, 0x3009, 0,
5647 11, 0xFE41, 0x300C, 0,
5648 11, 0xFE42, 0x300D, 0,
5649 11, 0xFE43, 0x300E, 0,
5650 11, 0xFE44, 0x300F, 0,
5651 16, 0xFE49, 0x203E, 0,
5652 16, 0xFE4A, 0x203E, 0,
5653 16, 0xFE4B, 0x203E, 0,
5654 16, 0xFE4C, 0x203E, 0,
5655 16, 0xFE4D, 0x005F, 0,
5656 16, 0xFE4E, 0x005F, 0,
5657 16, 0xFE4F, 0x005F, 0,
5658 14, 0xFE50, 0x002C, 0,
5659 14, 0xFE51, 0x3001, 0,
5660 14, 0xFE52, 0x002E, 0,
5661 14, 0xFE54, 0x003B, 0,
5662 14, 0xFE55, 0x003A, 0,
5663 14, 0xFE56, 0x003F, 0,
5664 14, 0xFE57, 0x0021, 0,
5665 14, 0xFE58, 0x2014, 0,
5666 14, 0xFE59, 0x0028, 0,
5667 14, 0xFE5A, 0x0029, 0,
5668 14, 0xFE5B, 0x007B, 0,
5669 14, 0xFE5C, 0x007D, 0,
5670 14, 0xFE5D, 0x3014, 0,
5671 14, 0xFE5E, 0x3015, 0,
5672 14, 0xFE5F, 0x0023, 0,
5673 14, 0xFE60, 0x0026, 0,
5674 14, 0xFE61, 0x002A, 0,
5675 14, 0xFE62, 0x002B, 0,
5676 14, 0xFE63, 0x002D, 0,
5677 14, 0xFE64, 0x003C, 0,
5678 14, 0xFE65, 0x003E, 0,
5679 14, 0xFE66, 0x003D, 0,
5680 14, 0xFE68, 0x005C, 0,
5681 14, 0xFE69, 0x0024, 0,
5682 14, 0xFE6A, 0x0025, 0,
5683 14, 0xFE6B, 0x0040, 0,
5684 7, 0xFE70, 0x0020, 0x064B, 0,
5685 5, 0xFE71, 0x0640, 0x064B, 0,
5686 7, 0xFE72, 0x0020, 0x064C, 0,
5687 7, 0xFE74, 0x0020, 0x064D, 0,
5688 7, 0xFE76, 0x0020, 0x064E, 0,
5689 5, 0xFE77, 0x0640, 0x064E, 0,
5690 7, 0xFE78, 0x0020, 0x064F, 0,
5691 5, 0xFE79, 0x0640, 0x064F, 0,
5692 7, 0xFE7A, 0x0020, 0x0650, 0,
5693 5, 0xFE7B, 0x0640, 0x0650, 0,
5694 7, 0xFE7C, 0x0020, 0x0651, 0,
5695 5, 0xFE7D, 0x0640, 0x0651, 0,
5696 7, 0xFE7E, 0x0020, 0x0652, 0,
5697 5, 0xFE7F, 0x0640, 0x0652, 0,
5698 7, 0xFE80, 0x0621, 0,
5699 7, 0xFE81, 0x0622, 0,
5700 6, 0xFE82, 0x0622, 0,
5701 7, 0xFE83, 0x0623, 0,
5702 6, 0xFE84, 0x0623, 0,
5703 7, 0xFE85, 0x0624, 0,
5704 6, 0xFE86, 0x0624, 0,
5705 7, 0xFE87, 0x0625, 0,
5706 6, 0xFE88, 0x0625, 0,
5707 7, 0xFE89, 0x0626, 0,
5708 6, 0xFE8A, 0x0626, 0,
5709 4, 0xFE8B, 0x0626, 0,
5710 5, 0xFE8C, 0x0626, 0,
5711 7, 0xFE8D, 0x0627, 0,
5712 6, 0xFE8E, 0x0627, 0,
5713 7, 0xFE8F, 0x0628, 0,
5714 6, 0xFE90, 0x0628, 0,
5715 4, 0xFE91, 0x0628, 0,
5716 5, 0xFE92, 0x0628, 0,
5717 7, 0xFE93, 0x0629, 0,
5718 6, 0xFE94, 0x0629, 0,
5719 7, 0xFE95, 0x062A, 0,
5720 6, 0xFE96, 0x062A, 0,
5721 4, 0xFE97, 0x062A, 0,
5722 5, 0xFE98, 0x062A, 0,
5723 7, 0xFE99, 0x062B, 0,
5724 6, 0xFE9A, 0x062B, 0,
5725 4, 0xFE9B, 0x062B, 0,
5726 5, 0xFE9C, 0x062B, 0,
5727 7, 0xFE9D, 0x062C, 0,
5728 6, 0xFE9E, 0x062C, 0,
5729 4, 0xFE9F, 0x062C, 0,
5730 5, 0xFEA0, 0x062C, 0,
5731 7, 0xFEA1, 0x062D, 0,
5732 6, 0xFEA2, 0x062D, 0,
5733 4, 0xFEA3, 0x062D, 0,
5734 5, 0xFEA4, 0x062D, 0,
5735 7, 0xFEA5, 0x062E, 0,
5736 6, 0xFEA6, 0x062E, 0,
5737 4, 0xFEA7, 0x062E, 0,
5738 5, 0xFEA8, 0x062E, 0,
5739 7, 0xFEA9, 0x062F, 0,
5740 6, 0xFEAA, 0x062F, 0,
5741 7, 0xFEAB, 0x0630, 0,
5742 6, 0xFEAC, 0x0630, 0,
5743 7, 0xFEAD, 0x0631, 0,
5744 6, 0xFEAE, 0x0631, 0,
5745 7, 0xFEAF, 0x0632, 0,
5746 6, 0xFEB0, 0x0632, 0,
5747 7, 0xFEB1, 0x0633, 0,
5748 6, 0xFEB2, 0x0633, 0,
5749 4, 0xFEB3, 0x0633, 0,
5750 5, 0xFEB4, 0x0633, 0,
5751 7, 0xFEB5, 0x0634, 0,
5752 6, 0xFEB6, 0x0634, 0,
5753 4, 0xFEB7, 0x0634, 0,
5754 5, 0xFEB8, 0x0634, 0,
5755 7, 0xFEB9, 0x0635, 0,
5756 6, 0xFEBA, 0x0635, 0,
5757 4, 0xFEBB, 0x0635, 0,
5758 5, 0xFEBC, 0x0635, 0,
5759 7, 0xFEBD, 0x0636, 0,
5760 6, 0xFEBE, 0x0636, 0,
5761 4, 0xFEBF, 0x0636, 0,
5762 5, 0xFEC0, 0x0636, 0,
5763 7, 0xFEC1, 0x0637, 0,
5764 6, 0xFEC2, 0x0637, 0,
5765 4, 0xFEC3, 0x0637, 0,
5766 5, 0xFEC4, 0x0637, 0,
5767 7, 0xFEC5, 0x0638, 0,
5768 6, 0xFEC6, 0x0638, 0,
5769 4, 0xFEC7, 0x0638, 0,
5770 5, 0xFEC8, 0x0638, 0,
5771 7, 0xFEC9, 0x0639, 0,
5772 6, 0xFECA, 0x0639, 0,
5773 4, 0xFECB, 0x0639, 0,
5774 5, 0xFECC, 0x0639, 0,
5775 7, 0xFECD, 0x063A, 0,
5776 6, 0xFECE, 0x063A, 0,
5777 4, 0xFECF, 0x063A, 0,
5778 5, 0xFED0, 0x063A, 0,
5779 7, 0xFED1, 0x0641, 0,
5780 6, 0xFED2, 0x0641, 0,
5781 4, 0xFED3, 0x0641, 0,
5782 5, 0xFED4, 0x0641, 0,
5783 7, 0xFED5, 0x0642, 0,
5784 6, 0xFED6, 0x0642, 0,
5785 4, 0xFED7, 0x0642, 0,
5786 5, 0xFED8, 0x0642, 0,
5787 7, 0xFED9, 0x0643, 0,
5788 6, 0xFEDA, 0x0643, 0,
5789 4, 0xFEDB, 0x0643, 0,
5790 5, 0xFEDC, 0x0643, 0,
5791 7, 0xFEDD, 0x0644, 0,
5792 6, 0xFEDE, 0x0644, 0,
5793 4, 0xFEDF, 0x0644, 0,
5794 5, 0xFEE0, 0x0644, 0,
5795 7, 0xFEE1, 0x0645, 0,
5796 6, 0xFEE2, 0x0645, 0,
5797 4, 0xFEE3, 0x0645, 0,
5798 5, 0xFEE4, 0x0645, 0,
5799 7, 0xFEE5, 0x0646, 0,
5800 6, 0xFEE6, 0x0646, 0,
5801 4, 0xFEE7, 0x0646, 0,
5802 5, 0xFEE8, 0x0646, 0,
5803 7, 0xFEE9, 0x0647, 0,
5804 6, 0xFEEA, 0x0647, 0,
5805 4, 0xFEEB, 0x0647, 0,
5806 5, 0xFEEC, 0x0647, 0,
5807 7, 0xFEED, 0x0648, 0,
5808 6, 0xFEEE, 0x0648, 0,
5809 7, 0xFEEF, 0x0649, 0,
5810 6, 0xFEF0, 0x0649, 0,
5811 7, 0xFEF1, 0x064A, 0,
5812 6, 0xFEF2, 0x064A, 0,
5813 4, 0xFEF3, 0x064A, 0,
5814 5, 0xFEF4, 0x064A, 0,
5815 7, 0xFEF5, 0x0644, 0x0622, 0,
5816 6, 0xFEF6, 0x0644, 0x0622, 0,
5817 7, 0xFEF7, 0x0644, 0x0623, 0,
5818 6, 0xFEF8, 0x0644, 0x0623, 0,
5819 7, 0xFEF9, 0x0644, 0x0625, 0,
5820 6, 0xFEFA, 0x0644, 0x0625, 0,
5821 7, 0xFEFB, 0x0644, 0x0627, 0,
5822 6, 0xFEFC, 0x0644, 0x0627, 0,
5823 12, 0xFF01, 0x0021, 0,
5824 12, 0xFF02, 0x0022, 0,
5825 12, 0xFF03, 0x0023, 0,
5826 12, 0xFF04, 0x0024, 0,
5827 12, 0xFF05, 0x0025, 0,
5828 12, 0xFF06, 0x0026, 0,
5829 12, 0xFF07, 0x0027, 0,
5830 12, 0xFF08, 0x0028, 0,
5831 12, 0xFF09, 0x0029, 0,
5832 12, 0xFF0A, 0x002A, 0,
5833 12, 0xFF0B, 0x002B, 0,
5834 12, 0xFF0C, 0x002C, 0,
5835 12, 0xFF0D, 0x002D, 0,
5836 12, 0xFF0E, 0x002E, 0,
5837 12, 0xFF0F, 0x002F, 0,
5838 12, 0xFF10, 0x0030, 0,
5839 12, 0xFF11, 0x0031, 0,
5840 12, 0xFF12, 0x0032, 0,
5841 12, 0xFF13, 0x0033, 0,
5842 12, 0xFF14, 0x0034, 0,
5843 12, 0xFF15, 0x0035, 0,
5844 12, 0xFF16, 0x0036, 0,
5845 12, 0xFF17, 0x0037, 0,
5846 12, 0xFF18, 0x0038, 0,
5847 12, 0xFF19, 0x0039, 0,
5848 12, 0xFF1A, 0x003A, 0,
5849 12, 0xFF1B, 0x003B, 0,
5850 12, 0xFF1C, 0x003C, 0,
5851 12, 0xFF1D, 0x003D, 0,
5852 12, 0xFF1E, 0x003E, 0,
5853 12, 0xFF1F, 0x003F, 0,
5854 12, 0xFF20, 0x0040, 0,
5855 12, 0xFF21, 0x0041, 0,
5856 12, 0xFF22, 0x0042, 0,
5857 12, 0xFF23, 0x0043, 0,
5858 12, 0xFF24, 0x0044, 0,
5859 12, 0xFF25, 0x0045, 0,
5860 12, 0xFF26, 0x0046, 0,
5861 12, 0xFF27, 0x0047, 0,
5862 12, 0xFF28, 0x0048, 0,
5863 12, 0xFF29, 0x0049, 0,
5864 12, 0xFF2A, 0x004A, 0,
5865 12, 0xFF2B, 0x004B, 0,
5866 12, 0xFF2C, 0x004C, 0,
5867 12, 0xFF2D, 0x004D, 0,
5868 12, 0xFF2E, 0x004E, 0,
5869 12, 0xFF2F, 0x004F, 0,
5870 12, 0xFF30, 0x0050, 0,
5871 12, 0xFF31, 0x0051, 0,
5872 12, 0xFF32, 0x0052, 0,
5873 12, 0xFF33, 0x0053, 0,
5874 12, 0xFF34, 0x0054, 0,
5875 12, 0xFF35, 0x0055, 0,
5876 12, 0xFF36, 0x0056, 0,
5877 12, 0xFF37, 0x0057, 0,
5878 12, 0xFF38, 0x0058, 0,
5879 12, 0xFF39, 0x0059, 0,
5880 12, 0xFF3A, 0x005A, 0,
5881 12, 0xFF3B, 0x005B, 0,
5882 12, 0xFF3C, 0x005C, 0,
5883 12, 0xFF3D, 0x005D, 0,
5884 12, 0xFF3E, 0x005E, 0,
5885 12, 0xFF3F, 0x005F, 0,
5886 12, 0xFF40, 0x0060, 0,
5887 12, 0xFF41, 0x0061, 0,
5888 12, 0xFF42, 0x0062, 0,
5889 12, 0xFF43, 0x0063, 0,
5890 12, 0xFF44, 0x0064, 0,
5891 12, 0xFF45, 0x0065, 0,
5892 12, 0xFF46, 0x0066, 0,
5893 12, 0xFF47, 0x0067, 0,
5894 12, 0xFF48, 0x0068, 0,
5895 12, 0xFF49, 0x0069, 0,
5896 12, 0xFF4A, 0x006A, 0,
5897 12, 0xFF4B, 0x006B, 0,
5898 12, 0xFF4C, 0x006C, 0,
5899 12, 0xFF4D, 0x006D, 0,
5900 12, 0xFF4E, 0x006E, 0,
5901 12, 0xFF4F, 0x006F, 0,
5902 12, 0xFF50, 0x0070, 0,
5903 12, 0xFF51, 0x0071, 0,
5904 12, 0xFF52, 0x0072, 0,
5905 12, 0xFF53, 0x0073, 0,
5906 12, 0xFF54, 0x0074, 0,
5907 12, 0xFF55, 0x0075, 0,
5908 12, 0xFF56, 0x0076, 0,
5909 12, 0xFF57, 0x0077, 0,
5910 12, 0xFF58, 0x0078, 0,
5911 12, 0xFF59, 0x0079, 0,
5912 12, 0xFF5A, 0x007A, 0,
5913 12, 0xFF5B, 0x007B, 0,
5914 12, 0xFF5C, 0x007C, 0,
5915 12, 0xFF5D, 0x007D, 0,
5916 12, 0xFF5E, 0x007E, 0,
5917 12, 0xFF5F, 0x2985, 0,
5918 12, 0xFF60, 0x2986, 0,
5919 13, 0xFF61, 0x3002, 0,
5920 13, 0xFF62, 0x300C, 0,
5921 13, 0xFF63, 0x300D, 0,
5922 13, 0xFF64, 0x3001, 0,
5923 13, 0xFF65, 0x30FB, 0,
5924 13, 0xFF66, 0x30F2, 0,
5925 13, 0xFF67, 0x30A1, 0,
5926 13, 0xFF68, 0x30A3, 0,
5927 13, 0xFF69, 0x30A5, 0,
5928 13, 0xFF6A, 0x30A7, 0,
5929 13, 0xFF6B, 0x30A9, 0,
5930 13, 0xFF6C, 0x30E3, 0,
5931 13, 0xFF6D, 0x30E5, 0,
5932 13, 0xFF6E, 0x30E7, 0,
5933 13, 0xFF6F, 0x30C3, 0,
5934 13, 0xFF70, 0x30FC, 0,
5935 13, 0xFF71, 0x30A2, 0,
5936 13, 0xFF72, 0x30A4, 0,
5937 13, 0xFF73, 0x30A6, 0,
5938 13, 0xFF74, 0x30A8, 0,
5939 13, 0xFF75, 0x30AA, 0,
5940 13, 0xFF76, 0x30AB, 0,
5941 13, 0xFF77, 0x30AD, 0,
5942 13, 0xFF78, 0x30AF, 0,
5943 13, 0xFF79, 0x30B1, 0,
5944 13, 0xFF7A, 0x30B3, 0,
5945 13, 0xFF7B, 0x30B5, 0,
5946 13, 0xFF7C, 0x30B7, 0,
5947 13, 0xFF7D, 0x30B9, 0,
5948 13, 0xFF7E, 0x30BB, 0,
5949 13, 0xFF7F, 0x30BD, 0,
5950 13, 0xFF80, 0x30BF, 0,
5951 13, 0xFF81, 0x30C1, 0,
5952 13, 0xFF82, 0x30C4, 0,
5953 13, 0xFF83, 0x30C6, 0,
5954 13, 0xFF84, 0x30C8, 0,
5955 13, 0xFF85, 0x30CA, 0,
5956 13, 0xFF86, 0x30CB, 0,
5957 13, 0xFF87, 0x30CC, 0,
5958 13, 0xFF88, 0x30CD, 0,
5959 13, 0xFF89, 0x30CE, 0,
5960 13, 0xFF8A, 0x30CF, 0,
5961 13, 0xFF8B, 0x30D2, 0,
5962 13, 0xFF8C, 0x30D5, 0,
5963 13, 0xFF8D, 0x30D8, 0,
5964 13, 0xFF8E, 0x30DB, 0,
5965 13, 0xFF8F, 0x30DE, 0,
5966 13, 0xFF90, 0x30DF, 0,
5967 13, 0xFF91, 0x30E0, 0,
5968 13, 0xFF92, 0x30E1, 0,
5969 13, 0xFF93, 0x30E2, 0,
5970 13, 0xFF94, 0x30E4, 0,
5971 13, 0xFF95, 0x30E6, 0,
5972 13, 0xFF96, 0x30E8, 0,
5973 13, 0xFF97, 0x30E9, 0,
5974 13, 0xFF98, 0x30EA, 0,
5975 13, 0xFF99, 0x30EB, 0,
5976 13, 0xFF9A, 0x30EC, 0,
5977 13, 0xFF9B, 0x30ED, 0,
5978 13, 0xFF9C, 0x30EF, 0,
5979 13, 0xFF9D, 0x30F3, 0,
5980 13, 0xFF9E, 0x3099, 0,
5981 13, 0xFF9F, 0x309A, 0,
5982 13, 0xFFA0, 0x3164, 0,
5983 13, 0xFFA1, 0x3131, 0,
5984 13, 0xFFA2, 0x3132, 0,
5985 13, 0xFFA3, 0x3133, 0,
5986 13, 0xFFA4, 0x3134, 0,
5987 13, 0xFFA5, 0x3135, 0,
5988 13, 0xFFA6, 0x3136, 0,
5989 13, 0xFFA7, 0x3137, 0,
5990 13, 0xFFA8, 0x3138, 0,
5991 13, 0xFFA9, 0x3139, 0,
5992 13, 0xFFAA, 0x313A, 0,
5993 13, 0xFFAB, 0x313B, 0,
5994 13, 0xFFAC, 0x313C, 0,
5995 13, 0xFFAD, 0x313D, 0,
5996 13, 0xFFAE, 0x313E, 0,
5997 13, 0xFFAF, 0x313F, 0,
5998 13, 0xFFB0, 0x3140, 0,
5999 13, 0xFFB1, 0x3141, 0,
6000 13, 0xFFB2, 0x3142, 0,
6001 13, 0xFFB3, 0x3143, 0,
6002 13, 0xFFB4, 0x3144, 0,
6003 13, 0xFFB5, 0x3145, 0,
6004 13, 0xFFB6, 0x3146, 0,
6005 13, 0xFFB7, 0x3147, 0,
6006 13, 0xFFB8, 0x3148, 0,
6007 13, 0xFFB9, 0x3149, 0,
6008 13, 0xFFBA, 0x314A, 0,
6009 13, 0xFFBB, 0x314B, 0,
6010 13, 0xFFBC, 0x314C, 0,
6011 13, 0xFFBD, 0x314D, 0,
6012 13, 0xFFBE, 0x314E, 0,
6013 13, 0xFFC2, 0x314F, 0,
6014 13, 0xFFC3, 0x3150, 0,
6015 13, 0xFFC4, 0x3151, 0,
6016 13, 0xFFC5, 0x3152, 0,
6017 13, 0xFFC6, 0x3153, 0,
6018 13, 0xFFC7, 0x3154, 0,
6019 13, 0xFFCA, 0x3155, 0,
6020 13, 0xFFCB, 0x3156, 0,
6021 13, 0xFFCC, 0x3157, 0,
6022 13, 0xFFCD, 0x3158, 0,
6023 13, 0xFFCE, 0x3159, 0,
6024 13, 0xFFCF, 0x315A, 0,
6025 13, 0xFFD2, 0x315B, 0,
6026 13, 0xFFD3, 0x315C, 0,
6027 13, 0xFFD4, 0x315D, 0,
6028 13, 0xFFD5, 0x315E, 0,
6029 13, 0xFFD6, 0x315F, 0,
6030 13, 0xFFD7, 0x3160, 0,
6031 13, 0xFFDA, 0x3161, 0,
6032 13, 0xFFDB, 0x3162, 0,
6033 13, 0xFFDC, 0x3163, 0,
6034 12, 0xFFE0, 0x00A2, 0,
6035 12, 0xFFE1, 0x00A3, 0,
6036 12, 0xFFE2, 0x00AC, 0,
6037 12, 0xFFE3, 0x00AF, 0,
6038 12, 0xFFE4, 0x00A6, 0,
6039 12, 0xFFE5, 0x00A5, 0,
6040 12, 0xFFE6, 0x20A9, 0,
6041 13, 0xFFE8, 0x2502, 0,
6042 13, 0xFFE9, 0x2190, 0,
6043 13, 0xFFEA, 0x2191, 0,
6044 13, 0xFFEB, 0x2192, 0,
6045 13, 0xFFEC, 0x2193, 0,
6046 13, 0xFFED, 0x25A0, 0,
6047 13, 0xFFEE, 0x25CB, 0,
6048
6049};
6050
6051static const Q_UINT16 di_00[] = {
6052 0, 0, 0, 0, 0, 0, 0, 0,
6053 0, 0, 0, 0, 0, 0, 0, 0,
6054 0, 0, 0, 0, 0, 0, 0, 0,
6055 0, 0, 0, 0, 0, 0, 0, 0,
6056 0, 0, 0, 0, 0, 0, 0, 0,
6057 0, 0, 0, 0, 0, 0, 0, 0,
6058 0, 0, 0, 0, 0, 0, 0, 0,
6059 0, 0, 0, 0, 0, 0, 0, 0,
6060 0, 0, 0, 0, 0, 0, 0, 0,
6061 0, 0, 0, 0, 0, 0, 0, 0,
6062 0, 0, 0, 0, 0, 0, 0, 0,
6063 0, 0, 0, 0, 0, 0, 0, 0,
6064 0, 0, 0, 0, 0, 0, 0, 0,
6065 0, 0, 0, 0, 0, 0, 0, 0,
6066 0, 0, 0, 0, 0, 0, 0, 0,
6067 0, 0, 0, 0, 0, 0, 0, 0,
6068 0, 0, 0, 0, 0, 0, 0, 0,
6069 0, 0, 0, 0, 0, 0, 0, 0,
6070 0, 0, 0, 0, 0, 0, 0, 0,
6071 0, 0, 0, 0, 0, 0, 0, 0,
6072 1, 0, 0, 0, 0, 0, 0, 0,
6073 5, 0, 10, 0, 0, 0, 0, 14,
6074 0, 0, 19, 23, 27, 32, 0, 0,
6075 36, 41, 45, 0, 49, 55, 61, 0,
6076 67, 72, 77, 82, 87, 92, 0, 97,
6077 102, 107, 112, 117, 122, 127, 132, 137,
6078 0, 142, 147, 152, 157, 162, 167, 0,
6079 0, 172, 177, 182, 187, 192, 0, 0,
6080 197, 202, 207, 212, 217, 222, 0, 227,
6081 232, 237, 242, 247, 252, 257, 262, 267,
6082 0, 272, 277, 282, 287, 292, 297, 0,
6083 0, 302, 307, 312, 317, 322, 0, 327,
6084};
6085
6086static const Q_UINT16 di_01[] = {
6087 332, 337, 342, 347, 352, 357, 362, 367,
6088 372, 377, 382, 387, 392, 397, 402, 407,
6089 0, 0, 412, 417, 422, 427, 432, 437,
6090 442, 447, 452, 457, 462, 467, 472, 477,
6091 482, 487, 492, 497, 502, 507, 0, 0,
6092 512, 517, 522, 527, 532, 537, 542, 547,
6093 552, 0, 557, 562, 567, 572, 577, 582,
6094 0, 587, 592, 597, 602, 607, 612, 617,
6095 622, 0, 0, 627, 632, 637, 642, 647,
6096 652, 657, 0, 0, 662, 667, 672, 677,
6097 682, 687, 0, 0, 692, 697, 702, 707,
6098 712, 717, 722, 727, 732, 737, 742, 747,
6099 752, 757, 762, 767, 772, 777, 0, 0,
6100 782, 787, 792, 797, 802, 807, 812, 817,
6101 822, 827, 832, 837, 842, 847, 852, 857,
6102 862, 867, 872, 877, 882, 887, 892, 897,
6103 0, 0, 0, 0, 0, 0, 0, 0,
6104 0, 0, 0, 0, 0, 0, 0, 0,
6105 0, 0, 0, 0, 0, 0, 0, 0,
6106 0, 0, 0, 0, 0, 0, 0, 0,
6107 901, 906, 0, 0, 0, 0, 0, 0,
6108 0, 0, 0, 0, 0, 0, 0, 911,
6109 916, 0, 0, 0, 0, 0, 0, 0,
6110 0, 0, 0, 0, 0, 0, 0, 0,
6111 0, 0, 0, 0, 921, 926, 931, 936,
6112 941, 946, 951, 956, 961, 966, 971, 976,
6113 981, 986, 991, 996, 1001, 1006, 1011, 1016,
6114 1021, 1026, 1031, 1036, 1041, 0, 1046, 1051,
6115 1056, 1061, 1066, 1071, 0, 0, 1076, 1081,
6116 1086, 1091, 1096, 1101, 1106, 1111, 1116, 1121,
6117 1126, 1131, 1136, 1141, 1146, 1151, 0, 0,
6118 1156, 1161, 1166, 1171, 1176, 1181, 1186, 1191,
6119};
6120
6121static const Q_UINT16 di_02[] = {
6122 1196, 1201, 1206, 1211, 1216, 1221, 1226, 1231,
6123 1236, 1241, 1246, 1251, 1256, 1261, 1266, 1271,
6124 1276, 1281, 1286, 1291, 1296, 1301, 1306, 1311,
6125 1316, 1321, 1326, 1331, 0, 0, 1336, 1341,
6126 0, 0, 0, 0, 0, 0, 1346, 1351,
6127 1356, 1361, 1366, 1371, 1376, 1381, 1386, 1391,
6128 1396, 1401, 1406, 1411, 0, 0, 0, 0,
6129 0, 0, 0, 0, 0, 0, 0, 0,
6130 0, 0, 0, 0, 0, 0, 0, 0,
6131 0, 0, 0, 0, 0, 0, 0, 0,
6132 0, 0, 0, 0, 0, 0, 0, 0,
6133 0, 0, 0, 0, 0, 0, 0, 0,
6134 0, 0, 0, 0, 0, 0, 0, 0,
6135 0, 0, 0, 0, 0, 0, 0, 0,
6136 0, 0, 0, 0, 0, 0, 0, 0,
6137 0, 0, 0, 0, 0, 0, 0, 0,
6138 0, 0, 0, 0, 0, 0, 0, 0,
6139 0, 0, 0, 0, 0, 0, 0, 0,
6140 0, 0, 0, 0, 0, 0, 0, 0,
6141 0, 0, 0, 0, 0, 0, 0, 0,
6142 0, 0, 0, 0, 0, 0, 0, 0,
6143 0, 0, 0, 0, 0, 0, 0, 0,
6144 1416, 1420, 1424, 1428, 1432, 1436, 1440, 1444,
6145 1448, 0, 0, 0, 0, 0, 0, 0,
6146 0, 0, 0, 0, 0, 0, 0, 0,
6147 0, 0, 0, 0, 0, 0, 0, 0,
6148 0, 0, 0, 0, 0, 0, 0, 0,
6149 1452, 1457, 1462, 1467, 1472, 1477, 0, 0,
6150 1482, 1486, 1490, 1494, 1498, 0, 0, 0,
6151 0, 0, 0, 0, 0, 0, 0, 0,
6152 0, 0, 0, 0, 0, 0, 0, 0,
6153 0, 0, 0, 0, 0, 0, 0, 0,
6154};
6155
6156static const Q_UINT16 di_03[] = {
6157 0, 0, 0, 0, 0, 0, 0, 0,
6158 0, 0, 0, 0, 0, 0, 0, 0,
6159 0, 0, 0, 0, 0, 0, 0, 0,
6160 0, 0, 0, 0, 0, 0, 0, 0,
6161 0, 0, 0, 0, 0, 0, 0, 0,
6162 0, 0, 0, 0, 0, 0, 0, 0,
6163 0, 0, 0, 0, 0, 0, 0, 0,
6164 0, 0, 0, 0, 0, 0, 0, 0,
6165 1502, 1506, 0, 1510, 1514, 0, 0, 0,
6166 0, 0, 0, 0, 0, 0, 0, 0,
6167 0, 0, 0, 0, 0, 0, 0, 0,
6168 0, 0, 0, 0, 0, 0, 0, 0,
6169 0, 0, 0, 0, 0, 0, 0, 0,
6170 0, 0, 0, 0, 0, 0, 0, 0,
6171 0, 0, 0, 0, 1519, 0, 0, 0,
6172 0, 0, 1523, 0, 0, 0, 1528, 0,
6173 0, 0, 0, 0, 1532, 1537, 1542, 1547,
6174 1551, 1556, 1561, 0, 1566, 0, 1571, 1576,
6175 1581, 0, 0, 0, 0, 0, 0, 0,
6176 0, 0, 0, 0, 0, 0, 0, 0,
6177 0, 0, 0, 0, 0, 0, 0, 0,
6178 0, 0, 1586, 1591, 1596, 1601, 1606, 1611,
6179 1616, 0, 0, 0, 0, 0, 0, 0,
6180 0, 0, 0, 0, 0, 0, 0, 0,
6181 0, 0, 0, 0, 0, 0, 0, 0,
6182 0, 0, 1621, 1626, 1631, 1636, 1641, 0,
6183 1646, 1650, 1654, 1658, 1663, 1668, 1672, 0,
6184 0, 0, 0, 0, 0, 0, 0, 0,
6185 0, 0, 0, 0, 0, 0, 0, 0,
6186 0, 0, 0, 0, 0, 0, 0, 0,
6187 1676, 1680, 1684, 0, 1688, 1692, 0, 0,
6188 0, 0, 0, 0, 0, 0, 0, 0,
6189};
6190
6191static const Q_UINT16 di_04[] = {
6192 1696, 1701, 0, 1706, 0, 0, 0, 1711,
6193 0, 0, 0, 0, 1716, 1721, 1726, 0,
6194 0, 0, 0, 0, 0, 0, 0, 0,
6195 0, 1731, 0, 0, 0, 0, 0, 0,
6196 0, 0, 0, 0, 0, 0, 0, 0,
6197 0, 0, 0, 0, 0, 0, 0, 0,
6198 0, 0, 0, 0, 0, 0, 0, 0,
6199 0, 1736, 0, 0, 0, 0, 0, 0,
6200 0, 0, 0, 0, 0, 0, 0, 0,
6201 0, 0, 0, 0, 0, 0, 0, 0,
6202 1741, 1746, 0, 1751, 0, 0, 0, 1756,
6203 0, 0, 0, 0, 1761, 1766, 1771, 0,
6204 0, 0, 0, 0, 0, 0, 0, 0,
6205 0, 0, 0, 0, 0, 0, 0, 0,
6206 0, 0, 0, 0, 0, 0, 1776, 1781,
6207 0, 0, 0, 0, 0, 0, 0, 0,
6208 0, 0, 0, 0, 0, 0, 0, 0,
6209 0, 0, 0, 0, 0, 0, 0, 0,
6210 0, 0, 0, 0, 0, 0, 0, 0,
6211 0, 0, 0, 0, 0, 0, 0, 0,
6212 0, 0, 0, 0, 0, 0, 0, 0,
6213 0, 0, 0, 0, 0, 0, 0, 0,
6214 0, 0, 0, 0, 0, 0, 0, 0,
6215 0, 0, 0, 0, 0, 0, 0, 0,
6216 0, 1786, 1791, 0, 0, 0, 0, 0,
6217 0, 0, 0, 0, 0, 0, 0, 0,
6218 1796, 1801, 1806, 1811, 0, 0, 1816, 1821,
6219 0, 0, 1826, 1831, 1836, 1841, 1846, 1851,
6220 0, 0, 1856, 1861, 1866, 1871, 1876, 1881,
6221 0, 0, 1886, 1891, 1896, 1901, 1906, 1911,
6222 1916, 1921, 1926, 1931, 1936, 1941, 0, 0,
6223 1946, 1951, 0, 0, 0, 0, 0, 0,
6224};
6225
6226static const Q_UINT16 di_05[] = {
6227 0, 0, 0, 0, 0, 0, 0, 0,
6228 0, 0, 0, 0, 0, 0, 0, 0,
6229 0, 0, 0, 0, 0, 0, 0, 0,
6230 0, 0, 0, 0, 0, 0, 0, 0,
6231 0, 0, 0, 0, 0, 0, 0, 0,
6232 0, 0, 0, 0, 0, 0, 0, 0,
6233 0, 0, 0, 0, 0, 0, 0, 0,
6234 0, 0, 0, 0, 0, 0, 0, 0,
6235 0, 0, 0, 0, 0, 0, 0, 0,
6236 0, 0, 0, 0, 0, 0, 0, 0,
6237 0, 0, 0, 0, 0, 0, 0, 0,
6238 0, 0, 0, 0, 0, 0, 0, 0,
6239 0, 0, 0, 0, 0, 0, 0, 0,
6240 0, 0, 0, 0, 0, 0, 0, 0,
6241 0, 0, 0, 0, 0, 0, 0, 0,
6242 0, 0, 0, 0, 0, 0, 0, 0,
6243 0, 0, 0, 0, 0, 0, 0, 1956,
6244 0, 0, 0, 0, 0, 0, 0, 0,
6245 0, 0, 0, 0, 0, 0, 0, 0,
6246 0, 0, 0, 0, 0, 0, 0, 0,
6247 0, 0, 0, 0, 0, 0, 0, 0,
6248 0, 0, 0, 0, 0, 0, 0, 0,
6249 0, 0, 0, 0, 0, 0, 0, 0,
6250 0, 0, 0, 0, 0, 0, 0, 0,
6251 0, 0, 0, 0, 0, 0, 0, 0,
6252 0, 0, 0, 0, 0, 0, 0, 0,
6253 0, 0, 0, 0, 0, 0, 0, 0,
6254 0, 0, 0, 0, 0, 0, 0, 0,
6255 0, 0, 0, 0, 0, 0, 0, 0,
6256 0, 0, 0, 0, 0, 0, 0, 0,
6257 0, 0, 0, 0, 0, 0, 0, 0,
6258 0, 0, 0, 0, 0, 0, 0, 0,
6259};
6260
6261static const Q_UINT16 di_06[] = {
6262 0, 0, 0, 0, 0, 0, 0, 0,
6263 0, 0, 0, 0, 0, 0, 0, 0,
6264 0, 0, 0, 0, 0, 0, 0, 0,
6265 0, 0, 0, 0, 0, 0, 0, 0,
6266 0, 0, 1961, 1966, 1971, 1976, 1981, 0,
6267 0, 0, 0, 0, 0, 0, 0, 0,
6268 0, 0, 0, 0, 0, 0, 0, 0,
6269 0, 0, 0, 0, 0, 0, 0, 0,
6270 0, 0, 0, 0, 0, 0, 0, 0,
6271 0, 0, 0, 0, 0, 0, 0, 0,
6272 0, 0, 0, 0, 0, 0, 0, 0,
6273 0, 0, 0, 0, 0, 0, 0, 0,
6274 0, 0, 0, 0, 0, 0, 0, 0,
6275 0, 0, 0, 0, 0, 0, 0, 0,
6276 0, 0, 0, 0, 0, 1986, 1991, 1996,
6277 2001, 0, 0, 0, 0, 0, 0, 0,
6278 0, 0, 0, 0, 0, 0, 0, 0,
6279 0, 0, 0, 0, 0, 0, 0, 0,
6280 0, 0, 0, 0, 0, 0, 0, 0,
6281 0, 0, 0, 0, 0, 0, 0, 0,
6282 0, 0, 0, 0, 0, 0, 0, 0,
6283 0, 0, 0, 0, 0, 0, 0, 0,
6284 0, 0, 0, 0, 0, 0, 0, 0,
6285 0, 0, 0, 0, 0, 0, 0, 0,
6286 2006, 0, 2011, 0, 0, 0, 0, 0,
6287 0, 0, 0, 0, 0, 0, 0, 0,
6288 0, 0, 0, 2016, 0, 0, 0, 0,
6289 0, 0, 0, 0, 0, 0, 0, 0,
6290 0, 0, 0, 0, 0, 0, 0, 0,
6291 0, 0, 0, 0, 0, 0, 0, 0,
6292 0, 0, 0, 0, 0, 0, 0, 0,
6293 0, 0, 0, 0, 0, 0, 0, 0,
6294};
6295
6296static const Q_UINT16 di_07[] = {
6297 0, 0, 0, 0, 0, 0, 0, 0,
6298 0, 0, 0, 0, 0, 0, 0, 0,
6299 0, 0, 0, 0, 0, 0, 0, 0,
6300 0, 0, 0, 0, 0, 0, 0, 0,
6301 0, 0, 0, 0, 0, 0, 0, 0,
6302 0, 0, 0, 0, 0, 0, 0, 0,
6303 0, 0, 0, 0, 0, 0, 0, 0,
6304 0, 0, 0, 0, 0, 0, 0, 0,
6305 0, 0, 0, 0, 0, 0, 0, 0,
6306 0, 0, 0, 0, 0, 0, 0, 0,
6307 0, 0, 0, 0, 0, 0, 0, 0,
6308 0, 0, 0, 0, 0, 0, 0, 0,
6309 0, 0, 0, 0, 0, 0, 0, 0,
6310 0, 0, 0, 0, 0, 0, 0, 0,
6311 0, 0, 0, 0, 0, 0, 0, 0,
6312 0, 0, 0, 0, 0, 0, 0, 0,
6313 0, 0, 0, 0, 0, 0, 0, 0,
6314 0, 0, 0, 0, 0, 0, 0, 0,
6315 0, 0, 0, 0, 0, 0, 0, 0,
6316 0, 0, 0, 0, 0, 0, 0, 0,
6317 0, 0, 0, 0, 0, 0, 0, 0,
6318 0, 0, 0, 0, 0, 0, 0, 0,
6319 0, 0, 0, 0, 0, 0, 0, 0,
6320 0, 0, 0, 0, 0, 0, 0, 0,
6321 0, 0, 0, 0, 0, 0, 0, 0,
6322 0, 0, 0, 0, 0, 0, 0, 0,
6323 0, 0, 0, 0, 0, 0, 0, 0,
6324 0, 0, 0, 0, 0, 0, 0, 0,
6325 0, 0, 0, 0, 0, 0, 0, 0,
6326 0, 0, 0, 0, 0, 0, 0, 0,
6327 0, 0, 0, 0, 0, 0, 0, 0,
6328 0, 0, 0, 0, 0, 0, 0, 0,
6329};
6330
6331static const Q_UINT16 di_09[] = {
6332 0, 0, 0, 0, 0, 0, 0, 0,
6333 0, 0, 0, 0, 0, 0, 0, 0,
6334 0, 0, 0, 0, 0, 0, 0, 0,
6335 0, 0, 0, 0, 0, 0, 0, 0,
6336 0, 0, 0, 0, 0, 0, 0, 0,
6337 0, 2021, 0, 0, 0, 0, 0, 0,
6338 0, 2026, 0, 0, 2031, 0, 0, 0,
6339 0, 0, 0, 0, 0, 0, 0, 0,
6340 0, 0, 0, 0, 0, 0, 0, 0,
6341 0, 0, 0, 0, 0, 0, 0, 0,
6342 0, 0, 0, 0, 0, 0, 0, 0,
6343 2036, 2041, 2046, 2051, 2056, 2061, 2066, 2071,
6344 0, 0, 0, 0, 0, 0, 0, 0,
6345 0, 0, 0, 0, 0, 0, 0, 0,
6346 0, 0, 0, 0, 0, 0, 0, 0,
6347 0, 0, 0, 0, 0, 0, 0, 0,
6348 0, 0, 0, 0, 0, 0, 0, 0,
6349 0, 0, 0, 0, 0, 0, 0, 0,
6350 0, 0, 0, 0, 0, 0, 0, 0,
6351 0, 0, 0, 0, 0, 0, 0, 0,
6352 0, 0, 0, 0, 0, 0, 0, 0,
6353 0, 0, 0, 0, 0, 0, 0, 0,
6354 0, 0, 0, 0, 0, 0, 0, 0,
6355 0, 0, 0, 0, 0, 0, 0, 0,
6356 0, 0, 0, 0, 0, 0, 0, 0,
6357 0, 0, 0, 2076, 2081, 0, 0, 0,
6358 0, 0, 0, 0, 0, 0, 0, 0,
6359 0, 0, 0, 0, 2086, 2091, 0, 2096,
6360 0, 0, 0, 0, 0, 0, 0, 0,
6361 0, 0, 0, 0, 0, 0, 0, 0,
6362 0, 0, 0, 0, 0, 0, 0, 0,
6363 0, 0, 0, 0, 0, 0, 0, 0,
6364};
6365
6366static const Q_UINT16 di_0A[] = {
6367 0, 0, 0, 0, 0, 0, 0, 0,
6368 0, 0, 0, 0, 0, 0, 0, 0,
6369 0, 0, 0, 0, 0, 0, 0, 0,
6370 0, 0, 0, 0, 0, 0, 0, 0,
6371 0, 0, 0, 0, 0, 0, 0, 0,
6372 0, 0, 0, 0, 0, 0, 0, 0,
6373 0, 0, 0, 2101, 0, 0, 2106, 0,
6374 0, 0, 0, 0, 0, 0, 0, 0,
6375 0, 0, 0, 0, 0, 0, 0, 0,
6376 0, 0, 0, 0, 0, 0, 0, 0,
6377 0, 0, 0, 0, 0, 0, 0, 0,
6378 0, 2111, 2116, 2121, 0, 0, 2126, 0,
6379 0, 0, 0, 0, 0, 0, 0, 0,
6380 0, 0, 0, 0, 0, 0, 0, 0,
6381 0, 0, 0, 0, 0, 0, 0, 0,
6382 0, 0, 0, 0, 0, 0, 0, 0,
6383 0, 0, 0, 0, 0, 0, 0, 0,
6384 0, 0, 0, 0, 0, 0, 0, 0,
6385 0, 0, 0, 0, 0, 0, 0, 0,
6386 0, 0, 0, 0, 0, 0, 0, 0,
6387 0, 0, 0, 0, 0, 0, 0, 0,
6388 0, 0, 0, 0, 0, 0, 0, 0,
6389 0, 0, 0, 0, 0, 0, 0, 0,
6390 0, 0, 0, 0, 0, 0, 0, 0,
6391 0, 0, 0, 0, 0, 0, 0, 0,
6392 0, 0, 0, 0, 0, 0, 0, 0,
6393 0, 0, 0, 0, 0, 0, 0, 0,
6394 0, 0, 0, 0, 0, 0, 0, 0,
6395 0, 0, 0, 0, 0, 0, 0, 0,
6396 0, 0, 0, 0, 0, 0, 0, 0,
6397 0, 0, 0, 0, 0, 0, 0, 0,
6398 0, 0, 0, 0, 0, 0, 0, 0,
6399};
6400
6401static const Q_UINT16 di_0B[] = {
6402 0, 0, 0, 0, 0, 0, 0, 0,
6403 0, 0, 0, 0, 0, 0, 0, 0,
6404 0, 0, 0, 0, 0, 0, 0, 0,
6405 0, 0, 0, 0, 0, 0, 0, 0,
6406 0, 0, 0, 0, 0, 0, 0, 0,
6407 0, 0, 0, 0, 0, 0, 0, 0,
6408 0, 0, 0, 0, 0, 0, 0, 0,
6409 0, 0, 0, 0, 0, 0, 0, 0,
6410 0, 0, 0, 0, 0, 0, 0, 0,
6411 2131, 0, 0, 2136, 2141, 0, 0, 0,
6412 0, 0, 0, 0, 0, 0, 0, 0,
6413 0, 0, 0, 0, 2146, 2151, 0, 0,
6414 0, 0, 0, 0, 0, 0, 0, 0,
6415 0, 0, 0, 0, 0, 0, 0, 0,
6416 0, 0, 0, 0, 0, 0, 0, 0,
6417 0, 0, 0, 0, 0, 0, 0, 0,
6418 0, 0, 0, 0, 0, 0, 0, 0,
6419 0, 0, 0, 0, 0, 0, 0, 0,
6420 0, 0, 0, 0, 2156, 0, 0, 0,
6421 0, 0, 0, 0, 0, 0, 0, 0,
6422 0, 0, 0, 0, 0, 0, 0, 0,
6423 0, 0, 0, 0, 0, 0, 0, 0,
6424 0, 0, 0, 0, 0, 0, 0, 0,
6425 0, 0, 0, 0, 0, 0, 0, 0,
6426 0, 0, 0, 0, 0, 0, 0, 0,
6427 0, 0, 2161, 2166, 2171, 0, 0, 0,
6428 0, 0, 0, 0, 0, 0, 0, 0,
6429 0, 0, 0, 0, 0, 0, 0, 0,
6430 0, 0, 0, 0, 0, 0, 0, 0,
6431 0, 0, 0, 0, 0, 0, 0, 0,
6432 0, 0, 0, 0, 0, 0, 0, 0,
6433 0, 0, 0, 0, 0, 0, 0, 0,
6434};
6435
6436static const Q_UINT16 di_0C[] = {
6437 0, 0, 0, 0, 0, 0, 0, 0,
6438 0, 0, 0, 0, 0, 0, 0, 0,
6439 0, 0, 0, 0, 0, 0, 0, 0,
6440 0, 0, 0, 0, 0, 0, 0, 0,
6441 0, 0, 0, 0, 0, 0, 0, 0,
6442 0, 0, 0, 0, 0, 0, 0, 0,
6443 0, 0, 0, 0, 0, 0, 0, 0,
6444 0, 0, 0, 0, 0, 0, 0, 0,
6445 0, 0, 0, 0, 0, 0, 0, 0,
6446 2176, 0, 0, 0, 0, 0, 0, 0,
6447 0, 0, 0, 0, 0, 0, 0, 0,
6448 0, 0, 0, 0, 0, 0, 0, 0,
6449 0, 0, 0, 0, 0, 0, 0, 0,
6450 0, 0, 0, 0, 0, 0, 0, 0,
6451 0, 0, 0, 0, 0, 0, 0, 0,
6452 0, 0, 0, 0, 0, 0, 0, 0,
6453 0, 0, 0, 0, 0, 0, 0, 0,
6454 0, 0, 0, 0, 0, 0, 0, 0,
6455 0, 0, 0, 0, 0, 0, 0, 0,
6456 0, 0, 0, 0, 0, 0, 0, 0,
6457 0, 0, 0, 0, 0, 0, 0, 0,
6458 0, 0, 0, 0, 0, 0, 0, 0,
6459 0, 0, 0, 0, 0, 0, 0, 0,
6460 0, 0, 0, 0, 0, 0, 0, 0,
6461 2181, 0, 0, 0, 0, 0, 0, 2186,
6462 2191, 0, 2196, 2201, 0, 0, 0, 0,
6463 0, 0, 0, 0, 0, 0, 0, 0,
6464 0, 0, 0, 0, 0, 0, 0, 0,
6465 0, 0, 0, 0, 0, 0, 0, 0,
6466 0, 0, 0, 0, 0, 0, 0, 0,
6467 0, 0, 0, 0, 0, 0, 0, 0,
6468 0, 0, 0, 0, 0, 0, 0, 0,
6469};
6470
6471static const Q_UINT16 di_0D[] = {
6472 0, 0, 0, 0, 0, 0, 0, 0,
6473 0, 0, 0, 0, 0, 0, 0, 0,
6474 0, 0, 0, 0, 0, 0, 0, 0,
6475 0, 0, 0, 0, 0, 0, 0, 0,
6476 0, 0, 0, 0, 0, 0, 0, 0,
6477 0, 0, 0, 0, 0, 0, 0, 0,
6478 0, 0, 0, 0, 0, 0, 0, 0,
6479 0, 0, 0, 0, 0, 0, 0, 0,
6480 0, 0, 0, 0, 0, 0, 0, 0,
6481 0, 0, 2206, 2211, 2216, 0, 0, 0,
6482 0, 0, 0, 0, 0, 0, 0, 0,
6483 0, 0, 0, 0, 0, 0, 0, 0,
6484 0, 0, 0, 0, 0, 0, 0, 0,
6485 0, 0, 0, 0, 0, 0, 0, 0,
6486 0, 0, 0, 0, 0, 0, 0, 0,
6487 0, 0, 0, 0, 0, 0, 0, 0,
6488 0, 0, 0, 0, 0, 0, 0, 0,
6489 0, 0, 0, 0, 0, 0, 0, 0,
6490 0, 0, 0, 0, 0, 0, 0, 0,
6491 0, 0, 0, 0, 0, 0, 0, 0,
6492 0, 0, 0, 0, 0, 0, 0, 0,
6493 0, 0, 0, 0, 0, 0, 0, 0,
6494 0, 0, 0, 0, 0, 0, 0, 0,
6495 0, 0, 0, 0, 0, 0, 0, 0,
6496 0, 0, 0, 0, 0, 0, 0, 0,
6497 0, 0, 0, 0, 0, 0, 0, 0,
6498 0, 0, 0, 0, 0, 0, 0, 0,
6499 0, 0, 2221, 0, 2226, 2231, 2236, 0,
6500 0, 0, 0, 0, 0, 0, 0, 0,
6501 0, 0, 0, 0, 0, 0, 0, 0,
6502 0, 0, 0, 0, 0, 0, 0, 0,
6503 0, 0, 0, 0, 0, 0, 0, 0,
6504};
6505
6506static const Q_UINT16 di_0E[] = {
6507 0, 0, 0, 0, 0, 0, 0, 0,
6508 0, 0, 0, 0, 0, 0, 0, 0,
6509 0, 0, 0, 0, 0, 0, 0, 0,
6510 0, 0, 0, 0, 0, 0, 0, 0,
6511 0, 0, 0, 0, 0, 0, 0, 0,
6512 0, 0, 0, 0, 0, 0, 0, 0,
6513 0, 0, 0, 2241, 0, 0, 0, 0,
6514 0, 0, 0, 0, 0, 0, 0, 0,
6515 0, 0, 0, 0, 0, 0, 0, 0,
6516 0, 0, 0, 0, 0, 0, 0, 0,
6517 0, 0, 0, 0, 0, 0, 0, 0,
6518 0, 0, 0, 0, 0, 0, 0, 0,
6519 0, 0, 0, 0, 0, 0, 0, 0,
6520 0, 0, 0, 0, 0, 0, 0, 0,
6521 0, 0, 0, 0, 0, 0, 0, 0,
6522 0, 0, 0, 0, 0, 0, 0, 0,
6523 0, 0, 0, 0, 0, 0, 0, 0,
6524 0, 0, 0, 0, 0, 0, 0, 0,
6525 0, 0, 0, 0, 0, 0, 0, 0,
6526 0, 0, 0, 0, 0, 0, 0, 0,
6527 0, 0, 0, 0, 0, 0, 0, 0,
6528 0, 0, 0, 0, 0, 0, 0, 0,
6529 0, 0, 0, 2246, 0, 0, 0, 0,
6530 0, 0, 0, 0, 0, 0, 0, 0,
6531 0, 0, 0, 0, 0, 0, 0, 0,
6532 0, 0, 0, 0, 0, 0, 0, 0,
6533 0, 0, 0, 0, 0, 0, 0, 0,
6534 0, 0, 0, 0, 2251, 2256, 0, 0,
6535 0, 0, 0, 0, 0, 0, 0, 0,
6536 0, 0, 0, 0, 0, 0, 0, 0,
6537 0, 0, 0, 0, 0, 0, 0, 0,
6538 0, 0, 0, 0, 0, 0, 0, 0,
6539};
6540
6541static const Q_UINT16 di_0F[] = {
6542 0, 0, 0, 0, 0, 0, 0, 0,
6543 0, 0, 0, 0, 2261, 0, 0, 0,
6544 0, 0, 0, 0, 0, 0, 0, 0,
6545 0, 0, 0, 0, 0, 0, 0, 0,
6546 0, 0, 0, 0, 0, 0, 0, 0,
6547 0, 0, 0, 0, 0, 0, 0, 0,
6548 0, 0, 0, 0, 0, 0, 0, 0,
6549 0, 0, 0, 0, 0, 0, 0, 0,
6550 0, 0, 0, 2265, 0, 0, 0, 0,
6551 0, 0, 0, 0, 0, 2270, 0, 0,
6552 0, 0, 2275, 0, 0, 0, 0, 2280,
6553 0, 0, 0, 0, 2285, 0, 0, 0,
6554 0, 0, 0, 0, 0, 0, 0, 0,
6555 0, 2290, 0, 0, 0, 0, 0, 0,
6556 0, 0, 0, 2295, 0, 2300, 2305, 2310,
6557 2315, 2320, 0, 0, 0, 0, 0, 0,
6558 0, 2325, 0, 0, 0, 0, 0, 0,
6559 0, 0, 0, 0, 0, 0, 0, 0,
6560 0, 0, 0, 2330, 0, 0, 0, 0,
6561 0, 0, 0, 0, 0, 2335, 0, 0,
6562 0, 0, 2340, 0, 0, 0, 0, 2345,
6563 0, 0, 0, 0, 2350, 0, 0, 0,
6564 0, 0, 0, 0, 0, 0, 0, 0,
6565 0, 2355, 0, 0, 0, 0, 0, 0,
6566 0, 0, 0, 0, 0, 0, 0, 0,
6567 0, 0, 0, 0, 0, 0, 0, 0,
6568 0, 0, 0, 0, 0, 0, 0, 0,
6569 0, 0, 0, 0, 0, 0, 0, 0,
6570 0, 0, 0, 0, 0, 0, 0, 0,
6571 0, 0, 0, 0, 0, 0, 0, 0,
6572 0, 0, 0, 0, 0, 0, 0, 0,
6573 0, 0, 0, 0, 0, 0, 0, 0,
6574};
6575
6576static const Q_UINT16 di_10[] = {
6577 0, 0, 0, 0, 0, 0, 0, 0,
6578 0, 0, 0, 0, 0, 0, 0, 0,
6579 0, 0, 0, 0, 0, 0, 0, 0,
6580 0, 0, 0, 0, 0, 0, 0, 0,
6581 0, 0, 0, 0, 0, 0, 2360, 0,
6582 0, 0, 0, 0, 0, 0, 0, 0,
6583 0, 0, 0, 0, 0, 0, 0, 0,
6584 0, 0, 0, 0, 0, 0, 0, 0,
6585 0, 0, 0, 0, 0, 0, 0, 0,
6586 0, 0, 0, 0, 0, 0, 0, 0,
6587 0, 0, 0, 0, 0, 0, 0, 0,
6588 0, 0, 0, 0, 0, 0, 0, 0,
6589 0, 0, 0, 0, 0, 0, 0, 0,
6590 0, 0, 0, 0, 0, 0, 0, 0,
6591 0, 0, 0, 0, 0, 0, 0, 0,
6592 0, 0, 0, 0, 0, 0, 0, 0,
6593 0, 0, 0, 0, 0, 0, 0, 0,
6594 0, 0, 0, 0, 0, 0, 0, 0,
6595 0, 0, 0, 0, 0, 0, 0, 0,
6596 0, 0, 0, 0, 0, 0, 0, 0,
6597 0, 0, 0, 0, 0, 0, 0, 0,
6598 0, 0, 0, 0, 0, 0, 0, 0,
6599 0, 0, 0, 0, 0, 0, 0, 0,
6600 0, 0, 0, 0, 0, 0, 0, 0,
6601 0, 0, 0, 0, 0, 0, 0, 0,
6602 0, 0, 0, 0, 0, 0, 0, 0,
6603 0, 0, 0, 0, 0, 0, 0, 0,
6604 0, 0, 0, 0, 0, 0, 0, 0,
6605 0, 0, 0, 0, 0, 0, 0, 0,
6606 0, 0, 0, 0, 0, 0, 0, 0,
6607 0, 0, 0, 0, 0, 0, 0, 0,
6608 0, 0, 0, 0, 0, 0, 0, 0,
6609};
6610
6611static const Q_UINT16 di_1E[] = {
6612 2365, 2370, 2375, 2380, 2385, 2390, 2395, 2400,
6613 2405, 2410, 2415, 2420, 2425, 2430, 2435, 2440,
6614 2445, 2450, 2455, 2460, 2465, 2470, 2475, 2480,
6615 2485, 2490, 2495, 2500, 2505, 2510, 2515, 2520,
6616 2525, 2530, 2535, 2540, 2545, 2550, 2555, 2560,
6617 2565, 2570, 2575, 2580, 2585, 2590, 2595, 2600,
6618 2605, 2610, 2615, 2620, 2625, 2630, 2635, 2640,
6619 2645, 2650, 2655, 2660, 2665, 2670, 2675, 2680,
6620 2685, 2690, 2695, 2700, 2705, 2710, 2715, 2720,
6621 2725, 2730, 2735, 2740, 2745, 2750, 2755, 2760,
6622 2765, 2770, 2775, 2780, 2785, 2790, 2795, 2800,
6623 2805, 2810, 2815, 2820, 2825, 2830, 2835, 2840,
6624 2845, 2850, 2855, 2860, 2865, 2870, 2875, 2880,
6625 2885, 2890, 2895, 2900, 2905, 2910, 2915, 2920,
6626 2925, 2930, 2935, 2940, 2945, 2950, 2955, 2960,
6627 2965, 2970, 2975, 2980, 2985, 2990, 2995, 3000,
6628 3005, 3010, 3015, 3020, 3025, 3030, 3035, 3040,
6629 3045, 3050, 3055, 3060, 3065, 3070, 3075, 3080,
6630 3085, 3090, 3095, 3100, 3105, 3110, 3115, 3120,
6631 3125, 3130, 3135, 3140, 0, 0, 0, 0,
6632 3145, 3150, 3155, 3160, 3165, 3170, 3175, 3180,
6633 3185, 3190, 3195, 3200, 3205, 3210, 3215, 3220,
6634 3225, 3230, 3235, 3240, 3245, 3250, 3255, 3260,
6635 3265, 3270, 3275, 3280, 3285, 3290, 3295, 3300,
6636 3305, 3310, 3315, 3320, 3325, 3330, 3335, 3340,
6637 3345, 3350, 3355, 3360, 3365, 3370, 3375, 3380,
6638 3385, 3390, 3395, 3400, 3405, 3410, 3415, 3420,
6639 3425, 3430, 3435, 3440, 3445, 3450, 3455, 3460,
6640 3465, 3470, 3475, 3480, 3485, 3490, 3495, 3500,
6641 3505, 3510, 3515, 3520, 3525, 3530, 3535, 3540,
6642 3545, 3550, 3555, 3560, 3565, 3570, 3575, 3580,
6643 3585, 3590, 0, 0, 0, 0, 0, 0,
6644};
6645
6646static const Q_UINT16 di_1F[] = {
6647 3595, 3600, 3605, 3610, 3615, 3620, 3625, 3630,
6648 3635, 3640, 3645, 3650, 3655, 3660, 3665, 3670,
6649 3675, 3680, 3685, 3690, 3695, 3700, 0, 0,
6650 3705, 3710, 3715, 3720, 3725, 3730, 0, 0,
6651 3735, 3740, 3745, 3750, 3755, 3760, 3765, 3770,
6652 3775, 3780, 3785, 3790, 3795, 3800, 3805, 3810,
6653 3815, 3820, 3825, 3830, 3835, 3840, 3845, 3850,
6654 3855, 3860, 3865, 3870, 3875, 3880, 3885, 3890,
6655 3895, 3900, 3905, 3910, 3915, 3920, 0, 0,
6656 3925, 3930, 3935, 3940, 3945, 3950, 0, 0,
6657 3955, 3960, 3965, 3970, 3975, 3980, 3985, 3990,
6658 0, 3995, 0, 4000, 0, 4005, 0, 4010,
6659 4015, 4020, 4025, 4030, 4035, 4040, 4045, 4050,
6660 4055, 4060, 4065, 4070, 4075, 4080, 4085, 4090,
6661 4095, 4100, 4104, 4109, 4113, 4118, 4122, 4127,
6662 4131, 4136, 4140, 4145, 4149, 4154, 0, 0,
6663 4158, 4163, 4168, 4173, 4178, 4183, 4188, 4193,
6664 4198, 4203, 4208, 4213, 4218, 4223, 4228, 4233,
6665 4238, 4243, 4248, 4253, 4258, 4263, 4268, 4273,
6666 4278, 4283, 4288, 4293, 4298, 4303, 4308, 4313,
6667 4318, 4323, 4328, 4333, 4338, 4343, 4348, 4353,
6668 4358, 4363, 4368, 4373, 4378, 4383, 4388, 4393,
6669 4398, 4403, 4408, 4413, 4418, 0, 4423, 4428,
6670 4433, 4438, 4443, 4448, 4452, 4457, 4462, 4466,
6671 4471, 4476, 4481, 4486, 4491, 0, 4496, 4501,
6672 4506, 4511, 4515, 4520, 4524, 4529, 4534, 4539,
6673 4544, 4549, 4554, 4559, 0, 0, 4563, 4568,
6674 4573, 4578, 4583, 4588, 0, 4592, 4597, 4602,
6675 4607, 4612, 4617, 4622, 4626, 4631, 4636, 4641,
6676 4646, 4651, 4656, 4661, 4665, 4670, 4675, 4679,
6677 0, 0, 4683, 4688, 4693, 0, 4698, 4703,
6678 4708, 4713, 4717, 4722, 4726, 4731, 4735, 0,
6679};
6680
6681static const Q_UINT16 di_20[] = {
6682 4740, 4744, 4748, 4752, 4756, 4760, 4764, 4768,
6683 4772, 4776, 4780, 0, 0, 0, 0, 0,
6684 0, 4784, 0, 0, 0, 0, 0, 4788,
6685 0, 0, 0, 0, 0, 0, 0, 0,
6686 0, 0, 0, 0, 4793, 4797, 4802, 0,
6687 0, 0, 0, 0, 0, 0, 0, 4808,
6688 0, 0, 0, 4812, 4817, 0, 4823, 4828,
6689 0, 0, 0, 0, 4834, 0, 4839, 0,
6690 0, 0, 0, 0, 0, 0, 0, 4844,
6691 4849, 4854, 0, 0, 0, 0, 0, 0,
6692 0, 0, 0, 0, 0, 0, 0, 4859,
6693 0, 0, 0, 0, 0, 0, 0, 4866,
6694 0, 0, 0, 0, 0, 0, 0, 0,
6695 0, 0, 0, 0, 0, 0, 0, 0,
6696 4870, 4874, 0, 0, 4878, 4882, 4886, 4890,
6697 4894, 4898, 4902, 4906, 4910, 4914, 4918, 4922,
6698 4926, 4930, 4934, 4938, 4942, 4946, 4950, 4954,
6699 4958, 4962, 4966, 4970, 4974, 4978, 4982, 0,
6700 0, 0, 0, 0, 0, 0, 0, 0,
6701 0, 0, 0, 0, 0, 0, 0, 0,
6702 0, 0, 0, 0, 0, 0, 0, 0,
6703 4986, 0, 0, 0, 0, 0, 0, 0,
6704 0, 0, 0, 0, 0, 0, 0, 0,
6705 0, 0, 0, 0, 0, 0, 0, 0,
6706 0, 0, 0, 0, 0, 0, 0, 0,
6707 0, 0, 0, 0, 0, 0, 0, 0,
6708 0, 0, 0, 0, 0, 0, 0, 0,
6709 0, 0, 0, 0, 0, 0, 0, 0,
6710 0, 0, 0, 0, 0, 0, 0, 0,
6711 0, 0, 0, 0, 0, 0, 0, 0,
6712 0, 0, 0, 0, 0, 0, 0, 0,
6713 0, 0, 0, 0, 0, 0, 0, 0,
6714};
6715
6716static const Q_UINT16 di_21[] = {
6717 4991, 4997, 5003, 5007, 0, 5012, 5018, 5024,
6718 0, 5028, 5033, 5037, 5041, 5045, 5049, 5053,
6719 5057, 5061, 5065, 5069, 0, 5073, 5077, 0,
6720 0, 5082, 5086, 5090, 5094, 5098, 0, 0,
6721 5102, 5107, 5113, 0, 5118, 0, 5122, 0,
6722 5126, 0, 5130, 5134, 5138, 5142, 0, 5146,
6723 5150, 5154, 0, 5158, 5162, 5166, 5170, 5174,
6724 5178, 5182, 0, 0, 0, 5186, 5190, 5194,
6725 5198, 0, 0, 0, 0, 5202, 5206, 5210,
6726 5214, 5218, 0, 0, 0, 0, 0, 0,
6727 0, 0, 0, 5222, 5228, 5234, 5240, 5246,
6728 5252, 5258, 5264, 5270, 5276, 5282, 5288, 5294,
6729 5299, 5303, 5308, 5314, 5319, 5323, 5328, 5334,
6730 5341, 5346, 5350, 5355, 5361, 5365, 5369, 5373,
6731 5377, 5381, 5386, 5392, 5397, 5401, 5406, 5412,
6732 5419, 5424, 5428, 5433, 5439, 5443, 5447, 5451,
6733 0, 0, 0, 0, 0, 0, 0, 0,
6734 0, 0, 0, 0, 0, 0, 0, 0,
6735 0, 0, 0, 0, 0, 0, 0, 0,
6736 0, 0, 5455, 5460, 0, 0, 0, 0,
6737 0, 0, 0, 0, 0, 0, 0, 0,
6738 0, 0, 0, 0, 0, 0, 5465, 0,
6739 0, 0, 0, 0, 0, 0, 0, 0,
6740 0, 0, 0, 0, 0, 0, 0, 0,
6741 0, 0, 0, 0, 0, 0, 0, 0,
6742 0, 0, 0, 0, 0, 5470, 5475, 5480,
6743 0, 0, 0, 0, 0, 0, 0, 0,
6744 0, 0, 0, 0, 0, 0, 0, 0,
6745 0, 0, 0, 0, 0, 0, 0, 0,
6746 0, 0, 0, 0, 0, 0, 0, 0,
6747 0, 0, 0, 0, 0, 0, 0, 0,
6748 0, 0, 0, 0, 0, 0, 0, 0,
6749};
6750
6751static const Q_UINT16 di_22[] = {
6752 0, 0, 0, 0, 5485, 0, 0, 0,
6753 0, 5490, 0, 0, 5495, 0, 0, 0,
6754 0, 0, 0, 0, 0, 0, 0, 0,
6755 0, 0, 0, 0, 0, 0, 0, 0,
6756 0, 0, 0, 0, 5500, 0, 5505, 0,
6757 0, 0, 0, 0, 5510, 5515, 0, 5521,
6758 5526, 0, 0, 0, 0, 0, 0, 0,
6759 0, 0, 0, 0, 0, 0, 0, 0,
6760 0, 5532, 0, 0, 5537, 0, 0, 5542,
6761 0, 5547, 0, 0, 0, 0, 0, 0,
6762 0, 0, 0, 0, 0, 0, 0, 0,
6763 0, 0, 0, 0, 0, 0, 0, 0,
6764 5552, 0, 5557, 0, 0, 0, 0, 0,
6765 0, 0, 0, 0, 0, 5562, 5567, 5572,
6766 5577, 5582, 0, 0, 5587, 5592, 0, 0,
6767 5597, 5602, 0, 0, 0, 0, 0, 0,
6768 5607, 5612, 0, 0, 5617, 5622, 0, 0,
6769 5627, 5632, 0, 0, 0, 0, 0, 0,
6770 0, 0, 0, 0, 0, 0, 0, 0,
6771 0, 0, 0, 0, 0, 0, 0, 0,
6772 0, 0, 0, 0, 0, 0, 0, 0,
6773 0, 0, 0, 0, 5637, 5642, 5647, 5652,
6774 0, 0, 0, 0, 0, 0, 0, 0,
6775 0, 0, 0, 0, 0, 0, 0, 0,
6776 0, 0, 0, 0, 0, 0, 0, 0,
6777 0, 0, 0, 0, 0, 0, 0, 0,
6778 0, 0, 0, 0, 0, 0, 0, 0,
6779 0, 0, 0, 0, 0, 0, 0, 0,
6780 5657, 5662, 5667, 5672, 0, 0, 0, 0,
6781 0, 0, 5677, 5682, 5687, 5692, 0, 0,
6782 0, 0, 0, 0, 0, 0, 0, 0,
6783 0, 0, 0, 0, 0, 0, 0, 0,
6784};
6785
6786static const Q_UINT16 di_23[] = {
6787 0, 0, 0, 0, 0, 0, 0, 0,
6788 0, 0, 0, 0, 0, 0, 0, 0,
6789 0, 0, 0, 0, 0, 0, 0, 0,
6790 0, 0, 0, 0, 0, 0, 0, 0,
6791 0, 0, 0, 0, 0, 0, 0, 0,
6792 0, 5697, 5701, 0, 0, 0, 0, 0,
6793 0, 0, 0, 0, 0, 0, 0, 0,
6794 0, 0, 0, 0, 0, 0, 0, 0,
6795 0, 0, 0, 0, 0, 0, 0, 0,
6796 0, 0, 0, 0, 0, 0, 0, 0,
6797 0, 0, 0, 0, 0, 0, 0, 0,
6798 0, 0, 0, 0, 0, 0, 0, 0,
6799 0, 0, 0, 0, 0, 0, 0, 0,
6800 0, 0, 0, 0, 0, 0, 0, 0,
6801 0, 0, 0, 0, 0, 0, 0, 0,
6802 0, 0, 0, 0, 0, 0, 0, 0,
6803 0, 0, 0, 0, 0, 0, 0, 0,
6804 0, 0, 0, 0, 0, 0, 0, 0,
6805 0, 0, 0, 0, 0, 0, 0, 0,
6806 0, 0, 0, 0, 0, 0, 0, 0,
6807 0, 0, 0, 0, 0, 0, 0, 0,
6808 0, 0, 0, 0, 0, 0, 0, 0,
6809 0, 0, 0, 0, 0, 0, 0, 0,
6810 0, 0, 0, 0, 0, 0, 0, 0,
6811 0, 0, 0, 0, 0, 0, 0, 0,
6812 0, 0, 0, 0, 0, 0, 0, 0,
6813 0, 0, 0, 0, 0, 0, 0, 0,
6814 0, 0, 0, 0, 0, 0, 0, 0,
6815 0, 0, 0, 0, 0, 0, 0, 0,
6816 0, 0, 0, 0, 0, 0, 0, 0,
6817 0, 0, 0, 0, 0, 0, 0, 0,
6818 0, 0, 0, 0, 0, 0, 0, 0,
6819};
6820
6821static const Q_UINT16 di_24[] = {
6822 0, 0, 0, 0, 0, 0, 0, 0,
6823 0, 0, 0, 0, 0, 0, 0, 0,
6824 0, 0, 0, 0, 0, 0, 0, 0,
6825 0, 0, 0, 0, 0, 0, 0, 0,
6826 0, 0, 0, 0, 0, 0, 0, 0,
6827 0, 0, 0, 0, 0, 0, 0, 0,
6828 0, 0, 0, 0, 0, 0, 0, 0,
6829 0, 0, 0, 0, 0, 0, 0, 0,
6830 0, 0, 0, 0, 0, 0, 0, 0,
6831 0, 0, 0, 0, 0, 0, 0, 0,
6832 0, 0, 0, 0, 0, 0, 0, 0,
6833 0, 0, 0, 0, 0, 0, 0, 0,
6834 5705, 5709, 5713, 5717, 5721, 5725, 5729, 5733,
6835 5737, 5741, 5746, 5751, 5756, 5761, 5766, 5771,
6836 5776, 5781, 5786, 5791, 5796, 5802, 5808, 5814,
6837 5820, 5826, 5832, 5838, 5844, 5850, 5857, 5864,
6838 5871, 5878, 5885, 5892, 5899, 5906, 5913, 5920,
6839 5927, 5932, 5937, 5942, 5947, 5952, 5957, 5962,
6840 5967, 5972, 5978, 5984, 5990, 5996, 6002, 6008,
6841 6014, 6020, 6026, 6032, 6038, 6044, 6050, 6056,
6842 6062, 6068, 6074, 6080, 6086, 6092, 6098, 6104,
6843 6110, 6116, 6122, 6128, 6134, 6140, 6146, 6152,
6844 6158, 6164, 6170, 6176, 6182, 6188, 6194, 6198,
6845 6202, 6206, 6210, 6214, 6218, 6222, 6226, 6230,
6846 6234, 6238, 6242, 6246, 6250, 6254, 6258, 6262,
6847 6266, 6270, 6274, 6278, 6282, 6286, 6290, 6294,
6848 6298, 6302, 6306, 6310, 6314, 6318, 6322, 6326,
6849 6330, 6334, 6338, 6342, 6346, 6350, 6354, 6358,
6850 6362, 6366, 6370, 6374, 6378, 6382, 6386, 6390,
6851 6394, 6398, 6402, 0, 0, 0, 0, 0,
6852 0, 0, 0, 0, 0, 0, 0, 0,
6853 0, 0, 0, 0, 0, 0, 0, 0,
6854};
6855
6856static const Q_UINT16 di_2A[] = {
6857 0, 0, 0, 0, 0, 0, 0, 0,
6858 0, 0, 0, 0, 6406, 0, 0, 0,
6859 0, 0, 0, 0, 0, 0, 0, 0,
6860 0, 0, 0, 0, 0, 0, 0, 0,
6861 0, 0, 0, 0, 0, 0, 0, 0,
6862 0, 0, 0, 0, 0, 0, 0, 0,
6863 0, 0, 0, 0, 0, 0, 0, 0,
6864 0, 0, 0, 0, 0, 0, 0, 0,
6865 0, 0, 0, 0, 0, 0, 0, 0,
6866 0, 0, 0, 0, 0, 0, 0, 0,
6867 0, 0, 0, 0, 0, 0, 0, 0,
6868 0, 0, 0, 0, 0, 0, 0, 0,
6869 0, 0, 0, 0, 0, 0, 0, 0,
6870 0, 0, 0, 0, 0, 0, 0, 0,
6871 0, 0, 0, 0, 6413, 6419, 6424, 0,
6872 0, 0, 0, 0, 0, 0, 0, 0,
6873 0, 0, 0, 0, 0, 0, 0, 0,
6874 0, 0, 0, 0, 0, 0, 0, 0,
6875 0, 0, 0, 0, 0, 0, 0, 0,
6876 0, 0, 0, 0, 0, 0, 0, 0,
6877 0, 0, 0, 0, 0, 0, 0, 0,
6878 0, 0, 0, 0, 0, 0, 0, 0,
6879 0, 0, 0, 0, 0, 0, 0, 0,
6880 0, 0, 0, 0, 0, 0, 0, 0,
6881 0, 0, 0, 0, 0, 0, 0, 0,
6882 0, 0, 0, 0, 0, 0, 0, 0,
6883 0, 0, 0, 0, 0, 0, 0, 0,
6884 0, 0, 0, 0, 6430, 0, 0, 0,
6885 0, 0, 0, 0, 0, 0, 0, 0,
6886 0, 0, 0, 0, 0, 0, 0, 0,
6887 0, 0, 0, 0, 0, 0, 0, 0,
6888 0, 0, 0, 0, 0, 0, 0, 0,
6889};
6890
6891static const Q_UINT16 di_2E[] = {
6892 0, 0, 0, 0, 0, 0, 0, 0,
6893 0, 0, 0, 0, 0, 0, 0, 0,
6894 0, 0, 0, 0, 0, 0, 0, 0,
6895 0, 0, 0, 0, 0, 0, 0, 0,
6896 0, 0, 0, 0, 0, 0, 0, 0,
6897 0, 0, 0, 0, 0, 0, 0, 0,
6898 0, 0, 0, 0, 0, 0, 0, 0,
6899 0, 0, 0, 0, 0, 0, 0, 0,
6900 0, 0, 0, 0, 0, 0, 0, 0,
6901 0, 0, 0, 0, 0, 0, 0, 0,
6902 0, 0, 0, 0, 0, 0, 0, 0,
6903 0, 0, 0, 0, 0, 0, 0, 0,
6904 0, 0, 0, 0, 0, 0, 0, 0,
6905 0, 0, 0, 0, 0, 0, 0, 0,
6906 0, 0, 0, 0, 0, 0, 0, 0,
6907 0, 0, 0, 0, 0, 0, 0, 0,
6908 0, 0, 0, 0, 0, 0, 0, 0,
6909 0, 0, 0, 0, 0, 0, 0, 0,
6910 0, 0, 0, 0, 0, 0, 0, 0,
6911 0, 0, 0, 0, 0, 0, 0, 6435,
6912 0, 0, 0, 0, 0, 0, 0, 0,
6913 0, 0, 0, 0, 0, 0, 0, 0,
6914 0, 0, 0, 0, 0, 0, 0, 0,
6915 0, 0, 0, 0, 0, 0, 0, 0,
6916 0, 0, 0, 0, 0, 0, 0, 0,
6917 0, 0, 0, 0, 0, 0, 0, 0,
6918 0, 0, 0, 0, 0, 0, 0, 0,
6919 0, 0, 0, 0, 0, 0, 0, 0,
6920 0, 0, 0, 0, 0, 0, 0, 0,
6921 0, 0, 0, 0, 0, 0, 0, 0,
6922 0, 0, 0, 6439, 0, 0, 0, 0,
6923 0, 0, 0, 0, 0, 0, 0, 0,
6924};
6925
6926static const Q_UINT16 di_2F[] = {
6927 6443, 6447, 6451, 6455, 6459, 6463, 6467, 6471,
6928 6475, 6479, 6483, 6487, 6491, 6495, 6499, 6503,
6929 6507, 6511, 6515, 6519, 6523, 6527, 6531, 6535,
6930 6539, 6543, 6547, 6551, 6555, 6559, 6563, 6567,
6931 6571, 6575, 6579, 6583, 6587, 6591, 6595, 6599,
6932 6603, 6607, 6611, 6615, 6619, 6623, 6627, 6631,
6933 6635, 6639, 6643, 6647, 6651, 6655, 6659, 6663,
6934 6667, 6671, 6675, 6679, 6683, 6687, 6691, 6695,
6935 6699, 6703, 6707, 6711, 6715, 6719, 6723, 6727,
6936 6731, 6735, 6739, 6743, 6747, 6751, 6755, 6759,
6937 6763, 6767, 6771, 6775, 6779, 6783, 6787, 6791,
6938 6795, 6799, 6803, 6807, 6811, 6815, 6819, 6823,
6939 6827, 6831, 6835, 6839, 6843, 6847, 6851, 6855,
6940 6859, 6863, 6867, 6871, 6875, 6879, 6883, 6887,
6941 6891, 6895, 6899, 6903, 6907, 6911, 6915, 6919,
6942 6923, 6927, 6931, 6935, 6939, 6943, 6947, 6951,
6943 6955, 6959, 6963, 6967, 6971, 6975, 6979, 6983,
6944 6987, 6991, 6995, 6999, 7003, 7007, 7011, 7015,
6945 7019, 7023, 7027, 7031, 7035, 7039, 7043, 7047,
6946 7051, 7055, 7059, 7063, 7067, 7071, 7075, 7079,
6947 7083, 7087, 7091, 7095, 7099, 7103, 7107, 7111,
6948 7115, 7119, 7123, 7127, 7131, 7135, 7139, 7143,
6949 7147, 7151, 7155, 7159, 7163, 7167, 7171, 7175,
6950 7179, 7183, 7187, 7191, 7195, 7199, 7203, 7207,
6951 7211, 7215, 7219, 7223, 7227, 7231, 7235, 7239,
6952 7243, 7247, 7251, 7255, 7259, 7263, 7267, 7271,
6953 7275, 7279, 7283, 7287, 7291, 7295, 0, 0,
6954 0, 0, 0, 0, 0, 0, 0, 0,
6955 0, 0, 0, 0, 0, 0, 0, 0,
6956 0, 0, 0, 0, 0, 0, 0, 0,
6957 0, 0, 0, 0, 0, 0, 0, 0,
6958 0, 0, 0, 0, 0, 0, 0, 0,
6959};
6960
6961static const Q_UINT16 di_30[] = {
6962 7299, 0, 0, 0, 0, 0, 0, 0,
6963 0, 0, 0, 0, 0, 0, 0, 0,
6964 0, 0, 0, 0, 0, 0, 0, 0,
6965 0, 0, 0, 0, 0, 0, 0, 0,
6966 0, 0, 0, 0, 0, 0, 0, 0,
6967 0, 0, 0, 0, 0, 0, 0, 0,
6968 0, 0, 0, 0, 0, 0, 7303, 0,
6969 7307, 7311, 7315, 0, 0, 0, 0, 0,
6970 0, 0, 0, 0, 0, 0, 0, 0,
6971 0, 0, 0, 0, 7319, 0, 7324, 0,
6972 7329, 0, 7334, 0, 7339, 0, 7344, 0,
6973 7349, 0, 7354, 0, 7359, 0, 7364, 0,
6974 7369, 0, 7374, 0, 0, 7379, 0, 7384,
6975 0, 7389, 0, 0, 0, 0, 0, 0,
6976 7394, 7399, 0, 7404, 7409, 0, 7414, 7419,
6977 0, 7424, 7429, 0, 7434, 7439, 0, 0,
6978 0, 0, 0, 0, 0, 0, 0, 0,
6979 0, 0, 0, 0, 0, 0, 0, 0,
6980 0, 0, 0, 0, 7444, 0, 0, 0,
6981 0, 0, 0, 7449, 7454, 0, 7459, 7464,
6982 0, 0, 0, 0, 0, 0, 0, 0,
6983 0, 0, 0, 0, 7469, 0, 7474, 0,
6984 7479, 0, 7484, 0, 7489, 0, 7494, 0,
6985 7499, 0, 7504, 0, 7509, 0, 7514, 0,
6986 7519, 0, 7524, 0, 0, 7529, 0, 7534,
6987 0, 7539, 0, 0, 0, 0, 0, 0,
6988 7544, 7549, 0, 7554, 7559, 0, 7564, 7569,
6989 0, 7574, 7579, 0, 7584, 7589, 0, 0,
6990 0, 0, 0, 0, 0, 0, 0, 0,
6991 0, 0, 0, 0, 0, 0, 0, 0,
6992 0, 0, 0, 0, 7594, 0, 0, 7599,
6993 7604, 7609, 7614, 0, 0, 0, 7619, 7624,
6994};
6995
6996static const Q_UINT16 di_31[] = {
6997 0, 0, 0, 0, 0, 0, 0, 0,
6998 0, 0, 0, 0, 0, 0, 0, 0,
6999 0, 0, 0, 0, 0, 0, 0, 0,
7000 0, 0, 0, 0, 0, 0, 0, 0,
7001 0, 0, 0, 0, 0, 0, 0, 0,
7002 0, 0, 0, 0, 0, 0, 0, 0,
7003 0, 7629, 7633, 7637, 7641, 7645, 7649, 7653,
7004 7657, 7661, 7665, 7669, 7673, 7677, 7681, 7685,
7005 7689, 7693, 7697, 7701, 7705, 7709, 7713, 7717,
7006 7721, 7725, 7729, 7733, 7737, 7741, 7745, 7749,
7007 7753, 7757, 7761, 7765, 7769, 7773, 7777, 7781,
7008 7785, 7789, 7793, 7797, 7801, 7805, 7809, 7813,
7009 7817, 7821, 7825, 7829, 7833, 7837, 7841, 7845,
7010 7849, 7853, 7857, 7861, 7865, 7869, 7873, 7877,
7011 7881, 7885, 7889, 7893, 7897, 7901, 7905, 7909,
7012 7913, 7917, 7921, 7925, 7929, 7933, 7937, 7941,
7013 7945, 7949, 7953, 7957, 7961, 7965, 7969, 7973,
7014 7977, 7981, 7985, 7989, 7993, 7997, 8001, 0,
7015 0, 0, 8005, 8009, 8013, 8017, 8021, 8025,
7016 8029, 8033, 8037, 8041, 8045, 8049, 8053, 8057,
7017 0, 0, 0, 0, 0, 0, 0, 0,
7018 0, 0, 0, 0, 0, 0, 0, 0,
7019 0, 0, 0, 0, 0, 0, 0, 0,
7020 0, 0, 0, 0, 0, 0, 0, 0,
7021 0, 0, 0, 0, 0, 0, 0, 0,
7022 0, 0, 0, 0, 0, 0, 0, 0,
7023 0, 0, 0, 0, 0, 0, 0, 0,
7024 0, 0, 0, 0, 0, 0, 0, 0,
7025 0, 0, 0, 0, 0, 0, 0, 0,
7026 0, 0, 0, 0, 0, 0, 0, 0,
7027 0, 0, 0, 0, 0, 0, 0, 0,
7028 0, 0, 0, 0, 0, 0, 0, 0,
7029};
7030
7031static const Q_UINT16 di_32[] = {
7032 8061, 8067, 8073, 8079, 8085, 8091, 8097, 8103,
7033 8109, 8115, 8121, 8127, 8133, 8139, 8145, 8152,
7034 8159, 8166, 8173, 8180, 8187, 8194, 8201, 8208,
7035 8215, 8222, 8229, 8236, 8243, 0, 0, 0,
7036 8250, 8256, 8262, 8268, 8274, 8280, 8286, 8292,
7037 8298, 8304, 8310, 8316, 8322, 8328, 8334, 8340,
7038 8346, 8352, 8358, 8364, 8370, 8376, 8382, 8388,
7039 8394, 8400, 8406, 8412, 8418, 8424, 8430, 8436,
7040 8442, 8448, 8454, 8460, 0, 0, 0, 0,
7041 0, 0, 0, 0, 0, 0, 0, 0,
7042 0, 8466, 8471, 8476, 8481, 8486, 8491, 8496,
7043 8501, 8506, 8511, 8516, 8521, 8526, 8531, 8536,
7044 8541, 8545, 8549, 8553, 8557, 8561, 8565, 8569,
7045 8573, 8577, 8581, 8585, 8589, 8593, 8597, 8602,
7046 8607, 8612, 8617, 8622, 8627, 8632, 8637, 8642,
7047 8647, 8652, 8657, 8662, 0, 0, 0, 0,
7048 8667, 8671, 8675, 8679, 8683, 8687, 8691, 8695,
7049 8699, 8703, 8707, 8711, 8715, 8719, 8723, 8727,
7050 8731, 8735, 8739, 8743, 8747, 8751, 8755, 8759,
7051 8763, 8767, 8771, 8775, 8779, 8783, 8787, 8791,
7052 8795, 8799, 8803, 8807, 8811, 8815, 8819, 8823,
7053 8827, 8831, 8835, 8839, 8843, 8847, 8851, 8855,
7054 8859, 8863, 8868, 8873, 8878, 8883, 8888, 8893,
7055 8898, 8903, 8908, 8913, 8918, 8923, 8928, 8933,
7056 8938, 8943, 8948, 8953, 8958, 8963, 8968, 8973,
7057 8978, 8983, 8989, 8995, 0, 0, 0, 0,
7058 9001, 9005, 9009, 9013, 9017, 9021, 9025, 9029,
7059 9033, 9037, 9041, 9045, 9049, 9053, 9057, 9061,
7060 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093,
7061 9097, 9101, 9105, 9109, 9113, 9117, 9121, 9125,
7062 9129, 9133, 9137, 9141, 9145, 9149, 9153, 9157,
7063 9161, 9165, 9169, 9173, 9177, 9181, 9185, 0,
7064};
7065
7066static const Q_UINT16 di_33[] = {
7067 9189, 9196, 9203, 9210, 9216, 9223, 9229, 9235,
7068 9243, 9250, 9256, 9262, 9268, 9275, 9282, 9288,
7069 9294, 9299, 9305, 9312, 9319, 9324, 9332, 9341,
7070 9349, 9355, 9363, 9371, 9378, 9384, 9390, 9396,
7071 9403, 9411, 9418, 9424, 9430, 9436, 9441, 9446,
7072 9451, 9456, 9462, 9468, 9476, 9482, 9489, 9497,
7073 9503, 9508, 9513, 9521, 9528, 9536, 9542, 9550,
7074 9555, 9561, 9567, 9573, 9579, 9585, 9592, 9598,
7075 9603, 9609, 9615, 9621, 9628, 9634, 9640, 9646,
7076 9654, 9661, 9666, 9674, 9679, 9686, 9693, 9699,
7077 9705, 9711, 9718, 9723, 9729, 9736, 9741, 9749,
7078 9755, 9760, 9765, 9770, 9775, 9780, 9785, 9790,
7079 9795, 9800, 9805, 9811, 9817, 9823, 9829, 9835,
7080 9841, 9847, 9853, 9859, 9865, 9871, 9877, 9883,
7081 9889, 9895, 9901, 9906, 9911, 9917, 9922, 0,
7082 0, 0, 0, 9927, 9932, 9937, 9942, 9947,
7083 9954, 9959, 9964, 9969, 9974, 9979, 9984, 9989,
7084 9994, 10000, 10007, 10012, 10017, 10022, 10027, 10032,
7085 10037, 10042, 10048, 10054, 10060, 10066, 10071, 10076,
7086 10081, 10086, 10091, 10096, 10101, 10106, 10111, 10116,
7087 10122, 10128, 10133, 10139, 10145, 10151, 10156, 10162,
7088 10168, 10175, 10180, 10186, 10192, 10198, 10204, 10212,
7089 10221, 10226, 10231, 10236, 10241, 10246, 10251, 10256,
7090 10261, 10266, 10271, 10276, 10281, 10286, 10291, 10296,
7091 10301, 10306, 10311, 10318, 10323, 10328, 10333, 10340,
7092 10346, 10351, 10356, 10361, 10366, 10371, 10376, 10381,
7093 10386, 10391, 10396, 10402, 10407, 10412, 10418, 10424,
7094 10429, 10436, 10442, 10447, 10452, 10457, 0, 0,
7095 10462, 10467, 10472, 10477, 10482, 10487, 10492, 10497,
7096 10502, 10507, 10513, 10519, 10525, 10531, 10537, 10543,
7097 10549, 10555, 10561, 10567, 10573, 10579, 10585, 10591,
7098 10597, 10603, 10609, 10615, 10621, 10627, 10633, 0,
7099};
7100
7101static const Q_UINT16 di_F9[] = {
7102 10639, 10643, 10647, 10651, 10655, 10659, 10663, 10667,
7103 10671, 10675, 10679, 10683, 10687, 10691, 10695, 10699,
7104 10703, 10707, 10711, 10715, 10719, 10723, 10727, 10731,
7105 10735, 10739, 10743, 10747, 10751, 10755, 10759, 10763,
7106 10767, 10771, 10775, 10779, 10783, 10787, 10791, 10795,
7107 10799, 10803, 10807, 10811, 10815, 10819, 10823, 10827,
7108 10831, 10835, 10839, 10843, 10847, 10851, 10855, 10859,
7109 10863, 10867, 10871, 10875, 10879, 10883, 10887, 10891,
7110 10895, 10899, 10903, 10907, 10911, 10915, 10919, 10923,
7111 10927, 10931, 10935, 10939, 10943, 10947, 10951, 10955,
7112 10959, 10963, 10967, 10971, 10975, 10979, 10983, 10987,
7113 10991, 10995, 10999, 11003, 11007, 11011, 11015, 11019,
7114 11023, 11027, 11031, 11035, 11039, 11043, 11047, 11051,
7115 11055, 11059, 11063, 11067, 11071, 11075, 11079, 11083,
7116 11087, 11091, 11095, 11099, 11103, 11107, 11111, 11115,
7117 11119, 11123, 11127, 11131, 11135, 11139, 11143, 11147,
7118 11151, 11155, 11159, 11163, 11167, 11171, 11175, 11179,
7119 11183, 11187, 11191, 11195, 11199, 11203, 11207, 11211,
7120 11215, 11219, 11223, 11227, 11231, 11235, 11239, 11243,
7121 11247, 11251, 11255, 11259, 11263, 11267, 11271, 11275,
7122 11279, 11283, 11287, 11291, 11295, 11299, 11303, 11307,
7123 11311, 11315, 11319, 11323, 11327, 11331, 11335, 11339,
7124 11343, 11347, 11351, 11355, 11359, 11363, 11367, 11371,
7125 11375, 11379, 11383, 11387, 11391, 11395, 11399, 11403,
7126 11407, 11411, 11415, 11419, 11423, 11427, 11431, 11435,
7127 11439, 11443, 11447, 11451, 11455, 11459, 11463, 11467,
7128 11471, 11475, 11479, 11483, 11487, 11491, 11495, 11499,
7129 11503, 11507, 11511, 11515, 11519, 11523, 11527, 11531,
7130 11535, 11539, 11543, 11547, 11551, 11555, 11559, 11563,
7131 11567, 11571, 11575, 11579, 11583, 11587, 11591, 11595,
7132 11599, 11603, 11607, 11611, 11615, 11619, 11623, 11627,
7133 11631, 11635, 11639, 11643, 11647, 11651, 11655, 11659,
7134};
7135
7136static const Q_UINT16 di_FA[] = {
7137 11663, 11667, 11671, 11675, 11679, 11683, 11687, 11691,
7138 11695, 11699, 11703, 11707, 11711, 11715, 0, 0,
7139 11719, 0, 11723, 0, 0, 11727, 11731, 11735,
7140 11739, 11743, 11747, 11751, 11755, 11759, 11763, 0,
7141 11767, 0, 11771, 0, 0, 11775, 11779, 0,
7142 0, 0, 11783, 11787, 11791, 11795, 0, 0,
7143 11799, 11803, 11807, 11811, 11815, 11819, 11823, 11827,
7144 11831, 11835, 11839, 11843, 11847, 11851, 11855, 11859,
7145 11863, 11867, 11871, 11875, 11879, 11883, 11887, 11891,
7146 11895, 11899, 11903, 11907, 11911, 11915, 11919, 11923,
7147 11927, 11931, 11935, 11939, 11943, 11947, 11951, 11955,
7148 11959, 11963, 11967, 11971, 11975, 11979, 11983, 11987,
7149 11991, 11995, 11999, 12003, 12007, 12011, 12015, 12019,
7150 12023, 12027, 12031, 0, 0, 0, 0, 0,
7151 0, 0, 0, 0, 0, 0, 0, 0,
7152 0, 0, 0, 0, 0, 0, 0, 0,
7153 0, 0, 0, 0, 0, 0, 0, 0,
7154 0, 0, 0, 0, 0, 0, 0, 0,
7155 0, 0, 0, 0, 0, 0, 0, 0,
7156 0, 0, 0, 0, 0, 0, 0, 0,
7157 0, 0, 0, 0, 0, 0, 0, 0,
7158 0, 0, 0, 0, 0, 0, 0, 0,
7159 0, 0, 0, 0, 0, 0, 0, 0,
7160 0, 0, 0, 0, 0, 0, 0, 0,
7161 0, 0, 0, 0, 0, 0, 0, 0,
7162 0, 0, 0, 0, 0, 0, 0, 0,
7163 0, 0, 0, 0, 0, 0, 0, 0,
7164 0, 0, 0, 0, 0, 0, 0, 0,
7165 0, 0, 0, 0, 0, 0, 0, 0,
7166 0, 0, 0, 0, 0, 0, 0, 0,
7167 0, 0, 0, 0, 0, 0, 0, 0,
7168 0, 0, 0, 0, 0, 0, 0, 0,
7169};
7170
7171static const Q_UINT16 di_FB[] = {
7172 12035, 12040, 12045, 12050, 12056, 12062, 12067, 0,
7173 0, 0, 0, 0, 0, 0, 0, 0,
7174 0, 0, 0, 12072, 12077, 12082, 12087, 12092,
7175 0, 0, 0, 0, 0, 12097, 0, 12102,
7176 12107, 12111, 12115, 12119, 12123, 12127, 12131, 12135,
7177 12139, 12143, 12147, 12152, 12157, 12162, 12167, 12172,
7178 12177, 12182, 12187, 12192, 12197, 12202, 12207, 0,
7179 12212, 12217, 12222, 12227, 12232, 0, 12237, 0,
7180 12242, 12247, 0, 12252, 12257, 0, 12262, 12267,
7181 12272, 12277, 12282, 12287, 12292, 12297, 12302, 12307,
7182 12312, 12316, 12320, 12324, 12328, 12332, 12336, 12340,
7183 12344, 12348, 12352, 12356, 12360, 12364, 12368, 12372,
7184 12376, 12380, 12384, 12388, 12392, 12396, 12400, 12404,
7185 12408, 12412, 12416, 12420, 12424, 12428, 12432, 12436,
7186 12440, 12444, 12448, 12452, 12456, 12460, 12464, 12468,
7187 12472, 12476, 12480, 12484, 12488, 12492, 12496, 12500,
7188 12504, 12508, 12512, 12516, 12520, 12524, 12528, 12532,
7189 12536, 12540, 12544, 12548, 12552, 12556, 12560, 12564,
7190 12568, 12572, 12576, 12580, 12584, 12588, 12592, 12596,
7191 12600, 12604, 12608, 12612, 12616, 12620, 12624, 12628,
7192 12632, 12636, 12640, 12644, 12648, 12652, 12656, 12660,
7193 12664, 12668, 12672, 12676, 12680, 12684, 12688, 12692,
7194 12696, 12700, 0, 0, 0, 0, 0, 0,
7195 0, 0, 0, 0, 0, 0, 0, 0,
7196 0, 0, 0, 0, 0, 0, 0, 0,
7197 0, 0, 0, 0, 0, 0, 0, 0,
7198 0, 0, 0, 12704, 12708, 12712, 12716, 12720,
7199 12724, 12728, 12732, 12736, 12740, 12744, 12748, 12752,
7200 12756, 12760, 12764, 12768, 12772, 12776, 12780, 12784,
7201 12788, 12792, 12796, 12801, 12806, 12811, 12816, 12821,
7202 12826, 12831, 12836, 12841, 12846, 12851, 12856, 12861,
7203 12866, 12871, 12876, 12881, 12886, 12890, 12894, 12898,
7204};
7205
7206static const Q_UINT16 di_FC[] = {
7207 12902, 12907, 12912, 12917, 12922, 12927, 12932, 12937,
7208 12942, 12947, 12952, 12957, 12962, 12967, 12972, 12977,
7209 12982, 12987, 12992, 12997, 13002, 13007, 13012, 13017,
7210 13022, 13027, 13032, 13037, 13042, 13047, 13052, 13057,
7211 13062, 13067, 13072, 13077, 13082, 13087, 13092, 13097,
7212 13102, 13107, 13112, 13117, 13122, 13127, 13132, 13137,
7213 13142, 13147, 13152, 13157, 13162, 13167, 13172, 13177,
7214 13182, 13187, 13192, 13197, 13202, 13207, 13212, 13217,
7215 13222, 13227, 13232, 13237, 13242, 13247, 13252, 13257,
7216 13262, 13267, 13272, 13277, 13282, 13287, 13292, 13297,
7217 13302, 13307, 13312, 13317, 13322, 13327, 13332, 13337,
7218 13342, 13347, 13352, 13357, 13362, 13367, 13372, 13378,
7219 13384, 13390, 13396, 13402, 13408, 13413, 13418, 13423,
7220 13428, 13433, 13438, 13443, 13448, 13453, 13458, 13463,
7221 13468, 13473, 13478, 13483, 13488, 13493, 13498, 13503,
7222 13508, 13513, 13518, 13523, 13528, 13533, 13538, 13543,
7223 13548, 13553, 13558, 13563, 13568, 13573, 13578, 13583,
7224 13588, 13593, 13598, 13603, 13608, 13613, 13618, 13623,
7225 13628, 13633, 13638, 13643, 13648, 13653, 13658, 13663,
7226 13668, 13673, 13678, 13683, 13688, 13693, 13698, 13703,
7227 13708, 13713, 13718, 13723, 13728, 13733, 13738, 13743,
7228 13748, 13753, 13758, 13763, 13768, 13773, 13778, 13783,
7229 13788, 13793, 13798, 13803, 13808, 13813, 13818, 13823,
7230 13828, 13833, 13838, 13843, 13848, 13853, 13858, 13863,
7231 13868, 13873, 13878, 13883, 13888, 13893, 13898, 13903,
7232 13908, 13913, 13918, 13923, 13928, 13933, 13938, 13943,
7233 13948, 13953, 13958, 13963, 13968, 13973, 13978, 13983,
7234 13988, 13993, 13998, 14003, 14008, 14013, 14018, 14023,
7235 14028, 14033, 14038, 14043, 14048, 14053, 14058, 14063,
7236 14068, 14073, 14078, 14083, 14088, 14093, 14098, 14103,
7237 14108, 14113, 14118, 14124, 14130, 14136, 14141, 14146,
7238 14151, 14156, 14161, 14166, 14171, 14176, 14181, 14186,
7239};
7240
7241static const Q_UINT16 di_FD[] = {
7242 14191, 14196, 14201, 14206, 14211, 14216, 14221, 14226,
7243 14231, 14236, 14241, 14246, 14251, 14256, 14261, 14266,
7244 14271, 14276, 14281, 14286, 14291, 14296, 14301, 14306,
7245 14311, 14316, 14321, 14326, 14331, 14336, 14341, 14346,
7246 14351, 14356, 14361, 14366, 14371, 14376, 14381, 14386,
7247 14391, 14396, 14401, 14406, 14411, 14416, 14421, 14426,
7248 14431, 14436, 14441, 14446, 14451, 14456, 14461, 14466,
7249 14471, 14476, 14481, 14486, 14491, 14496, 0, 0,
7250 0, 0, 0, 0, 0, 0, 0, 0,
7251 0, 0, 0, 0, 0, 0, 0, 0,
7252 14501, 14507, 14513, 14519, 14525, 14531, 14537, 14543,
7253 14549, 14555, 14561, 14567, 14573, 14579, 14585, 14591,
7254 14597, 14603, 14609, 14615, 14621, 14627, 14633, 14639,
7255 14645, 14651, 14657, 14663, 14669, 14675, 14681, 14687,
7256 14693, 14699, 14705, 14711, 14717, 14723, 14729, 14735,
7257 14741, 14747, 14753, 14759, 14765, 14771, 14777, 14783,
7258 14789, 14795, 14801, 14807, 14813, 14819, 14825, 14831,
7259 14837, 14843, 14849, 14855, 14861, 14867, 14873, 14879,
7260 0, 0, 14885, 14891, 14897, 14903, 14909, 14915,
7261 14921, 14927, 14933, 14939, 14945, 14951, 14957, 14963,
7262 14969, 14975, 14981, 14987, 14993, 14999, 15005, 15011,
7263 15017, 15023, 15029, 15035, 15041, 15047, 15053, 15059,
7264 15065, 15071, 15077, 15083, 15089, 15095, 15101, 15107,
7265 15113, 15119, 15125, 15131, 15137, 15143, 15149, 15155,
7266 15161, 15167, 15173, 15179, 15185, 15191, 15197, 15203,
7267 0, 0, 0, 0, 0, 0, 0, 0,
7268 0, 0, 0, 0, 0, 0, 0, 0,
7269 0, 0, 0, 0, 0, 0, 0, 0,
7270 0, 0, 0, 0, 0, 0, 0, 0,
7271 0, 0, 0, 0, 0, 0, 0, 0,
7272 15209, 15215, 15221, 15228, 15235, 15242, 15249, 15256,
7273 15263, 15270, 15276, 15297, 15308, 0, 0, 0,
7274};
7275
7276static const Q_UINT16 di_FE[] = {
7277 0, 0, 0, 0, 0, 0, 0, 0,
7278 0, 0, 0, 0, 0, 0, 0, 0,
7279 0, 0, 0, 0, 0, 0, 0, 0,
7280 0, 0, 0, 0, 0, 0, 0, 0,
7281 0, 0, 0, 0, 0, 0, 0, 0,
7282 0, 0, 0, 0, 0, 0, 0, 0,
7283 15315, 15319, 15323, 15327, 15331, 15335, 15339, 15343,
7284 15347, 15351, 15355, 15359, 15363, 15367, 15371, 15375,
7285 15379, 15383, 15387, 15391, 15395, 0, 0, 0,
7286 0, 15399, 15403, 15407, 15411, 15415, 15419, 15423,
7287 15427, 15431, 15435, 0, 15439, 15443, 15447, 15451,
7288 15455, 15459, 15463, 15467, 15471, 15475, 15479, 15483,
7289 15487, 15491, 15495, 15499, 15503, 15507, 15511, 0,
7290 15515, 15519, 15523, 15527, 0, 0, 0, 0,
7291 15531, 15536, 15541, 0, 15546, 0, 15551, 15556,
7292 15561, 15566, 15571, 15576, 15581, 15586, 15591, 15596,
7293 15601, 15605, 15609, 15613, 15617, 15621, 15625, 15629,
7294 15633, 15637, 15641, 15645, 15649, 15653, 15657, 15661,
7295 15665, 15669, 15673, 15677, 15681, 15685, 15689, 15693,
7296 15697, 15701, 15705, 15709, 15713, 15717, 15721, 15725,
7297 15729, 15733, 15737, 15741, 15745, 15749, 15753, 15757,
7298 15761, 15765, 15769, 15773, 15777, 15781, 15785, 15789,
7299 15793, 15797, 15801, 15805, 15809, 15813, 15817, 15821,
7300 15825, 15829, 15833, 15837, 15841, 15845, 15849, 15853,
7301 15857, 15861, 15865, 15869, 15873, 15877, 15881, 15885,
7302 15889, 15893, 15897, 15901, 15905, 15909, 15913, 15917,
7303 15921, 15925, 15929, 15933, 15937, 15941, 15945, 15949,
7304 15953, 15957, 15961, 15965, 15969, 15973, 15977, 15981,
7305 15985, 15989, 15993, 15997, 16001, 16005, 16009, 16013,
7306 16017, 16021, 16025, 16029, 16033, 16037, 16041, 16045,
7307 16049, 16053, 16057, 16061, 16065, 16069, 16074, 16079,
7308 16084, 16089, 16094, 16099, 16104, 0, 0, 0,
7309};
7310
7311static const Q_UINT16 di_FF[] = {
7312 0, 16109, 16113, 16117, 16121, 16125, 16129, 16133,
7313 16137, 16141, 16145, 16149, 16153, 16157, 16161, 16165,
7314 16169, 16173, 16177, 16181, 16185, 16189, 16193, 16197,
7315 16201, 16205, 16209, 16213, 16217, 16221, 16225, 16229,
7316 16233, 16237, 16241, 16245, 16249, 16253, 16257, 16261,
7317 16265, 16269, 16273, 16277, 16281, 16285, 16289, 16293,
7318 16297, 16301, 16305, 16309, 16313, 16317, 16321, 16325,
7319 16329, 16333, 16337, 16341, 16345, 16349, 16353, 16357,
7320 16361, 16365, 16369, 16373, 16377, 16381, 16385, 16389,
7321 16393, 16397, 16401, 16405, 16409, 16413, 16417, 16421,
7322 16425, 16429, 16433, 16437, 16441, 16445, 16449, 16453,
7323 16457, 16461, 16465, 16469, 16473, 16477, 16481, 16485,
7324 16489, 16493, 16497, 16501, 16505, 16509, 16513, 16517,
7325 16521, 16525, 16529, 16533, 16537, 16541, 16545, 16549,
7326 16553, 16557, 16561, 16565, 16569, 16573, 16577, 16581,
7327 16585, 16589, 16593, 16597, 16601, 16605, 16609, 16613,
7328 16617, 16621, 16625, 16629, 16633, 16637, 16641, 16645,
7329 16649, 16653, 16657, 16661, 16665, 16669, 16673, 16677,
7330 16681, 16685, 16689, 16693, 16697, 16701, 16705, 16709,
7331 16713, 16717, 16721, 16725, 16729, 16733, 16737, 16741,
7332 16745, 16749, 16753, 16757, 16761, 16765, 16769, 16773,
7333 16777, 16781, 16785, 16789, 16793, 16797, 16801, 16805,
7334 16809, 16813, 16817, 16821, 16825, 16829, 16833, 16837,
7335 16841, 16845, 16849, 16853, 16857, 16861, 16865, 0,
7336 0, 0, 16869, 16873, 16877, 16881, 16885, 16889,
7337 0, 0, 16893, 16897, 16901, 16905, 16909, 16913,
7338 0, 0, 16917, 16921, 16925, 16929, 16933, 16937,
7339 0, 0, 16941, 16945, 16949, 0, 0, 0,
7340 16953, 16957, 16961, 16965, 16969, 16973, 16977, 0,
7341 16981, 16985, 16989, 16993, 16997, 17001, 17005, 0,
7342 0, 0, 0, 0, 0, 0, 0, 0,
7343 0, 0, 0, 0, 0, 0, 0, 0,
7344};
7345
7346static const Q_UINT16 * const decomposition_info[256] = {
7347 di_00, di_01, di_02, di_03, di_04, di_05, di_06, di_07,
7348 di_07, di_09, di_0A, di_0B, di_0C, di_0D, di_0E, di_0F,
7349 di_10, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7350 di_07, di_07, di_07, di_07, di_07, di_07, di_1E, di_1F,
7351 di_20, di_21, di_22, di_23, di_24, di_07, di_07, di_07,
7352 di_07, di_07, di_2A, di_07, di_07, di_07, di_2E, di_2F,
7353 di_30, di_31, di_32, di_33, di_07, di_07, di_07, di_07,
7354 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7355 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7356 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7357 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7358 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7359 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7360 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7361 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7362 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7363 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7364 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7365 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7366 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7367 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7368 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7369 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7370 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7371 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7372 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7373 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7374 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7375 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7376 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7377 di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
7378 di_07, di_F9, di_FA, di_FB, di_FC, di_FD, di_FE, di_FF,
7379};
7380// 68832 bytes
7381
7382static const Q_UINT16 ligature_map[] = {
7383 0,
7384 5567, 0,
7385 5552, 0,
7386 5572, 0,
7387 67, 72, 77, 82, 87, 92, 332, 342, 352, 966, 1196, 1206, 1346, 2365, 3145, 3155, 0,
7388 2375, 2385, 2395, 0,
7389 97, 362, 372, 382, 392, 0,
7390 402, 2415, 2425, 2435, 2445, 2455, 0,
7391 102, 107, 112, 117, 412, 422, 432, 442, 452, 1216, 1226, 1356, 2485, 2495, 3265, 3275, 3285, 0,
7392 2515, 0,
7393 462, 472, 482, 492, 1076, 1146, 2525, 0,
7394 502, 1336, 2535, 2545, 2555, 2565, 2575, 0,
7395 122, 127, 132, 137, 512, 522, 532, 542, 552, 976, 1236, 1246, 2585, 3345, 3355, 0,
7396 567, 0,
7397 577, 1086, 2605, 2615, 2625, 0,
7398 587, 597, 607, 2635, 2655, 2665, 0,
7399 2675, 2685, 2695, 0,
7400 142, 627, 637, 647, 1156, 2705, 2715, 2725, 2735, 0,
7401 147, 152, 157, 162, 167, 662, 672, 682, 901, 986, 1096, 1256, 1266, 1386, 3365, 3375, 0,
7402 2785, 2795, 0,
7403 692, 702, 712, 1276, 1286, 2805, 2815, 2835, 0,
7404 722, 732, 742, 752, 1316, 2845, 2855, 0,
7405 762, 772, 1326, 2895, 2905, 2915, 2925, 0,
7406 172, 177, 182, 187, 782, 792, 802, 812, 822, 832, 911, 996, 1296, 1306, 2935, 2945, 2955, 3485, 3495, 0,
7407 2985, 2995, 0,
7408 842, 3005, 3015, 3025, 3035, 3045, 0,
7409 3055, 3065, 0,
7410 192, 852, 862, 1406, 3075, 3555, 3565, 3575, 3585, 0,
7411 867, 877, 887, 3085, 3095, 3105, 0,
7412 197, 202, 207, 212, 217, 222, 337, 347, 357, 971, 1201, 1211, 1351, 2370, 3150, 3160, 0,
7413 2380, 2390, 2400, 0,
7414 227, 367, 377, 387, 397, 0,
7415 407, 2420, 2430, 2440, 2450, 2460, 0,
7416 232, 237, 242, 247, 417, 427, 437, 447, 457, 1221, 1231, 1361, 2490, 2500, 3270, 3280, 3290, 0,
7417 2520, 0,
7418 467, 477, 487, 497, 1081, 1151, 2530, 0,
7419 507, 1341, 2540, 2550, 2560, 2570, 2580, 3115, 0,
7420 252, 257, 262, 267, 517, 527, 537, 547, 981, 1241, 1251, 2590, 3350, 3360, 0,
7421 572, 1126, 0,
7422 582, 1091, 2610, 2620, 2630, 0,
7423 592, 602, 612, 2640, 2660, 2670, 0,
7424 2680, 2690, 2700, 0,
7425 272, 632, 642, 652, 1161, 2710, 2720, 2730, 2740, 0,
7426 277, 282, 287, 292, 297, 667, 677, 687, 906, 991, 1101, 1261, 1271, 1391, 3370, 3380, 0,
7427 2790, 2800, 0,
7428 697, 707, 717, 1281, 1291, 2810, 2820, 2840, 0,
7429 727, 737, 747, 757, 1321, 2850, 2860, 0,
7430 767, 777, 1331, 2900, 2910, 2920, 2930, 3120, 0,
7431 302, 307, 312, 317, 787, 797, 807, 817, 827, 837, 916, 1001, 1301, 1311, 2940, 2950, 2960, 3490, 3500, 0,
7432 2990, 3000, 0,
7433 847, 3010, 3020, 3030, 3040, 3050, 3125, 0,
7434 3060, 3070, 0,
7435 322, 327, 857, 1411, 3080, 3130, 3560, 3570, 3580, 3590, 0,
7436 872, 882, 892, 3090, 3100, 3110, 0,
7437 1537, 4476, 4670, 0,
7438 3165, 3175, 3185, 3195, 0,
7439 1046, 0,
7440 1166, 0,
7441 1066, 1176, 0,
7442 2405, 0,
7443 3295, 3305, 3315, 3325, 0,
7444 2595, 0,
7445 3385, 3395, 3405, 3415, 0,
7446 1376, 2745, 2755, 0,
7447 1366, 0,
7448 1186, 0,
7449 1006, 1016, 1026, 1036, 0,
7450 3170, 3180, 3190, 3200, 0,
7451 1051, 0,
7452 1171, 0,
7453 1071, 1181, 0,
7454 2410, 0,
7455 3300, 3310, 3320, 3330, 0,
7456 2600, 0,
7457 3390, 3400, 3410, 3420, 0,
7458 1381, 2750, 2760, 0,
7459 1371, 0,
7460 1191, 0,
7461 1011, 1021, 1031, 1041, 0,
7462 3215, 3225, 3235, 3245, 0,
7463 3220, 3230, 3240, 3250, 0,
7464 2465, 2475, 0,
7465 2470, 2480, 0,
7466 2765, 2775, 0,
7467 2770, 2780, 0,
7468 2865, 0,
7469 2870, 0,
7470 2875, 0,
7471 2880, 0,
7472 2965, 0,
7473 2970, 0,
7474 2975, 0,
7475 2980, 0,
7476 3140, 0,
7477 3435, 3445, 3455, 3465, 3475, 0,
7478 3440, 3450, 3460, 3470, 3480, 0,
7479 3505, 3515, 3525, 3535, 3545, 0,
7480 3510, 3520, 3530, 3540, 3550, 0,
7481 1116, 0,
7482 1106, 0,
7483 1111, 0,
7484 1056, 0,
7485 1061, 0,
7486 2505, 0,
7487 2510, 0,
7488 1396, 0,
7489 1401, 0,
7490 1121, 0,
7491 1514, 0,
7492 1542, 3635, 3640, 4433, 4438, 4443, 4452, 0,
7493 1551, 3705, 3710, 4506, 0,
7494 1556, 3775, 3780, 4515, 4524, 0,
7495 1561, 1586, 3855, 3860, 4573, 4578, 4583, 0,
7496 1566, 3925, 3930, 4708, 0,
7497 4665, 0,
7498 1571, 1591, 3995, 4646, 4651, 4656, 0,
7499 1576, 4055, 4060, 4717, 4726, 0,
7500 4418, 0,
7501 4491, 0,
7502 1596, 3595, 3600, 4095, 4398, 4403, 4413, 4423, 0,
7503 1601, 3675, 3680, 4104, 0,
7504 1606, 3735, 3740, 4113, 4486, 4496, 0,
7505 1611, 1621, 3815, 3820, 4122, 4544, 4549, 4563, 0,
7506 1631, 3895, 3900, 4131, 0,
7507 4626, 4631, 0,
7508 1626, 1636, 3955, 3960, 4140, 4607, 4612, 4636, 0,
7509 1641, 4015, 4020, 4149, 4688, 4698, 0,
7510 1581, 4554, 4568, 0,
7511 1616, 4617, 4641, 0,
7512 4693, 0,
7513 1658, 1663, 0,
7514 1711, 0,
7515 1796, 1806, 0,
7516 1706, 0,
7517 1696, 1701, 1816, 0,
7518 1786, 1836, 0,
7519 1846, 0,
7520 1721, 1731, 1856, 1866, 0,
7521 1716, 0,
7522 1876, 0,
7523 1726, 1906, 1916, 1926, 0,
7524 1936, 0,
7525 1946, 0,
7526 1896, 0,
7527 1801, 1811, 0,
7528 1751, 0,
7529 1741, 1746, 1821, 0,
7530 1791, 1841, 0,
7531 1851, 0,
7532 1736, 1766, 1861, 1871, 0,
7533 1761, 0,
7534 1881, 0,
7535 1771, 1911, 1921, 1931, 0,
7536 1941, 0,
7537 1951, 0,
7538 1901, 0,
7539 1756, 0,
7540 1776, 0,
7541 1781, 0,
7542 1826, 0,
7543 1831, 0,
7544 1886, 0,
7545 1891, 0,
7546 12167, 12172, 12177, 0,
7547 12182, 12292, 0,
7548 12187, 0,
7549 12192, 0,
7550 12197, 0,
7551 12202, 12287, 0,
7552 12207, 0,
7553 12212, 0,
7554 12097, 12217, 0,
7555 12222, 0,
7556 12227, 12297, 0,
7557 12232, 0,
7558 12237, 0,
7559 12242, 0,
7560 12247, 0,
7561 12252, 0,
7562 12257, 12302, 0,
7563 12262, 0,
7564 12267, 0,
7565 12272, 0,
7566 12147, 12152, 12277, 0,
7567 12282, 0,
7568 12102, 0,
7569 1961, 1966, 1976, 0,
7570 1971, 0,
7571 1981, 0,
7572 2011, 0,
7573 2016, 0,
7574 2006, 0,
7575 2036, 0,
7576 2041, 0,
7577 2046, 0,
7578 2051, 0,
7579 2056, 0,
7580 2061, 0,
7581 2021, 0,
7582 2066, 0,
7583 2071, 0,
7584 2026, 0,
7585 2031, 0,
7586 2086, 0,
7587 2091, 0,
7588 2096, 0,
7589 2076, 2081, 0,
7590 2111, 0,
7591 2116, 0,
7592 2121, 0,
7593 2126, 0,
7594 2101, 0,
7595 2106, 0,
7596 2146, 0,
7597 2151, 0,
7598 2131, 2136, 2141, 0,
7599 2156, 0,
7600 2161, 2171, 0,
7601 2166, 0,
7602 2176, 0,
7603 2181, 0,
7604 2186, 2191, 2196, 0,
7605 2201, 0,
7606 2206, 2216, 0,
7607 2211, 0,
7608 2221, 2226, 2236, 0,
7609 2231, 0,
7610 2290, 0,
7611 2265, 0,
7612 2270, 0,
7613 2275, 0,
7614 2280, 0,
7615 2285, 0,
7616 2295, 2300, 2325, 0,
7617 2355, 0,
7618 2330, 0,
7619 2335, 0,
7620 2340, 0,
7621 2345, 0,
7622 2350, 0,
7623 2305, 0,
7624 2315, 0,
7625 2360, 0,
7626 2645, 0,
7627 2650, 0,
7628 2825, 0,
7629 2830, 0,
7630 2885, 0,
7631 2890, 0,
7632 3205, 3255, 0,
7633 3210, 3260, 0,
7634 3335, 0,
7635 3340, 0,
7636 3425, 0,
7637 3430, 0,
7638 3605, 3615, 3625, 4158, 0,
7639 3610, 3620, 3630, 4163, 0,
7640 4168, 0,
7641 4173, 0,
7642 4178, 0,
7643 4183, 0,
7644 4188, 0,
7645 4193, 0,
7646 3645, 3655, 3665, 4198, 0,
7647 3650, 3660, 3670, 4203, 0,
7648 4208, 0,
7649 4213, 0,
7650 4218, 0,
7651 4223, 0,
7652 4228, 0,
7653 4233, 0,
7654 3685, 3695, 0,
7655 3690, 3700, 0,
7656 3715, 3725, 0,
7657 3720, 3730, 0,
7658 3745, 3755, 3765, 4238, 0,
7659 3750, 3760, 3770, 4243, 0,
7660 4248, 0,
7661 4253, 0,
7662 4258, 0,
7663 4263, 0,
7664 4268, 0,
7665 4273, 0,
7666 3785, 3795, 3805, 4278, 0,
7667 3790, 3800, 3810, 4283, 0,
7668 4288, 0,
7669 4293, 0,
7670 4298, 0,
7671 4303, 0,
7672 4308, 0,
7673 4313, 0,
7674 3825, 3835, 3845, 0,
7675 3830, 3840, 3850, 0,
7676 3865, 3875, 3885, 0,
7677 3870, 3880, 3890, 0,
7678 3905, 3915, 0,
7679 3910, 3920, 0,
7680 3935, 3945, 0,
7681 3940, 3950, 0,
7682 3965, 3975, 3985, 0,
7683 3970, 3980, 3990, 0,
7684 4000, 4005, 4010, 0,
7685 4025, 4035, 4045, 4318, 0,
7686 4030, 4040, 4050, 4323, 0,
7687 4328, 0,
7688 4333, 0,
7689 4338, 0,
7690 4343, 0,
7691 4348, 0,
7692 4353, 0,
7693 4065, 4075, 4085, 4358, 0,
7694 4070, 4080, 4090, 4363, 0,
7695 4368, 0,
7696 4373, 0,
7697 4378, 0,
7698 4383, 0,
7699 4388, 0,
7700 4393, 0,
7701 4408, 0,
7702 4481, 0,
7703 4683, 0,
7704 4428, 0,
7705 4529, 4534, 4539, 0,
7706 4501, 0,
7707 4703, 0,
7708 4592, 4597, 4602, 0,
7709 5455, 0,
7710 5460, 0,
7711 5465, 0,
7712 5470, 0,
7713 5480, 0,
7714 5475, 0,
7715 5485, 0,
7716 5490, 0,
7717 5495, 0,
7718 5500, 0,
7719 5505, 0,
7720 5532, 0,
7721 5537, 0,
7722 5542, 0,
7723 5547, 0,
7724 5562, 0,
7725 5557, 0,
7726 5577, 0,
7727 5582, 0,
7728 5587, 0,
7729 5592, 0,
7730 5597, 0,
7731 5602, 0,
7732 5607, 0,
7733 5612, 0,
7734 5657, 0,
7735 5662, 0,
7736 5617, 0,
7737 5622, 0,
7738 5627, 0,
7739 5632, 0,
7740 5667, 0,
7741 5672, 0,
7742 5637, 0,
7743 5642, 0,
7744 5647, 0,
7745 5652, 0,
7746 5677, 0,
7747 5682, 0,
7748 5687, 0,
7749 5692, 0,
7750 6430, 0,
7751 7444, 0,
7752 7319, 0,
7753 7324, 0,
7754 7329, 0,
7755 7334, 0,
7756 7339, 0,
7757 7344, 0,
7758 7349, 0,
7759 7354, 0,
7760 7359, 0,
7761 7364, 0,
7762 7369, 0,
7763 7374, 0,
7764 7379, 0,
7765 7384, 0,
7766 7389, 0,
7767 7394, 7399, 0,
7768 7404, 7409, 0,
7769 7414, 7419, 0,
7770 7424, 7429, 0,
7771 7434, 7439, 0,
7772 7459, 0,
7773 7594, 0,
7774 7469, 0,
7775 7474, 0,
7776 7479, 0,
7777 7484, 0,
7778 7489, 0,
7779 7494, 0,
7780 7499, 0,
7781 7504, 0,
7782 7509, 0,
7783 7514, 0,
7784 7519, 0,
7785 7524, 0,
7786 7529, 0,
7787 7534, 0,
7788 7539, 0,
7789 7544, 7549, 0,
7790 7554, 7559, 0,
7791 7564, 7569, 0,
7792 7574, 7579, 0,
7793 7584, 7589, 0,
7794 7599, 0,
7795 7604, 0,
7796 7609, 0,
7797 7614, 0,
7798 7619, 0,
7799 12157, 12162, 0,
7800
7801};
7802
7803static const Q_UINT16 li_00[] = {
7804 0, 0, 0, 0, 0, 0, 0, 0,
7805 0, 0, 0, 0, 0, 0, 0, 0,
7806 0, 0, 0, 0, 0, 0, 0, 0,
7807 0, 0, 0, 0, 0, 0, 0, 0,
7808 0, 0, 0, 0, 0, 0, 0, 0,
7809 0, 0, 0, 0, 0, 0, 0, 0,
7810 0, 0, 0, 0, 0, 0, 0, 0,
7811 0, 0, 0, 0, 1, 3, 5, 0,
7812 0, 7, 24, 28, 34, 41, 59, 61,
7813 69, 77, 93, 95, 101, 108, 112, 122,
7814 139, 0, 142, 151, 159, 167, 187, 190,
7815 197, 200, 210, 0, 0, 0, 0, 0,
7816 0, 217, 234, 238, 244, 251, 269, 271,
7817 279, 288, 303, 306, 312, 319, 323, 333,
7818 350, 0, 353, 362, 370, 379, 399, 402,
7819 410, 413, 424, 0, 0, 0, 0, 0,
7820 0, 0, 0, 0, 0, 0, 0, 0,
7821 0, 0, 0, 0, 0, 0, 0, 0,
7822 0, 0, 0, 0, 0, 0, 0, 0,
7823 0, 0, 0, 0, 0, 0, 0, 0,
7824 0, 0, 0, 0, 0, 0, 0, 0,
7825 431, 0, 0, 0, 0, 0, 0, 0,
7826 0, 0, 0, 0, 0, 0, 0, 0,
7827 0, 0, 0, 0, 0, 0, 0, 0,
7828 0, 0, 435, 0, 440, 442, 444, 447,
7829 0, 0, 449, 0, 0, 0, 0, 454,
7830 0, 0, 0, 0, 456, 461, 465, 0,
7831 467, 0, 0, 0, 469, 0, 0, 0,
7832 0, 0, 474, 0, 479, 481, 483, 486,
7833 0, 0, 488, 0, 0, 0, 0, 493,
7834 0, 0, 0, 0, 495, 500, 504, 0,
7835 506, 0, 0, 0, 508, 0, 0, 0,
7836};
7837
7838static const Q_UINT16 li_01[] = {
7839 0, 0, 513, 518, 0, 0, 0, 0,
7840 0, 0, 0, 0, 0, 0, 0, 0,
7841 0, 0, 523, 526, 0, 0, 0, 0,
7842 0, 0, 0, 0, 0, 0, 0, 0,
7843 0, 0, 0, 0, 0, 0, 0, 0,
7844 0, 0, 0, 0, 0, 0, 0, 0,
7845 0, 0, 0, 0, 0, 0, 0, 0,
7846 0, 0, 0, 0, 0, 0, 0, 0,
7847 0, 0, 0, 0, 0, 0, 0, 0,
7848 0, 0, 0, 0, 529, 532, 0, 0,
7849 0, 0, 0, 0, 0, 0, 0, 0,
7850 0, 0, 535, 537, 0, 0, 0, 0,
7851 539, 541, 0, 0, 0, 0, 0, 0,
7852 543, 545, 547, 549, 0, 0, 0, 0,
7853 0, 0, 0, 0, 0, 0, 0, 0,
7854 0, 0, 0, 0, 0, 0, 0, 551,
7855 0, 0, 0, 0, 0, 0, 0, 0,
7856 0, 0, 0, 0, 0, 0, 0, 0,
7857 0, 0, 0, 0, 0, 0, 0, 0,
7858 0, 0, 0, 0, 0, 0, 0, 0,
7859 553, 559, 0, 0, 0, 0, 0, 0,
7860 0, 0, 0, 0, 0, 0, 0, 565,
7861 571, 0, 0, 0, 0, 0, 0, 577,
7862 0, 0, 0, 0, 0, 0, 0, 0,
7863 0, 0, 0, 0, 0, 0, 0, 0,
7864 0, 0, 0, 0, 0, 0, 0, 0,
7865 0, 0, 0, 0, 0, 0, 0, 0,
7866 0, 0, 0, 0, 0, 0, 0, 0,
7867 0, 0, 0, 0, 0, 0, 0, 0,
7868 0, 0, 579, 581, 0, 0, 0, 0,
7869 0, 0, 0, 0, 0, 0, 0, 0,
7870 0, 0, 0, 0, 0, 0, 0, 0,
7871};
7872
7873static const Q_UINT16 li_02[] = {
7874 0, 0, 0, 0, 0, 0, 0, 0,
7875 0, 0, 0, 0, 0, 0, 0, 0,
7876 0, 0, 0, 0, 0, 0, 0, 0,
7877 0, 0, 0, 0, 0, 0, 0, 0,
7878 0, 0, 0, 0, 0, 0, 583, 585,
7879 587, 589, 0, 0, 0, 0, 591, 593,
7880 0, 0, 0, 0, 0, 0, 0, 0,
7881 0, 0, 0, 0, 0, 0, 0, 0,
7882 0, 0, 0, 0, 0, 0, 0, 0,
7883 0, 0, 0, 0, 0, 0, 0, 0,
7884 0, 0, 0, 0, 0, 0, 0, 0,
7885 0, 0, 0, 0, 0, 0, 0, 0,
7886 0, 0, 0, 0, 0, 0, 0, 0,
7887 0, 0, 0, 0, 0, 0, 0, 0,
7888 0, 0, 0, 0, 0, 0, 0, 0,
7889 0, 0, 0, 0, 0, 0, 0, 0,
7890 0, 0, 0, 0, 0, 0, 0, 0,
7891 0, 0, 0, 0, 0, 0, 0, 0,
7892 0, 0, 595, 0, 0, 0, 0, 0,
7893 0, 0, 0, 0, 0, 0, 0, 0,
7894 0, 0, 0, 0, 0, 0, 0, 0,
7895 0, 0, 0, 0, 0, 0, 0, 0,
7896 0, 0, 0, 0, 0, 0, 0, 0,
7897 0, 0, 0, 0, 0, 0, 0, 0,
7898 0, 0, 0, 0, 0, 0, 0, 0,
7899 0, 0, 0, 0, 0, 0, 0, 0,
7900 0, 0, 0, 0, 0, 0, 0, 0,
7901 0, 0, 0, 0, 0, 0, 0, 0,
7902 0, 0, 0, 0, 0, 0, 0, 0,
7903 0, 0, 0, 0, 0, 0, 0, 0,
7904 0, 0, 0, 0, 0, 0, 0, 0,
7905 0, 0, 0, 0, 0, 0, 0, 0,
7906};
7907
7908static const Q_UINT16 li_03[] = {
7909 0, 0, 0, 0, 0, 0, 0, 0,
7910 597, 0, 0, 0, 0, 0, 0, 0,
7911 0, 0, 0, 0, 0, 0, 0, 0,
7912 0, 0, 0, 0, 0, 0, 0, 0,
7913 0, 0, 0, 0, 0, 0, 0, 0,
7914 0, 0, 0, 0, 0, 0, 0, 0,
7915 0, 0, 0, 0, 0, 0, 0, 0,
7916 0, 0, 0, 0, 0, 0, 0, 0,
7917 0, 0, 0, 0, 0, 0, 0, 0,
7918 0, 0, 0, 0, 0, 0, 0, 0,
7919 0, 0, 0, 0, 0, 0, 0, 0,
7920 0, 0, 0, 0, 0, 0, 0, 0,
7921 0, 0, 0, 0, 0, 0, 0, 0,
7922 0, 0, 0, 0, 0, 0, 0, 0,
7923 0, 0, 0, 0, 0, 0, 0, 0,
7924 0, 0, 0, 0, 0, 0, 0, 0,
7925 0, 0, 0, 0, 0, 0, 0, 0,
7926 0, 0, 0, 0, 0, 0, 0, 0,
7927 0, 599, 0, 0, 0, 607, 0, 612,
7928 0, 618, 0, 0, 0, 0, 0, 626,
7929 0, 631, 0, 0, 0, 633, 0, 0,
7930 0, 640, 0, 0, 646, 0, 648, 0,
7931 0, 650, 0, 0, 0, 659, 0, 664,
7932 0, 671, 0, 0, 0, 0, 0, 680,
7933 0, 685, 0, 0, 0, 688, 0, 0,
7934 0, 697, 704, 708, 0, 0, 712, 0,
7935 0, 0, 714, 0, 0, 0, 0, 0,
7936 0, 0, 0, 0, 0, 0, 0, 0,
7937 0, 0, 0, 0, 0, 0, 0, 0,
7938 0, 0, 0, 0, 0, 0, 0, 0,
7939 0, 0, 0, 0, 0, 0, 0, 0,
7940 0, 0, 0, 0, 0, 0, 0, 0,
7941};
7942
7943static const Q_UINT16 li_04[] = {
7944 0, 0, 0, 0, 0, 0, 717, 0,
7945 0, 0, 0, 0, 0, 0, 0, 0,
7946 719, 0, 0, 722, 0, 724, 728, 731,
7947 733, 0, 738, 0, 0, 0, 740, 0,
7948 0, 0, 0, 742, 0, 0, 0, 747,
7949 0, 0, 0, 749, 0, 751, 0, 0,
7950 753, 0, 0, 756, 0, 758, 762, 765,
7951 767, 0, 772, 0, 0, 0, 774, 0,
7952 0, 0, 0, 776, 0, 0, 0, 781,
7953 0, 0, 0, 783, 0, 785, 0, 0,
7954 0, 0, 0, 0, 0, 0, 787, 0,
7955 0, 0, 0, 0, 0, 0, 0, 0,
7956 0, 0, 0, 0, 0, 0, 0, 0,
7957 0, 0, 0, 0, 0, 0, 0, 0,
7958 0, 0, 0, 0, 789, 791, 0, 0,
7959 0, 0, 0, 0, 0, 0, 0, 0,
7960 0, 0, 0, 0, 0, 0, 0, 0,
7961 0, 0, 0, 0, 0, 0, 0, 0,
7962 0, 0, 0, 0, 0, 0, 0, 0,
7963 0, 0, 0, 0, 0, 0, 0, 0,
7964 0, 0, 0, 0, 0, 0, 0, 0,
7965 0, 0, 0, 0, 0, 0, 0, 0,
7966 0, 0, 0, 0, 0, 0, 0, 0,
7967 0, 0, 0, 0, 0, 0, 0, 0,
7968 0, 0, 0, 0, 0, 0, 0, 0,
7969 0, 0, 0, 0, 0, 0, 0, 0,
7970 0, 0, 0, 0, 0, 0, 0, 0,
7971 793, 795, 0, 0, 0, 0, 0, 0,
7972 0, 0, 0, 0, 0, 0, 0, 0,
7973 797, 799, 0, 0, 0, 0, 0, 0,
7974 0, 0, 0, 0, 0, 0, 0, 0,
7975 0, 0, 0, 0, 0, 0, 0, 0,
7976};
7977
7978static const Q_UINT16 li_05[] = {
7979 0, 0, 0, 0, 0, 0, 0, 0,
7980 0, 0, 0, 0, 0, 0, 0, 0,
7981 0, 0, 0, 0, 0, 0, 0, 0,
7982 0, 0, 0, 0, 0, 0, 0, 0,
7983 0, 0, 0, 0, 0, 0, 0, 0,
7984 0, 0, 0, 0, 0, 0, 0, 0,
7985 0, 0, 0, 0, 0, 0, 0, 0,
7986 0, 0, 0, 0, 0, 0, 0, 0,
7987 0, 0, 0, 0, 0, 0, 0, 0,
7988 0, 0, 0, 0, 0, 0, 0, 0,
7989 0, 0, 0, 0, 0, 0, 0, 0,
7990 0, 0, 0, 0, 0, 0, 0, 0,
7991 0, 0, 0, 0, 0, 0, 0, 0,
7992 0, 0, 0, 0, 0, 0, 0, 0,
7993 0, 0, 0, 0, 0, 0, 0, 0,
7994 0, 0, 0, 0, 0, 0, 0, 0,
7995 0, 0, 0, 0, 0, 0, 0, 0,
7996 0, 0, 0, 0, 0, 0, 0, 0,
7997 0, 0, 0, 0, 0, 0, 0, 0,
7998 0, 0, 0, 0, 0, 0, 0, 0,
7999 0, 0, 0, 0, 0, 0, 0, 0,
8000 0, 0, 0, 0, 0, 0, 0, 0,
8001 0, 0, 0, 0, 0, 0, 0, 0,
8002 0, 0, 0, 0, 0, 0, 0, 0,
8003 0, 0, 0, 0, 0, 0, 0, 0,
8004 0, 0, 0, 0, 0, 0, 0, 0,
8005 801, 805, 808, 810, 812, 814, 817, 0,
8006 819, 821, 824, 826, 829, 0, 831, 0,
8007 833, 835, 0, 837, 839, 0, 842, 844,
8008 846, 848, 852, 0, 0, 0, 0, 0,
8009 0, 0, 854, 0, 0, 0, 0, 0,
8010 0, 0, 0, 0, 0, 0, 0, 0,
8011};
8012
8013static const Q_UINT16 li_06[] = {
8014 0, 0, 0, 0, 0, 0, 0, 0,
8015 0, 0, 0, 0, 0, 0, 0, 0,
8016 0, 0, 0, 0, 0, 0, 0, 0,
8017 0, 0, 0, 0, 0, 0, 0, 0,
8018 0, 0, 0, 0, 0, 0, 0, 856,
8019 0, 0, 0, 0, 0, 0, 0, 0,
8020 0, 0, 0, 0, 0, 0, 0, 0,
8021 0, 0, 0, 0, 0, 0, 0, 0,
8022 0, 0, 0, 0, 0, 0, 0, 0,
8023 860, 0, 862, 0, 0, 0, 0, 0,
8024 0, 0, 0, 0, 0, 0, 0, 0,
8025 0, 0, 0, 0, 0, 0, 0, 0,
8026 0, 0, 0, 0, 0, 0, 0, 0,
8027 0, 0, 0, 0, 0, 0, 0, 0,
8028 0, 0, 0, 0, 0, 0, 0, 0,
8029 0, 0, 0, 0, 0, 0, 0, 0,
8030 0, 0, 0, 0, 0, 0, 0, 0,
8031 0, 0, 0, 0, 0, 0, 0, 0,
8032 0, 0, 0, 0, 0, 0, 0, 0,
8033 0, 0, 0, 0, 0, 0, 0, 0,
8034 0, 0, 0, 0, 0, 0, 0, 0,
8035 0, 0, 0, 0, 0, 0, 0, 0,
8036 0, 0, 0, 0, 0, 0, 0, 0,
8037 0, 0, 0, 0, 0, 0, 0, 0,
8038 0, 864, 0, 0, 0, 0, 0, 0,
8039 0, 0, 0, 0, 0, 0, 0, 0,
8040 0, 0, 866, 0, 0, 868, 0, 0,
8041 0, 0, 0, 0, 0, 0, 0, 0,
8042 0, 0, 0, 0, 0, 0, 0, 0,
8043 0, 0, 0, 0, 0, 0, 0, 0,
8044 0, 0, 0, 0, 0, 0, 0, 0,
8045 0, 0, 0, 0, 0, 0, 0, 0,
8046};
8047
8048static const Q_UINT16 li_07[] = {
8049 0, 0, 0, 0, 0, 0, 0, 0,
8050 0, 0, 0, 0, 0, 0, 0, 0,
8051 0, 0, 0, 0, 0, 0, 0, 0,
8052 0, 0, 0, 0, 0, 0, 0, 0,
8053 0, 0, 0, 0, 0, 0, 0, 0,
8054 0, 0, 0, 0, 0, 0, 0, 0,
8055 0, 0, 0, 0, 0, 0, 0, 0,
8056 0, 0, 0, 0, 0, 0, 0, 0,
8057 0, 0, 0, 0, 0, 0, 0, 0,
8058 0, 0, 0, 0, 0, 0, 0, 0,
8059 0, 0, 0, 0, 0, 0, 0, 0,
8060 0, 0, 0, 0, 0, 0, 0, 0,
8061 0, 0, 0, 0, 0, 0, 0, 0,
8062 0, 0, 0, 0, 0, 0, 0, 0,
8063 0, 0, 0, 0, 0, 0, 0, 0,
8064 0, 0, 0, 0, 0, 0, 0, 0,
8065 0, 0, 0, 0, 0, 0, 0, 0,
8066 0, 0, 0, 0, 0, 0, 0, 0,
8067 0, 0, 0, 0, 0, 0, 0, 0,
8068 0, 0, 0, 0, 0, 0, 0, 0,
8069 0, 0, 0, 0, 0, 0, 0, 0,
8070 0, 0, 0, 0, 0, 0, 0, 0,
8071 0, 0, 0, 0, 0, 0, 0, 0,
8072 0, 0, 0, 0, 0, 0, 0, 0,
8073 0, 0, 0, 0, 0, 0, 0, 0,
8074 0, 0, 0, 0, 0, 0, 0, 0,
8075 0, 0, 0, 0, 0, 0, 0, 0,
8076 0, 0, 0, 0, 0, 0, 0, 0,
8077 0, 0, 0, 0, 0, 0, 0, 0,
8078 0, 0, 0, 0, 0, 0, 0, 0,
8079 0, 0, 0, 0, 0, 0, 0, 0,
8080 0, 0, 0, 0, 0, 0, 0, 0,
8081};
8082
8083static const Q_UINT16 li_09[] = {
8084 0, 0, 0, 0, 0, 0, 0, 0,
8085 0, 0, 0, 0, 0, 0, 0, 0,
8086 0, 0, 0, 0, 0, 870, 872, 874,
8087 0, 0, 0, 0, 876, 0, 0, 0,
8088 0, 878, 880, 0, 0, 0, 0, 0,
8089 882, 0, 0, 884, 0, 0, 0, 886,
8090 888, 0, 0, 890, 0, 0, 0, 0,
8091 0, 0, 0, 0, 0, 0, 0, 0,
8092 0, 0, 0, 0, 0, 0, 0, 0,
8093 0, 0, 0, 0, 0, 0, 0, 0,
8094 0, 0, 0, 0, 0, 0, 0, 0,
8095 0, 0, 0, 0, 0, 0, 0, 0,
8096 0, 0, 0, 0, 0, 0, 0, 0,
8097 0, 0, 0, 0, 0, 0, 0, 0,
8098 0, 0, 0, 0, 0, 0, 0, 0,
8099 0, 0, 0, 0, 0, 0, 0, 0,
8100 0, 0, 0, 0, 0, 0, 0, 0,
8101 0, 0, 0, 0, 0, 0, 0, 0,
8102 0, 0, 0, 0, 0, 0, 0, 0,
8103 0, 0, 0, 0, 0, 0, 0, 0,
8104 0, 892, 894, 0, 0, 0, 0, 0,
8105 0, 0, 0, 0, 0, 0, 0, 896,
8106 0, 0, 0, 0, 0, 0, 0, 0,
8107 0, 0, 0, 0, 0, 0, 0, 0,
8108 0, 0, 0, 0, 0, 0, 0, 898,
8109 0, 0, 0, 0, 0, 0, 0, 0,
8110 0, 0, 0, 0, 0, 0, 0, 0,
8111 0, 0, 0, 0, 0, 0, 0, 0,
8112 0, 0, 0, 0, 0, 0, 0, 0,
8113 0, 0, 0, 0, 0, 0, 0, 0,
8114 0, 0, 0, 0, 0, 0, 0, 0,
8115 0, 0, 0, 0, 0, 0, 0, 0,
8116};
8117
8118static const Q_UINT16 li_0A[] = {
8119 0, 0, 0, 0, 0, 0, 0, 0,
8120 0, 0, 0, 0, 0, 0, 0, 0,
8121 0, 0, 0, 0, 0, 0, 901, 903,
8122 0, 0, 0, 0, 905, 0, 0, 0,
8123 0, 0, 0, 0, 0, 0, 0, 0,
8124 0, 0, 0, 907, 0, 0, 0, 0,
8125 0, 0, 909, 0, 0, 0, 0, 0,
8126 911, 0, 0, 0, 0, 0, 0, 0,
8127 0, 0, 0, 0, 0, 0, 0, 0,
8128 0, 0, 0, 0, 0, 0, 0, 0,
8129 0, 0, 0, 0, 0, 0, 0, 0,
8130 0, 0, 0, 0, 0, 0, 0, 0,
8131 0, 0, 0, 0, 0, 0, 0, 0,
8132 0, 0, 0, 0, 0, 0, 0, 0,
8133 0, 0, 0, 0, 0, 0, 0, 0,
8134 0, 0, 0, 0, 0, 0, 0, 0,
8135 0, 0, 0, 0, 0, 0, 0, 0,
8136 0, 0, 0, 0, 0, 0, 0, 0,
8137 0, 0, 0, 0, 0, 0, 0, 0,
8138 0, 0, 0, 0, 0, 0, 0, 0,
8139 0, 0, 0, 0, 0, 0, 0, 0,
8140 0, 0, 0, 0, 0, 0, 0, 0,
8141 0, 0, 0, 0, 0, 0, 0, 0,
8142 0, 0, 0, 0, 0, 0, 0, 0,
8143 0, 0, 0, 0, 0, 0, 0, 0,
8144 0, 0, 0, 0, 0, 0, 0, 0,
8145 0, 0, 0, 0, 0, 0, 0, 0,
8146 0, 0, 0, 0, 0, 0, 0, 0,
8147 0, 0, 0, 0, 0, 0, 0, 0,
8148 0, 0, 0, 0, 0, 0, 0, 0,
8149 0, 0, 0, 0, 0, 0, 0, 0,
8150 0, 0, 0, 0, 0, 0, 0, 0,
8151};
8152
8153static const Q_UINT16 li_0B[] = {
8154 0, 0, 0, 0, 0, 0, 0, 0,
8155 0, 0, 0, 0, 0, 0, 0, 0,
8156 0, 0, 0, 0, 0, 0, 0, 0,
8157 0, 0, 0, 0, 0, 0, 0, 0,
8158 0, 913, 915, 0, 0, 0, 0, 0,
8159 0, 0, 0, 0, 0, 0, 0, 0,
8160 0, 0, 0, 0, 0, 0, 0, 0,
8161 0, 0, 0, 0, 0, 0, 0, 0,
8162 0, 0, 0, 0, 0, 0, 0, 917,
8163 0, 0, 0, 0, 0, 0, 0, 0,
8164 0, 0, 0, 0, 0, 0, 0, 0,
8165 0, 0, 0, 0, 0, 0, 0, 0,
8166 0, 0, 0, 0, 0, 0, 0, 0,
8167 0, 0, 0, 0, 0, 0, 0, 0,
8168 0, 0, 0, 0, 0, 0, 0, 0,
8169 0, 0, 0, 0, 0, 0, 0, 0,
8170 0, 0, 0, 0, 0, 0, 0, 0,
8171 0, 0, 0, 0, 0, 0, 0, 0,
8172 0, 0, 921, 0, 0, 0, 0, 0,
8173 0, 0, 0, 0, 0, 0, 0, 0,
8174 0, 0, 0, 0, 0, 0, 0, 0,
8175 0, 0, 0, 0, 0, 0, 0, 0,
8176 0, 0, 0, 0, 0, 0, 0, 0,
8177 0, 0, 0, 0, 0, 0, 0, 0,
8178 0, 0, 0, 0, 0, 0, 923, 926,
8179 0, 0, 0, 0, 0, 0, 0, 0,
8180 0, 0, 0, 0, 0, 0, 0, 0,
8181 0, 0, 0, 0, 0, 0, 0, 0,
8182 0, 0, 0, 0, 0, 0, 0, 0,
8183 0, 0, 0, 0, 0, 0, 0, 0,
8184 0, 0, 0, 0, 0, 0, 0, 0,
8185 0, 0, 0, 0, 0, 0, 0, 0,
8186};
8187
8188static const Q_UINT16 li_0C[] = {
8189 0, 0, 0, 0, 0, 0, 0, 0,
8190 0, 0, 0, 0, 0, 0, 0, 0,
8191 0, 0, 0, 0, 0, 0, 0, 0,
8192 0, 0, 0, 0, 0, 0, 0, 0,
8193 0, 0, 0, 0, 0, 0, 0, 0,
8194 0, 0, 0, 0, 0, 0, 0, 0,
8195 0, 0, 0, 0, 0, 0, 0, 0,
8196 0, 0, 0, 0, 0, 0, 0, 0,
8197 0, 0, 0, 0, 0, 0, 928, 0,
8198 0, 0, 0, 0, 0, 0, 0, 0,
8199 0, 0, 0, 0, 0, 0, 0, 0,
8200 0, 0, 0, 0, 0, 0, 0, 0,
8201 0, 0, 0, 0, 0, 0, 0, 0,
8202 0, 0, 0, 0, 0, 0, 0, 0,
8203 0, 0, 0, 0, 0, 0, 0, 0,
8204 0, 0, 0, 0, 0, 0, 0, 0,
8205 0, 0, 0, 0, 0, 0, 0, 0,
8206 0, 0, 0, 0, 0, 0, 0, 0,
8207 0, 0, 0, 0, 0, 0, 0, 0,
8208 0, 0, 0, 0, 0, 0, 0, 0,
8209 0, 0, 0, 0, 0, 0, 0, 0,
8210 0, 0, 0, 0, 0, 0, 0, 0,
8211 0, 0, 0, 0, 0, 0, 0, 0,
8212 0, 0, 0, 0, 0, 0, 0, 930,
8213 0, 0, 0, 0, 0, 0, 932, 0,
8214 0, 0, 936, 0, 0, 0, 0, 0,
8215 0, 0, 0, 0, 0, 0, 0, 0,
8216 0, 0, 0, 0, 0, 0, 0, 0,
8217 0, 0, 0, 0, 0, 0, 0, 0,
8218 0, 0, 0, 0, 0, 0, 0, 0,
8219 0, 0, 0, 0, 0, 0, 0, 0,
8220 0, 0, 0, 0, 0, 0, 0, 0,
8221};
8222
8223static const Q_UINT16 li_0D[] = {
8224 0, 0, 0, 0, 0, 0, 0, 0,
8225 0, 0, 0, 0, 0, 0, 0, 0,
8226 0, 0, 0, 0, 0, 0, 0, 0,
8227 0, 0, 0, 0, 0, 0, 0, 0,
8228 0, 0, 0, 0, 0, 0, 0, 0,
8229 0, 0, 0, 0, 0, 0, 0, 0,
8230 0, 0, 0, 0, 0, 0, 0, 0,
8231 0, 0, 0, 0, 0, 0, 0, 0,
8232 0, 0, 0, 0, 0, 0, 938, 941,
8233 0, 0, 0, 0, 0, 0, 0, 0,
8234 0, 0, 0, 0, 0, 0, 0, 0,
8235 0, 0, 0, 0, 0, 0, 0, 0,
8236 0, 0, 0, 0, 0, 0, 0, 0,
8237 0, 0, 0, 0, 0, 0, 0, 0,
8238 0, 0, 0, 0, 0, 0, 0, 0,
8239 0, 0, 0, 0, 0, 0, 0, 0,
8240 0, 0, 0, 0, 0, 0, 0, 0,
8241 0, 0, 0, 0, 0, 0, 0, 0,
8242 0, 0, 0, 0, 0, 0, 0, 0,
8243 0, 0, 0, 0, 0, 0, 0, 0,
8244 0, 0, 0, 0, 0, 0, 0, 0,
8245 0, 0, 0, 0, 0, 0, 0, 0,
8246 0, 0, 0, 0, 0, 0, 0, 0,
8247 0, 0, 0, 0, 0, 0, 0, 0,
8248 0, 0, 0, 0, 0, 0, 0, 0,
8249 0, 0, 0, 0, 0, 0, 0, 0,
8250 0, 0, 0, 0, 0, 0, 0, 0,
8251 0, 943, 0, 0, 947, 0, 0, 0,
8252 0, 0, 0, 0, 0, 0, 0, 0,
8253 0, 0, 0, 0, 0, 0, 0, 0,
8254 0, 0, 0, 0, 0, 0, 0, 0,
8255 0, 0, 0, 0, 0, 0, 0, 0,
8256};
8257
8258static const Q_UINT16 li_0F[] = {
8259 0, 0, 0, 0, 0, 0, 0, 0,
8260 0, 0, 0, 0, 0, 0, 0, 0,
8261 0, 0, 0, 0, 0, 0, 0, 0,
8262 0, 0, 0, 0, 0, 0, 0, 0,
8263 0, 0, 0, 0, 0, 0, 0, 0,
8264 0, 0, 0, 0, 0, 0, 0, 0,
8265 0, 0, 0, 0, 0, 0, 0, 0,
8266 0, 0, 0, 0, 0, 0, 0, 0,
8267 949, 0, 951, 0, 0, 0, 0, 0,
8268 0, 0, 0, 0, 953, 0, 0, 0,
8269 0, 955, 0, 0, 0, 0, 957, 0,
8270 0, 0, 0, 959, 0, 0, 0, 0,
8271 0, 0, 0, 0, 0, 0, 0, 0,
8272 0, 0, 0, 0, 0, 0, 0, 0,
8273 0, 961, 0, 0, 0, 0, 0, 0,
8274 0, 0, 0, 0, 0, 0, 0, 0,
8275 0, 0, 0, 0, 0, 0, 0, 0,
8276 0, 0, 0, 0, 0, 0, 0, 0,
8277 965, 0, 967, 0, 0, 0, 0, 0,
8278 0, 0, 0, 0, 969, 0, 0, 0,
8279 0, 971, 0, 0, 0, 0, 973, 0,
8280 0, 0, 0, 975, 0, 0, 0, 0,
8281 0, 0, 977, 979, 0, 0, 0, 0,
8282 0, 0, 0, 0, 0, 0, 0, 0,
8283 0, 0, 0, 0, 0, 0, 0, 0,
8284 0, 0, 0, 0, 0, 0, 0, 0,
8285 0, 0, 0, 0, 0, 0, 0, 0,
8286 0, 0, 0, 0, 0, 0, 0, 0,
8287 0, 0, 0, 0, 0, 0, 0, 0,
8288 0, 0, 0, 0, 0, 0, 0, 0,
8289 0, 0, 0, 0, 0, 0, 0, 0,
8290 0, 0, 0, 0, 0, 0, 0, 0,
8291};
8292
8293static const Q_UINT16 li_10[] = {
8294 0, 0, 0, 0, 0, 0, 0, 0,
8295 0, 0, 0, 0, 0, 0, 0, 0,
8296 0, 0, 0, 0, 0, 0, 0, 0,
8297 0, 0, 0, 0, 0, 0, 0, 0,
8298 0, 0, 0, 0, 0, 981, 0, 0,
8299 0, 0, 0, 0, 0, 0, 0, 0,
8300 0, 0, 0, 0, 0, 0, 0, 0,
8301 0, 0, 0, 0, 0, 0, 0, 0,
8302 0, 0, 0, 0, 0, 0, 0, 0,
8303 0, 0, 0, 0, 0, 0, 0, 0,
8304 0, 0, 0, 0, 0, 0, 0, 0,
8305 0, 0, 0, 0, 0, 0, 0, 0,
8306 0, 0, 0, 0, 0, 0, 0, 0,
8307 0, 0, 0, 0, 0, 0, 0, 0,
8308 0, 0, 0, 0, 0, 0, 0, 0,
8309 0, 0, 0, 0, 0, 0, 0, 0,
8310 0, 0, 0, 0, 0, 0, 0, 0,
8311 0, 0, 0, 0, 0, 0, 0, 0,
8312 0, 0, 0, 0, 0, 0, 0, 0,
8313 0, 0, 0, 0, 0, 0, 0, 0,
8314 0, 0, 0, 0, 0, 0, 0, 0,
8315 0, 0, 0, 0, 0, 0, 0, 0,
8316 0, 0, 0, 0, 0, 0, 0, 0,
8317 0, 0, 0, 0, 0, 0, 0, 0,
8318 0, 0, 0, 0, 0, 0, 0, 0,
8319 0, 0, 0, 0, 0, 0, 0, 0,
8320 0, 0, 0, 0, 0, 0, 0, 0,
8321 0, 0, 0, 0, 0, 0, 0, 0,
8322 0, 0, 0, 0, 0, 0, 0, 0,
8323 0, 0, 0, 0, 0, 0, 0, 0,
8324 0, 0, 0, 0, 0, 0, 0, 0,
8325 0, 0, 0, 0, 0, 0, 0, 0,
8326};
8327
8328static const Q_UINT16 li_1E[] = {
8329 0, 0, 0, 0, 0, 0, 0, 0,
8330 0, 0, 0, 0, 0, 0, 0, 0,
8331 0, 0, 0, 0, 0, 0, 0, 0,
8332 0, 0, 0, 0, 0, 0, 0, 0,
8333 0, 0, 0, 0, 0, 0, 0, 0,
8334 0, 0, 0, 0, 0, 0, 0, 0,
8335 0, 0, 0, 0, 0, 0, 983, 985,
8336 0, 0, 0, 0, 0, 0, 0, 0,
8337 0, 0, 0, 0, 0, 0, 0, 0,
8338 0, 0, 0, 0, 0, 0, 0, 0,
8339 0, 0, 0, 0, 0, 0, 0, 0,
8340 0, 0, 987, 989, 0, 0, 0, 0,
8341 0, 0, 991, 993, 0, 0, 0, 0,
8342 0, 0, 0, 0, 0, 0, 0, 0,
8343 0, 0, 0, 0, 0, 0, 0, 0,
8344 0, 0, 0, 0, 0, 0, 0, 0,
8345 0, 0, 0, 0, 0, 0, 0, 0,
8346 0, 0, 0, 0, 0, 0, 0, 0,
8347 0, 0, 0, 0, 0, 0, 0, 0,
8348 0, 0, 0, 0, 0, 0, 0, 0,
8349 995, 998, 0, 0, 0, 0, 0, 0,
8350 0, 0, 0, 0, 0, 0, 0, 0,
8351 0, 0, 0, 0, 0, 0, 0, 0,
8352 1001, 1003, 0, 0, 0, 0, 0, 0,
8353 0, 0, 0, 0, 0, 0, 0, 0,
8354 0, 0, 0, 0, 1005, 1007, 0, 0,
8355 0, 0, 0, 0, 0, 0, 0, 0,
8356 0, 0, 0, 0, 0, 0, 0, 0,
8357 0, 0, 0, 0, 0, 0, 0, 0,
8358 0, 0, 0, 0, 0, 0, 0, 0,
8359 0, 0, 0, 0, 0, 0, 0, 0,
8360 0, 0, 0, 0, 0, 0, 0, 0,
8361};
8362
8363static const Q_UINT16 li_1F[] = {
8364 1009, 1014, 1019, 1021, 1023, 1025, 1027, 1029,
8365 1031, 1036, 1041, 1043, 1045, 1047, 1049, 1051,
8366 1053, 1056, 0, 0, 0, 0, 0, 0,
8367 1059, 1062, 0, 0, 0, 0, 0, 0,
8368 1065, 1070, 1075, 1077, 1079, 1081, 1083, 1085,
8369 1087, 1092, 1097, 1099, 1101, 1103, 1105, 1107,
8370 1109, 1113, 0, 0, 0, 0, 0, 0,
8371 1117, 1121, 0, 0, 0, 0, 0, 0,
8372 1125, 1128, 0, 0, 0, 0, 0, 0,
8373 1131, 1134, 0, 0, 0, 0, 0, 0,
8374 1137, 1141, 0, 0, 0, 0, 0, 0,
8375 0, 1145, 0, 0, 0, 0, 0, 0,
8376 1149, 1154, 1159, 1161, 1163, 1165, 1167, 1169,
8377 1171, 1176, 1181, 1183, 1185, 1187, 1189, 1191,
8378 1193, 0, 0, 0, 1195, 0, 0, 0,
8379 0, 0, 0, 0, 1197, 0, 0, 0,
8380 0, 0, 0, 0, 0, 0, 0, 0,
8381 0, 0, 0, 0, 0, 0, 0, 0,
8382 0, 0, 0, 0, 0, 0, 0, 0,
8383 0, 0, 0, 0, 0, 0, 0, 0,
8384 0, 0, 0, 0, 0, 0, 0, 0,
8385 0, 0, 0, 0, 0, 0, 0, 0,
8386 0, 0, 0, 0, 0, 0, 1199, 0,
8387 0, 0, 0, 0, 0, 0, 0, 1201,
8388 0, 0, 0, 0, 0, 0, 1205, 0,
8389 0, 0, 0, 0, 0, 0, 0, 0,
8390 0, 0, 0, 0, 0, 0, 0, 0,
8391 0, 0, 0, 0, 0, 0, 0, 0,
8392 0, 0, 0, 0, 0, 0, 0, 0,
8393 0, 0, 0, 0, 0, 0, 0, 0,
8394 0, 0, 0, 0, 0, 0, 1207, 0,
8395 0, 0, 0, 0, 0, 0, 1209, 0,
8396};
8397
8398static const Q_UINT16 li_21[] = {
8399 0, 0, 0, 0, 0, 0, 0, 0,
8400 0, 0, 0, 0, 0, 0, 0, 0,
8401 0, 0, 0, 0, 0, 0, 0, 0,
8402 0, 0, 0, 0, 0, 0, 0, 0,
8403 0, 0, 0, 0, 0, 0, 0, 0,
8404 0, 0, 0, 0, 0, 0, 0, 0,
8405 0, 0, 0, 0, 0, 0, 0, 0,
8406 0, 0, 0, 0, 0, 0, 0, 0,
8407 0, 0, 0, 0, 0, 0, 0, 0,
8408 0, 0, 0, 0, 0, 0, 0, 0,
8409 0, 0, 0, 0, 0, 0, 0, 0,
8410 0, 0, 0, 0, 0, 0, 0, 0,
8411 0, 0, 0, 0, 0, 0, 0, 0,
8412 0, 0, 0, 0, 0, 0, 0, 0,
8413 0, 0, 0, 0, 0, 0, 0, 0,
8414 0, 0, 0, 0, 0, 0, 0, 0,
8415 0, 0, 0, 0, 0, 0, 0, 0,
8416 0, 0, 0, 0, 0, 0, 0, 0,
8417 1213, 0, 1215, 0, 1217, 0, 0, 0,
8418 0, 0, 0, 0, 0, 0, 0, 0,
8419 0, 0, 0, 0, 0, 0, 0, 0,
8420 0, 0, 0, 0, 0, 0, 0, 0,
8421 0, 0, 0, 0, 0, 0, 0, 0,
8422 0, 0, 0, 0, 0, 0, 0, 0,
8423 0, 0, 0, 0, 0, 0, 0, 0,
8424 0, 0, 0, 0, 0, 0, 0, 0,
8425 1219, 0, 1221, 0, 1223, 0, 0, 0,
8426 0, 0, 0, 0, 0, 0, 0, 0,
8427 0, 0, 0, 0, 0, 0, 0, 0,
8428 0, 0, 0, 0, 0, 0, 0, 0,
8429 0, 0, 0, 0, 0, 0, 0, 0,
8430 0, 0, 0, 0, 0, 0, 0, 0,
8431};
8432
8433static const Q_UINT16 li_22[] = {
8434 0, 0, 0, 1225, 0, 0, 0, 0,
8435 1227, 0, 0, 1229, 0, 0, 0, 0,
8436 0, 0, 0, 0, 0, 0, 0, 0,
8437 0, 0, 0, 0, 0, 0, 0, 0,
8438 0, 0, 0, 1231, 0, 1233, 0, 0,
8439 0, 0, 0, 0, 0, 0, 0, 0,
8440 0, 0, 0, 0, 0, 0, 0, 0,
8441 0, 0, 0, 0, 1235, 0, 0, 0,
8442 0, 0, 0, 1237, 0, 1239, 0, 0,
8443 1241, 0, 0, 0, 0, 1243, 0, 0,
8444 0, 0, 0, 0, 0, 0, 0, 0,
8445 0, 0, 0, 0, 0, 0, 0, 0,
8446 0, 1245, 0, 0, 1247, 1249, 0, 0,
8447 0, 0, 0, 0, 0, 0, 0, 0,
8448 0, 0, 1251, 1253, 0, 0, 1255, 1257,
8449 0, 0, 1259, 1261, 1263, 1265, 0, 0,
8450 0, 0, 1267, 1269, 0, 0, 1271, 1273,
8451 0, 0, 0, 0, 0, 0, 0, 0,
8452 0, 1275, 1277, 0, 0, 0, 0, 0,
8453 0, 0, 0, 0, 0, 0, 0, 0,
8454 0, 0, 1279, 0, 0, 0, 0, 0,
8455 1281, 1283, 0, 1285, 0, 0, 0, 0,
8456 0, 0, 1287, 1289, 1291, 1293, 0, 0,
8457 0, 0, 0, 0, 0, 0, 0, 0,
8458 0, 0, 0, 0, 0, 0, 0, 0,
8459 0, 0, 0, 0, 0, 0, 0, 0,
8460 0, 0, 0, 0, 0, 0, 0, 0,
8461 0, 0, 0, 0, 0, 0, 0, 0,
8462 0, 0, 0, 0, 0, 0, 0, 0,
8463 0, 0, 0, 0, 0, 0, 0, 0,
8464 0, 0, 0, 0, 0, 0, 0, 0,
8465 0, 0, 0, 0, 0, 0, 0, 0,
8466};
8467
8468static const Q_UINT16 li_2A[] = {
8469 0, 0, 0, 0, 0, 0, 0, 0,
8470 0, 0, 0, 0, 0, 0, 0, 0,
8471 0, 0, 0, 0, 0, 0, 0, 0,
8472 0, 0, 0, 0, 0, 0, 0, 0,
8473 0, 0, 0, 0, 0, 0, 0, 0,
8474 0, 0, 0, 0, 0, 0, 0, 0,
8475 0, 0, 0, 0, 0, 0, 0, 0,
8476 0, 0, 0, 0, 0, 0, 0, 0,
8477 0, 0, 0, 0, 0, 0, 0, 0,
8478 0, 0, 0, 0, 0, 0, 0, 0,
8479 0, 0, 0, 0, 0, 0, 0, 0,
8480 0, 0, 0, 0, 0, 0, 0, 0,
8481 0, 0, 0, 0, 0, 0, 0, 0,
8482 0, 0, 0, 0, 0, 0, 0, 0,
8483 0, 0, 0, 0, 0, 0, 0, 0,
8484 0, 0, 0, 0, 0, 0, 0, 0,
8485 0, 0, 0, 0, 0, 0, 0, 0,
8486 0, 0, 0, 0, 0, 0, 0, 0,
8487 0, 0, 0, 0, 0, 0, 0, 0,
8488 0, 0, 0, 0, 0, 0, 0, 0,
8489 0, 0, 0, 0, 0, 0, 0, 0,
8490 0, 0, 0, 0, 0, 0, 0, 0,
8491 0, 0, 0, 0, 0, 0, 0, 0,
8492 0, 0, 0, 0, 0, 0, 0, 0,
8493 0, 0, 0, 0, 0, 0, 0, 0,
8494 0, 0, 0, 0, 0, 0, 0, 0,
8495 0, 0, 0, 0, 0, 0, 0, 0,
8496 0, 0, 0, 0, 0, 1295, 0, 0,
8497 0, 0, 0, 0, 0, 0, 0, 0,
8498 0, 0, 0, 0, 0, 0, 0, 0,
8499 0, 0, 0, 0, 0, 0, 0, 0,
8500 0, 0, 0, 0, 0, 0, 0, 0,
8501};
8502
8503static const Q_UINT16 li_30[] = {
8504 0, 0, 0, 0, 0, 0, 0, 0,
8505 0, 0, 0, 0, 0, 0, 0, 0,
8506 0, 0, 0, 0, 0, 0, 0, 0,
8507 0, 0, 0, 0, 0, 0, 0, 0,
8508 0, 0, 0, 0, 0, 0, 0, 0,
8509 0, 0, 0, 0, 0, 0, 0, 0,
8510 0, 0, 0, 0, 0, 0, 0, 0,
8511 0, 0, 0, 0, 0, 0, 0, 0,
8512 0, 0, 0, 0, 0, 0, 1297, 0,
8513 0, 0, 0, 1299, 0, 1301, 0, 1303,
8514 0, 1305, 0, 1307, 0, 1309, 0, 1311,
8515 0, 1313, 0, 1315, 0, 1317, 0, 1319,
8516 0, 1321, 0, 0, 1323, 0, 1325, 0,
8517 1327, 0, 0, 0, 0, 0, 0, 1329,
8518 0, 0, 1332, 0, 0, 1335, 0, 0,
8519 1338, 0, 0, 1341, 0, 0, 0, 0,
8520 0, 0, 0, 0, 0, 0, 0, 0,
8521 0, 0, 0, 0, 0, 0, 0, 0,
8522 0, 0, 0, 0, 0, 0, 0, 0,
8523 0, 0, 0, 0, 0, 1344, 0, 0,
8524 0, 0, 0, 0, 0, 0, 1346, 0,
8525 0, 0, 0, 1348, 0, 1350, 0, 1352,
8526 0, 1354, 0, 1356, 0, 1358, 0, 1360,
8527 0, 1362, 0, 1364, 0, 1366, 0, 1368,
8528 0, 1370, 0, 0, 1372, 0, 1374, 0,
8529 1376, 0, 0, 0, 0, 0, 0, 1378,
8530 0, 0, 1381, 0, 0, 1384, 0, 0,
8531 1387, 0, 0, 1390, 0, 0, 0, 0,
8532 0, 0, 0, 0, 0, 0, 0, 0,
8533 0, 0, 0, 0, 0, 0, 0, 1393,
8534 1395, 1397, 1399, 0, 0, 0, 0, 0,
8535 0, 0, 0, 0, 0, 1401, 0, 0,
8536};
8537
8538static const Q_UINT16 li_FB[] = {
8539 0, 0, 0, 0, 0, 0, 0, 0,
8540 0, 0, 0, 0, 0, 0, 0, 0,
8541 0, 0, 0, 0, 0, 0, 0, 0,
8542 0, 0, 0, 0, 0, 0, 0, 0,
8543 0, 0, 0, 0, 0, 0, 0, 0,
8544 0, 0, 0, 0, 0, 0, 0, 0,
8545 0, 0, 0, 0, 0, 0, 0, 0,
8546 0, 0, 0, 0, 0, 0, 0, 0,
8547 0, 0, 0, 0, 0, 0, 0, 0,
8548 0, 1403, 0, 0, 0, 0, 0, 0,
8549 0, 0, 0, 0, 0, 0, 0, 0,
8550 0, 0, 0, 0, 0, 0, 0, 0,
8551 0, 0, 0, 0, 0, 0, 0, 0,
8552 0, 0, 0, 0, 0, 0, 0, 0,
8553 0, 0, 0, 0, 0, 0, 0, 0,
8554 0, 0, 0, 0, 0, 0, 0, 0,
8555 0, 0, 0, 0, 0, 0, 0, 0,
8556 0, 0, 0, 0, 0, 0, 0, 0,
8557 0, 0, 0, 0, 0, 0, 0, 0,
8558 0, 0, 0, 0, 0, 0, 0, 0,
8559 0, 0, 0, 0, 0, 0, 0, 0,
8560 0, 0, 0, 0, 0, 0, 0, 0,
8561 0, 0, 0, 0, 0, 0, 0, 0,
8562 0, 0, 0, 0, 0, 0, 0, 0,
8563 0, 0, 0, 0, 0, 0, 0, 0,
8564 0, 0, 0, 0, 0, 0, 0, 0,
8565 0, 0, 0, 0, 0, 0, 0, 0,
8566 0, 0, 0, 0, 0, 0, 0, 0,
8567 0, 0, 0, 0, 0, 0, 0, 0,
8568 0, 0, 0, 0, 0, 0, 0, 0,
8569 0, 0, 0, 0, 0, 0, 0, 0,
8570 0, 0, 0, 0, 0, 0, 0, 0,
8571};
8572
8573static const Q_UINT16 * const ligature_info[256] = {
8574 li_00, li_01, li_02, li_03, li_04, li_05, li_06, li_07,
8575 li_07, li_09, li_0A, li_0B, li_0C, li_0D, li_07, li_0F,
8576 li_10, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8577 li_07, li_07, li_07, li_07, li_07, li_07, li_1E, li_1F,
8578 li_07, li_21, li_22, li_07, li_07, li_07, li_07, li_07,
8579 li_07, li_07, li_2A, li_07, li_07, li_07, li_07, li_07,
8580 li_30, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8581 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8582 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8583 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8584 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8585 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8586 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8587 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8588 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8589 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8590 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8591 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8592 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8593 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8594 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8595 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8596 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8597 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8598 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8599 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8600 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8601 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8602 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8603 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8604 li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
8605 li_07, li_07, li_07, li_FB, li_07, li_07, li_07, li_07,
8606};
8607// 15098 bytes
8608
8609static const Q_UINT8 dir_00[] = {
8610 18, 18, 18, 18, 18, 18, 18, 18,
8611 18, 8, 7, 8, 9, 7, 18, 18,
8612 18, 18, 18, 18, 18, 18, 18, 18,
8613 18, 18, 18, 18, 7, 7, 7, 8,
8614 9, 10, 10, 4, 4, 4, 10, 10,
8615 138, 138, 10, 4, 6, 4, 6, 3,
8616 2, 2, 2, 2, 2, 2, 2, 2,
8617 2, 2, 6, 10, 138, 10, 138, 10,
8618 10, 0, 0, 0, 0, 0, 0, 0,
8619 0, 0, 0, 0, 0, 0, 0, 0,
8620 0, 0, 0, 0, 0, 0, 0, 0,
8621 0, 0, 0, 138, 10, 138, 10, 10,
8622 10, 0, 0, 0, 0, 0, 0, 0,
8623 0, 0, 0, 0, 0, 0, 0, 0,
8624 0, 0, 0, 0, 0, 0, 0, 0,
8625 0, 0, 0, 138, 10, 138, 10, 18,
8626 18, 18, 18, 18, 18, 7, 18, 18,
8627 18, 18, 18, 18, 18, 18, 18, 18,
8628 18, 18, 18, 18, 18, 18, 18, 18,
8629 18, 18, 18, 18, 18, 18, 18, 18,
8630 6, 10, 4, 4, 4, 4, 10, 10,
8631 10, 10, 0, 138, 10, 10, 10, 10,
8632 4, 4, 2, 2, 10, 0, 10, 10,
8633 10, 2, 0, 138, 10, 10, 10, 10,
8634 0, 0, 0, 0, 0, 0, 0, 0,
8635 0, 0, 0, 0, 0, 0, 0, 0,
8636 0, 0, 0, 0, 0, 0, 0, 10,
8637 0, 0, 0, 0, 0, 0, 0, 0,
8638 0, 0, 0, 0, 0, 0, 0, 0,
8639 0, 0, 0, 0, 0, 0, 0, 0,
8640 0, 0, 0, 0, 0, 0, 0, 10,
8641 0, 0, 0, 0, 0, 0, 0, 0,
8642};
8643
8644static const Q_UINT8 dir_01[] = {
8645 0, 0, 0, 0, 0, 0, 0, 0,
8646 0, 0, 0, 0, 0, 0, 0, 0,
8647 0, 0, 0, 0, 0, 0, 0, 0,
8648 0, 0, 0, 0, 0, 0, 0, 0,
8649 0, 0, 0, 0, 0, 0, 0, 0,
8650 0, 0, 0, 0, 0, 0, 0, 0,
8651 0, 0, 0, 0, 0, 0, 0, 0,
8652 0, 0, 0, 0, 0, 0, 0, 0,
8653 0, 0, 0, 0, 0, 0, 0, 0,
8654 0, 0, 0, 0, 0, 0, 0, 0,
8655 0, 0, 0, 0, 0, 0, 0, 0,
8656 0, 0, 0, 0, 0, 0, 0, 0,
8657 0, 0, 0, 0, 0, 0, 0, 0,
8658 0, 0, 0, 0, 0, 0, 0, 0,
8659 0, 0, 0, 0, 0, 0, 0, 0,
8660 0, 0, 0, 0, 0, 0, 0, 0,
8661 0, 0, 0, 0, 0, 0, 0, 0,
8662 0, 0, 0, 0, 0, 0, 0, 0,
8663 0, 0, 0, 0, 0, 0, 0, 0,
8664 0, 0, 0, 0, 0, 0, 0, 0,
8665 0, 0, 0, 0, 0, 0, 0, 0,
8666 0, 0, 0, 0, 0, 0, 0, 0,
8667 0, 0, 0, 0, 0, 0, 0, 0,
8668 0, 0, 0, 0, 0, 0, 0, 0,
8669 0, 0, 0, 0, 0, 0, 0, 0,
8670 0, 0, 0, 0, 0, 0, 0, 0,
8671 0, 0, 0, 0, 0, 0, 0, 0,
8672 0, 0, 0, 0, 0, 0, 0, 0,
8673 0, 0, 0, 0, 0, 0, 0, 0,
8674 0, 0, 0, 0, 0, 0, 0, 0,
8675 0, 0, 0, 0, 0, 0, 0, 0,
8676 0, 0, 0, 0, 0, 0, 0, 0,
8677};
8678
8679static const Q_UINT8 dir_02[] = {
8680 0, 0, 0, 0, 0, 0, 0, 0,
8681 0, 0, 0, 0, 0, 0, 0, 0,
8682 0, 0, 0, 0, 0, 0, 0, 0,
8683 0, 0, 0, 0, 0, 0, 0, 0,
8684 0, 0, 0, 0, 0, 0, 0, 0,
8685 0, 0, 0, 0, 0, 0, 0, 0,
8686 0, 0, 0, 0, 0, 0, 0, 0,
8687 0, 0, 0, 0, 0, 0, 0, 0,
8688 0, 0, 0, 0, 0, 0, 0, 0,
8689 0, 0, 0, 0, 0, 0, 0, 0,
8690 0, 0, 0, 0, 0, 0, 0, 0,
8691 0, 0, 0, 0, 0, 0, 0, 0,
8692 0, 0, 0, 0, 0, 0, 0, 0,
8693 0, 0, 0, 0, 0, 0, 0, 0,
8694 0, 0, 0, 0, 0, 0, 0, 0,
8695 0, 0, 0, 0, 0, 0, 0, 0,
8696 0, 0, 0, 0, 0, 0, 0, 0,
8697 0, 0, 0, 0, 0, 0, 0, 0,
8698 0, 0, 0, 0, 0, 0, 0, 0,
8699 0, 0, 0, 0, 0, 0, 0, 0,
8700 0, 0, 0, 0, 0, 0, 0, 0,
8701 0, 0, 0, 0, 0, 0, 0, 0,
8702 0, 0, 0, 0, 0, 0, 0, 0,
8703 0, 10, 10, 0, 0, 0, 0, 0,
8704 0, 0, 10, 10, 10, 10, 10, 10,
8705 10, 10, 10, 10, 10, 10, 10, 10,
8706 0, 0, 10, 10, 10, 10, 10, 10,
8707 10, 10, 10, 10, 10, 10, 10, 10,
8708 0, 0, 0, 0, 0, 10, 10, 10,
8709 10, 10, 10, 10, 10, 10, 0, 0,
8710 0, 0, 0, 0, 0, 0, 0, 0,
8711 0, 0, 0, 0, 0, 0, 0, 0,
8712};
8713
8714static const Q_UINT8 dir_03[] = {
8715 17, 17, 17, 17, 17, 17, 17, 17,
8716 17, 17, 17, 17, 17, 17, 17, 17,
8717 17, 17, 17, 17, 17, 17, 17, 17,
8718 17, 17, 17, 17, 17, 17, 17, 17,
8719 17, 17, 17, 17, 17, 17, 17, 17,
8720 17, 17, 17, 17, 17, 17, 17, 17,
8721 17, 17, 17, 17, 17, 17, 17, 17,
8722 17, 17, 17, 17, 17, 17, 17, 17,
8723 17, 17, 17, 17, 17, 17, 17, 17,
8724 17, 17, 17, 17, 17, 17, 17, 17,
8725 0, 0, 0, 0, 0, 0, 0, 0,
8726 0, 0, 0, 0, 0, 0, 0, 0,
8727 17, 17, 17, 17, 17, 17, 17, 17,
8728 17, 17, 17, 17, 17, 17, 17, 17,
8729 0, 0, 0, 0, 10, 10, 0, 0,
8730 0, 0, 0, 0, 0, 0, 10, 0,
8731 0, 0, 0, 0, 10, 10, 0, 10,
8732 0, 0, 0, 0, 0, 0, 0, 0,
8733 0, 0, 0, 0, 0, 0, 0, 0,
8734 0, 0, 0, 0, 0, 0, 0, 0,
8735 0, 0, 0, 0, 0, 0, 0, 0,
8736 0, 0, 0, 0, 0, 0, 0, 0,
8737 0, 0, 0, 0, 0, 0, 0, 0,
8738 0, 0, 0, 0, 0, 0, 0, 0,
8739 0, 0, 0, 0, 0, 0, 0, 0,
8740 0, 0, 0, 0, 0, 0, 0, 0,
8741 0, 0, 0, 0, 0, 0, 0, 0,
8742 0, 0, 0, 0, 0, 0, 0, 0,
8743 0, 0, 0, 0, 0, 0, 0, 0,
8744 0, 0, 0, 0, 0, 0, 0, 0,
8745 0, 0, 0, 0, 0, 0, 10, 0,
8746 0, 0, 0, 0, 0, 0, 0, 0,
8747};
8748
8749static const Q_UINT8 dir_04[] = {
8750 0, 0, 0, 0, 0, 0, 0, 0,
8751 0, 0, 0, 0, 0, 0, 0, 0,
8752 0, 0, 0, 0, 0, 0, 0, 0,
8753 0, 0, 0, 0, 0, 0, 0, 0,
8754 0, 0, 0, 0, 0, 0, 0, 0,
8755 0, 0, 0, 0, 0, 0, 0, 0,
8756 0, 0, 0, 0, 0, 0, 0, 0,
8757 0, 0, 0, 0, 0, 0, 0, 0,
8758 0, 0, 0, 0, 0, 0, 0, 0,
8759 0, 0, 0, 0, 0, 0, 0, 0,
8760 0, 0, 0, 0, 0, 0, 0, 0,
8761 0, 0, 0, 0, 0, 0, 0, 0,
8762 0, 0, 0, 0, 0, 0, 0, 0,
8763 0, 0, 0, 0, 0, 0, 0, 0,
8764 0, 0, 0, 0, 0, 0, 0, 0,
8765 0, 0, 0, 0, 0, 0, 0, 0,
8766 0, 0, 0, 17, 17, 17, 17, 0,
8767 17, 17, 0, 0, 0, 0, 0, 0,
8768 0, 0, 0, 0, 0, 0, 0, 0,
8769 0, 0, 0, 0, 0, 0, 0, 0,
8770 0, 0, 0, 0, 0, 0, 0, 0,
8771 0, 0, 0, 0, 0, 0, 0, 0,
8772 0, 0, 0, 0, 0, 0, 0, 0,
8773 0, 0, 0, 0, 0, 0, 0, 0,
8774 0, 0, 0, 0, 0, 0, 0, 0,
8775 0, 0, 0, 0, 0, 0, 0, 0,
8776 0, 0, 0, 0, 0, 0, 0, 0,
8777 0, 0, 0, 0, 0, 0, 0, 0,
8778 0, 0, 0, 0, 0, 0, 0, 0,
8779 0, 0, 0, 0, 0, 0, 0, 0,
8780 0, 0, 0, 0, 0, 0, 0, 0,
8781 0, 0, 0, 0, 0, 0, 0, 0,
8782};
8783
8784static const Q_UINT8 dir_05[] = {
8785 0, 0, 0, 0, 0, 0, 0, 0,
8786 0, 0, 0, 0, 0, 0, 0, 0,
8787 0, 0, 0, 0, 0, 0, 0, 0,
8788 0, 0, 0, 0, 0, 0, 0, 0,
8789 0, 0, 0, 0, 0, 0, 0, 0,
8790 0, 0, 0, 0, 0, 0, 0, 0,
8791 0, 0, 0, 0, 0, 0, 0, 0,
8792 0, 0, 0, 0, 0, 0, 0, 0,
8793 0, 0, 0, 0, 0, 0, 0, 0,
8794 0, 0, 0, 0, 0, 0, 0, 0,
8795 0, 0, 0, 0, 0, 0, 0, 0,
8796 0, 0, 0, 0, 0, 0, 0, 0,
8797 0, 0, 0, 0, 0, 0, 0, 0,
8798 0, 0, 0, 0, 0, 0, 0, 0,
8799 0, 0, 0, 0, 0, 0, 0, 0,
8800 0, 0, 0, 0, 0, 0, 0, 0,
8801 0, 0, 0, 0, 0, 0, 0, 0,
8802 0, 0, 10, 0, 0, 0, 0, 0,
8803 0, 17, 17, 17, 17, 17, 17, 17,
8804 17, 17, 17, 17, 17, 17, 17, 17,
8805 17, 17, 0, 17, 17, 17, 17, 17,
8806 17, 17, 17, 17, 17, 17, 17, 17,
8807 17, 17, 17, 17, 17, 17, 17, 17,
8808 17, 17, 0, 17, 17, 17, 1, 17,
8809 1, 17, 17, 1, 17, 0, 0, 0,
8810 0, 0, 0, 0, 0, 0, 0, 0,
8811 1, 1, 1, 1, 1, 1, 1, 1,
8812 1, 1, 1, 1, 1, 1, 1, 1,
8813 1, 1, 1, 1, 1, 1, 1, 1,
8814 1, 1, 1, 0, 0, 0, 0, 0,
8815 1, 1, 1, 1, 1, 0, 0, 0,
8816 0, 0, 0, 0, 0, 0, 0, 0,
8817};
8818
8819static const Q_UINT8 dir_06[] = {
8820 0, 0, 0, 0, 0, 0, 0, 0,
8821 0, 0, 0, 0, 6, 0, 0, 0,
8822 0, 0, 0, 0, 0, 0, 0, 0,
8823 0, 0, 0, 13, 0, 0, 0, 13,
8824 0, 13, 77, 77, 77, 77, 45, 77,
8825 45, 77, 45, 45, 45, 45, 45, 77,
8826 77, 77, 77, 45, 45, 45, 45, 45,
8827 45, 45, 45, 0, 0, 0, 0, 0,
8828 109, 45, 45, 45, 45, 45, 45, 45,
8829 77, 45, 45, 17, 17, 17, 17, 17,
8830 17, 17, 17, 17, 17, 17, 0, 0,
8831 0, 0, 0, 0, 0, 0, 0, 0,
8832 5, 5, 5, 5, 5, 5, 5, 5,
8833 5, 5, 4, 5, 5, 13, 45, 45,
8834 17, 77, 77, 77, 13, 77, 77, 77,
8835 45, 45, 45, 45, 45, 45, 45, 45,
8836 45, 45, 45, 45, 45, 45, 45, 45,
8837 77, 77, 77, 77, 77, 77, 77, 77,
8838 77, 77, 77, 77, 77, 77, 77, 77,
8839 77, 77, 45, 45, 45, 45, 45, 45,
8840 45, 45, 45, 45, 45, 45, 45, 45,
8841 45, 45, 45, 45, 45, 45, 45, 45,
8842 45, 45, 45, 45, 45, 45, 45, 45,
8843 45, 45, 45, 45, 45, 45, 45, 45,
8844 77, 45, 77, 77, 77, 77, 77, 77,
8845 77, 77, 77, 77, 45, 77, 45, 77,
8846 45, 45, 77, 77, 13, 77, 17, 17,
8847 17, 17, 17, 17, 17, 13, 17, 17,
8848 17, 17, 17, 17, 17, 13, 13, 17,
8849 17, 10, 17, 17, 17, 17, 0, 0,
8850 2, 2, 2, 2, 2, 2, 2, 2,
8851 2, 2, 45, 45, 45, 13, 13, 0,
8852};
8853
8854static const Q_UINT8 dir_07[] = {
8855 13, 13, 13, 13, 13, 13, 13, 13,
8856 13, 13, 13, 13, 13, 13, 0, 18,
8857 77, 17, 45, 45, 45, 77, 77, 77,
8858 77, 77, 45, 45, 45, 45, 77, 45,
8859 45, 45, 45, 45, 45, 45, 45, 45,
8860 77, 45, 77, 45, 77, 0, 0, 0,
8861 17, 17, 17, 17, 17, 17, 17, 17,
8862 17, 17, 17, 17, 17, 17, 17, 17,
8863 17, 17, 17, 17, 17, 17, 17, 17,
8864 17, 17, 17, 0, 0, 0, 0, 0,
8865 0, 0, 0, 0, 0, 0, 0, 0,
8866 0, 0, 0, 0, 0, 0, 0, 0,
8867 0, 0, 0, 0, 0, 0, 0, 0,
8868 0, 0, 0, 0, 0, 0, 0, 0,
8869 0, 0, 0, 0, 0, 0, 0, 0,
8870 0, 0, 0, 0, 0, 0, 0, 0,
8871 13, 13, 13, 13, 13, 13, 13, 13,
8872 13, 13, 13, 13, 13, 13, 13, 13,
8873 13, 13, 13, 13, 13, 13, 13, 13,
8874 13, 13, 13, 13, 13, 13, 13, 13,
8875 13, 13, 13, 13, 13, 13, 17, 17,
8876 17, 17, 17, 17, 17, 17, 17, 17,
8877 17, 13, 0, 0, 0, 0, 0, 0,
8878 0, 0, 0, 0, 0, 0, 0, 0,
8879 0, 0, 0, 0, 0, 0, 0, 0,
8880 0, 0, 0, 0, 0, 0, 0, 0,
8881 0, 0, 0, 0, 0, 0, 0, 0,
8882 0, 0, 0, 0, 0, 0, 0, 0,
8883 0, 0, 0, 0, 0, 0, 0, 0,
8884 0, 0, 0, 0, 0, 0, 0, 0,
8885 0, 0, 0, 0, 0, 0, 0, 0,
8886 0, 0, 0, 0, 0, 0, 0, 0,
8887};
8888
8889static const Q_UINT8 dir_09[] = {
8890 0, 17, 17, 0, 0, 0, 0, 0,
8891 0, 0, 0, 0, 0, 0, 0, 0,
8892 0, 0, 0, 0, 0, 0, 0, 0,
8893 0, 0, 0, 0, 0, 0, 0, 0,
8894 0, 0, 0, 0, 0, 0, 0, 0,
8895 0, 0, 0, 0, 0, 0, 0, 0,
8896 0, 0, 0, 0, 0, 0, 0, 0,
8897 0, 0, 0, 0, 17, 0, 0, 0,
8898 0, 17, 17, 17, 17, 17, 17, 17,
8899 17, 0, 0, 0, 0, 17, 0, 0,
8900 0, 17, 17, 17, 17, 0, 0, 0,
8901 0, 0, 0, 0, 0, 0, 0, 0,
8902 0, 0, 17, 17, 0, 0, 0, 0,
8903 0, 0, 0, 0, 0, 0, 0, 0,
8904 0, 0, 0, 0, 0, 0, 0, 0,
8905 0, 0, 0, 0, 0, 0, 0, 0,
8906 0, 17, 0, 0, 0, 0, 0, 0,
8907 0, 0, 0, 0, 0, 0, 0, 0,
8908 0, 0, 0, 0, 0, 0, 0, 0,
8909 0, 0, 0, 0, 0, 0, 0, 0,
8910 0, 0, 0, 0, 0, 0, 0, 0,
8911 0, 0, 0, 0, 0, 0, 0, 0,
8912 0, 0, 0, 0, 0, 0, 0, 0,
8913 0, 0, 0, 0, 17, 0, 0, 0,
8914 0, 17, 17, 17, 17, 0, 0, 0,
8915 0, 0, 0, 0, 0, 17, 0, 0,
8916 0, 0, 0, 0, 0, 0, 0, 0,
8917 0, 0, 0, 0, 0, 0, 0, 0,
8918 0, 0, 17, 17, 0, 0, 0, 0,
8919 0, 0, 0, 0, 0, 0, 0, 0,
8920 0, 0, 4, 4, 0, 0, 0, 0,
8921 0, 0, 0, 0, 0, 0, 0, 0,
8922};
8923
8924static const Q_UINT8 dir_0A[] = {
8925 0, 0, 17, 0, 0, 0, 0, 0,
8926 0, 0, 0, 0, 0, 0, 0, 0,
8927 0, 0, 0, 0, 0, 0, 0, 0,
8928 0, 0, 0, 0, 0, 0, 0, 0,
8929 0, 0, 0, 0, 0, 0, 0, 0,
8930 0, 0, 0, 0, 0, 0, 0, 0,
8931 0, 0, 0, 0, 0, 0, 0, 0,
8932 0, 0, 0, 0, 17, 0, 0, 0,
8933 0, 17, 17, 0, 0, 0, 0, 17,
8934 17, 0, 0, 17, 17, 17, 0, 0,
8935 0, 0, 0, 0, 0, 0, 0, 0,
8936 0, 0, 0, 0, 0, 0, 0, 0,
8937 0, 0, 0, 0, 0, 0, 0, 0,
8938 0, 0, 0, 0, 0, 0, 0, 0,
8939 17, 17, 0, 0, 0, 0, 0, 0,
8940 0, 0, 0, 0, 0, 0, 0, 0,
8941 0, 17, 17, 0, 0, 0, 0, 0,
8942 0, 0, 0, 0, 0, 0, 0, 0,
8943 0, 0, 0, 0, 0, 0, 0, 0,
8944 0, 0, 0, 0, 0, 0, 0, 0,
8945 0, 0, 0, 0, 0, 0, 0, 0,
8946 0, 0, 0, 0, 0, 0, 0, 0,
8947 0, 0, 0, 0, 0, 0, 0, 0,
8948 0, 0, 0, 0, 17, 0, 0, 0,
8949 0, 17, 17, 17, 17, 17, 0, 17,
8950 17, 0, 0, 0, 0, 17, 0, 0,
8951 0, 0, 0, 0, 0, 0, 0, 0,
8952 0, 0, 0, 0, 0, 0, 0, 0,
8953 0, 0, 0, 0, 0, 0, 0, 0,
8954 0, 0, 0, 0, 0, 0, 0, 0,
8955 0, 0, 0, 0, 0, 0, 0, 0,
8956 0, 0, 0, 0, 0, 0, 0, 0,
8957};
8958
8959static const Q_UINT8 dir_0B[] = {
8960 0, 17, 0, 0, 0, 0, 0, 0,
8961 0, 0, 0, 0, 0, 0, 0, 0,
8962 0, 0, 0, 0, 0, 0, 0, 0,
8963 0, 0, 0, 0, 0, 0, 0, 0,
8964 0, 0, 0, 0, 0, 0, 0, 0,
8965 0, 0, 0, 0, 0, 0, 0, 0,
8966 0, 0, 0, 0, 0, 0, 0, 0,
8967 0, 0, 0, 0, 17, 0, 0, 17,
8968 0, 17, 17, 17, 0, 0, 0, 0,
8969 0, 0, 0, 0, 0, 17, 0, 0,
8970 0, 0, 0, 0, 0, 0, 17, 0,
8971 0, 0, 0, 0, 0, 0, 0, 0,
8972 0, 0, 0, 0, 0, 0, 0, 0,
8973 0, 0, 0, 0, 0, 0, 0, 0,
8974 0, 0, 0, 0, 0, 0, 0, 0,
8975 0, 0, 0, 0, 0, 0, 0, 0,
8976 0, 0, 17, 0, 0, 0, 0, 0,
8977 0, 0, 0, 0, 0, 0, 0, 0,
8978 0, 0, 0, 0, 0, 0, 0, 0,
8979 0, 0, 0, 0, 0, 0, 0, 0,
8980 0, 0, 0, 0, 0, 0, 0, 0,
8981 0, 0, 0, 0, 0, 0, 0, 0,
8982 0, 0, 0, 0, 0, 0, 0, 0,
8983 0, 0, 0, 0, 0, 0, 0, 0,
8984 17, 0, 0, 0, 0, 0, 0, 0,
8985 0, 0, 0, 0, 0, 17, 0, 0,
8986 0, 0, 0, 0, 0, 0, 0, 0,
8987 0, 0, 0, 0, 0, 0, 0, 0,
8988 0, 0, 0, 0, 0, 0, 0, 0,
8989 0, 0, 0, 0, 0, 0, 0, 0,
8990 0, 0, 0, 0, 0, 0, 0, 0,
8991 0, 0, 0, 0, 0, 0, 0, 0,
8992};
8993
8994static const Q_UINT8 dir_0C[] = {
8995 0, 0, 0, 0, 0, 0, 0, 0,
8996 0, 0, 0, 0, 0, 0, 0, 0,
8997 0, 0, 0, 0, 0, 0, 0, 0,
8998 0, 0, 0, 0, 0, 0, 0, 0,
8999 0, 0, 0, 0, 0, 0, 0, 0,
9000 0, 0, 0, 0, 0, 0, 0, 0,
9001 0, 0, 0, 0, 0, 0, 0, 0,
9002 0, 0, 0, 0, 0, 0, 17, 17,
9003 17, 0, 0, 0, 0, 0, 17, 17,
9004 17, 0, 17, 17, 17, 17, 0, 0,
9005 0, 0, 0, 0, 0, 17, 17, 0,
9006 0, 0, 0, 0, 0, 0, 0, 0,
9007 0, 0, 0, 0, 0, 0, 0, 0,
9008 0, 0, 0, 0, 0, 0, 0, 0,
9009 0, 0, 0, 0, 0, 0, 0, 0,
9010 0, 0, 0, 0, 0, 0, 0, 0,
9011 0, 0, 0, 0, 0, 0, 0, 0,
9012 0, 0, 0, 0, 0, 0, 0, 0,
9013 0, 0, 0, 0, 0, 0, 0, 0,
9014 0, 0, 0, 0, 0, 0, 0, 0,
9015 0, 0, 0, 0, 0, 0, 0, 0,
9016 0, 0, 0, 0, 0, 0, 0, 0,
9017 0, 0, 0, 0, 0, 0, 0, 0,
9018 0, 0, 0, 0, 0, 0, 0, 17,
9019 0, 0, 0, 0, 0, 0, 17, 0,
9020 0, 0, 0, 0, 17, 17, 0, 0,
9021 0, 0, 0, 0, 0, 0, 0, 0,
9022 0, 0, 0, 0, 0, 0, 0, 0,
9023 0, 0, 0, 0, 0, 0, 0, 0,
9024 0, 0, 0, 0, 0, 0, 0, 0,
9025 0, 0, 0, 0, 0, 0, 0, 0,
9026 0, 0, 0, 0, 0, 0, 0, 0,
9027};
9028
9029static const Q_UINT8 dir_0D[] = {
9030 0, 0, 0, 0, 0, 0, 0, 0,
9031 0, 0, 0, 0, 0, 0, 0, 0,
9032 0, 0, 0, 0, 0, 0, 0, 0,
9033 0, 0, 0, 0, 0, 0, 0, 0,
9034 0, 0, 0, 0, 0, 0, 0, 0,
9035 0, 0, 0, 0, 0, 0, 0, 0,
9036 0, 0, 0, 0, 0, 0, 0, 0,
9037 0, 0, 0, 0, 0, 0, 0, 0,
9038 0, 17, 17, 17, 0, 0, 0, 0,
9039 0, 0, 0, 0, 0, 17, 0, 0,
9040 0, 0, 0, 0, 0, 0, 0, 0,
9041 0, 0, 0, 0, 0, 0, 0, 0,
9042 0, 0, 0, 0, 0, 0, 0, 0,
9043 0, 0, 0, 0, 0, 0, 0, 0,
9044 0, 0, 0, 0, 0, 0, 0, 0,
9045 0, 0, 0, 0, 0, 0, 0, 0,
9046 0, 0, 0, 0, 0, 0, 0, 0,
9047 0, 0, 0, 0, 0, 0, 0, 0,
9048 0, 0, 0, 0, 0, 0, 0, 0,
9049 0, 0, 0, 0, 0, 0, 0, 0,
9050 0, 0, 0, 0, 0, 0, 0, 0,
9051 0, 0, 0, 0, 0, 0, 0, 0,
9052 0, 0, 0, 0, 0, 0, 0, 0,
9053 0, 0, 0, 0, 0, 0, 0, 0,
9054 0, 0, 0, 0, 0, 0, 0, 0,
9055 0, 0, 17, 0, 0, 0, 0, 0,
9056 0, 0, 17, 17, 17, 0, 17, 0,
9057 0, 0, 0, 0, 0, 0, 0, 0,
9058 0, 0, 0, 0, 0, 0, 0, 0,
9059 0, 0, 0, 0, 0, 0, 0, 0,
9060 0, 0, 0, 0, 0, 0, 0, 0,
9061 0, 0, 0, 0, 0, 0, 0, 0,
9062};
9063
9064static const Q_UINT8 dir_0E[] = {
9065 0, 0, 0, 0, 0, 0, 0, 0,
9066 0, 0, 0, 0, 0, 0, 0, 0,
9067 0, 0, 0, 0, 0, 0, 0, 0,
9068 0, 0, 0, 0, 0, 0, 0, 0,
9069 0, 0, 0, 0, 0, 0, 0, 0,
9070 0, 0, 0, 0, 0, 0, 0, 0,
9071 0, 17, 0, 0, 17, 17, 17, 17,
9072 17, 17, 17, 0, 0, 0, 0, 4,
9073 0, 0, 0, 0, 0, 0, 0, 17,
9074 17, 17, 17, 17, 17, 17, 17, 0,
9075 0, 0, 0, 0, 0, 0, 0, 0,
9076 0, 0, 0, 0, 0, 0, 0, 0,
9077 0, 0, 0, 0, 0, 0, 0, 0,
9078 0, 0, 0, 0, 0, 0, 0, 0,
9079 0, 0, 0, 0, 0, 0, 0, 0,
9080 0, 0, 0, 0, 0, 0, 0, 0,
9081 0, 0, 0, 0, 0, 0, 0, 0,
9082 0, 0, 0, 0, 0, 0, 0, 0,
9083 0, 0, 0, 0, 0, 0, 0, 0,
9084 0, 0, 0, 0, 0, 0, 0, 0,
9085 0, 0, 0, 0, 0, 0, 0, 0,
9086 0, 0, 0, 0, 0, 0, 0, 0,
9087 0, 17, 0, 0, 17, 17, 17, 17,
9088 17, 17, 0, 17, 17, 0, 0, 0,
9089 0, 0, 0, 0, 0, 0, 0, 0,
9090 17, 17, 17, 17, 17, 17, 0, 0,
9091 0, 0, 0, 0, 0, 0, 0, 0,
9092 0, 0, 0, 0, 0, 0, 0, 0,
9093 0, 0, 0, 0, 0, 0, 0, 0,
9094 0, 0, 0, 0, 0, 0, 0, 0,
9095 0, 0, 0, 0, 0, 0, 0, 0,
9096 0, 0, 0, 0, 0, 0, 0, 0,
9097};
9098
9099static const Q_UINT8 dir_0F[] = {
9100 0, 0, 0, 0, 0, 0, 0, 0,
9101 0, 0, 0, 0, 0, 0, 0, 0,
9102 0, 0, 0, 0, 0, 0, 0, 0,
9103 17, 17, 0, 0, 0, 0, 0, 0,
9104 0, 0, 0, 0, 0, 0, 0, 0,
9105 0, 0, 0, 0, 0, 0, 0, 0,
9106 0, 0, 0, 0, 0, 17, 0, 17,
9107 0, 17, 10, 10, 10, 10, 0, 0,
9108 0, 0, 0, 0, 0, 0, 0, 0,
9109 0, 0, 0, 0, 0, 0, 0, 0,
9110 0, 0, 0, 0, 0, 0, 0, 0,
9111 0, 0, 0, 0, 0, 0, 0, 0,
9112 0, 0, 0, 0, 0, 0, 0, 0,
9113 0, 0, 0, 0, 0, 0, 0, 0,
9114 0, 17, 17, 17, 17, 17, 17, 17,
9115 17, 17, 17, 17, 17, 17, 17, 0,
9116 17, 17, 17, 17, 17, 0, 17, 17,
9117 0, 0, 0, 0, 0, 0, 0, 0,
9118 17, 17, 17, 17, 17, 17, 17, 17,
9119 0, 17, 17, 17, 17, 17, 17, 17,
9120 17, 17, 17, 17, 17, 17, 17, 17,
9121 17, 17, 17, 17, 17, 17, 17, 17,
9122 17, 17, 17, 17, 17, 17, 17, 17,
9123 17, 17, 17, 17, 17, 0, 0, 0,
9124 0, 0, 0, 0, 0, 0, 17, 0,
9125 0, 0, 0, 0, 0, 0, 0, 0,
9126 0, 0, 0, 0, 0, 0, 0, 0,
9127 0, 0, 0, 0, 0, 0, 0, 0,
9128 0, 0, 0, 0, 0, 0, 0, 0,
9129 0, 0, 0, 0, 0, 0, 0, 0,
9130 0, 0, 0, 0, 0, 0, 0, 0,
9131 0, 0, 0, 0, 0, 0, 0, 0,
9132};
9133
9134static const Q_UINT8 dir_10[] = {
9135 0, 0, 0, 0, 0, 0, 0, 0,
9136 0, 0, 0, 0, 0, 0, 0, 0,
9137 0, 0, 0, 0, 0, 0, 0, 0,
9138 0, 0, 0, 0, 0, 0, 0, 0,
9139 0, 0, 0, 0, 0, 0, 0, 0,
9140 0, 0, 0, 0, 0, 17, 17, 17,
9141 17, 0, 17, 0, 0, 0, 17, 17,
9142 0, 17, 0, 0, 0, 0, 0, 0,
9143 0, 0, 0, 0, 0, 0, 0, 0,
9144 0, 0, 0, 0, 0, 0, 0, 0,
9145 0, 0, 0, 0, 0, 0, 0, 0,
9146 17, 17, 0, 0, 0, 0, 0, 0,
9147 0, 0, 0, 0, 0, 0, 0, 0,
9148 0, 0, 0, 0, 0, 0, 0, 0,
9149 0, 0, 0, 0, 0, 0, 0, 0,
9150 0, 0, 0, 0, 0, 0, 0, 0,
9151 0, 0, 0, 0, 0, 0, 0, 0,
9152 0, 0, 0, 0, 0, 0, 0, 0,
9153 0, 0, 0, 0, 0, 0, 0, 0,
9154 0, 0, 0, 0, 0, 0, 0, 0,
9155 0, 0, 0, 0, 0, 0, 0, 0,
9156 0, 0, 0, 0, 0, 0, 0, 0,
9157 0, 0, 0, 0, 0, 0, 0, 0,
9158 0, 0, 0, 0, 0, 0, 0, 0,
9159 0, 0, 0, 0, 0, 0, 0, 0,
9160 0, 0, 0, 0, 0, 0, 0, 0,
9161 0, 0, 0, 0, 0, 0, 0, 0,
9162 0, 0, 0, 0, 0, 0, 0, 0,
9163 0, 0, 0, 0, 0, 0, 0, 0,
9164 0, 0, 0, 0, 0, 0, 0, 0,
9165 0, 0, 0, 0, 0, 0, 0, 0,
9166 0, 0, 0, 0, 0, 0, 0, 0,
9167};
9168
9169static const Q_UINT8 dir_16[] = {
9170 0, 0, 0, 0, 0, 0, 0, 0,
9171 0, 0, 0, 0, 0, 0, 0, 0,
9172 0, 0, 0, 0, 0, 0, 0, 0,
9173 0, 0, 0, 0, 0, 0, 0, 0,
9174 0, 0, 0, 0, 0, 0, 0, 0,
9175 0, 0, 0, 0, 0, 0, 0, 0,
9176 0, 0, 0, 0, 0, 0, 0, 0,
9177 0, 0, 0, 0, 0, 0, 0, 0,
9178 0, 0, 0, 0, 0, 0, 0, 0,
9179 0, 0, 0, 0, 0, 0, 0, 0,
9180 0, 0, 0, 0, 0, 0, 0, 0,
9181 0, 0, 0, 0, 0, 0, 0, 0,
9182 0, 0, 0, 0, 0, 0, 0, 0,
9183 0, 0, 0, 0, 0, 0, 0, 0,
9184 0, 0, 0, 0, 0, 0, 0, 0,
9185 0, 0, 0, 0, 0, 0, 0, 0,
9186 9, 0, 0, 0, 0, 0, 0, 0,
9187 0, 0, 0, 0, 0, 0, 0, 0,
9188 0, 0, 0, 0, 0, 0, 0, 0,
9189 0, 0, 0, 10, 10, 0, 0, 0,
9190 0, 0, 0, 0, 0, 0, 0, 0,
9191 0, 0, 0, 0, 0, 0, 0, 0,
9192 0, 0, 0, 0, 0, 0, 0, 0,
9193 0, 0, 0, 0, 0, 0, 0, 0,
9194 0, 0, 0, 0, 0, 0, 0, 0,
9195 0, 0, 0, 0, 0, 0, 0, 0,
9196 0, 0, 0, 0, 0, 0, 0, 0,
9197 0, 0, 0, 0, 0, 0, 0, 0,
9198 0, 0, 0, 0, 0, 0, 0, 0,
9199 0, 0, 0, 0, 0, 0, 0, 0,
9200 0, 0, 0, 0, 0, 0, 0, 0,
9201 0, 0, 0, 0, 0, 0, 0, 0,
9202};
9203
9204static const Q_UINT8 dir_17[] = {
9205 0, 0, 0, 0, 0, 0, 0, 0,
9206 0, 0, 0, 0, 0, 0, 0, 0,
9207 0, 0, 17, 17, 17, 0, 0, 0,
9208 0, 0, 0, 0, 0, 0, 0, 0,
9209 0, 0, 0, 0, 0, 0, 0, 0,
9210 0, 0, 0, 0, 0, 0, 0, 0,
9211 0, 0, 17, 17, 17, 0, 0, 0,
9212 0, 0, 0, 0, 0, 0, 0, 0,
9213 0, 0, 0, 0, 0, 0, 0, 0,
9214 0, 0, 0, 0, 0, 0, 0, 0,
9215 0, 0, 17, 17, 0, 0, 0, 0,
9216 0, 0, 0, 0, 0, 0, 0, 0,
9217 0, 0, 0, 0, 0, 0, 0, 0,
9218 0, 0, 0, 0, 0, 0, 0, 0,
9219 0, 0, 17, 17, 0, 0, 0, 0,
9220 0, 0, 0, 0, 0, 0, 0, 0,
9221 0, 0, 0, 0, 0, 0, 0, 0,
9222 0, 0, 0, 0, 0, 0, 0, 0,
9223 0, 0, 0, 0, 0, 0, 0, 0,
9224 0, 0, 0, 0, 0, 0, 0, 0,
9225 0, 0, 0, 0, 0, 0, 0, 0,
9226 0, 0, 0, 0, 0, 0, 0, 0,
9227 0, 0, 0, 0, 0, 0, 0, 17,
9228 17, 17, 17, 17, 17, 17, 0, 0,
9229 0, 0, 0, 0, 0, 0, 17, 0,
9230 0, 17, 17, 17, 17, 17, 17, 17,
9231 17, 17, 17, 17, 0, 0, 0, 0,
9232 0, 0, 0, 4, 0, 0, 0, 0,
9233 0, 0, 0, 0, 0, 0, 0, 0,
9234 0, 0, 0, 0, 0, 0, 0, 0,
9235 0, 0, 0, 0, 0, 0, 0, 0,
9236 0, 0, 0, 0, 0, 0, 0, 0,
9237};
9238
9239static const Q_UINT8 dir_18[] = {
9240 10, 10, 10, 10, 10, 10, 10, 10,
9241 10, 10, 10, 17, 17, 17, 18, 0,
9242 0, 0, 0, 0, 0, 0, 0, 0,
9243 0, 0, 0, 0, 0, 0, 0, 0,
9244 0, 0, 0, 0, 0, 0, 0, 0,
9245 0, 0, 0, 0, 0, 0, 0, 0,
9246 0, 0, 0, 0, 0, 0, 0, 0,
9247 0, 0, 0, 0, 0, 0, 0, 0,
9248 0, 0, 0, 0, 0, 0, 0, 0,
9249 0, 0, 0, 0, 0, 0, 0, 0,
9250 0, 0, 0, 0, 0, 0, 0, 0,
9251 0, 0, 0, 0, 0, 0, 0, 0,
9252 0, 0, 0, 0, 0, 0, 0, 0,
9253 0, 0, 0, 0, 0, 0, 0, 0,
9254 0, 0, 0, 0, 0, 0, 0, 0,
9255 0, 0, 0, 0, 0, 0, 0, 0,
9256 0, 0, 0, 0, 0, 0, 0, 0,
9257 0, 0, 0, 0, 0, 0, 0, 0,
9258 0, 0, 0, 0, 0, 0, 0, 0,
9259 0, 0, 0, 0, 0, 0, 0, 0,
9260 0, 0, 0, 0, 0, 0, 0, 0,
9261 0, 17, 0, 0, 0, 0, 0, 0,
9262 0, 0, 0, 0, 0, 0, 0, 0,
9263 0, 0, 0, 0, 0, 0, 0, 0,
9264 0, 0, 0, 0, 0, 0, 0, 0,
9265 0, 0, 0, 0, 0, 0, 0, 0,
9266 0, 0, 0, 0, 0, 0, 0, 0,
9267 0, 0, 0, 0, 0, 0, 0, 0,
9268 0, 0, 0, 0, 0, 0, 0, 0,
9269 0, 0, 0, 0, 0, 0, 0, 0,
9270 0, 0, 0, 0, 0, 0, 0, 0,
9271 0, 0, 0, 0, 0, 0, 0, 0,
9272};
9273
9274static const Q_UINT8 dir_1F[] = {
9275 0, 0, 0, 0, 0, 0, 0, 0,
9276 0, 0, 0, 0, 0, 0, 0, 0,
9277 0, 0, 0, 0, 0, 0, 0, 0,
9278 0, 0, 0, 0, 0, 0, 0, 0,
9279 0, 0, 0, 0, 0, 0, 0, 0,
9280 0, 0, 0, 0, 0, 0, 0, 0,
9281 0, 0, 0, 0, 0, 0, 0, 0,
9282 0, 0, 0, 0, 0, 0, 0, 0,
9283 0, 0, 0, 0, 0, 0, 0, 0,
9284 0, 0, 0, 0, 0, 0, 0, 0,
9285 0, 0, 0, 0, 0, 0, 0, 0,
9286 0, 0, 0, 0, 0, 0, 0, 0,
9287 0, 0, 0, 0, 0, 0, 0, 0,
9288 0, 0, 0, 0, 0, 0, 0, 0,
9289 0, 0, 0, 0, 0, 0, 0, 0,
9290 0, 0, 0, 0, 0, 0, 0, 0,
9291 0, 0, 0, 0, 0, 0, 0, 0,
9292 0, 0, 0, 0, 0, 0, 0, 0,
9293 0, 0, 0, 0, 0, 0, 0, 0,
9294 0, 0, 0, 0, 0, 0, 0, 0,
9295 0, 0, 0, 0, 0, 0, 0, 0,
9296 0, 0, 0, 0, 0, 0, 0, 0,
9297 0, 0, 0, 0, 0, 0, 0, 0,
9298 0, 0, 0, 0, 0, 10, 0, 10,
9299 10, 10, 0, 0, 0, 0, 0, 0,
9300 0, 0, 0, 0, 0, 10, 10, 10,
9301 0, 0, 0, 0, 0, 0, 0, 0,
9302 0, 0, 0, 0, 0, 10, 10, 10,
9303 0, 0, 0, 0, 0, 0, 0, 0,
9304 0, 0, 0, 0, 0, 10, 10, 10,
9305 0, 0, 0, 0, 0, 0, 0, 0,
9306 0, 0, 0, 0, 0, 10, 10, 0,
9307};
9308
9309static const Q_UINT8 dir_20[] = {
9310 9, 9, 9, 9, 9, 9, 9, 9,
9311 9, 9, 9, 18, 18, 114, 0, 1,
9312 10, 10, 10, 10, 10, 10, 10, 10,
9313 10, 10, 10, 10, 10, 10, 10, 10,
9314 10, 10, 10, 10, 10, 10, 10, 10,
9315 9, 7, 11, 14, 16, 12, 15, 9,
9316 4, 4, 4, 4, 4, 10, 10, 10,
9317 10, 138, 138, 10, 10, 10, 10, 10,
9318 10, 10, 10, 10, 10, 138, 138, 10,
9319 10, 10, 10, 10, 10, 10, 10, 10,
9320 10, 10, 10, 0, 0, 0, 0, 10,
9321 0, 0, 0, 0, 0, 0, 0, 9,
9322 18, 18, 18, 18, 0, 0, 0, 0,
9323 0, 0, 18, 18, 18, 18, 18, 18,
9324 2, 0, 0, 0, 2, 2, 2, 2,
9325 2, 2, 4, 4, 10, 138, 138, 0,
9326 2, 2, 2, 2, 2, 2, 2, 2,
9327 2, 2, 4, 4, 10, 138, 138, 0,
9328 0, 0, 0, 0, 0, 0, 0, 0,
9329 0, 0, 0, 0, 0, 0, 0, 0,
9330 4, 4, 4, 4, 4, 4, 4, 4,
9331 4, 4, 4, 4, 4, 4, 4, 4,
9332 4, 4, 0, 0, 0, 0, 0, 0,
9333 0, 0, 0, 0, 0, 0, 0, 0,
9334 0, 0, 0, 0, 0, 0, 0, 0,
9335 0, 0, 0, 0, 0, 0, 0, 0,
9336 17, 17, 17, 17, 17, 17, 17, 17,
9337 17, 17, 17, 17, 17, 17, 17, 17,
9338 17, 17, 17, 17, 17, 17, 17, 17,
9339 17, 17, 17, 0, 0, 0, 0, 0,
9340 0, 0, 0, 0, 0, 0, 0, 0,
9341 0, 0, 0, 0, 0, 0, 0, 0,
9342};
9343
9344static const Q_UINT8 dir_21[] = {
9345 10, 10, 0, 10, 10, 10, 10, 0,
9346 10, 10, 0, 0, 0, 0, 0, 0,
9347 0, 0, 0, 0, 10, 0, 10, 10,
9348 10, 0, 0, 0, 0, 0, 10, 10,
9349 10, 10, 10, 10, 0, 10, 0, 10,
9350 0, 10, 0, 0, 0, 0, 4, 0,
9351 0, 0, 10, 0, 0, 0, 0, 0,
9352 0, 0, 10, 0, 0, 0, 0, 0,
9353 138, 10, 10, 10, 10, 0, 0, 0,
9354 0, 0, 10, 10, 0, 0, 0, 0,
9355 0, 0, 0, 10, 10, 10, 10, 10,
9356 10, 10, 10, 10, 10, 10, 10, 10,
9357 0, 0, 0, 0, 0, 0, 0, 0,
9358 0, 0, 0, 0, 0, 0, 0, 0,
9359 0, 0, 0, 0, 0, 0, 0, 0,
9360 0, 0, 0, 0, 0, 0, 0, 0,
9361 0, 0, 0, 0, 0, 0, 0, 0,
9362 0, 0, 0, 0, 0, 0, 0, 0,
9363 10, 10, 10, 10, 10, 10, 10, 10,
9364 10, 10, 10, 10, 10, 10, 10, 10,
9365 10, 10, 10, 10, 10, 10, 10, 10,
9366 10, 10, 10, 10, 10, 10, 10, 10,
9367 10, 10, 10, 10, 10, 10, 10, 10,
9368 10, 10, 10, 10, 10, 10, 10, 10,
9369 10, 10, 10, 10, 10, 10, 10, 10,
9370 10, 10, 10, 10, 10, 10, 10, 10,
9371 10, 10, 10, 10, 10, 10, 10, 10,
9372 10, 10, 10, 10, 10, 10, 10, 10,
9373 10, 10, 10, 10, 10, 10, 10, 10,
9374 10, 10, 10, 10, 10, 10, 10, 10,
9375 10, 10, 10, 10, 10, 10, 10, 10,
9376 10, 10, 10, 10, 10, 10, 10, 10,
9377};
9378
9379static const Q_UINT8 dir_22[] = {
9380 10, 138, 138, 138, 138, 10, 10, 10,
9381 138, 138, 138, 138, 138, 138, 10, 10,
9382 10, 138, 4, 4, 10, 138, 138, 10,
9383 10, 10, 138, 138, 138, 138, 10, 138,
9384 138, 138, 138, 10, 138, 10, 138, 10,
9385 10, 10, 10, 138, 138, 138, 138, 138,
9386 138, 138, 138, 138, 10, 10, 10, 10,
9387 10, 138, 10, 138, 138, 138, 138, 138,
9388 138, 138, 138, 138, 138, 138, 138, 138,
9389 138, 138, 138, 138, 138, 10, 10, 10,
9390 10, 10, 138, 138, 138, 138, 10, 10,
9391 10, 10, 10, 10, 10, 10, 10, 138,
9392 138, 10, 138, 10, 138, 138, 138, 138,
9393 138, 138, 138, 138, 10, 10, 138, 138,
9394 138, 138, 138, 138, 138, 138, 138, 138,
9395 138, 138, 138, 138, 138, 138, 138, 138,
9396 138, 138, 138, 138, 138, 138, 138, 138,
9397 138, 138, 138, 138, 138, 10, 10, 138,
9398 138, 138, 138, 10, 10, 10, 10, 10,
9399 138, 10, 10, 10, 10, 10, 10, 10,
9400 10, 10, 138, 138, 10, 10, 138, 138,
9401 138, 138, 138, 138, 138, 138, 138, 138,
9402 138, 138, 138, 138, 138, 138, 138, 138,
9403 138, 10, 10, 10, 10, 10, 138, 138,
9404 10, 10, 10, 10, 10, 10, 10, 10,
9405 10, 138, 138, 138, 138, 138, 10, 10,
9406 138, 138, 10, 10, 10, 10, 138, 138,
9407 138, 138, 138, 138, 138, 138, 138, 138,
9408 138, 138, 138, 138, 138, 138, 138, 138,
9409 138, 138, 138, 138, 138, 138, 10, 10,
9410 138, 138, 138, 138, 138, 138, 138, 138,
9411 138, 138, 138, 138, 138, 138, 138, 138,
9412};
9413
9414static const Q_UINT8 dir_23[] = {
9415 10, 10, 10, 10, 10, 10, 10, 10,
9416 138, 138, 138, 138, 10, 10, 10, 10,
9417 10, 10, 10, 10, 10, 10, 10, 10,
9418 10, 10, 10, 10, 10, 10, 10, 10,
9419 138, 138, 10, 10, 10, 10, 10, 10,
9420 10, 138, 138, 10, 10, 10, 10, 10,
9421 10, 10, 10, 10, 10, 10, 0, 0,
9422 0, 0, 0, 0, 0, 0, 0, 0,
9423 0, 0, 0, 0, 0, 0, 0, 0,
9424 0, 0, 0, 0, 0, 0, 0, 0,
9425 0, 0, 0, 0, 0, 0, 0, 0,
9426 0, 0, 0, 0, 0, 0, 0, 0,
9427 0, 0, 0, 0, 0, 0, 0, 0,
9428 0, 0, 0, 0, 0, 0, 0, 0,
9429 0, 0, 0, 0, 0, 0, 0, 0,
9430 0, 0, 0, 10, 10, 10, 10, 10,
9431 10, 10, 10, 10, 10, 10, 10, 10,
9432 10, 10, 10, 10, 10, 10, 10, 10,
9433 10, 10, 10, 10, 10, 0, 10, 10,
9434 10, 10, 10, 10, 10, 10, 10, 10,
9435 10, 10, 10, 10, 10, 10, 10, 10,
9436 10, 10, 10, 10, 10, 10, 10, 10,
9437 10, 10, 10, 10, 10, 10, 10, 10,
9438 10, 10, 10, 10, 10, 10, 10, 10,
9439 10, 10, 10, 10, 10, 10, 10, 10,
9440 10, 10, 10, 10, 10, 10, 10, 0,
9441 0, 0, 0, 0, 0, 0, 0, 0,
9442 0, 0, 0, 0, 0, 0, 0, 0,
9443 0, 0, 0, 0, 0, 0, 0, 0,
9444 0, 0, 0, 0, 0, 0, 0, 0,
9445 0, 0, 0, 0, 0, 0, 0, 0,
9446 0, 0, 0, 0, 0, 0, 0, 0,
9447};
9448
9449static const Q_UINT8 dir_24[] = {
9450 10, 10, 10, 10, 10, 10, 10, 10,
9451 10, 10, 10, 10, 10, 10, 10, 10,
9452 10, 10, 10, 10, 10, 10, 10, 10,
9453 10, 10, 10, 10, 10, 10, 10, 10,
9454 10, 10, 10, 10, 10, 10, 10, 0,
9455 0, 0, 0, 0, 0, 0, 0, 0,
9456 0, 0, 0, 0, 0, 0, 0, 0,
9457 0, 0, 0, 0, 0, 0, 0, 0,
9458 10, 10, 10, 10, 10, 10, 10, 10,
9459 10, 10, 10, 0, 0, 0, 0, 0,
9460 0, 0, 0, 0, 0, 0, 0, 0,
9461 0, 0, 0, 0, 0, 0, 0, 0,
9462 2, 2, 2, 2, 2, 2, 2, 2,
9463 2, 2, 2, 2, 2, 2, 2, 2,
9464 2, 2, 2, 2, 2, 2, 2, 2,
9465 2, 2, 2, 2, 2, 2, 2, 2,
9466 2, 2, 2, 2, 2, 2, 2, 2,
9467 2, 2, 2, 2, 2, 2, 2, 2,
9468 2, 2, 2, 2, 2, 2, 2, 2,
9469 2, 2, 2, 2, 0, 0, 0, 0,
9470 0, 0, 0, 0, 0, 0, 0, 0,
9471 0, 0, 0, 0, 0, 0, 0, 0,
9472 0, 0, 0, 0, 0, 0, 0, 0,
9473 0, 0, 0, 0, 0, 0, 0, 0,
9474 0, 0, 0, 0, 0, 0, 0, 0,
9475 0, 0, 0, 0, 0, 0, 0, 0,
9476 0, 0, 0, 0, 0, 0, 0, 0,
9477 0, 0, 0, 0, 0, 0, 0, 0,
9478 0, 0, 0, 0, 0, 0, 0, 0,
9479 0, 0, 2, 10, 10, 10, 10, 10,
9480 10, 10, 10, 10, 10, 10, 10, 10,
9481 10, 10, 10, 10, 10, 10, 10, 0,
9482};
9483
9484static const Q_UINT8 dir_25[] = {
9485 10, 10, 10, 10, 10, 10, 10, 10,
9486 10, 10, 10, 10, 10, 10, 10, 10,
9487 10, 10, 10, 10, 10, 10, 10, 10,
9488 10, 10, 10, 10, 10, 10, 10, 10,
9489 10, 10, 10, 10, 10, 10, 10, 10,
9490 10, 10, 10, 10, 10, 10, 10, 10,
9491 10, 10, 10, 10, 10, 10, 10, 10,
9492 10, 10, 10, 10, 10, 10, 10, 10,
9493 10, 10, 10, 10, 10, 10, 10, 10,
9494 10, 10, 10, 10, 10, 10, 10, 10,
9495 10, 10, 10, 10, 10, 10, 10, 10,
9496 10, 10, 10, 10, 10, 10, 10, 10,
9497 10, 10, 10, 10, 10, 10, 10, 10,
9498 10, 10, 10, 10, 10, 10, 10, 10,
9499 10, 10, 10, 10, 10, 10, 10, 10,
9500 10, 10, 10, 10, 10, 10, 10, 10,
9501 10, 10, 10, 10, 10, 10, 10, 10,
9502 10, 10, 10, 10, 10, 10, 10, 10,
9503 10, 10, 10, 10, 10, 10, 10, 10,
9504 10, 10, 10, 10, 10, 10, 10, 10,
9505 10, 10, 10, 10, 10, 10, 10, 10,
9506 10, 10, 10, 10, 10, 10, 10, 10,
9507 10, 10, 10, 10, 10, 10, 10, 10,
9508 10, 10, 10, 10, 10, 10, 10, 10,
9509 10, 10, 10, 10, 10, 10, 10, 10,
9510 10, 10, 10, 10, 10, 10, 10, 10,
9511 10, 10, 10, 10, 10, 10, 10, 10,
9512 10, 10, 10, 10, 10, 10, 10, 10,
9513 10, 10, 10, 10, 10, 10, 10, 10,
9514 10, 10, 10, 10, 10, 10, 10, 10,
9515 10, 10, 10, 10, 10, 10, 10, 10,
9516 10, 10, 10, 10, 10, 10, 10, 10,
9517};
9518
9519static const Q_UINT8 dir_26[] = {
9520 10, 10, 10, 10, 10, 10, 10, 10,
9521 10, 10, 10, 10, 10, 10, 10, 10,
9522 10, 10, 10, 10, 0, 0, 10, 10,
9523 0, 10, 10, 10, 10, 10, 10, 10,
9524 10, 10, 10, 10, 10, 10, 10, 10,
9525 10, 10, 10, 10, 10, 10, 10, 10,
9526 10, 10, 10, 10, 10, 10, 10, 10,
9527 10, 10, 10, 10, 10, 10, 10, 10,
9528 10, 10, 10, 10, 10, 10, 10, 10,
9529 10, 10, 10, 10, 10, 10, 10, 10,
9530 10, 10, 10, 10, 10, 10, 10, 10,
9531 10, 10, 10, 10, 10, 10, 10, 10,
9532 10, 10, 10, 10, 10, 10, 10, 10,
9533 10, 10, 10, 10, 10, 10, 10, 10,
9534 10, 10, 10, 10, 10, 10, 10, 10,
9535 10, 10, 10, 10, 10, 10, 0, 0,
9536 10, 10, 10, 10, 10, 10, 10, 10,
9537 10, 10, 0, 0, 0, 0, 0, 0,
9538 0, 0, 0, 0, 0, 0, 0, 0,
9539 0, 0, 0, 0, 0, 0, 0, 0,
9540 0, 0, 0, 0, 0, 0, 0, 0,
9541 0, 0, 0, 0, 0, 0, 0, 0,
9542 0, 0, 0, 0, 0, 0, 0, 0,
9543 0, 0, 0, 0, 0, 0, 0, 0,
9544 0, 0, 0, 0, 0, 0, 0, 0,
9545 0, 0, 0, 0, 0, 0, 0, 0,
9546 0, 0, 0, 0, 0, 0, 0, 0,
9547 0, 0, 0, 0, 0, 0, 0, 0,
9548 0, 0, 0, 0, 0, 0, 0, 0,
9549 0, 0, 0, 0, 0, 0, 0, 0,
9550 0, 0, 0, 0, 0, 0, 0, 0,
9551 0, 0, 0, 0, 0, 0, 0, 0,
9552};
9553
9554static const Q_UINT8 dir_27[] = {
9555 0, 10, 10, 10, 10, 0, 10, 10,
9556 10, 10, 0, 0, 10, 10, 10, 10,
9557 10, 10, 10, 10, 10, 10, 10, 10,
9558 10, 10, 10, 10, 10, 10, 10, 10,
9559 10, 10, 10, 10, 10, 10, 10, 10,
9560 0, 10, 10, 10, 10, 10, 10, 10,
9561 10, 10, 10, 10, 10, 10, 10, 10,
9562 10, 10, 10, 10, 10, 10, 10, 10,
9563 10, 10, 10, 10, 10, 10, 10, 10,
9564 10, 10, 10, 10, 0, 10, 0, 10,
9565 10, 10, 10, 0, 0, 0, 10, 0,
9566 10, 10, 10, 10, 10, 10, 10, 0,
9567 0, 10, 10, 10, 10, 10, 10, 10,
9568 138, 138, 138, 138, 138, 138, 138, 138,
9569 138, 138, 138, 138, 138, 138, 10, 10,
9570 10, 10, 10, 10, 10, 10, 10, 10,
9571 10, 10, 10, 10, 10, 10, 10, 10,
9572 10, 10, 10, 10, 10, 10, 10, 10,
9573 10, 10, 10, 10, 10, 0, 0, 0,
9574 10, 10, 10, 10, 10, 10, 10, 10,
9575 10, 10, 10, 10, 10, 10, 10, 10,
9576 10, 10, 10, 10, 10, 10, 10, 10,
9577 0, 10, 10, 10, 10, 10, 10, 10,
9578 10, 10, 10, 10, 10, 10, 10, 0,
9579 0, 0, 0, 0, 0, 0, 0, 0,
9580 0, 0, 0, 0, 0, 0, 0, 0,
9581 10, 10, 10, 138, 138, 138, 138, 10,
9582 10, 10, 10, 10, 138, 138, 138, 10,
9583 10, 10, 138, 138, 138, 138, 138, 138,
9584 138, 138, 138, 138, 0, 0, 0, 0,
9585 10, 10, 10, 10, 10, 10, 10, 10,
9586 10, 10, 10, 10, 10, 10, 10, 10,
9587};
9588
9589static const Q_UINT8 dir_29[] = {
9590 10, 10, 10, 10, 10, 10, 10, 10,
9591 10, 10, 10, 10, 10, 10, 10, 10,
9592 10, 10, 10, 10, 10, 10, 10, 10,
9593 10, 10, 10, 10, 10, 10, 10, 10,
9594 10, 10, 10, 10, 10, 10, 10, 10,
9595 10, 10, 10, 10, 10, 10, 10, 10,
9596 10, 10, 10, 10, 10, 10, 10, 10,
9597 10, 10, 10, 10, 10, 10, 10, 10,
9598 10, 10, 10, 10, 10, 10, 10, 10,
9599 10, 10, 10, 10, 10, 10, 10, 10,
9600 10, 10, 10, 10, 10, 10, 10, 10,
9601 10, 10, 10, 10, 10, 10, 10, 10,
9602 10, 10, 10, 10, 10, 10, 10, 10,
9603 10, 10, 10, 10, 10, 10, 10, 10,
9604 10, 10, 10, 10, 10, 10, 10, 10,
9605 10, 10, 10, 10, 10, 10, 10, 10,
9606 10, 10, 10, 138, 138, 138, 138, 138,
9607 138, 138, 138, 138, 138, 138, 138, 138,
9608 138, 138, 138, 138, 138, 138, 138, 138,
9609 138, 10, 10, 138, 138, 138, 138, 138,
9610 138, 138, 138, 138, 138, 138, 138, 138,
9611 138, 138, 138, 138, 138, 138, 138, 138,
9612 10, 10, 10, 10, 10, 10, 10, 10,
9613 138, 10, 10, 10, 10, 10, 10, 10,
9614 138, 138, 138, 138, 138, 138, 10, 10,
9615 10, 138, 10, 10, 10, 10, 138, 138,
9616 138, 138, 138, 10, 138, 138, 10, 10,
9617 138, 138, 138, 138, 138, 10, 10, 10,
9618 10, 138, 10, 138, 138, 138, 10, 10,
9619 138, 138, 10, 10, 10, 10, 10, 10,
9620 10, 10, 10, 10, 138, 138, 138, 138,
9621 138, 138, 10, 10, 138, 138, 10, 10,
9622};
9623
9624static const Q_UINT8 dir_2A[] = {
9625 10, 10, 10, 10, 10, 10, 10, 10,
9626 10, 10, 138, 138, 138, 138, 138, 138,
9627 138, 138, 138, 138, 138, 138, 138, 138,
9628 138, 138, 138, 138, 138, 10, 138, 138,
9629 138, 138, 10, 10, 138, 10, 138, 10,
9630 10, 138, 10, 138, 138, 138, 138, 10,
9631 10, 10, 10, 10, 138, 138, 10, 10,
9632 10, 10, 10, 10, 138, 138, 138, 10,
9633 10, 10, 10, 10, 10, 10, 10, 10,
9634 10, 10, 10, 10, 10, 10, 10, 10,
9635 10, 10, 10, 10, 10, 10, 10, 138,
9636 138, 10, 10, 10, 10, 10, 10, 10,
9637 10, 10, 10, 10, 138, 138, 10, 10,
9638 10, 10, 138, 138, 138, 138, 10, 138,
9639 138, 10, 10, 138, 138, 10, 10, 10,
9640 10, 138, 138, 138, 138, 138, 138, 138,
9641 138, 138, 138, 138, 138, 138, 138, 138,
9642 138, 138, 138, 138, 138, 138, 138, 138,
9643 138, 138, 138, 138, 138, 138, 138, 138,
9644 138, 138, 138, 138, 138, 138, 138, 138,
9645 138, 138, 138, 138, 10, 10, 138, 138,
9646 138, 138, 138, 138, 138, 138, 10, 138,
9647 138, 138, 138, 138, 138, 138, 138, 138,
9648 138, 138, 138, 138, 138, 138, 138, 138,
9649 138, 138, 138, 138, 138, 138, 138, 138,
9650 138, 138, 138, 138, 138, 138, 138, 138,
9651 138, 138, 138, 138, 138, 138, 138, 10,
9652 10, 10, 10, 10, 138, 10, 138, 10,
9653 10, 10, 138, 138, 138, 138, 138, 10,
9654 10, 10, 10, 10, 138, 138, 138, 10,
9655 10, 10, 10, 138, 10, 10, 10, 138,
9656 138, 138, 138, 138, 10, 138, 10, 10,
9657};
9658
9659static const Q_UINT8 dir_2E[] = {
9660 0, 0, 0, 0, 0, 0, 0, 0,
9661 0, 0, 0, 0, 0, 0, 0, 0,
9662 0, 0, 0, 0, 0, 0, 0, 0,
9663 0, 0, 0, 0, 0, 0, 0, 0,
9664 0, 0, 0, 0, 0, 0, 0, 0,
9665 0, 0, 0, 0, 0, 0, 0, 0,
9666 0, 0, 0, 0, 0, 0, 0, 0,
9667 0, 0, 0, 0, 0, 0, 0, 0,
9668 0, 0, 0, 0, 0, 0, 0, 0,
9669 0, 0, 0, 0, 0, 0, 0, 0,
9670 0, 0, 0, 0, 0, 0, 0, 0,
9671 0, 0, 0, 0, 0, 0, 0, 0,
9672 0, 0, 0, 0, 0, 0, 0, 0,
9673 0, 0, 0, 0, 0, 0, 0, 0,
9674 0, 0, 0, 0, 0, 0, 0, 0,
9675 0, 0, 0, 0, 0, 0, 0, 0,
9676 10, 10, 10, 10, 10, 10, 10, 10,
9677 10, 10, 10, 10, 10, 10, 10, 10,
9678 10, 10, 10, 10, 10, 10, 10, 10,
9679 10, 10, 0, 10, 10, 10, 10, 10,
9680 10, 10, 10, 10, 10, 10, 10, 10,
9681 10, 10, 10, 10, 10, 10, 10, 10,
9682 10, 10, 10, 10, 10, 10, 10, 10,
9683 10, 10, 10, 10, 10, 10, 10, 10,
9684 10, 10, 10, 10, 10, 10, 10, 10,
9685 10, 10, 10, 10, 10, 10, 10, 10,
9686 10, 10, 10, 10, 10, 10, 10, 10,
9687 10, 10, 10, 10, 10, 10, 10, 10,
9688 10, 10, 10, 10, 10, 10, 10, 10,
9689 10, 10, 10, 10, 10, 10, 10, 10,
9690 10, 10, 10, 10, 0, 0, 0, 0,
9691 0, 0, 0, 0, 0, 0, 0, 0,
9692};
9693
9694static const Q_UINT8 dir_2F[] = {
9695 10, 10, 10, 10, 10, 10, 10, 10,
9696 10, 10, 10, 10, 10, 10, 10, 10,
9697 10, 10, 10, 10, 10, 10, 10, 10,
9698 10, 10, 10, 10, 10, 10, 10, 10,
9699 10, 10, 10, 10, 10, 10, 10, 10,
9700 10, 10, 10, 10, 10, 10, 10, 10,
9701 10, 10, 10, 10, 10, 10, 10, 10,
9702 10, 10, 10, 10, 10, 10, 10, 10,
9703 10, 10, 10, 10, 10, 10, 10, 10,
9704 10, 10, 10, 10, 10, 10, 10, 10,
9705 10, 10, 10, 10, 10, 10, 10, 10,
9706 10, 10, 10, 10, 10, 10, 10, 10,
9707 10, 10, 10, 10, 10, 10, 10, 10,
9708 10, 10, 10, 10, 10, 10, 10, 10,
9709 10, 10, 10, 10, 10, 10, 10, 10,
9710 10, 10, 10, 10, 10, 10, 10, 10,
9711 10, 10, 10, 10, 10, 10, 10, 10,
9712 10, 10, 10, 10, 10, 10, 10, 10,
9713 10, 10, 10, 10, 10, 10, 10, 10,
9714 10, 10, 10, 10, 10, 10, 10, 10,
9715 10, 10, 10, 10, 10, 10, 10, 10,
9716 10, 10, 10, 10, 10, 10, 10, 10,
9717 10, 10, 10, 10, 10, 10, 10, 10,
9718 10, 10, 10, 10, 10, 10, 10, 10,
9719 10, 10, 10, 10, 10, 10, 10, 10,
9720 10, 10, 10, 10, 10, 10, 10, 10,
9721 10, 10, 10, 10, 10, 10, 0, 0,
9722 0, 0, 0, 0, 0, 0, 0, 0,
9723 0, 0, 0, 0, 0, 0, 0, 0,
9724 0, 0, 0, 0, 0, 0, 0, 0,
9725 10, 10, 10, 10, 10, 10, 10, 10,
9726 10, 10, 10, 10, 0, 0, 0, 0,
9727};
9728
9729static const Q_UINT8 dir_30[] = {
9730 9, 10, 10, 10, 10, 0, 0, 0,
9731 138, 138, 138, 138, 138, 138, 138, 138,
9732 138, 138, 10, 10, 138, 138, 138, 138,
9733 138, 138, 138, 138, 10, 10, 10, 10,
9734 10, 0, 0, 0, 0, 0, 0, 0,
9735 0, 0, 17, 17, 17, 17, 17, 17,
9736 10, 0, 0, 0, 0, 0, 10, 10,
9737 0, 0, 0, 0, 0, 10, 10, 10,
9738 0, 0, 0, 0, 0, 0, 0, 0,
9739 0, 0, 0, 0, 0, 0, 0, 0,
9740 0, 0, 0, 0, 0, 0, 0, 0,
9741 0, 0, 0, 0, 0, 0, 0, 0,
9742 0, 0, 0, 0, 0, 0, 0, 0,
9743 0, 0, 0, 0, 0, 0, 0, 0,
9744 0, 0, 0, 0, 0, 0, 0, 0,
9745 0, 0, 0, 0, 0, 0, 0, 0,
9746 0, 0, 0, 0, 0, 0, 0, 0,
9747 0, 0, 0, 0, 0, 0, 0, 0,
9748 0, 0, 0, 0, 0, 0, 0, 0,
9749 0, 17, 17, 10, 10, 0, 0, 0,
9750 10, 0, 0, 0, 0, 0, 0, 0,
9751 0, 0, 0, 0, 0, 0, 0, 0,
9752 0, 0, 0, 0, 0, 0, 0, 0,
9753 0, 0, 0, 0, 0, 0, 0, 0,
9754 0, 0, 0, 0, 0, 0, 0, 0,
9755 0, 0, 0, 0, 0, 0, 0, 0,
9756 0, 0, 0, 0, 0, 0, 0, 0,
9757 0, 0, 0, 0, 0, 0, 0, 0,
9758 0, 0, 0, 0, 0, 0, 0, 0,
9759 0, 0, 0, 0, 0, 0, 0, 0,
9760 0, 0, 0, 0, 0, 0, 0, 0,
9761 0, 0, 0, 10, 0, 0, 0, 0,
9762};
9763
9764static const Q_UINT8 dir_32[] = {
9765 0, 0, 0, 0, 0, 0, 0, 0,
9766 0, 0, 0, 0, 0, 0, 0, 0,
9767 0, 0, 0, 0, 0, 0, 0, 0,
9768 0, 0, 0, 0, 0, 0, 0, 0,
9769 0, 0, 0, 0, 0, 0, 0, 0,
9770 0, 0, 0, 0, 0, 0, 0, 0,
9771 0, 0, 0, 0, 0, 0, 0, 0,
9772 0, 0, 0, 0, 0, 0, 0, 0,
9773 0, 0, 0, 0, 0, 0, 0, 0,
9774 0, 0, 0, 0, 0, 0, 0, 0,
9775 0, 10, 10, 10, 10, 10, 10, 10,
9776 10, 10, 10, 10, 10, 10, 10, 10,
9777 0, 0, 0, 0, 0, 0, 0, 0,
9778 0, 0, 0, 0, 0, 0, 0, 0,
9779 0, 0, 0, 0, 0, 0, 0, 0,
9780 0, 0, 0, 0, 0, 0, 0, 0,
9781 0, 0, 0, 0, 0, 0, 0, 0,
9782 0, 0, 0, 0, 0, 0, 0, 0,
9783 0, 0, 0, 0, 0, 0, 0, 0,
9784 0, 0, 0, 0, 0, 0, 0, 0,
9785 0, 0, 0, 0, 0, 0, 0, 0,
9786 0, 0, 0, 0, 0, 0, 0, 0,
9787 0, 10, 10, 10, 10, 10, 10, 10,
9788 10, 10, 10, 10, 10, 10, 10, 10,
9789 0, 0, 0, 0, 0, 0, 0, 0,
9790 0, 0, 0, 0, 0, 0, 0, 0,
9791 0, 0, 0, 0, 0, 0, 0, 0,
9792 0, 0, 0, 0, 0, 0, 0, 0,
9793 0, 0, 0, 0, 0, 0, 0, 0,
9794 0, 0, 0, 0, 0, 0, 0, 0,
9795 0, 0, 0, 0, 0, 0, 0, 0,
9796 0, 0, 0, 0, 0, 0, 0, 0,
9797};
9798
9799static const Q_UINT8 dir_A4[] = {
9800 0, 0, 0, 0, 0, 0, 0, 0,
9801 0, 0, 0, 0, 0, 0, 0, 0,
9802 0, 0, 0, 0, 0, 0, 0, 0,
9803 0, 0, 0, 0, 0, 0, 0, 0,
9804 0, 0, 0, 0, 0, 0, 0, 0,
9805 0, 0, 0, 0, 0, 0, 0, 0,
9806 0, 0, 0, 0, 0, 0, 0, 0,
9807 0, 0, 0, 0, 0, 0, 0, 0,
9808 0, 0, 0, 0, 0, 0, 0, 0,
9809 0, 0, 0, 0, 0, 0, 0, 0,
9810 0, 0, 0, 0, 0, 0, 0, 0,
9811 0, 0, 0, 0, 0, 0, 0, 0,
9812 0, 0, 0, 0, 0, 0, 0, 0,
9813 0, 0, 0, 0, 0, 0, 0, 0,
9814 0, 0, 0, 0, 0, 0, 0, 0,
9815 0, 0, 0, 0, 0, 0, 0, 0,
9816 0, 0, 0, 0, 0, 0, 0, 0,
9817 0, 0, 0, 0, 0, 0, 0, 0,
9818 10, 10, 10, 10, 10, 10, 10, 10,
9819 10, 10, 10, 10, 10, 10, 10, 10,
9820 10, 10, 10, 10, 10, 10, 10, 10,
9821 10, 10, 10, 10, 10, 10, 10, 10,
9822 10, 10, 10, 10, 10, 10, 10, 10,
9823 10, 10, 10, 10, 10, 10, 10, 10,
9824 10, 10, 10, 10, 10, 10, 10, 0,
9825 0, 0, 0, 0, 0, 0, 0, 0,
9826 0, 0, 0, 0, 0, 0, 0, 0,
9827 0, 0, 0, 0, 0, 0, 0, 0,
9828 0, 0, 0, 0, 0, 0, 0, 0,
9829 0, 0, 0, 0, 0, 0, 0, 0,
9830 0, 0, 0, 0, 0, 0, 0, 0,
9831 0, 0, 0, 0, 0, 0, 0, 0,
9832};
9833
9834static const Q_UINT8 dir_FB[] = {
9835 0, 0, 0, 0, 0, 0, 0, 0,
9836 0, 0, 0, 0, 0, 0, 0, 0,
9837 0, 0, 0, 0, 0, 0, 0, 0,
9838 0, 0, 0, 0, 0, 1, 17, 1,
9839 1, 1, 1, 1, 1, 1, 1, 1,
9840 1, 4, 1, 1, 1, 1, 1, 1,
9841 1, 1, 1, 1, 1, 1, 1, 0,
9842 1, 1, 1, 1, 1, 0, 1, 0,
9843 1, 1, 0, 1, 1, 0, 1, 1,
9844 1, 1, 1, 1, 1, 1, 1, 1,
9845 13, 13, 13, 13, 13, 13, 13, 13,
9846 13, 13, 13, 13, 13, 13, 13, 13,
9847 13, 13, 13, 13, 13, 13, 13, 13,
9848 13, 13, 13, 13, 13, 13, 13, 13,
9849 13, 13, 13, 13, 13, 13, 13, 13,
9850 13, 13, 13, 13, 13, 13, 13, 13,
9851 13, 13, 13, 13, 13, 13, 13, 13,
9852 13, 13, 13, 13, 13, 13, 13, 13,
9853 13, 13, 13, 13, 13, 13, 13, 13,
9854 13, 13, 13, 13, 13, 13, 13, 13,
9855 13, 13, 13, 13, 13, 13, 13, 13,
9856 13, 13, 13, 13, 13, 13, 13, 13,
9857 13, 13, 0, 0, 0, 0, 0, 0,
9858 0, 0, 0, 0, 0, 0, 0, 0,
9859 0, 0, 0, 0, 0, 0, 0, 0,
9860 0, 0, 0, 0, 0, 0, 0, 0,
9861 0, 0, 0, 13, 13, 13, 13, 13,
9862 13, 13, 13, 13, 13, 13, 13, 13,
9863 13, 13, 13, 13, 13, 13, 13, 13,
9864 13, 13, 13, 13, 13, 13, 13, 13,
9865 13, 13, 13, 13, 13, 13, 13, 13,
9866 13, 13, 13, 13, 13, 13, 13, 13,
9867};
9868
9869static const Q_UINT8 dir_FC[] = {
9870 13, 13, 13, 13, 13, 13, 13, 13,
9871 13, 13, 13, 13, 13, 13, 13, 13,
9872 13, 13, 13, 13, 13, 13, 13, 13,
9873 13, 13, 13, 13, 13, 13, 13, 13,
9874 13, 13, 13, 13, 13, 13, 13, 13,
9875 13, 13, 13, 13, 13, 13, 13, 13,
9876 13, 13, 13, 13, 13, 13, 13, 13,
9877 13, 13, 13, 13, 13, 13, 13, 13,
9878 13, 13, 13, 13, 13, 13, 13, 13,
9879 13, 13, 13, 13, 13, 13, 13, 13,
9880 13, 13, 13, 13, 13, 13, 13, 13,
9881 13, 13, 13, 13, 13, 13, 13, 13,
9882 13, 13, 13, 13, 13, 13, 13, 13,
9883 13, 13, 13, 13, 13, 13, 13, 13,
9884 13, 13, 13, 13, 13, 13, 13, 13,
9885 13, 13, 13, 13, 13, 13, 13, 13,
9886 13, 13, 13, 13, 13, 13, 13, 13,
9887 13, 13, 13, 13, 13, 13, 13, 13,
9888 13, 13, 13, 13, 13, 13, 13, 13,
9889 13, 13, 13, 13, 13, 13, 13, 13,
9890 13, 13, 13, 13, 13, 13, 13, 13,
9891 13, 13, 13, 13, 13, 13, 13, 13,
9892 13, 13, 13, 13, 13, 13, 13, 13,
9893 13, 13, 13, 13, 13, 13, 13, 13,
9894 13, 13, 13, 13, 13, 13, 13, 13,
9895 13, 13, 13, 13, 13, 13, 13, 13,
9896 13, 13, 13, 13, 13, 13, 13, 13,
9897 13, 13, 13, 13, 13, 13, 13, 13,
9898 13, 13, 13, 13, 13, 13, 13, 13,
9899 13, 13, 13, 13, 13, 13, 13, 13,
9900 13, 13, 13, 13, 13, 13, 13, 13,
9901 13, 13, 13, 13, 13, 13, 13, 13,
9902};
9903
9904static const Q_UINT8 dir_FD[] = {
9905 13, 13, 13, 13, 13, 13, 13, 13,
9906 13, 13, 13, 13, 13, 13, 13, 13,
9907 13, 13, 13, 13, 13, 13, 13, 13,
9908 13, 13, 13, 13, 13, 13, 13, 13,
9909 13, 13, 13, 13, 13, 13, 13, 13,
9910 13, 13, 13, 13, 13, 13, 13, 13,
9911 13, 13, 13, 13, 13, 13, 13, 13,
9912 13, 13, 13, 13, 13, 13, 10, 10,
9913 0, 0, 0, 0, 0, 0, 0, 0,
9914 0, 0, 0, 0, 0, 0, 0, 0,
9915 13, 13, 13, 13, 13, 13, 13, 13,
9916 13, 13, 13, 13, 13, 13, 13, 13,
9917 13, 13, 13, 13, 13, 13, 13, 13,
9918 13, 13, 13, 13, 13, 13, 13, 13,
9919 13, 13, 13, 13, 13, 13, 13, 13,
9920 13, 13, 13, 13, 13, 13, 13, 13,
9921 13, 13, 13, 13, 13, 13, 13, 13,
9922 13, 13, 13, 13, 13, 13, 13, 13,
9923 0, 0, 13, 13, 13, 13, 13, 13,
9924 13, 13, 13, 13, 13, 13, 13, 13,
9925 13, 13, 13, 13, 13, 13, 13, 13,
9926 13, 13, 13, 13, 13, 13, 13, 13,
9927 13, 13, 13, 13, 13, 13, 13, 13,
9928 13, 13, 13, 13, 13, 13, 13, 13,
9929 13, 13, 13, 13, 13, 13, 13, 13,
9930 0, 0, 0, 0, 0, 0, 0, 0,
9931 0, 0, 0, 0, 0, 0, 0, 0,
9932 0, 0, 0, 0, 0, 0, 0, 0,
9933 0, 0, 0, 0, 0, 0, 0, 0,
9934 0, 0, 0, 0, 0, 0, 0, 0,
9935 13, 13, 13, 13, 13, 13, 13, 13,
9936 13, 13, 13, 13, 13, 0, 0, 0,
9937};
9938
9939static const Q_UINT8 dir_FE[] = {
9940 17, 17, 17, 17, 17, 17, 17, 17,
9941 17, 17, 17, 17, 17, 17, 17, 17,
9942 0, 0, 0, 0, 0, 0, 0, 0,
9943 0, 0, 0, 0, 0, 0, 0, 0,
9944 17, 17, 17, 17, 0, 0, 0, 0,
9945 0, 0, 0, 0, 0, 0, 0, 0,
9946 10, 10, 10, 10, 10, 10, 10, 10,
9947 10, 10, 10, 10, 10, 10, 10, 10,
9948 10, 10, 10, 10, 10, 10, 10, 0,
9949 0, 10, 10, 10, 10, 10, 10, 10,
9950 6, 10, 6, 0, 10, 6, 10, 10,
9951 10, 10, 10, 10, 10, 10, 10, 4,
9952 10, 10, 4, 4, 10, 10, 10, 0,
9953 10, 4, 4, 10, 0, 0, 0, 0,
9954 13, 13, 13, 13, 13, 0, 13, 13,
9955 13, 13, 13, 13, 13, 13, 13, 13,
9956 13, 13, 13, 13, 13, 13, 13, 13,
9957 13, 13, 13, 13, 13, 13, 13, 13,
9958 13, 13, 13, 13, 13, 13, 13, 13,
9959 13, 13, 13, 13, 13, 13, 13, 13,
9960 13, 13, 13, 13, 13, 13, 13, 13,
9961 13, 13, 13, 13, 13, 13, 13, 13,
9962 13, 13, 13, 13, 13, 13, 13, 13,
9963 13, 13, 13, 13, 13, 13, 13, 13,
9964 13, 13, 13, 13, 13, 13, 13, 13,
9965 13, 13, 13, 13, 13, 13, 13, 13,
9966 13, 13, 13, 13, 13, 13, 13, 13,
9967 13, 13, 13, 13, 13, 13, 13, 13,
9968 13, 13, 13, 13, 13, 13, 13, 13,
9969 13, 13, 13, 13, 13, 13, 13, 13,
9970 13, 13, 13, 13, 13, 13, 13, 13,
9971 13, 13, 13, 13, 13, 0, 0, 18,
9972};
9973
9974static const Q_UINT8 dir_FF[] = {
9975 0, 10, 10, 4, 4, 4, 10, 10,
9976 138, 138, 10, 4, 6, 4, 6, 3,
9977 2, 2, 2, 2, 2, 2, 2, 2,
9978 2, 2, 6, 10, 138, 10, 138, 10,
9979 10, 0, 0, 0, 0, 0, 0, 0,
9980 0, 0, 0, 0, 0, 0, 0, 0,
9981 0, 0, 0, 0, 0, 0, 0, 0,
9982 0, 0, 0, 138, 10, 138, 10, 10,
9983 10, 0, 0, 0, 0, 0, 0, 0,
9984 0, 0, 0, 0, 0, 0, 0, 0,
9985 0, 0, 0, 0, 0, 0, 0, 0,
9986 0, 0, 0, 138, 10, 138, 10, 138,
9987 138, 10, 138, 138, 10, 10, 0, 0,
9988 0, 0, 0, 0, 0, 0, 0, 0,
9989 0, 0, 0, 0, 0, 0, 0, 0,
9990 0, 0, 0, 0, 0, 0, 0, 0,
9991 0, 0, 0, 0, 0, 0, 0, 0,
9992 0, 0, 0, 0, 0, 0, 0, 0,
9993 0, 0, 0, 0, 0, 0, 0, 0,
9994 0, 0, 0, 0, 0, 0, 0, 0,
9995 0, 0, 0, 0, 0, 0, 0, 0,
9996 0, 0, 0, 0, 0, 0, 0, 0,
9997 0, 0, 0, 0, 0, 0, 0, 0,
9998 0, 0, 0, 0, 0, 0, 0, 0,
9999 0, 0, 0, 0, 0, 0, 0, 0,
10000 0, 0, 0, 0, 0, 0, 0, 0,
10001 0, 0, 0, 0, 0, 0, 0, 0,
10002 0, 0, 0, 0, 0, 0, 0, 0,
10003 4, 4, 10, 10, 10, 4, 4, 0,
10004 10, 10, 10, 10, 10, 10, 10, 0,
10005 0, 0, 0, 0, 0, 0, 0, 0,
10006 0, 18, 18, 18, 10, 10, 0, 0,
10007};
10008
10009static const Q_UINT8 * const direction_info[256] = {
10010 dir_00, dir_01, dir_02, dir_03, dir_04, dir_05, dir_06, dir_07,
10011 dir_01, dir_09, dir_0A, dir_0B, dir_0C, dir_0D, dir_0E, dir_0F,
10012 dir_10, dir_01, dir_01, dir_01, dir_01, dir_01, dir_16, dir_17,
10013 dir_18, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_1F,
10014 dir_20, dir_21, dir_22, dir_23, dir_24, dir_25, dir_26, dir_27,
10015 dir_25, dir_29, dir_2A, dir_01, dir_01, dir_01, dir_2E, dir_2F,
10016 dir_30, dir_01, dir_32, dir_01, dir_01, dir_01, dir_01, dir_01,
10017 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10018 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10019 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10020 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10021 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10022 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10023 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10024 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10025 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10026 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10027 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10028 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10029 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10030 dir_01, dir_01, dir_01, dir_01, dir_A4, dir_01, dir_01, dir_01,
10031 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10032 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10033 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10034 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10035 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10036 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10037 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10038 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10039 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10040 dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
10041 dir_01, dir_01, dir_01, dir_FB, dir_FC, dir_FD, dir_FE, dir_FF,
10042};
10043// 26362 bytes
10044
10045static const Q_UINT8 cmb_00[] = {
10046 0, 0, 0, 0, 0, 0, 0, 0,
10047 0, 0, 0, 0, 0, 0, 0, 0,
10048 0, 0, 0, 0, 0, 0, 0, 0,
10049 0, 0, 0, 0, 0, 0, 0, 0,
10050 0, 0, 0, 0, 0, 0, 0, 0,
10051 0, 0, 0, 0, 0, 0, 0, 0,
10052 0, 0, 0, 0, 0, 0, 0, 0,
10053 0, 0, 0, 0, 0, 0, 0, 0,
10054 0, 0, 0, 0, 0, 0, 0, 0,
10055 0, 0, 0, 0, 0, 0, 0, 0,
10056 0, 0, 0, 0, 0, 0, 0, 0,
10057 0, 0, 0, 0, 0, 0, 0, 0,
10058 0, 0, 0, 0, 0, 0, 0, 0,
10059 0, 0, 0, 0, 0, 0, 0, 0,
10060 0, 0, 0, 0, 0, 0, 0, 0,
10061 0, 0, 0, 0, 0, 0, 0, 0,
10062 0, 0, 0, 0, 0, 0, 0, 0,
10063 0, 0, 0, 0, 0, 0, 0, 0,
10064 0, 0, 0, 0, 0, 0, 0, 0,
10065 0, 0, 0, 0, 0, 0, 0, 0,
10066 0, 0, 0, 0, 0, 0, 0, 0,
10067 0, 0, 0, 0, 0, 0, 0, 0,
10068 0, 0, 0, 0, 0, 0, 0, 0,
10069 0, 0, 0, 0, 0, 0, 0, 0,
10070 0, 0, 0, 0, 0, 0, 0, 0,
10071 0, 0, 0, 0, 0, 0, 0, 0,
10072 0, 0, 0, 0, 0, 0, 0, 0,
10073 0, 0, 0, 0, 0, 0, 0, 0,
10074 0, 0, 0, 0, 0, 0, 0, 0,
10075 0, 0, 0, 0, 0, 0, 0, 0,
10076 0, 0, 0, 0, 0, 0, 0, 0,
10077 0, 0, 0, 0, 0, 0, 0, 0,
10078};
10079
10080static const Q_UINT8 cmb_03[] = {
10081 230, 230, 230, 230, 230, 230, 230, 230,
10082 230, 230, 230, 230, 230, 230, 230, 230,
10083 230, 230, 230, 230, 230, 232, 220, 220,
10084 220, 220, 232, 216, 220, 220, 220, 220,
10085 220, 202, 202, 220, 220, 220, 220, 202,
10086 202, 220, 220, 220, 220, 220, 220, 220,
10087 220, 220, 220, 220, 1, 1, 1, 1,
10088 1, 220, 220, 220, 220, 230, 230, 230,
10089 230, 230, 230, 230, 230, 240, 230, 220,
10090 220, 220, 230, 230, 230, 220, 220, 0,
10091 0, 0, 0, 0, 0, 0, 0, 0,
10092 0, 0, 0, 0, 0, 0, 0, 0,
10093 234, 234, 233, 230, 230, 230, 230, 230,
10094 230, 230, 230, 230, 230, 230, 230, 230,
10095 0, 0, 0, 0, 0, 0, 0, 0,
10096 0, 0, 0, 0, 0, 0, 0, 0,
10097 0, 0, 0, 0, 0, 0, 0, 0,
10098 0, 0, 0, 0, 0, 0, 0, 0,
10099 0, 0, 0, 0, 0, 0, 0, 0,
10100 0, 0, 0, 0, 0, 0, 0, 0,
10101 0, 0, 0, 0, 0, 0, 0, 0,
10102 0, 0, 0, 0, 0, 0, 0, 0,
10103 0, 0, 0, 0, 0, 0, 0, 0,
10104 0, 0, 0, 0, 0, 0, 0, 0,
10105 0, 0, 0, 0, 0, 0, 0, 0,
10106 0, 0, 0, 0, 0, 0, 0, 0,
10107 0, 0, 0, 0, 0, 0, 0, 0,
10108 0, 0, 0, 0, 0, 0, 0, 0,
10109 0, 0, 0, 0, 0, 0, 0, 0,
10110 0, 0, 0, 0, 0, 0, 0, 0,
10111 0, 0, 0, 0, 0, 0, 0, 0,
10112 0, 0, 0, 0, 0, 0, 0, 0,
10113};
10114
10115static const Q_UINT8 cmb_04[] = {
10116 0, 0, 0, 0, 0, 0, 0, 0,
10117 0, 0, 0, 0, 0, 0, 0, 0,
10118 0, 0, 0, 0, 0, 0, 0, 0,
10119 0, 0, 0, 0, 0, 0, 0, 0,
10120 0, 0, 0, 0, 0, 0, 0, 0,
10121 0, 0, 0, 0, 0, 0, 0, 0,
10122 0, 0, 0, 0, 0, 0, 0, 0,
10123 0, 0, 0, 0, 0, 0, 0, 0,
10124 0, 0, 0, 0, 0, 0, 0, 0,
10125 0, 0, 0, 0, 0, 0, 0, 0,
10126 0, 0, 0, 0, 0, 0, 0, 0,
10127 0, 0, 0, 0, 0, 0, 0, 0,
10128 0, 0, 0, 0, 0, 0, 0, 0,
10129 0, 0, 0, 0, 0, 0, 0, 0,
10130 0, 0, 0, 0, 0, 0, 0, 0,
10131 0, 0, 0, 0, 0, 0, 0, 0,
10132 0, 0, 0, 230, 230, 230, 230, 0,
10133 0, 0, 0, 0, 0, 0, 0, 0,
10134 0, 0, 0, 0, 0, 0, 0, 0,
10135 0, 0, 0, 0, 0, 0, 0, 0,
10136 0, 0, 0, 0, 0, 0, 0, 0,
10137 0, 0, 0, 0, 0, 0, 0, 0,
10138 0, 0, 0, 0, 0, 0, 0, 0,
10139 0, 0, 0, 0, 0, 0, 0, 0,
10140 0, 0, 0, 0, 0, 0, 0, 0,
10141 0, 0, 0, 0, 0, 0, 0, 0,
10142 0, 0, 0, 0, 0, 0, 0, 0,
10143 0, 0, 0, 0, 0, 0, 0, 0,
10144 0, 0, 0, 0, 0, 0, 0, 0,
10145 0, 0, 0, 0, 0, 0, 0, 0,
10146 0, 0, 0, 0, 0, 0, 0, 0,
10147 0, 0, 0, 0, 0, 0, 0, 0,
10148};
10149
10150static const Q_UINT8 cmb_05[] = {
10151 0, 0, 0, 0, 0, 0, 0, 0,
10152 0, 0, 0, 0, 0, 0, 0, 0,
10153 0, 0, 0, 0, 0, 0, 0, 0,
10154 0, 0, 0, 0, 0, 0, 0, 0,
10155 0, 0, 0, 0, 0, 0, 0, 0,
10156 0, 0, 0, 0, 0, 0, 0, 0,
10157 0, 0, 0, 0, 0, 0, 0, 0,
10158 0, 0, 0, 0, 0, 0, 0, 0,
10159 0, 0, 0, 0, 0, 0, 0, 0,
10160 0, 0, 0, 0, 0, 0, 0, 0,
10161 0, 0, 0, 0, 0, 0, 0, 0,
10162 0, 0, 0, 0, 0, 0, 0, 0,
10163 0, 0, 0, 0, 0, 0, 0, 0,
10164 0, 0, 0, 0, 0, 0, 0, 0,
10165 0, 0, 0, 0, 0, 0, 0, 0,
10166 0, 0, 0, 0, 0, 0, 0, 0,
10167 0, 0, 0, 0, 0, 0, 0, 0,
10168 0, 0, 0, 0, 0, 0, 0, 0,
10169 0, 220, 230, 230, 230, 230, 220, 230,
10170 230, 230, 222, 220, 230, 230, 230, 230,
10171 230, 230, 0, 220, 220, 220, 220, 220,
10172 230, 230, 220, 230, 230, 222, 228, 230,
10173 10, 11, 12, 13, 14, 15, 16, 17,
10174 18, 19, 0, 20, 21, 22, 0, 23,
10175 0, 24, 25, 0, 230, 0, 0, 0,
10176 0, 0, 0, 0, 0, 0, 0, 0,
10177 0, 0, 0, 0, 0, 0, 0, 0,
10178 0, 0, 0, 0, 0, 0, 0, 0,
10179 0, 0, 0, 0, 0, 0, 0, 0,
10180 0, 0, 0, 0, 0, 0, 0, 0,
10181 0, 0, 0, 0, 0, 0, 0, 0,
10182 0, 0, 0, 0, 0, 0, 0, 0,
10183};
10184
10185static const Q_UINT8 cmb_06[] = {
10186 0, 0, 0, 0, 0, 0, 0, 0,
10187 0, 0, 0, 0, 0, 0, 0, 0,
10188 0, 0, 0, 0, 0, 0, 0, 0,
10189 0, 0, 0, 0, 0, 0, 0, 0,
10190 0, 0, 0, 0, 0, 0, 0, 0,
10191 0, 0, 0, 0, 0, 0, 0, 0,
10192 0, 0, 0, 0, 0, 0, 0, 0,
10193 0, 0, 0, 0, 0, 0, 0, 0,
10194 0, 0, 0, 0, 0, 0, 0, 0,
10195 0, 0, 0, 27, 28, 29, 30, 31,
10196 32, 33, 34, 230, 230, 220, 0, 0,
10197 0, 0, 0, 0, 0, 0, 0, 0,
10198 0, 0, 0, 0, 0, 0, 0, 0,
10199 0, 0, 0, 0, 0, 0, 0, 0,
10200 35, 0, 0, 0, 0, 0, 0, 0,
10201 0, 0, 0, 0, 0, 0, 0, 0,
10202 0, 0, 0, 0, 0, 0, 0, 0,
10203 0, 0, 0, 0, 0, 0, 0, 0,
10204 0, 0, 0, 0, 0, 0, 0, 0,
10205 0, 0, 0, 0, 0, 0, 0, 0,
10206 0, 0, 0, 0, 0, 0, 0, 0,
10207 0, 0, 0, 0, 0, 0, 0, 0,
10208 0, 0, 0, 0, 0, 0, 0, 0,
10209 0, 0, 0, 0, 0, 0, 0, 0,
10210 0, 0, 0, 0, 0, 0, 0, 0,
10211 0, 0, 0, 0, 0, 0, 0, 0,
10212 0, 0, 0, 0, 0, 0, 230, 230,
10213 230, 230, 230, 230, 230, 0, 0, 230,
10214 230, 230, 230, 220, 230, 0, 0, 230,
10215 230, 0, 220, 230, 230, 220, 0, 0,
10216 0, 0, 0, 0, 0, 0, 0, 0,
10217 0, 0, 0, 0, 0, 0, 0, 0,
10218};
10219
10220static const Q_UINT8 cmb_07[] = {
10221 0, 0, 0, 0, 0, 0, 0, 0,
10222 0, 0, 0, 0, 0, 0, 0, 0,
10223 0, 36, 0, 0, 0, 0, 0, 0,
10224 0, 0, 0, 0, 0, 0, 0, 0,
10225 0, 0, 0, 0, 0, 0, 0, 0,
10226 0, 0, 0, 0, 0, 0, 0, 0,
10227 230, 220, 230, 230, 220, 230, 230, 220,
10228 220, 220, 230, 220, 220, 230, 220, 230,
10229 230, 230, 220, 230, 220, 230, 220, 230,
10230 220, 230, 230, 0, 0, 0, 0, 0,
10231 0, 0, 0, 0, 0, 0, 0, 0,
10232 0, 0, 0, 0, 0, 0, 0, 0,
10233 0, 0, 0, 0, 0, 0, 0, 0,
10234 0, 0, 0, 0, 0, 0, 0, 0,
10235 0, 0, 0, 0, 0, 0, 0, 0,
10236 0, 0, 0, 0, 0, 0, 0, 0,
10237 0, 0, 0, 0, 0, 0, 0, 0,
10238 0, 0, 0, 0, 0, 0, 0, 0,
10239 0, 0, 0, 0, 0, 0, 0, 0,
10240 0, 0, 0, 0, 0, 0, 0, 0,
10241 0, 0, 0, 0, 0, 0, 0, 0,
10242 0, 0, 0, 0, 0, 0, 0, 0,
10243 0, 0, 0, 0, 0, 0, 0, 0,
10244 0, 0, 0, 0, 0, 0, 0, 0,
10245 0, 0, 0, 0, 0, 0, 0, 0,
10246 0, 0, 0, 0, 0, 0, 0, 0,
10247 0, 0, 0, 0, 0, 0, 0, 0,
10248 0, 0, 0, 0, 0, 0, 0, 0,
10249 0, 0, 0, 0, 0, 0, 0, 0,
10250 0, 0, 0, 0, 0, 0, 0, 0,
10251 0, 0, 0, 0, 0, 0, 0, 0,
10252 0, 0, 0, 0, 0, 0, 0, 0,
10253};
10254
10255static const Q_UINT8 cmb_09[] = {
10256 0, 0, 0, 0, 0, 0, 0, 0,
10257 0, 0, 0, 0, 0, 0, 0, 0,
10258 0, 0, 0, 0, 0, 0, 0, 0,
10259 0, 0, 0, 0, 0, 0, 0, 0,
10260 0, 0, 0, 0, 0, 0, 0, 0,
10261 0, 0, 0, 0, 0, 0, 0, 0,
10262 0, 0, 0, 0, 0, 0, 0, 0,
10263 0, 0, 0, 0, 7, 0, 0, 0,
10264 0, 0, 0, 0, 0, 0, 0, 0,
10265 0, 0, 0, 0, 0, 9, 0, 0,
10266 0, 230, 220, 230, 230, 0, 0, 0,
10267 0, 0, 0, 0, 0, 0, 0, 0,
10268 0, 0, 0, 0, 0, 0, 0, 0,
10269 0, 0, 0, 0, 0, 0, 0, 0,
10270 0, 0, 0, 0, 0, 0, 0, 0,
10271 0, 0, 0, 0, 0, 0, 0, 0,
10272 0, 0, 0, 0, 0, 0, 0, 0,
10273 0, 0, 0, 0, 0, 0, 0, 0,
10274 0, 0, 0, 0, 0, 0, 0, 0,
10275 0, 0, 0, 0, 0, 0, 0, 0,
10276 0, 0, 0, 0, 0, 0, 0, 0,
10277 0, 0, 0, 0, 0, 0, 0, 0,
10278 0, 0, 0, 0, 0, 0, 0, 0,
10279 0, 0, 0, 0, 7, 0, 0, 0,
10280 0, 0, 0, 0, 0, 0, 0, 0,
10281 0, 0, 0, 0, 0, 9, 0, 0,
10282 0, 0, 0, 0, 0, 0, 0, 0,
10283 0, 0, 0, 0, 0, 0, 0, 0,
10284 0, 0, 0, 0, 0, 0, 0, 0,
10285 0, 0, 0, 0, 0, 0, 0, 0,
10286 0, 0, 0, 0, 0, 0, 0, 0,
10287 0, 0, 0, 0, 0, 0, 0, 0,
10288};
10289
10290static const Q_UINT8 cmb_0A[] = {
10291 0, 0, 0, 0, 0, 0, 0, 0,
10292 0, 0, 0, 0, 0, 0, 0, 0,
10293 0, 0, 0, 0, 0, 0, 0, 0,
10294 0, 0, 0, 0, 0, 0, 0, 0,
10295 0, 0, 0, 0, 0, 0, 0, 0,
10296 0, 0, 0, 0, 0, 0, 0, 0,
10297 0, 0, 0, 0, 0, 0, 0, 0,
10298 0, 0, 0, 0, 7, 0, 0, 0,
10299 0, 0, 0, 0, 0, 0, 0, 0,
10300 0, 0, 0, 0, 0, 9, 0, 0,
10301 0, 0, 0, 0, 0, 0, 0, 0,
10302 0, 0, 0, 0, 0, 0, 0, 0,
10303 0, 0, 0, 0, 0, 0, 0, 0,
10304 0, 0, 0, 0, 0, 0, 0, 0,
10305 0, 0, 0, 0, 0, 0, 0, 0,
10306 0, 0, 0, 0, 0, 0, 0, 0,
10307 0, 0, 0, 0, 0, 0, 0, 0,
10308 0, 0, 0, 0, 0, 0, 0, 0,
10309 0, 0, 0, 0, 0, 0, 0, 0,
10310 0, 0, 0, 0, 0, 0, 0, 0,
10311 0, 0, 0, 0, 0, 0, 0, 0,
10312 0, 0, 0, 0, 0, 0, 0, 0,
10313 0, 0, 0, 0, 0, 0, 0, 0,
10314 0, 0, 0, 0, 7, 0, 0, 0,
10315 0, 0, 0, 0, 0, 0, 0, 0,
10316 0, 0, 0, 0, 0, 9, 0, 0,
10317 0, 0, 0, 0, 0, 0, 0, 0,
10318 0, 0, 0, 0, 0, 0, 0, 0,
10319 0, 0, 0, 0, 0, 0, 0, 0,
10320 0, 0, 0, 0, 0, 0, 0, 0,
10321 0, 0, 0, 0, 0, 0, 0, 0,
10322 0, 0, 0, 0, 0, 0, 0, 0,
10323};
10324
10325static const Q_UINT8 cmb_0B[] = {
10326 0, 0, 0, 0, 0, 0, 0, 0,
10327 0, 0, 0, 0, 0, 0, 0, 0,
10328 0, 0, 0, 0, 0, 0, 0, 0,
10329 0, 0, 0, 0, 0, 0, 0, 0,
10330 0, 0, 0, 0, 0, 0, 0, 0,
10331 0, 0, 0, 0, 0, 0, 0, 0,
10332 0, 0, 0, 0, 0, 0, 0, 0,
10333 0, 0, 0, 0, 7, 0, 0, 0,
10334 0, 0, 0, 0, 0, 0, 0, 0,
10335 0, 0, 0, 0, 0, 9, 0, 0,
10336 0, 0, 0, 0, 0, 0, 0, 0,
10337 0, 0, 0, 0, 0, 0, 0, 0,
10338 0, 0, 0, 0, 0, 0, 0, 0,
10339 0, 0, 0, 0, 0, 0, 0, 0,
10340 0, 0, 0, 0, 0, 0, 0, 0,
10341 0, 0, 0, 0, 0, 0, 0, 0,
10342 0, 0, 0, 0, 0, 0, 0, 0,
10343 0, 0, 0, 0, 0, 0, 0, 0,
10344 0, 0, 0, 0, 0, 0, 0, 0,
10345 0, 0, 0, 0, 0, 0, 0, 0,
10346 0, 0, 0, 0, 0, 0, 0, 0,
10347 0, 0, 0, 0, 0, 0, 0, 0,
10348 0, 0, 0, 0, 0, 0, 0, 0,
10349 0, 0, 0, 0, 0, 0, 0, 0,
10350 0, 0, 0, 0, 0, 0, 0, 0,
10351 0, 0, 0, 0, 0, 9, 0, 0,
10352 0, 0, 0, 0, 0, 0, 0, 0,
10353 0, 0, 0, 0, 0, 0, 0, 0,
10354 0, 0, 0, 0, 0, 0, 0, 0,
10355 0, 0, 0, 0, 0, 0, 0, 0,
10356 0, 0, 0, 0, 0, 0, 0, 0,
10357 0, 0, 0, 0, 0, 0, 0, 0,
10358};
10359
10360static const Q_UINT8 cmb_0C[] = {
10361 0, 0, 0, 0, 0, 0, 0, 0,
10362 0, 0, 0, 0, 0, 0, 0, 0,
10363 0, 0, 0, 0, 0, 0, 0, 0,
10364 0, 0, 0, 0, 0, 0, 0, 0,
10365 0, 0, 0, 0, 0, 0, 0, 0,
10366 0, 0, 0, 0, 0, 0, 0, 0,
10367 0, 0, 0, 0, 0, 0, 0, 0,
10368 0, 0, 0, 0, 0, 0, 0, 0,
10369 0, 0, 0, 0, 0, 0, 0, 0,
10370 0, 0, 0, 0, 0, 9, 0, 0,
10371 0, 0, 0, 0, 0, 84, 91, 0,
10372 0, 0, 0, 0, 0, 0, 0, 0,
10373 0, 0, 0, 0, 0, 0, 0, 0,
10374 0, 0, 0, 0, 0, 0, 0, 0,
10375 0, 0, 0, 0, 0, 0, 0, 0,
10376 0, 0, 0, 0, 0, 0, 0, 0,
10377 0, 0, 0, 0, 0, 0, 0, 0,
10378 0, 0, 0, 0, 0, 0, 0, 0,
10379 0, 0, 0, 0, 0, 0, 0, 0,
10380 0, 0, 0, 0, 0, 0, 0, 0,
10381 0, 0, 0, 0, 0, 0, 0, 0,
10382 0, 0, 0, 0, 0, 0, 0, 0,
10383 0, 0, 0, 0, 0, 0, 0, 0,
10384 0, 0, 0, 0, 0, 0, 0, 0,
10385 0, 0, 0, 0, 0, 0, 0, 0,
10386 0, 0, 0, 0, 0, 9, 0, 0,
10387 0, 0, 0, 0, 0, 0, 0, 0,
10388 0, 0, 0, 0, 0, 0, 0, 0,
10389 0, 0, 0, 0, 0, 0, 0, 0,
10390 0, 0, 0, 0, 0, 0, 0, 0,
10391 0, 0, 0, 0, 0, 0, 0, 0,
10392 0, 0, 0, 0, 0, 0, 0, 0,
10393};
10394
10395static const Q_UINT8 cmb_0D[] = {
10396 0, 0, 0, 0, 0, 0, 0, 0,
10397 0, 0, 0, 0, 0, 0, 0, 0,
10398 0, 0, 0, 0, 0, 0, 0, 0,
10399 0, 0, 0, 0, 0, 0, 0, 0,
10400 0, 0, 0, 0, 0, 0, 0, 0,
10401 0, 0, 0, 0, 0, 0, 0, 0,
10402 0, 0, 0, 0, 0, 0, 0, 0,
10403 0, 0, 0, 0, 0, 0, 0, 0,
10404 0, 0, 0, 0, 0, 0, 0, 0,
10405 0, 0, 0, 0, 0, 9, 0, 0,
10406 0, 0, 0, 0, 0, 0, 0, 0,
10407 0, 0, 0, 0, 0, 0, 0, 0,
10408 0, 0, 0, 0, 0, 0, 0, 0,
10409 0, 0, 0, 0, 0, 0, 0, 0,
10410 0, 0, 0, 0, 0, 0, 0, 0,
10411 0, 0, 0, 0, 0, 0, 0, 0,
10412 0, 0, 0, 0, 0, 0, 0, 0,
10413 0, 0, 0, 0, 0, 0, 0, 0,
10414 0, 0, 0, 0, 0, 0, 0, 0,
10415 0, 0, 0, 0, 0, 0, 0, 0,
10416 0, 0, 0, 0, 0, 0, 0, 0,
10417 0, 0, 0, 0, 0, 0, 0, 0,
10418 0, 0, 0, 0, 0, 0, 0, 0,
10419 0, 0, 0, 0, 0, 0, 0, 0,
10420 0, 0, 0, 0, 0, 0, 0, 0,
10421 0, 0, 9, 0, 0, 0, 0, 0,
10422 0, 0, 0, 0, 0, 0, 0, 0,
10423 0, 0, 0, 0, 0, 0, 0, 0,
10424 0, 0, 0, 0, 0, 0, 0, 0,
10425 0, 0, 0, 0, 0, 0, 0, 0,
10426 0, 0, 0, 0, 0, 0, 0, 0,
10427 0, 0, 0, 0, 0, 0, 0, 0,
10428};
10429
10430static const Q_UINT8 cmb_0E[] = {
10431 0, 0, 0, 0, 0, 0, 0, 0,
10432 0, 0, 0, 0, 0, 0, 0, 0,
10433 0, 0, 0, 0, 0, 0, 0, 0,
10434 0, 0, 0, 0, 0, 0, 0, 0,
10435 0, 0, 0, 0, 0, 0, 0, 0,
10436 0, 0, 0, 0, 0, 0, 0, 0,
10437 0, 0, 0, 0, 0, 0, 0, 0,
10438 103, 103, 9, 0, 0, 0, 0, 0,
10439 0, 0, 0, 0, 0, 0, 0, 0,
10440 107, 107, 107, 107, 0, 0, 0, 0,
10441 0, 0, 0, 0, 0, 0, 0, 0,
10442 0, 0, 0, 0, 0, 0, 0, 0,
10443 0, 0, 0, 0, 0, 0, 0, 0,
10444 0, 0, 0, 0, 0, 0, 0, 0,
10445 0, 0, 0, 0, 0, 0, 0, 0,
10446 0, 0, 0, 0, 0, 0, 0, 0,
10447 0, 0, 0, 0, 0, 0, 0, 0,
10448 0, 0, 0, 0, 0, 0, 0, 0,
10449 0, 0, 0, 0, 0, 0, 0, 0,
10450 0, 0, 0, 0, 0, 0, 0, 0,
10451 0, 0, 0, 0, 0, 0, 0, 0,
10452 0, 0, 0, 0, 0, 0, 0, 0,
10453 0, 0, 0, 0, 0, 0, 0, 0,
10454 118, 118, 0, 0, 0, 0, 0, 0,
10455 0, 0, 0, 0, 0, 0, 0, 0,
10456 122, 122, 122, 122, 0, 0, 0, 0,
10457 0, 0, 0, 0, 0, 0, 0, 0,
10458 0, 0, 0, 0, 0, 0, 0, 0,
10459 0, 0, 0, 0, 0, 0, 0, 0,
10460 0, 0, 0, 0, 0, 0, 0, 0,
10461 0, 0, 0, 0, 0, 0, 0, 0,
10462 0, 0, 0, 0, 0, 0, 0, 0,
10463};
10464
10465static const Q_UINT8 cmb_0F[] = {
10466 0, 0, 0, 0, 0, 0, 0, 0,
10467 0, 0, 0, 0, 0, 0, 0, 0,
10468 0, 0, 0, 0, 0, 0, 0, 0,
10469 220, 220, 0, 0, 0, 0, 0, 0,
10470 0, 0, 0, 0, 0, 0, 0, 0,
10471 0, 0, 0, 0, 0, 0, 0, 0,
10472 0, 0, 0, 0, 0, 220, 0, 220,
10473 0, 216, 0, 0, 0, 0, 0, 0,
10474 0, 0, 0, 0, 0, 0, 0, 0,
10475 0, 0, 0, 0, 0, 0, 0, 0,
10476 0, 0, 0, 0, 0, 0, 0, 0,
10477 0, 0, 0, 0, 0, 0, 0, 0,
10478 0, 0, 0, 0, 0, 0, 0, 0,
10479 0, 0, 0, 0, 0, 0, 0, 0,
10480 0, 129, 130, 0, 132, 0, 0, 0,
10481 0, 0, 130, 130, 130, 130, 0, 0,
10482 130, 0, 230, 230, 9, 0, 230, 230,
10483 0, 0, 0, 0, 0, 0, 0, 0,
10484 0, 0, 0, 0, 0, 0, 0, 0,
10485 0, 0, 0, 0, 0, 0, 0, 0,
10486 0, 0, 0, 0, 0, 0, 0, 0,
10487 0, 0, 0, 0, 0, 0, 0, 0,
10488 0, 0, 0, 0, 0, 0, 0, 0,
10489 0, 0, 0, 0, 0, 0, 0, 0,
10490 0, 0, 0, 0, 0, 0, 220, 0,
10491 0, 0, 0, 0, 0, 0, 0, 0,
10492 0, 0, 0, 0, 0, 0, 0, 0,
10493 0, 0, 0, 0, 0, 0, 0, 0,
10494 0, 0, 0, 0, 0, 0, 0, 0,
10495 0, 0, 0, 0, 0, 0, 0, 0,
10496 0, 0, 0, 0, 0, 0, 0, 0,
10497 0, 0, 0, 0, 0, 0, 0, 0,
10498};
10499
10500static const Q_UINT8 cmb_10[] = {
10501 0, 0, 0, 0, 0, 0, 0, 0,
10502 0, 0, 0, 0, 0, 0, 0, 0,
10503 0, 0, 0, 0, 0, 0, 0, 0,
10504 0, 0, 0, 0, 0, 0, 0, 0,
10505 0, 0, 0, 0, 0, 0, 0, 0,
10506 0, 0, 0, 0, 0, 0, 0, 0,
10507 0, 0, 0, 0, 0, 0, 0, 7,
10508 0, 9, 0, 0, 0, 0, 0, 0,
10509 0, 0, 0, 0, 0, 0, 0, 0,
10510 0, 0, 0, 0, 0, 0, 0, 0,
10511 0, 0, 0, 0, 0, 0, 0, 0,
10512 0, 0, 0, 0, 0, 0, 0, 0,
10513 0, 0, 0, 0, 0, 0, 0, 0,
10514 0, 0, 0, 0, 0, 0, 0, 0,
10515 0, 0, 0, 0, 0, 0, 0, 0,
10516 0, 0, 0, 0, 0, 0, 0, 0,
10517 0, 0, 0, 0, 0, 0, 0, 0,
10518 0, 0, 0, 0, 0, 0, 0, 0,
10519 0, 0, 0, 0, 0, 0, 0, 0,
10520 0, 0, 0, 0, 0, 0, 0, 0,
10521 0, 0, 0, 0, 0, 0, 0, 0,
10522 0, 0, 0, 0, 0, 0, 0, 0,
10523 0, 0, 0, 0, 0, 0, 0, 0,
10524 0, 0, 0, 0, 0, 0, 0, 0,
10525 0, 0, 0, 0, 0, 0, 0, 0,
10526 0, 0, 0, 0, 0, 0, 0, 0,
10527 0, 0, 0, 0, 0, 0, 0, 0,
10528 0, 0, 0, 0, 0, 0, 0, 0,
10529 0, 0, 0, 0, 0, 0, 0, 0,
10530 0, 0, 0, 0, 0, 0, 0, 0,
10531 0, 0, 0, 0, 0, 0, 0, 0,
10532 0, 0, 0, 0, 0, 0, 0, 0,
10533};
10534
10535static const Q_UINT8 cmb_17[] = {
10536 0, 0, 0, 0, 0, 0, 0, 0,
10537 0, 0, 0, 0, 0, 0, 0, 0,
10538 0, 0, 0, 0, 9, 0, 0, 0,
10539 0, 0, 0, 0, 0, 0, 0, 0,
10540 0, 0, 0, 0, 0, 0, 0, 0,
10541 0, 0, 0, 0, 0, 0, 0, 0,
10542 0, 0, 0, 0, 9, 0, 0, 0,
10543 0, 0, 0, 0, 0, 0, 0, 0,
10544 0, 0, 0, 0, 0, 0, 0, 0,
10545 0, 0, 0, 0, 0, 0, 0, 0,
10546 0, 0, 0, 0, 0, 0, 0, 0,
10547 0, 0, 0, 0, 0, 0, 0, 0,
10548 0, 0, 0, 0, 0, 0, 0, 0,
10549 0, 0, 0, 0, 0, 0, 0, 0,
10550 0, 0, 0, 0, 0, 0, 0, 0,
10551 0, 0, 0, 0, 0, 0, 0, 0,
10552 0, 0, 0, 0, 0, 0, 0, 0,
10553 0, 0, 0, 0, 0, 0, 0, 0,
10554 0, 0, 0, 0, 0, 0, 0, 0,
10555 0, 0, 0, 0, 0, 0, 0, 0,
10556 0, 0, 0, 0, 0, 0, 0, 0,
10557 0, 0, 0, 0, 0, 0, 0, 0,
10558 0, 0, 0, 0, 0, 0, 0, 0,
10559 0, 0, 0, 0, 0, 0, 0, 0,
10560 0, 0, 0, 0, 0, 0, 0, 0,
10561 0, 0, 0, 0, 0, 0, 0, 0,
10562 0, 0, 9, 0, 0, 0, 0, 0,
10563 0, 0, 0, 0, 0, 0, 0, 0,
10564 0, 0, 0, 0, 0, 0, 0, 0,
10565 0, 0, 0, 0, 0, 0, 0, 0,
10566 0, 0, 0, 0, 0, 0, 0, 0,
10567 0, 0, 0, 0, 0, 0, 0, 0,
10568};
10569
10570static const Q_UINT8 cmb_18[] = {
10571 0, 0, 0, 0, 0, 0, 0, 0,
10572 0, 0, 0, 0, 0, 0, 0, 0,
10573 0, 0, 0, 0, 0, 0, 0, 0,
10574 0, 0, 0, 0, 0, 0, 0, 0,
10575 0, 0, 0, 0, 0, 0, 0, 0,
10576 0, 0, 0, 0, 0, 0, 0, 0,
10577 0, 0, 0, 0, 0, 0, 0, 0,
10578 0, 0, 0, 0, 0, 0, 0, 0,
10579 0, 0, 0, 0, 0, 0, 0, 0,
10580 0, 0, 0, 0, 0, 0, 0, 0,
10581 0, 0, 0, 0, 0, 0, 0, 0,
10582 0, 0, 0, 0, 0, 0, 0, 0,
10583 0, 0, 0, 0, 0, 0, 0, 0,
10584 0, 0, 0, 0, 0, 0, 0, 0,
10585 0, 0, 0, 0, 0, 0, 0, 0,
10586 0, 0, 0, 0, 0, 0, 0, 0,
10587 0, 0, 0, 0, 0, 0, 0, 0,
10588 0, 0, 0, 0, 0, 0, 0, 0,
10589 0, 0, 0, 0, 0, 0, 0, 0,
10590 0, 0, 0, 0, 0, 0, 0, 0,
10591 0, 0, 0, 0, 0, 0, 0, 0,
10592 0, 228, 0, 0, 0, 0, 0, 0,
10593 0, 0, 0, 0, 0, 0, 0, 0,
10594 0, 0, 0, 0, 0, 0, 0, 0,
10595 0, 0, 0, 0, 0, 0, 0, 0,
10596 0, 0, 0, 0, 0, 0, 0, 0,
10597 0, 0, 0, 0, 0, 0, 0, 0,
10598 0, 0, 0, 0, 0, 0, 0, 0,
10599 0, 0, 0, 0, 0, 0, 0, 0,
10600 0, 0, 0, 0, 0, 0, 0, 0,
10601 0, 0, 0, 0, 0, 0, 0, 0,
10602 0, 0, 0, 0, 0, 0, 0, 0,
10603};
10604
10605static const Q_UINT8 cmb_20[] = {
10606 0, 0, 0, 0, 0, 0, 0, 0,
10607 0, 0, 0, 0, 0, 0, 0, 0,
10608 0, 0, 0, 0, 0, 0, 0, 0,
10609 0, 0, 0, 0, 0, 0, 0, 0,
10610 0, 0, 0, 0, 0, 0, 0, 0,
10611 0, 0, 0, 0, 0, 0, 0, 0,
10612 0, 0, 0, 0, 0, 0, 0, 0,
10613 0, 0, 0, 0, 0, 0, 0, 0,
10614 0, 0, 0, 0, 0, 0, 0, 0,
10615 0, 0, 0, 0, 0, 0, 0, 0,
10616 0, 0, 0, 0, 0, 0, 0, 0,
10617 0, 0, 0, 0, 0, 0, 0, 0,
10618 0, 0, 0, 0, 0, 0, 0, 0,
10619 0, 0, 0, 0, 0, 0, 0, 0,
10620 0, 0, 0, 0, 0, 0, 0, 0,
10621 0, 0, 0, 0, 0, 0, 0, 0,
10622 0, 0, 0, 0, 0, 0, 0, 0,
10623 0, 0, 0, 0, 0, 0, 0, 0,
10624 0, 0, 0, 0, 0, 0, 0, 0,
10625 0, 0, 0, 0, 0, 0, 0, 0,
10626 0, 0, 0, 0, 0, 0, 0, 0,
10627 0, 0, 0, 0, 0, 0, 0, 0,
10628 0, 0, 0, 0, 0, 0, 0, 0,
10629 0, 0, 0, 0, 0, 0, 0, 0,
10630 0, 0, 0, 0, 0, 0, 0, 0,
10631 0, 0, 0, 0, 0, 0, 0, 0,
10632 230, 230, 1, 1, 230, 230, 230, 230,
10633 1, 1, 1, 230, 230, 0, 0, 0,
10634 0, 230, 0, 0, 0, 1, 1, 230,
10635 220, 230, 1, 0, 0, 0, 0, 0,
10636 0, 0, 0, 0, 0, 0, 0, 0,
10637 0, 0, 0, 0, 0, 0, 0, 0,
10638};
10639
10640static const Q_UINT8 cmb_30[] = {
10641 0, 0, 0, 0, 0, 0, 0, 0,
10642 0, 0, 0, 0, 0, 0, 0, 0,
10643 0, 0, 0, 0, 0, 0, 0, 0,
10644 0, 0, 0, 0, 0, 0, 0, 0,
10645 0, 0, 0, 0, 0, 0, 0, 0,
10646 0, 0, 218, 228, 232, 222, 224, 224,
10647 0, 0, 0, 0, 0, 0, 0, 0,
10648 0, 0, 0, 0, 0, 0, 0, 0,
10649 0, 0, 0, 0, 0, 0, 0, 0,
10650 0, 0, 0, 0, 0, 0, 0, 0,
10651 0, 0, 0, 0, 0, 0, 0, 0,
10652 0, 0, 0, 0, 0, 0, 0, 0,
10653 0, 0, 0, 0, 0, 0, 0, 0,
10654 0, 0, 0, 0, 0, 0, 0, 0,
10655 0, 0, 0, 0, 0, 0, 0, 0,
10656 0, 0, 0, 0, 0, 0, 0, 0,
10657 0, 0, 0, 0, 0, 0, 0, 0,
10658 0, 0, 0, 0, 0, 0, 0, 0,
10659 0, 0, 0, 0, 0, 0, 0, 0,
10660 0, 8, 8, 0, 0, 0, 0, 0,
10661 0, 0, 0, 0, 0, 0, 0, 0,
10662 0, 0, 0, 0, 0, 0, 0, 0,
10663 0, 0, 0, 0, 0, 0, 0, 0,
10664 0, 0, 0, 0, 0, 0, 0, 0,
10665 0, 0, 0, 0, 0, 0, 0, 0,
10666 0, 0, 0, 0, 0, 0, 0, 0,
10667 0, 0, 0, 0, 0, 0, 0, 0,
10668 0, 0, 0, 0, 0, 0, 0, 0,
10669 0, 0, 0, 0, 0, 0, 0, 0,
10670 0, 0, 0, 0, 0, 0, 0, 0,
10671 0, 0, 0, 0, 0, 0, 0, 0,
10672 0, 0, 0, 0, 0, 0, 0, 0,
10673};
10674
10675static const Q_UINT8 cmb_FB[] = {
10676 0, 0, 0, 0, 0, 0, 0, 0,
10677 0, 0, 0, 0, 0, 0, 0, 0,
10678 0, 0, 0, 0, 0, 0, 0, 0,
10679 0, 0, 0, 0, 0, 0, 26, 0,
10680 0, 0, 0, 0, 0, 0, 0, 0,
10681 0, 0, 0, 0, 0, 0, 0, 0,
10682 0, 0, 0, 0, 0, 0, 0, 0,
10683 0, 0, 0, 0, 0, 0, 0, 0,
10684 0, 0, 0, 0, 0, 0, 0, 0,
10685 0, 0, 0, 0, 0, 0, 0, 0,
10686 0, 0, 0, 0, 0, 0, 0, 0,
10687 0, 0, 0, 0, 0, 0, 0, 0,
10688 0, 0, 0, 0, 0, 0, 0, 0,
10689 0, 0, 0, 0, 0, 0, 0, 0,
10690 0, 0, 0, 0, 0, 0, 0, 0,
10691 0, 0, 0, 0, 0, 0, 0, 0,
10692 0, 0, 0, 0, 0, 0, 0, 0,
10693 0, 0, 0, 0, 0, 0, 0, 0,
10694 0, 0, 0, 0, 0, 0, 0, 0,
10695 0, 0, 0, 0, 0, 0, 0, 0,
10696 0, 0, 0, 0, 0, 0, 0, 0,
10697 0, 0, 0, 0, 0, 0, 0, 0,
10698 0, 0, 0, 0, 0, 0, 0, 0,
10699 0, 0, 0, 0, 0, 0, 0, 0,
10700 0, 0, 0, 0, 0, 0, 0, 0,
10701 0, 0, 0, 0, 0, 0, 0, 0,
10702 0, 0, 0, 0, 0, 0, 0, 0,
10703 0, 0, 0, 0, 0, 0, 0, 0,
10704 0, 0, 0, 0, 0, 0, 0, 0,
10705 0, 0, 0, 0, 0, 0, 0, 0,
10706 0, 0, 0, 0, 0, 0, 0, 0,
10707 0, 0, 0, 0, 0, 0, 0, 0,
10708};
10709
10710static const Q_UINT8 cmb_FE[] = {
10711 0, 0, 0, 0, 0, 0, 0, 0,
10712 0, 0, 0, 0, 0, 0, 0, 0,
10713 0, 0, 0, 0, 0, 0, 0, 0,
10714 0, 0, 0, 0, 0, 0, 0, 0,
10715 230, 230, 230, 230, 0, 0, 0, 0,
10716 0, 0, 0, 0, 0, 0, 0, 0,
10717 0, 0, 0, 0, 0, 0, 0, 0,
10718 0, 0, 0, 0, 0, 0, 0, 0,
10719 0, 0, 0, 0, 0, 0, 0, 0,
10720 0, 0, 0, 0, 0, 0, 0, 0,
10721 0, 0, 0, 0, 0, 0, 0, 0,
10722 0, 0, 0, 0, 0, 0, 0, 0,
10723 0, 0, 0, 0, 0, 0, 0, 0,
10724 0, 0, 0, 0, 0, 0, 0, 0,
10725 0, 0, 0, 0, 0, 0, 0, 0,
10726 0, 0, 0, 0, 0, 0, 0, 0,
10727 0, 0, 0, 0, 0, 0, 0, 0,
10728 0, 0, 0, 0, 0, 0, 0, 0,
10729 0, 0, 0, 0, 0, 0, 0, 0,
10730 0, 0, 0, 0, 0, 0, 0, 0,
10731 0, 0, 0, 0, 0, 0, 0, 0,
10732 0, 0, 0, 0, 0, 0, 0, 0,
10733 0, 0, 0, 0, 0, 0, 0, 0,
10734 0, 0, 0, 0, 0, 0, 0, 0,
10735 0, 0, 0, 0, 0, 0, 0, 0,
10736 0, 0, 0, 0, 0, 0, 0, 0,
10737 0, 0, 0, 0, 0, 0, 0, 0,
10738 0, 0, 0, 0, 0, 0, 0, 0,
10739 0, 0, 0, 0, 0, 0, 0, 0,
10740 0, 0, 0, 0, 0, 0, 0, 0,
10741 0, 0, 0, 0, 0, 0, 0, 0,
10742 0, 0, 0, 0, 0, 0, 0, 0,
10743};
10744
10745static const Q_UINT8 * const combining_info[256] = {
10746 cmb_00, cmb_00, cmb_00, cmb_03, cmb_04, cmb_05, cmb_06, cmb_07,
10747 cmb_00, cmb_09, cmb_0A, cmb_0B, cmb_0C, cmb_0D, cmb_0E, cmb_0F,
10748 cmb_10, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_17,
10749 cmb_18, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10750 cmb_20, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10751 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10752 cmb_30, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10753 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10754 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10755 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10756 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10757 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10758 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10759 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10760 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10761 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10762 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10763 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10764 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10765 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10766 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10767 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10768 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10769 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10770 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10771 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10772 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10773 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10774 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10775 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10776 cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00, cmb_00,
10777 cmb_00, cmb_00, cmb_00, cmb_FB, cmb_00, cmb_00, cmb_FE, cmb_00,
10778};
10779// 32506 bytes
10780
10781static const Q_UINT16 case_00[] = {
10782 0, 0, 0, 0, 0, 0, 0, 0,
10783 0, 0, 0, 0, 0, 0, 0, 0,
10784 0, 0, 0, 0, 0, 0, 0, 0,
10785 0, 0, 0, 0, 0, 0, 0, 0,
10786 0, 0, 0, 0, 0, 0, 0, 0,
10787 0, 0, 0, 0, 0, 0, 0, 0,
10788 0, 0, 0, 0, 0, 0, 0, 0,
10789 0, 0, 0, 0, 0, 0, 0, 0,
10790 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
10791 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
10792 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
10793 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0,
10794 0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
10795 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
10796 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
10797 0x58, 0x59, 0x5a, 0, 0, 0, 0, 0,
10798 0, 0, 0, 0, 0, 0, 0, 0,
10799 0, 0, 0, 0, 0, 0, 0, 0,
10800 0, 0, 0, 0, 0, 0, 0, 0,
10801 0, 0, 0, 0, 0, 0, 0, 0,
10802 0, 0, 0, 0, 0, 0, 0, 0,
10803 0, 0, 0, 0, 0, 0, 0, 0,
10804 0, 0, 0, 0, 0, 0x39c, 0, 0,
10805 0, 0, 0, 0, 0, 0, 0, 0,
10806 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
10807 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
10808 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0,
10809 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0,
10810 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
10811 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
10812 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0,
10813 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x178,
10814};
10815
10816static const Q_UINT16 case_01[] = {
10817 0x101, 0x100, 0x103, 0x102, 0x105, 0x104, 0x107, 0x106,
10818 0x109, 0x108, 0x10b, 0x10a, 0x10d, 0x10c, 0x10f, 0x10e,
10819 0x111, 0x110, 0x113, 0x112, 0x115, 0x114, 0x117, 0x116,
10820 0x119, 0x118, 0x11b, 0x11a, 0x11d, 0x11c, 0x11f, 0x11e,
10821 0x121, 0x120, 0x123, 0x122, 0x125, 0x124, 0x127, 0x126,
10822 0x129, 0x128, 0x12b, 0x12a, 0x12d, 0x12c, 0x12f, 0x12e,
10823 0x69, 0x49, 0x133, 0x132, 0x135, 0x134, 0x137, 0x136,
10824 0, 0x13a, 0x139, 0x13c, 0x13b, 0x13e, 0x13d, 0x140,
10825 0x13f, 0x142, 0x141, 0x144, 0x143, 0x146, 0x145, 0x148,
10826 0x147, 0, 0x14b, 0x14a, 0x14d, 0x14c, 0x14f, 0x14e,
10827 0x151, 0x150, 0x153, 0x152, 0x155, 0x154, 0x157, 0x156,
10828 0x159, 0x158, 0x15b, 0x15a, 0x15d, 0x15c, 0x15f, 0x15e,
10829 0x161, 0x160, 0x163, 0x162, 0x165, 0x164, 0x167, 0x166,
10830 0x169, 0x168, 0x16b, 0x16a, 0x16d, 0x16c, 0x16f, 0x16e,
10831 0x171, 0x170, 0x173, 0x172, 0x175, 0x174, 0x177, 0x176,
10832 0xff, 0x17a, 0x179, 0x17c, 0x17b, 0x17e, 0x17d, 0x53,
10833 0, 0x253, 0x183, 0x182, 0x185, 0x184, 0x254, 0x188,
10834 0x187, 0x256, 0x257, 0x18c, 0x18b, 0, 0x1dd, 0x259,
10835 0x25b, 0x192, 0x191, 0x260, 0x263, 0x1f6, 0x269, 0x268,
10836 0x199, 0x198, 0, 0, 0x26f, 0x272, 0x220, 0x275,
10837 0x1a1, 0x1a0, 0x1a3, 0x1a2, 0x1a5, 0x1a4, 0x280, 0x1a8,
10838 0x1a7, 0x283, 0, 0, 0x1ad, 0x1ac, 0x288, 0x1b0,
10839 0x1af, 0x28a, 0x28b, 0x1b4, 0x1b3, 0x1b6, 0x1b5, 0x292,
10840 0x1b9, 0x1b8, 0, 0, 0x1bd, 0x1bc, 0, 0x1f7,
10841 0, 0, 0, 0, 0x1c6, 0x1c4, 0x1c4, 0x1c9,
10842 0x1c7, 0x1c7, 0x1cc, 0x1ca, 0x1ca, 0x1ce, 0x1cd, 0x1d0,
10843 0x1cf, 0x1d2, 0x1d1, 0x1d4, 0x1d3, 0x1d6, 0x1d5, 0x1d8,
10844 0x1d7, 0x1da, 0x1d9, 0x1dc, 0x1db, 0x18e, 0x1df, 0x1de,
10845 0x1e1, 0x1e0, 0x1e3, 0x1e2, 0x1e5, 0x1e4, 0x1e7, 0x1e6,
10846 0x1e9, 0x1e8, 0x1eb, 0x1ea, 0x1ed, 0x1ec, 0x1ef, 0x1ee,
10847 0, 0x1f3, 0x1f1, 0x1f1, 0x1f5, 0x1f4, 0x195, 0x1bf,
10848 0x1f9, 0x1f8, 0x1fb, 0x1fa, 0x1fd, 0x1fc, 0x1ff, 0x1fe,
10849};
10850
10851static const Q_UINT16 case_02[] = {
10852 0x201, 0x200, 0x203, 0x202, 0x205, 0x204, 0x207, 0x206,
10853 0x209, 0x208, 0x20b, 0x20a, 0x20d, 0x20c, 0x20f, 0x20e,
10854 0x211, 0x210, 0x213, 0x212, 0x215, 0x214, 0x217, 0x216,
10855 0x219, 0x218, 0x21b, 0x21a, 0x21d, 0x21c, 0x21f, 0x21e,
10856 0x19e, 0, 0x223, 0x222, 0x225, 0x224, 0x227, 0x226,
10857 0x229, 0x228, 0x22b, 0x22a, 0x22d, 0x22c, 0x22f, 0x22e,
10858 0x231, 0x230, 0x233, 0x232, 0, 0, 0, 0,
10859 0, 0, 0, 0, 0, 0, 0, 0,
10860 0, 0, 0, 0, 0, 0, 0, 0,
10861 0, 0, 0, 0, 0, 0, 0, 0,
10862 0, 0, 0, 0x181, 0x186, 0, 0x189, 0x18a,
10863 0, 0x18f, 0, 0x190, 0, 0, 0, 0,
10864 0x193, 0, 0, 0x194, 0, 0, 0, 0,
10865 0x197, 0x196, 0, 0, 0, 0, 0, 0x19c,
10866 0, 0, 0x19d, 0, 0, 0x19f, 0, 0,
10867 0, 0, 0, 0, 0, 0, 0, 0,
10868 0x1a6, 0, 0, 0x1a9, 0, 0, 0, 0,
10869 0x1ae, 0, 0x1b1, 0x1b2, 0, 0, 0, 0,
10870 0, 0, 0x1b7, 0, 0, 0, 0, 0,
10871 0, 0, 0, 0, 0, 0, 0, 0,
10872 0, 0, 0, 0, 0, 0, 0, 0,
10873 0, 0, 0, 0, 0, 0, 0, 0,
10874 0, 0, 0, 0, 0, 0, 0, 0,
10875 0, 0, 0, 0, 0, 0, 0, 0,
10876 0, 0, 0, 0, 0, 0, 0, 0,
10877 0, 0, 0, 0, 0, 0, 0, 0,
10878 0, 0, 0, 0, 0, 0, 0, 0,
10879 0, 0, 0, 0, 0, 0, 0, 0,
10880 0, 0, 0, 0, 0, 0, 0, 0,
10881 0, 0, 0, 0, 0, 0, 0, 0,
10882 0, 0, 0, 0, 0, 0, 0, 0,
10883 0, 0, 0, 0, 0, 0, 0, 0,
10884};
10885
10886static const Q_UINT16 case_03[] = {
10887 0, 0, 0, 0, 0, 0, 0, 0,
10888 0, 0, 0, 0, 0, 0, 0, 0,
10889 0, 0, 0, 0, 0, 0, 0, 0,
10890 0, 0, 0, 0, 0, 0, 0, 0,
10891 0, 0, 0, 0, 0, 0, 0, 0,
10892 0, 0, 0, 0, 0, 0, 0, 0,
10893 0, 0, 0, 0, 0, 0, 0, 0,
10894 0, 0, 0, 0, 0, 0, 0, 0,
10895 0, 0, 0, 0, 0, 0x399, 0, 0,
10896 0, 0, 0, 0, 0, 0, 0, 0,
10897 0, 0, 0, 0, 0, 0, 0, 0,
10898 0, 0, 0, 0, 0, 0, 0, 0,
10899 0, 0, 0, 0, 0, 0, 0, 0,
10900 0, 0, 0, 0, 0, 0, 0, 0,
10901 0, 0, 0, 0, 0, 0, 0, 0,
10902 0, 0, 0, 0, 0, 0, 0, 0,
10903 0, 0, 0, 0, 0, 0, 0x3ac, 0,
10904 0x3ad, 0x3ae, 0x3af, 0, 0x3cc, 0, 0x3cd, 0x3ce,
10905 0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7,
10906 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf,
10907 0x3c0, 0x3c1, 0, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7,
10908 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x386, 0x388, 0x389, 0x38a,
10909 0, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397,
10910 0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f,
10911 0x3a0, 0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7,
10912 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f, 0,
10913 0x392, 0x398, 0, 0, 0, 0x3a6, 0x3a0, 0,
10914 0x3d9, 0x3d8, 0x3db, 0x3da, 0x3dd, 0x3dc, 0x3df, 0x3de,
10915 0x3e1, 0x3e0, 0x3e3, 0x3e2, 0x3e5, 0x3e4, 0x3e7, 0x3e6,
10916 0x3e9, 0x3e8, 0x3eb, 0x3ea, 0x3ed, 0x3ec, 0x3ef, 0x3ee,
10917 0x39a, 0x3a1, 0x3a3, 0, 0x3b8, 0x395, 0, 0,
10918 0, 0, 0, 0, 0, 0, 0, 0,
10919};
10920
10921static const Q_UINT16 case_04[] = {
10922 0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457,
10923 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45d, 0x45e, 0x45f,
10924 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437,
10925 0x438, 0x439, 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f,
10926 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447,
10927 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, 0x44e, 0x44f,
10928 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,
10929 0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e, 0x41f,
10930 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427,
10931 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f,
10932 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407,
10933 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40d, 0x40e, 0x40f,
10934 0x461, 0x460, 0x463, 0x462, 0x465, 0x464, 0x467, 0x466,
10935 0x469, 0x468, 0x46b, 0x46a, 0x46d, 0x46c, 0x46f, 0x46e,
10936 0x471, 0x470, 0x473, 0x472, 0x475, 0x474, 0x477, 0x476,
10937 0x479, 0x478, 0x47b, 0x47a, 0x47d, 0x47c, 0x47f, 0x47e,
10938 0x481, 0x480, 0, 0, 0, 0, 0, 0,
10939 0, 0, 0x48b, 0x48a, 0x48d, 0x48c, 0x48f, 0x48e,
10940 0x491, 0x490, 0x493, 0x492, 0x495, 0x494, 0x497, 0x496,
10941 0x499, 0x498, 0x49b, 0x49a, 0x49d, 0x49c, 0x49f, 0x49e,
10942 0x4a1, 0x4a0, 0x4a3, 0x4a2, 0x4a5, 0x4a4, 0x4a7, 0x4a6,
10943 0x4a9, 0x4a8, 0x4ab, 0x4aa, 0x4ad, 0x4ac, 0x4af, 0x4ae,
10944 0x4b1, 0x4b0, 0x4b3, 0x4b2, 0x4b5, 0x4b4, 0x4b7, 0x4b6,
10945 0x4b9, 0x4b8, 0x4bb, 0x4ba, 0x4bd, 0x4bc, 0x4bf, 0x4be,
10946 0, 0x4c2, 0x4c1, 0x4c4, 0x4c3, 0x4c6, 0x4c5, 0x4c8,
10947 0x4c7, 0x4ca, 0x4c9, 0x4cc, 0x4cb, 0x4ce, 0x4cd, 0,
10948 0x4d1, 0x4d0, 0x4d3, 0x4d2, 0x4d5, 0x4d4, 0x4d7, 0x4d6,
10949 0x4d9, 0x4d8, 0x4db, 0x4da, 0x4dd, 0x4dc, 0x4df, 0x4de,
10950 0x4e1, 0x4e0, 0x4e3, 0x4e2, 0x4e5, 0x4e4, 0x4e7, 0x4e6,
10951 0x4e9, 0x4e8, 0x4eb, 0x4ea, 0x4ed, 0x4ec, 0x4ef, 0x4ee,
10952 0x4f1, 0x4f0, 0x4f3, 0x4f2, 0x4f5, 0x4f4, 0, 0,
10953 0x4f9, 0x4f8, 0, 0, 0, 0, 0, 0,
10954};
10955
10956static const Q_UINT16 case_05[] = {
10957 0x501, 0x500, 0x503, 0x502, 0x505, 0x504, 0x507, 0x506,
10958 0x509, 0x508, 0x50b, 0x50a, 0x50d, 0x50c, 0x50f, 0x50e,
10959 0, 0, 0, 0, 0, 0, 0, 0,
10960 0, 0, 0, 0, 0, 0, 0, 0,
10961 0, 0, 0, 0, 0, 0, 0, 0,
10962 0, 0, 0, 0, 0, 0, 0, 0,
10963 0, 0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567,
10964 0x568, 0x569, 0x56a, 0x56b, 0x56c, 0x56d, 0x56e, 0x56f,
10965 0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577,
10966 0x578, 0x579, 0x57a, 0x57b, 0x57c, 0x57d, 0x57e, 0x57f,
10967 0x580, 0x581, 0x582, 0x583, 0x584, 0x585, 0x586, 0,
10968 0, 0, 0, 0, 0, 0, 0, 0,
10969 0, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537,
10970 0x538, 0x539, 0x53a, 0x53b, 0x53c, 0x53d, 0x53e, 0x53f,
10971 0x540, 0x541, 0x542, 0x543, 0x544, 0x545, 0x546, 0x547,
10972 0x548, 0x549, 0x54a, 0x54b, 0x54c, 0x54d, 0x54e, 0x54f,
10973 0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 0,
10974 0, 0, 0, 0, 0, 0, 0, 0,
10975 0, 0, 0, 0, 0, 0, 0, 0,
10976 0, 0, 0, 0, 0, 0, 0, 0,
10977 0, 0, 0, 0, 0, 0, 0, 0,
10978 0, 0, 0, 0, 0, 0, 0, 0,
10979 0, 0, 0, 0, 0, 0, 0, 0,
10980 0, 0, 0, 0, 0, 0, 0, 0,
10981 0, 0, 0, 0, 0, 0, 0, 0,
10982 0, 0, 0, 0, 0, 0, 0, 0,
10983 0, 0, 0, 0, 0, 0, 0, 0,
10984 0, 0, 0, 0, 0, 0, 0, 0,
10985 0, 0, 0, 0, 0, 0, 0, 0,
10986 0, 0, 0, 0, 0, 0, 0, 0,
10987 0, 0, 0, 0, 0, 0, 0, 0,
10988 0, 0, 0, 0, 0, 0, 0, 0,
10989};
10990
10991static const Q_UINT16 case_1E[] = {
10992 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06,
10993 0x1e09, 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e,
10994 0x1e11, 0x1e10, 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16,
10995 0x1e19, 0x1e18, 0x1e1b, 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e,
10996 0x1e21, 0x1e20, 0x1e23, 0x1e22, 0x1e25, 0x1e24, 0x1e27, 0x1e26,
10997 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, 0x1e2c, 0x1e2f, 0x1e2e,
10998 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, 0x1e37, 0x1e36,
10999 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, 0x1e3e,
11000 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46,
11001 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e,
11002 0x1e51, 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56,
11003 0x1e59, 0x1e58, 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e,
11004 0x1e61, 0x1e60, 0x1e63, 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66,
11005 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e,
11006 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, 0x1e74, 0x1e77, 0x1e76,
11007 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, 0x1e7f, 0x1e7e,
11008 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, 0x1e86,
11009 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e,
11010 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0, 0,
11011 0, 0, 0, 0x1e60, 0, 0, 0, 0,
11012 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6,
11013 0x1ea9, 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae,
11014 0x1eb1, 0x1eb0, 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6,
11015 0x1eb9, 0x1eb8, 0x1ebb, 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe,
11016 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6,
11017 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, 0x1ecc, 0x1ecf, 0x1ece,
11018 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, 0x1ed7, 0x1ed6,
11019 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, 0x1ede,
11020 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6,
11021 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee,
11022 0x1ef1, 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6,
11023 0x1ef9, 0x1ef8, 0, 0, 0, 0, 0, 0,
11024};
11025
11026static const Q_UINT16 case_1F[] = {
11027 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f,
11028 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07,
11029 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0, 0,
11030 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0, 0,
11031 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f,
11032 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27,
11033 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f,
11034 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37,
11035 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0, 0,
11036 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0, 0,
11037 0, 0x1f59, 0, 0x1f5b, 0, 0x1f5d, 0, 0x1f5f,
11038 0, 0x1f51, 0, 0x1f53, 0, 0x1f55, 0, 0x1f57,
11039 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f,
11040 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67,
11041 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb,
11042 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb, 0, 0,
11043 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
11044 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
11045 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
11046 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
11047 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
11048 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
11049 0x1fb8, 0x1fb9, 0, 0x1fbc, 0, 0, 0, 0,
11050 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0, 0x399, 0,
11051 0, 0, 0, 0x1fcc, 0, 0, 0, 0,
11052 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0, 0, 0,
11053 0x1fd8, 0x1fd9, 0, 0, 0, 0, 0, 0,
11054 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0, 0, 0, 0,
11055 0x1fe8, 0x1fe9, 0, 0, 0, 0x1fec, 0, 0,
11056 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0, 0, 0,
11057 0, 0, 0, 0x1ffc, 0, 0, 0, 0,
11058 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0, 0, 0,
11059};
11060
11061static const Q_UINT16 case_21[] = {
11062 0, 0, 0, 0, 0, 0, 0, 0,
11063 0, 0, 0, 0, 0, 0, 0, 0,
11064 0, 0, 0, 0, 0, 0, 0, 0,
11065 0, 0, 0, 0, 0, 0, 0, 0,
11066 0, 0, 0, 0, 0, 0, 0x3c9, 0,
11067 0, 0, 0x6b, 0xe5, 0, 0, 0, 0,
11068 0, 0, 0, 0, 0, 0, 0, 0,
11069 0, 0, 0, 0, 0, 0, 0, 0,
11070 0, 0, 0, 0, 0, 0, 0, 0,
11071 0, 0, 0, 0, 0, 0, 0, 0,
11072 0, 0, 0, 0, 0, 0, 0, 0,
11073 0, 0, 0, 0, 0, 0, 0, 0,
11074 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
11075 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f,
11076 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167,
11077 0x2168, 0x2169, 0x216a, 0x216b, 0x216c, 0x216d, 0x216e, 0x216f,
11078 0, 0, 0, 0, 0, 0, 0, 0,
11079 0, 0, 0, 0, 0, 0, 0, 0,
11080 0, 0, 0, 0, 0, 0, 0, 0,
11081 0, 0, 0, 0, 0, 0, 0, 0,
11082 0, 0, 0, 0, 0, 0, 0, 0,
11083 0, 0, 0, 0, 0, 0, 0, 0,
11084 0, 0, 0, 0, 0, 0, 0, 0,
11085 0, 0, 0, 0, 0, 0, 0, 0,
11086 0, 0, 0, 0, 0, 0, 0, 0,
11087 0, 0, 0, 0, 0, 0, 0, 0,
11088 0, 0, 0, 0, 0, 0, 0, 0,
11089 0, 0, 0, 0, 0, 0, 0, 0,
11090 0, 0, 0, 0, 0, 0, 0, 0,
11091 0, 0, 0, 0, 0, 0, 0, 0,
11092 0, 0, 0, 0, 0, 0, 0, 0,
11093 0, 0, 0, 0, 0, 0, 0, 0,
11094};
11095
11096static const Q_UINT16 case_24[] = {
11097 0, 0, 0, 0, 0, 0, 0, 0,
11098 0, 0, 0, 0, 0, 0, 0, 0,
11099 0, 0, 0, 0, 0, 0, 0, 0,
11100 0, 0, 0, 0, 0, 0, 0, 0,
11101 0, 0, 0, 0, 0, 0, 0, 0,
11102 0, 0, 0, 0, 0, 0, 0, 0,
11103 0, 0, 0, 0, 0, 0, 0, 0,
11104 0, 0, 0, 0, 0, 0, 0, 0,
11105 0, 0, 0, 0, 0, 0, 0, 0,
11106 0, 0, 0, 0, 0, 0, 0, 0,
11107 0, 0, 0, 0, 0, 0, 0, 0,
11108 0, 0, 0, 0, 0, 0, 0, 0,
11109 0, 0, 0, 0, 0, 0, 0, 0,
11110 0, 0, 0, 0, 0, 0, 0, 0,
11111 0, 0, 0, 0, 0, 0, 0, 0,
11112 0, 0, 0, 0, 0, 0, 0, 0,
11113 0, 0, 0, 0, 0, 0, 0, 0,
11114 0, 0, 0, 0, 0, 0, 0, 0,
11115 0, 0, 0, 0, 0, 0, 0, 0,
11116 0, 0, 0, 0, 0, 0, 0, 0,
11117 0, 0, 0, 0, 0, 0, 0, 0,
11118 0, 0, 0, 0, 0, 0, 0, 0,
11119 0, 0, 0, 0, 0, 0, 0x24d0, 0x24d1,
11120 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9,
11121 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1,
11122 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9,
11123 0x24b6, 0x24b7, 0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd,
11124 0x24be, 0x24bf, 0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5,
11125 0x24c6, 0x24c7, 0x24c8, 0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd,
11126 0x24ce, 0x24cf, 0, 0, 0, 0, 0, 0,
11127 0, 0, 0, 0, 0, 0, 0, 0,
11128 0, 0, 0, 0, 0, 0, 0, 0,
11129};
11130
11131static const Q_UINT16 case_FF[] = {
11132 0, 0, 0, 0, 0, 0, 0, 0,
11133 0, 0, 0, 0, 0, 0, 0, 0,
11134 0, 0, 0, 0, 0, 0, 0, 0,
11135 0, 0, 0, 0, 0, 0, 0, 0,
11136 0, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47,
11137 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f,
11138 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57,
11139 0xff58, 0xff59, 0xff5a, 0, 0, 0, 0, 0,
11140 0, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
11141 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f,
11142 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37,
11143 0xff38, 0xff39, 0xff3a, 0, 0, 0, 0, 0,
11144 0, 0, 0, 0, 0, 0, 0, 0,
11145 0, 0, 0, 0, 0, 0, 0, 0,
11146 0, 0, 0, 0, 0, 0, 0, 0,
11147 0, 0, 0, 0, 0, 0, 0, 0,
11148 0, 0, 0, 0, 0, 0, 0, 0,
11149 0, 0, 0, 0, 0, 0, 0, 0,
11150 0, 0, 0, 0, 0, 0, 0, 0,
11151 0, 0, 0, 0, 0, 0, 0, 0,
11152 0, 0, 0, 0, 0, 0, 0, 0,
11153 0, 0, 0, 0, 0, 0, 0, 0,
11154 0, 0, 0, 0, 0, 0, 0, 0,
11155 0, 0, 0, 0, 0, 0, 0, 0,
11156 0, 0, 0, 0, 0, 0, 0, 0,
11157 0, 0, 0, 0, 0, 0, 0, 0,
11158 0, 0, 0, 0, 0, 0, 0, 0,
11159 0, 0, 0, 0, 0, 0, 0, 0,
11160 0, 0, 0, 0, 0, 0, 0, 0,
11161 0, 0, 0, 0, 0, 0, 0, 0,
11162 0, 0, 0, 0, 0, 0, 0, 0,
11163 0, 0, 0, 0, 0, 0, 0, 0,
11164};
11165
11166static const Q_UINT16 * const case_info[256] = {
11167 case_00, case_01, case_02, case_03, case_04, case_05, 0, 0,
11168 0, 0, 0, 0, 0, 0, 0, 0,
11169 0, 0, 0, 0, 0, 0, 0, 0,
11170 0, 0, 0, 0, 0, 0, case_1E, case_1F,
11171 0, case_21, 0, 0, case_24, 0, 0, 0,
11172 0, 0, 0, 0, 0, 0, 0, 0,
11173 0, 0, 0, 0, 0, 0, 0, 0,
11174 0, 0, 0, 0, 0, 0, 0, 0,
11175 0, 0, 0, 0, 0, 0, 0, 0,
11176 0, 0, 0, 0, 0, 0, 0, 0,
11177 0, 0, 0, 0, 0, 0, 0, 0,
11178 0, 0, 0, 0, 0, 0, 0, 0,
11179 0, 0, 0, 0, 0, 0, 0, 0,
11180 0, 0, 0, 0, 0, 0, 0, 0,
11181 0, 0, 0, 0, 0, 0, 0, 0,
11182 0, 0, 0, 0, 0, 0, 0, 0,
11183 0, 0, 0, 0, 0, 0, 0, 0,
11184 0, 0, 0, 0, 0, 0, 0, 0,
11185 0, 0, 0, 0, 0, 0, 0, 0,
11186 0, 0, 0, 0, 0, 0, 0, 0,
11187 0, 0, 0, 0, 0, 0, 0, 0,
11188 0, 0, 0, 0, 0, 0, 0, 0,
11189 0, 0, 0, 0, 0, 0, 0, 0,
11190 0, 0, 0, 0, 0, 0, 0, 0,
11191 0, 0, 0, 0, 0, 0, 0, 0,
11192 0, 0, 0, 0, 0, 0, 0, 0,
11193 0, 0, 0, 0, 0, 0, 0, 0,
11194 0, 0, 0, 0, 0, 0, 0, 0,
11195 0, 0, 0, 0, 0, 0, 0, 0,
11196 0, 0, 0, 0, 0, 0, 0, 0,
11197 0, 0, 0, 0, 0, 0, 0, 0,
11198 0, 0, 0, 0, 0, 0, 0, case_FF,
11199};
11200// 39162 bytes
11201
11202static const Q_INT8 num_00[] = {
11203 -1, -1, -1, -1, -1, -1, -1, -1,
11204 -1, -1, -1, -1, -1, -1, -1, -1,
11205 -1, -1, -1, -1, -1, -1, -1, -1,
11206 -1, -1, -1, -1, -1, -1, -1, -1,
11207 -1, -1, -1, -1, -1, -1, -1, -1,
11208 -1, -1, -1, -1, -1, -1, -1, -1,
11209 0, 1, 2, 3, 4, 5, 6, 7,
11210 8, 9, -1, -1, -1, -1, -1, -1,
11211 -1, -1, -1, -1, -1, -1, -1, -1,
11212 -1, -1, -1, -1, -1, -1, -1, -1,
11213 -1, -1, -1, -1, -1, -1, -1, -1,
11214 -1, -1, -1, -1, -1, -1, -1, -1,
11215 -1, -1, -1, -1, -1, -1, -1, -1,
11216 -1, -1, -1, -1, -1, -1, -1, -1,
11217 -1, -1, -1, -1, -1, -1, -1, -1,
11218 -1, -1, -1, -1, -1, -1, -1, -1,
11219 -1, -1, -1, -1, -1, -1, -1, -1,
11220 -1, -1, -1, -1, -1, -1, -1, -1,
11221 -1, -1, -1, -1, -1, -1, -1, -1,
11222 -1, -1, -1, -1, -1, -1, -1, -1,
11223 -1, -1, -1, -1, -1, -1, -1, -1,
11224 -1, -1, -1, -1, -1, -1, -1, -1,
11225 -1, -1, 2, 3, -1, -1, -1, -1,
11226 -1, 1, -1, -1, -1, -1, -1, -1,
11227 -1, -1, -1, -1, -1, -1, -1, -1,
11228 -1, -1, -1, -1, -1, -1, -1, -1,
11229 -1, -1, -1, -1, -1, -1, -1, -1,
11230 -1, -1, -1, -1, -1, -1, -1, -1,
11231 -1, -1, -1, -1, -1, -1, -1, -1,
11232 -1, -1, -1, -1, -1, -1, -1, -1,
11233 -1, -1, -1, -1, -1, -1, -1, -1,
11234 -1, -1, -1, -1, -1, -1, -1, -1,
11235};
11236
11237static const Q_INT8 num_06[] = {
11238 -1, -1, -1, -1, -1, -1, -1, -1,
11239 -1, -1, -1, -1, -1, -1, -1, -1,
11240 -1, -1, -1, -1, -1, -1, -1, -1,
11241 -1, -1, -1, -1, -1, -1, -1, -1,
11242 -1, -1, -1, -1, -1, -1, -1, -1,
11243 -1, -1, -1, -1, -1, -1, -1, -1,
11244 -1, -1, -1, -1, -1, -1, -1, -1,
11245 -1, -1, -1, -1, -1, -1, -1, -1,
11246 -1, -1, -1, -1, -1, -1, -1, -1,
11247 -1, -1, -1, -1, -1, -1, -1, -1,
11248 -1, -1, -1, -1, -1, -1, -1, -1,
11249 -1, -1, -1, -1, -1, -1, -1, -1,
11250 0, 1, 2, 3, 4, 5, 6, 7,
11251 8, 9, -1, -1, -1, -1, -1, -1,
11252 -1, -1, -1, -1, -1, -1, -1, -1,
11253 -1, -1, -1, -1, -1, -1, -1, -1,
11254 -1, -1, -1, -1, -1, -1, -1, -1,
11255 -1, -1, -1, -1, -1, -1, -1, -1,
11256 -1, -1, -1, -1, -1, -1, -1, -1,
11257 -1, -1, -1, -1, -1, -1, -1, -1,
11258 -1, -1, -1, -1, -1, -1, -1, -1,
11259 -1, -1, -1, -1, -1, -1, -1, -1,
11260 -1, -1, -1, -1, -1, -1, -1, -1,
11261 -1, -1, -1, -1, -1, -1, -1, -1,
11262 -1, -1, -1, -1, -1, -1, -1, -1,
11263 -1, -1, -1, -1, -1, -1, -1, -1,
11264 -1, -1, -1, -1, -1, -1, -1, -1,
11265 -1, -1, -1, -1, -1, -1, -1, -1,
11266 -1, -1, -1, -1, -1, -1, -1, -1,
11267 -1, -1, -1, -1, -1, -1, -1, -1,
11268 0, 1, 2, 3, 4, 5, 6, 7,
11269 8, 9, -1, -1, -1, -1, -1, -1,
11270};
11271
11272static const Q_INT8 num_09[] = {
11273 -1, -1, -1, -1, -1, -1, -1, -1,
11274 -1, -1, -1, -1, -1, -1, -1, -1,
11275 -1, -1, -1, -1, -1, -1, -1, -1,
11276 -1, -1, -1, -1, -1, -1, -1, -1,
11277 -1, -1, -1, -1, -1, -1, -1, -1,
11278 -1, -1, -1, -1, -1, -1, -1, -1,
11279 -1, -1, -1, -1, -1, -1, -1, -1,
11280 -1, -1, -1, -1, -1, -1, -1, -1,
11281 -1, -1, -1, -1, -1, -1, -1, -1,
11282 -1, -1, -1, -1, -1, -1, -1, -1,
11283 -1, -1, -1, -1, -1, -1, -1, -1,
11284 -1, -1, -1, -1, -1, -1, -1, -1,
11285 -1, -1, -1, -1, -1, -1, 0, 1,
11286 2, 3, 4, 5, 6, 7, 8, 9,
11287 -1, -1, -1, -1, -1, -1, -1, -1,
11288 -1, -1, -1, -1, -1, -1, -1, -1,
11289 -1, -1, -1, -1, -1, -1, -1, -1,
11290 -1, -1, -1, -1, -1, -1, -1, -1,
11291 -1, -1, -1, -1, -1, -1, -1, -1,
11292 -1, -1, -1, -1, -1, -1, -1, -1,
11293 -1, -1, -1, -1, -1, -1, -1, -1,
11294 -1, -1, -1, -1, -1, -1, -1, -1,
11295 -1, -1, -1, -1, -1, -1, -1, -1,
11296 -1, -1, -1, -1, -1, -1, -1, -1,
11297 -1, -1, -1, -1, -1, -1, -1, -1,
11298 -1, -1, -1, -1, -1, -1, -1, -1,
11299 -1, -1, -1, -1, -1, -1, -1, -1,
11300 -1, -1, -1, -1, -1, -1, -1, -1,
11301 -1, -1, -1, -1, -1, -1, 0, 1,
11302 2, 3, 4, 5, 6, 7, 8, 9,
11303 -1, -1, -1, -1, -1, -1, -1, -1,
11304 -1, -1, -1, -1, -1, -1, -1, -1,
11305};
11306
11307static const Q_INT8 num_0B[] = {
11308 -1, -1, -1, -1, -1, -1, -1, -1,
11309 -1, -1, -1, -1, -1, -1, -1, -1,
11310 -1, -1, -1, -1, -1, -1, -1, -1,
11311 -1, -1, -1, -1, -1, -1, -1, -1,
11312 -1, -1, -1, -1, -1, -1, -1, -1,
11313 -1, -1, -1, -1, -1, -1, -1, -1,
11314 -1, -1, -1, -1, -1, -1, -1, -1,
11315 -1, -1, -1, -1, -1, -1, -1, -1,
11316 -1, -1, -1, -1, -1, -1, -1, -1,
11317 -1, -1, -1, -1, -1, -1, -1, -1,
11318 -1, -1, -1, -1, -1, -1, -1, -1,
11319 -1, -1, -1, -1, -1, -1, -1, -1,
11320 -1, -1, -1, -1, -1, -1, 0, 1,
11321 2, 3, 4, 5, 6, 7, 8, 9,
11322 -1, -1, -1, -1, -1, -1, -1, -1,
11323 -1, -1, -1, -1, -1, -1, -1, -1,
11324 -1, -1, -1, -1, -1, -1, -1, -1,
11325 -1, -1, -1, -1, -1, -1, -1, -1,
11326 -1, -1, -1, -1, -1, -1, -1, -1,
11327 -1, -1, -1, -1, -1, -1, -1, -1,
11328 -1, -1, -1, -1, -1, -1, -1, -1,
11329 -1, -1, -1, -1, -1, -1, -1, -1,
11330 -1, -1, -1, -1, -1, -1, -1, -1,
11331 -1, -1, -1, -1, -1, -1, -1, -1,
11332 -1, -1, -1, -1, -1, -1, -1, -1,
11333 -1, -1, -1, -1, -1, -1, -1, -1,
11334 -1, -1, -1, -1, -1, -1, -1, -1,
11335 -1, -1, -1, -1, -1, -1, -1, -1,
11336 -1, -1, -1, -1, -1, -1, -1, 1,
11337 2, 3, 4, 5, 6, 7, 8, 9,
11338 -1, -1, -1, -1, -1, -1, -1, -1,
11339 -1, -1, -1, -1, -1, -1, -1, -1,
11340};
11341
11342static const Q_INT8 num_0D[] = {
11343 -1, -1, -1, -1, -1, -1, -1, -1,
11344 -1, -1, -1, -1, -1, -1, -1, -1,
11345 -1, -1, -1, -1, -1, -1, -1, -1,
11346 -1, -1, -1, -1, -1, -1, -1, -1,
11347 -1, -1, -1, -1, -1, -1, -1, -1,
11348 -1, -1, -1, -1, -1, -1, -1, -1,
11349 -1, -1, -1, -1, -1, -1, -1, -1,
11350 -1, -1, -1, -1, -1, -1, -1, -1,
11351 -1, -1, -1, -1, -1, -1, -1, -1,
11352 -1, -1, -1, -1, -1, -1, -1, -1,
11353 -1, -1, -1, -1, -1, -1, -1, -1,
11354 -1, -1, -1, -1, -1, -1, -1, -1,
11355 -1, -1, -1, -1, -1, -1, 0, 1,
11356 2, 3, 4, 5, 6, 7, 8, 9,
11357 -1, -1, -1, -1, -1, -1, -1, -1,
11358 -1, -1, -1, -1, -1, -1, -1, -1,
11359 -1, -1, -1, -1, -1, -1, -1, -1,
11360 -1, -1, -1, -1, -1, -1, -1, -1,
11361 -1, -1, -1, -1, -1, -1, -1, -1,
11362 -1, -1, -1, -1, -1, -1, -1, -1,
11363 -1, -1, -1, -1, -1, -1, -1, -1,
11364 -1, -1, -1, -1, -1, -1, -1, -1,
11365 -1, -1, -1, -1, -1, -1, -1, -1,
11366 -1, -1, -1, -1, -1, -1, -1, -1,
11367 -1, -1, -1, -1, -1, -1, -1, -1,
11368 -1, -1, -1, -1, -1, -1, -1, -1,
11369 -1, -1, -1, -1, -1, -1, -1, -1,
11370 -1, -1, -1, -1, -1, -1, -1, -1,
11371 -1, -1, -1, -1, -1, -1, -1, -1,
11372 -1, -1, -1, -1, -1, -1, -1, -1,
11373 -1, -1, -1, -1, -1, -1, -1, -1,
11374 -1, -1, -1, -1, -1, -1, -1, -1,
11375};
11376
11377static const Q_INT8 num_0E[] = {
11378 -1, -1, -1, -1, -1, -1, -1, -1,
11379 -1, -1, -1, -1, -1, -1, -1, -1,
11380 -1, -1, -1, -1, -1, -1, -1, -1,
11381 -1, -1, -1, -1, -1, -1, -1, -1,
11382 -1, -1, -1, -1, -1, -1, -1, -1,
11383 -1, -1, -1, -1, -1, -1, -1, -1,
11384 -1, -1, -1, -1, -1, -1, -1, -1,
11385 -1, -1, -1, -1, -1, -1, -1, -1,
11386 -1, -1, -1, -1, -1, -1, -1, -1,
11387 -1, -1, -1, -1, -1, -1, -1, -1,
11388 0, 1, 2, 3, 4, 5, 6, 7,
11389 8, 9, -1, -1, -1, -1, -1, -1,
11390 -1, -1, -1, -1, -1, -1, -1, -1,
11391 -1, -1, -1, -1, -1, -1, -1, -1,
11392 -1, -1, -1, -1, -1, -1, -1, -1,
11393 -1, -1, -1, -1, -1, -1, -1, -1,
11394 -1, -1, -1, -1, -1, -1, -1, -1,
11395 -1, -1, -1, -1, -1, -1, -1, -1,
11396 -1, -1, -1, -1, -1, -1, -1, -1,
11397 -1, -1, -1, -1, -1, -1, -1, -1,
11398 -1, -1, -1, -1, -1, -1, -1, -1,
11399 -1, -1, -1, -1, -1, -1, -1, -1,
11400 -1, -1, -1, -1, -1, -1, -1, -1,
11401 -1, -1, -1, -1, -1, -1, -1, -1,
11402 -1, -1, -1, -1, -1, -1, -1, -1,
11403 -1, -1, -1, -1, -1, -1, -1, -1,
11404 0, 1, 2, 3, 4, 5, 6, 7,
11405 8, 9, -1, -1, -1, -1, -1, -1,
11406 -1, -1, -1, -1, -1, -1, -1, -1,
11407 -1, -1, -1, -1, -1, -1, -1, -1,
11408 -1, -1, -1, -1, -1, -1, -1, -1,
11409 -1, -1, -1, -1, -1, -1, -1, -1,
11410};
11411
11412static const Q_INT8 num_0F[] = {
11413 -1, -1, -1, -1, -1, -1, -1, -1,
11414 -1, -1, -1, -1, -1, -1, -1, -1,
11415 -1, -1, -1, -1, -1, -1, -1, -1,
11416 -1, -1, -1, -1, -1, -1, -1, -1,
11417 0, 1, 2, 3, 4, 5, 6, 7,
11418 8, 9, -1, -1, -1, -1, -1, -1,
11419 -1, -1, -1, -1, -1, -1, -1, -1,
11420 -1, -1, -1, -1, -1, -1, -1, -1,
11421 -1, -1, -1, -1, -1, -1, -1, -1,
11422 -1, -1, -1, -1, -1, -1, -1, -1,
11423 -1, -1, -1, -1, -1, -1, -1, -1,
11424 -1, -1, -1, -1, -1, -1, -1, -1,
11425 -1, -1, -1, -1, -1, -1, -1, -1,
11426 -1, -1, -1, -1, -1, -1, -1, -1,
11427 -1, -1, -1, -1, -1, -1, -1, -1,
11428 -1, -1, -1, -1, -1, -1, -1, -1,
11429 -1, -1, -1, -1, -1, -1, -1, -1,
11430 -1, -1, -1, -1, -1, -1, -1, -1,
11431 -1, -1, -1, -1, -1, -1, -1, -1,
11432 -1, -1, -1, -1, -1, -1, -1, -1,
11433 -1, -1, -1, -1, -1, -1, -1, -1,
11434 -1, -1, -1, -1, -1, -1, -1, -1,
11435 -1, -1, -1, -1, -1, -1, -1, -1,
11436 -1, -1, -1, -1, -1, -1, -1, -1,
11437 -1, -1, -1, -1, -1, -1, -1, -1,
11438 -1, -1, -1, -1, -1, -1, -1, -1,
11439 -1, -1, -1, -1, -1, -1, -1, -1,
11440 -1, -1, -1, -1, -1, -1, -1, -1,
11441 -1, -1, -1, -1, -1, -1, -1, -1,
11442 -1, -1, -1, -1, -1, -1, -1, -1,
11443 -1, -1, -1, -1, -1, -1, -1, -1,
11444 -1, -1, -1, -1, -1, -1, -1, -1,
11445};
11446
11447static const Q_INT8 num_10[] = {
11448 -1, -1, -1, -1, -1, -1, -1, -1,
11449 -1, -1, -1, -1, -1, -1, -1, -1,
11450 -1, -1, -1, -1, -1, -1, -1, -1,
11451 -1, -1, -1, -1, -1, -1, -1, -1,
11452 -1, -1, -1, -1, -1, -1, -1, -1,
11453 -1, -1, -1, -1, -1, -1, -1, -1,
11454 -1, -1, -1, -1, -1, -1, -1, -1,
11455 -1, -1, -1, -1, -1, -1, -1, -1,
11456 0, 1, 2, 3, 4, 5, 6, 7,
11457 8, 9, -1, -1, -1, -1, -1, -1,
11458 -1, -1, -1, -1, -1, -1, -1, -1,
11459 -1, -1, -1, -1, -1, -1, -1, -1,
11460 -1, -1, -1, -1, -1, -1, -1, -1,
11461 -1, -1, -1, -1, -1, -1, -1, -1,
11462 -1, -1, -1, -1, -1, -1, -1, -1,
11463 -1, -1, -1, -1, -1, -1, -1, -1,
11464 -1, -1, -1, -1, -1, -1, -1, -1,
11465 -1, -1, -1, -1, -1, -1, -1, -1,
11466 -1, -1, -1, -1, -1, -1, -1, -1,
11467 -1, -1, -1, -1, -1, -1, -1, -1,
11468 -1, -1, -1, -1, -1, -1, -1, -1,
11469 -1, -1, -1, -1, -1, -1, -1, -1,
11470 -1, -1, -1, -1, -1, -1, -1, -1,
11471 -1, -1, -1, -1, -1, -1, -1, -1,
11472 -1, -1, -1, -1, -1, -1, -1, -1,
11473 -1, -1, -1, -1, -1, -1, -1, -1,
11474 -1, -1, -1, -1, -1, -1, -1, -1,
11475 -1, -1, -1, -1, -1, -1, -1, -1,
11476 -1, -1, -1, -1, -1, -1, -1, -1,
11477 -1, -1, -1, -1, -1, -1, -1, -1,
11478 -1, -1, -1, -1, -1, -1, -1, -1,
11479 -1, -1, -1, -1, -1, -1, -1, -1,
11480};
11481
11482static const Q_INT8 num_13[] = {
11483 -1, -1, -1, -1, -1, -1, -1, -1,
11484 -1, -1, -1, -1, -1, -1, -1, -1,
11485 -1, -1, -1, -1, -1, -1, -1, -1,
11486 -1, -1, -1, -1, -1, -1, -1, -1,
11487 -1, -1, -1, -1, -1, -1, -1, -1,
11488 -1, -1, -1, -1, -1, -1, -1, -1,
11489 -1, -1, -1, -1, -1, -1, -1, -1,
11490 -1, -1, -1, -1, -1, -1, -1, -1,
11491 -1, -1, -1, -1, -1, -1, -1, -1,
11492 -1, -1, -1, -1, -1, -1, -1, -1,
11493 -1, -1, -1, -1, -1, -1, -1, -1,
11494 -1, -1, -1, -1, -1, -1, -1, -1,
11495 -1, -1, -1, -1, -1, -1, -1, -1,
11496 -1, 1, 2, 3, 4, 5, 6, 7,
11497 8, 9, -1, -1, -1, -1, -1, -1,
11498 -1, -1, -1, -1, -1, -1, -1, -1,
11499 -1, -1, -1, -1, -1, -1, -1, -1,
11500 -1, -1, -1, -1, -1, -1, -1, -1,
11501 -1, -1, -1, -1, -1, -1, -1, -1,
11502 -1, -1, -1, -1, -1, -1, -1, -1,
11503 -1, -1, -1, -1, -1, -1, -1, -1,
11504 -1, -1, -1, -1, -1, -1, -1, -1,
11505 -1, -1, -1, -1, -1, -1, -1, -1,
11506 -1, -1, -1, -1, -1, -1, -1, -1,
11507 -1, -1, -1, -1, -1, -1, -1, -1,
11508 -1, -1, -1, -1, -1, -1, -1, -1,
11509 -1, -1, -1, -1, -1, -1, -1, -1,
11510 -1, -1, -1, -1, -1, -1, -1, -1,
11511 -1, -1, -1, -1, -1, -1, -1, -1,
11512 -1, -1, -1, -1, -1, -1, -1, -1,
11513 -1, -1, -1, -1, -1, -1, -1, -1,
11514 -1, -1, -1, -1, -1, -1, -1, -1,
11515};
11516
11517static const Q_INT8 num_17[] = {
11518 -1, -1, -1, -1, -1, -1, -1, -1,
11519 -1, -1, -1, -1, -1, -1, -1, -1,
11520 -1, -1, -1, -1, -1, -1, -1, -1,
11521 -1, -1, -1, -1, -1, -1, -1, -1,
11522 -1, -1, -1, -1, -1, -1, -1, -1,
11523 -1, -1, -1, -1, -1, -1, -1, -1,
11524 -1, -1, -1, -1, -1, -1, -1, -1,
11525 -1, -1, -1, -1, -1, -1, -1, -1,
11526 -1, -1, -1, -1, -1, -1, -1, -1,
11527 -1, -1, -1, -1, -1, -1, -1, -1,
11528 -1, -1, -1, -1, -1, -1, -1, -1,
11529 -1, -1, -1, -1, -1, -1, -1, -1,
11530 -1, -1, -1, -1, -1, -1, -1, -1,
11531 -1, -1, -1, -1, -1, -1, -1, -1,
11532 -1, -1, -1, -1, -1, -1, -1, -1,
11533 -1, -1, -1, -1, -1, -1, -1, -1,
11534 -1, -1, -1, -1, -1, -1, -1, -1,
11535 -1, -1, -1, -1, -1, -1, -1, -1,
11536 -1, -1, -1, -1, -1, -1, -1, -1,
11537 -1, -1, -1, -1, -1, -1, -1, -1,
11538 -1, -1, -1, -1, -1, -1, -1, -1,
11539 -1, -1, -1, -1, -1, -1, -1, -1,
11540 -1, -1, -1, -1, -1, -1, -1, -1,
11541 -1, -1, -1, -1, -1, -1, -1, -1,
11542 -1, -1, -1, -1, -1, -1, -1, -1,
11543 -1, -1, -1, -1, -1, -1, -1, -1,
11544 -1, -1, -1, -1, -1, -1, -1, -1,
11545 -1, -1, -1, -1, -1, -1, -1, -1,
11546 0, 1, 2, 3, 4, 5, 6, 7,
11547 8, 9, -1, -1, -1, -1, -1, -1,
11548 -1, -1, -1, -1, -1, -1, -1, -1,
11549 -1, -1, -1, -1, -1, -1, -1, -1,
11550};
11551
11552static const Q_INT8 num_18[] = {
11553 -1, -1, -1, -1, -1, -1, -1, -1,
11554 -1, -1, -1, -1, -1, -1, -1, -1,
11555 0, 1, 2, 3, 4, 5, 6, 7,
11556 8, 9, -1, -1, -1, -1, -1, -1,
11557 -1, -1, -1, -1, -1, -1, -1, -1,
11558 -1, -1, -1, -1, -1, -1, -1, -1,
11559 -1, -1, -1, -1, -1, -1, -1, -1,
11560 -1, -1, -1, -1, -1, -1, -1, -1,
11561 -1, -1, -1, -1, -1, -1, -1, -1,
11562 -1, -1, -1, -1, -1, -1, -1, -1,
11563 -1, -1, -1, -1, -1, -1, -1, -1,
11564 -1, -1, -1, -1, -1, -1, -1, -1,
11565 -1, -1, -1, -1, -1, -1, -1, -1,
11566 -1, -1, -1, -1, -1, -1, -1, -1,
11567 -1, -1, -1, -1, -1, -1, -1, -1,
11568 -1, -1, -1, -1, -1, -1, -1, -1,
11569 -1, -1, -1, -1, -1, -1, -1, -1,
11570 -1, -1, -1, -1, -1, -1, -1, -1,
11571 -1, -1, -1, -1, -1, -1, -1, -1,
11572 -1, -1, -1, -1, -1, -1, -1, -1,
11573 -1, -1, -1, -1, -1, -1, -1, -1,
11574 -1, -1, -1, -1, -1, -1, -1, -1,
11575 -1, -1, -1, -1, -1, -1, -1, -1,
11576 -1, -1, -1, -1, -1, -1, -1, -1,
11577 -1, -1, -1, -1, -1, -1, -1, -1,
11578 -1, -1, -1, -1, -1, -1, -1, -1,
11579 -1, -1, -1, -1, -1, -1, -1, -1,
11580 -1, -1, -1, -1, -1, -1, -1, -1,
11581 -1, -1, -1, -1, -1, -1, -1, -1,
11582 -1, -1, -1, -1, -1, -1, -1, -1,
11583 -1, -1, -1, -1, -1, -1, -1, -1,
11584 -1, -1, -1, -1, -1, -1, -1, -1,
11585};
11586
11587static const Q_INT8 num_20[] = {
11588 -1, -1, -1, -1, -1, -1, -1, -1,
11589 -1, -1, -1, -1, -1, -1, -1, -1,
11590 -1, -1, -1, -1, -1, -1, -1, -1,
11591 -1, -1, -1, -1, -1, -1, -1, -1,
11592 -1, -1, -1, -1, -1, -1, -1, -1,
11593 -1, -1, -1, -1, -1, -1, -1, -1,
11594 -1, -1, -1, -1, -1, -1, -1, -1,
11595 -1, -1, -1, -1, -1, -1, -1, -1,
11596 -1, -1, -1, -1, -1, -1, -1, -1,
11597 -1, -1, -1, -1, -1, -1, -1, -1,
11598 -1, -1, -1, -1, -1, -1, -1, -1,
11599 -1, -1, -1, -1, -1, -1, -1, -1,
11600 -1, -1, -1, -1, -1, -1, -1, -1,
11601 -1, -1, -1, -1, -1, -1, -1, -1,
11602 0, -1, -1, -1, 4, 5, 6, 7,
11603 8, 9, -1, -1, -1, -1, -1, -1,
11604 0, 1, 2, 3, 4, 5, 6, 7,
11605 8, 9, -1, -1, -1, -1, -1, -1,
11606 -1, -1, -1, -1, -1, -1, -1, -1,
11607 -1, -1, -1, -1, -1, -1, -1, -1,
11608 -1, -1, -1, -1, -1, -1, -1, -1,
11609 -1, -1, -1, -1, -1, -1, -1, -1,
11610 -1, -1, -1, -1, -1, -1, -1, -1,
11611 -1, -1, -1, -1, -1, -1, -1, -1,
11612 -1, -1, -1, -1, -1, -1, -1, -1,
11613 -1, -1, -1, -1, -1, -1, -1, -1,
11614 -1, -1, -1, -1, -1, -1, -1, -1,
11615 -1, -1, -1, -1, -1, -1, -1, -1,
11616 -1, -1, -1, -1, -1, -1, -1, -1,
11617 -1, -1, -1, -1, -1, -1, -1, -1,
11618 -1, -1, -1, -1, -1, -1, -1, -1,
11619 -1, -1, -1, -1, -1, -1, -1, -1,
11620};
11621
11622static const Q_INT8 num_24[] = {
11623 -1, -1, -1, -1, -1, -1, -1, -1,
11624 -1, -1, -1, -1, -1, -1, -1, -1,
11625 -1, -1, -1, -1, -1, -1, -1, -1,
11626 -1, -1, -1, -1, -1, -1, -1, -1,
11627 -1, -1, -1, -1, -1, -1, -1, -1,
11628 -1, -1, -1, -1, -1, -1, -1, -1,
11629 -1, -1, -1, -1, -1, -1, -1, -1,
11630 -1, -1, -1, -1, -1, -1, -1, -1,
11631 -1, -1, -1, -1, -1, -1, -1, -1,
11632 -1, -1, -1, -1, -1, -1, -1, -1,
11633 -1, -1, -1, -1, -1, -1, -1, -1,
11634 -1, -1, -1, -1, -1, -1, -1, -1,
11635 1, 2, 3, 4, 5, 6, 7, 8,
11636 9, -1, -1, -1, -1, -1, -1, -1,
11637 -1, -1, -1, -1, 1, 2, 3, 4,
11638 5, 6, 7, 8, 9, -1, -1, -1,
11639 -1, -1, -1, -1, -1, -1, -1, -1,
11640 1, 2, 3, 4, 5, 6, 7, 8,
11641 9, -1, -1, -1, -1, -1, -1, -1,
11642 -1, -1, -1, -1, -1, -1, -1, -1,
11643 -1, -1, -1, -1, -1, -1, -1, -1,
11644 -1, -1, -1, -1, -1, -1, -1, -1,
11645 -1, -1, -1, -1, -1, -1, -1, -1,
11646 -1, -1, -1, -1, -1, -1, -1, -1,
11647 -1, -1, -1, -1, -1, -1, -1, -1,
11648 -1, -1, -1, -1, -1, -1, -1, -1,
11649 -1, -1, -1, -1, -1, -1, -1, -1,
11650 -1, -1, -1, -1, -1, -1, -1, -1,
11651 -1, -1, -1, -1, -1, -1, -1, -1,
11652 -1, -1, 0, -1, -1, -1, -1, -1,
11653 -1, -1, -1, -1, -1, 1, 2, 3,
11654 4, 5, 6, 7, 8, 9, -1, -1,
11655};
11656
11657static const Q_INT8 num_27[] = {
11658 -1, -1, -1, -1, -1, -1, -1, -1,
11659 -1, -1, -1, -1, -1, -1, -1, -1,
11660 -1, -1, -1, -1, -1, -1, -1, -1,
11661 -1, -1, -1, -1, -1, -1, -1, -1,
11662 -1, -1, -1, -1, -1, -1, -1, -1,
11663 -1, -1, -1, -1, -1, -1, -1, -1,
11664 -1, -1, -1, -1, -1, -1, -1, -1,
11665 -1, -1, -1, -1, -1, -1, -1, -1,
11666 -1, -1, -1, -1, -1, -1, -1, -1,
11667 -1, -1, -1, -1, -1, -1, -1, -1,
11668 -1, -1, -1, -1, -1, -1, -1, -1,
11669 -1, -1, -1, -1, -1, -1, -1, -1,
11670 -1, -1, -1, -1, -1, -1, -1, -1,
11671 -1, -1, -1, -1, -1, -1, -1, -1,
11672 -1, -1, -1, -1, -1, -1, 1, 2,
11673 3, 4, 5, 6, 7, 8, 9, -1,
11674 1, 2, 3, 4, 5, 6, 7, 8,
11675 9, -1, 1, 2, 3, 4, 5, 6,
11676 7, 8, 9, -1, -1, -1, -1, -1,
11677 -1, -1, -1, -1, -1, -1, -1, -1,
11678 -1, -1, -1, -1, -1, -1, -1, -1,
11679 -1, -1, -1, -1, -1, -1, -1, -1,
11680 -1, -1, -1, -1, -1, -1, -1, -1,
11681 -1, -1, -1, -1, -1, -1, -1, -1,
11682 -1, -1, -1, -1, -1, -1, -1, -1,
11683 -1, -1, -1, -1, -1, -1, -1, -1,
11684 -1, -1, -1, -1, -1, -1, -1, -1,
11685 -1, -1, -1, -1, -1, -1, -1, -1,
11686 -1, -1, -1, -1, -1, -1, -1, -1,
11687 -1, -1, -1, -1, -1, -1, -1, -1,
11688 -1, -1, -1, -1, -1, -1, -1, -1,
11689 -1, -1, -1, -1, -1, -1, -1, -1,
11690};
11691
11692static const Q_INT8 * const decimal_info[256] = {
11693 num_00, 0, 0, 0, 0, 0, num_06, 0,
11694 0, num_09, num_09, num_0B, num_09, num_0D, num_0E, num_0F,
11695 num_10, 0, 0, num_13, 0, 0, 0, num_17,
11696 num_18, 0, 0, 0, 0, 0, 0, 0,
11697 num_20, 0, 0, 0, num_24, 0, 0, num_27,
11698 0, 0, 0, 0, 0, 0, 0, 0,
11699 0, 0, 0, 0, 0, 0, 0, 0,
11700 0, 0, 0, 0, 0, 0, 0, 0,
11701 0, 0, 0, 0, 0, 0, 0, 0,
11702 0, 0, 0, 0, 0, 0, 0, 0,
11703 0, 0, 0, 0, 0, 0, 0, 0,
11704 0, 0, 0, 0, 0, 0, 0, 0,
11705 0, 0, 0, 0, 0, 0, 0, 0,
11706 0, 0, 0, 0, 0, 0, 0, 0,
11707 0, 0, 0, 0, 0, 0, 0, 0,
11708 0, 0, 0, 0, 0, 0, 0, 0,
11709 0, 0, 0, 0, 0, 0, 0, 0,
11710 0, 0, 0, 0, 0, 0, 0, 0,
11711 0, 0, 0, 0, 0, 0, 0, 0,
11712 0, 0, 0, 0, 0, 0, 0, 0,
11713 0, 0, 0, 0, 0, 0, 0, 0,
11714 0, 0, 0, 0, 0, 0, 0, 0,
11715 0, 0, 0, 0, 0, 0, 0, 0,
11716 0, 0, 0, 0, 0, 0, 0, 0,
11717 0, 0, 0, 0, 0, 0, 0, 0,
11718 0, 0, 0, 0, 0, 0, 0, 0,
11719 0, 0, 0, 0, 0, 0, 0, 0,
11720 0, 0, 0, 0, 0, 0, 0, 0,
11721 0, 0, 0, 0, 0, 0, 0, 0,
11722 0, 0, 0, 0, 0, 0, 0, 0,
11723 0, 0, 0, 0, 0, 0, 0, 0,
11724 0, 0, 0, 0, 0, 0, 0, num_18,
11725};
11726// 47354 bytes
11727
11728// END OF GENERATED DATA
11729
11730#endif
11731
11732static inline QChar::Category category( const QChar &c )
11733{
11734#ifndef QT_NO_UNICODETABLES
11735 return (QChar::Category)(unicode_info[c.row()][c.cell()]);
11736#else
11737// ### just ASCII
11738 if ( c.unicode() < 0x100 ) {
11739 return (QChar::Category)(ui_00[c.unicode()]);
11740 }
11741 return QChar::Letter_Uppercase; //#######
11742#endif
11743}
11744
11745static inline QChar lower( const QChar &c )
11746{
11747#ifndef QT_NO_UNICODETABLES
11748 uchar row = c.row();
11749 uchar cell = c.cell();
11750 if ( unicode_info[row][cell] != QChar::Letter_Uppercase )
11751 return c;
11752 Q_UINT16 lower = *( case_info[row] + cell );
11753 if ( lower == 0 )
11754 return c;
11755 return lower;
11756#else
11757 if ( c.row() )
11758 return c;
11759 else
11760 return QChar( tolower((uchar) c.latin1()) );
11761#endif
11762}
11763
11764static inline QChar upper( const QChar &c )
11765{
11766#ifndef QT_NO_UNICODETABLES
11767 uchar row = c.row();
11768 uchar cell = c.cell();
11769 if ( unicode_info[row][cell] != QChar::Letter_Lowercase )
11770 return c;
11771 Q_UINT16 upper = *(case_info[row]+cell);
11772 if ( upper == 0 )
11773 return c;
11774 return upper;
11775#else
11776 if ( c.row() )
11777 return c;
11778 else
11779 return QChar( toupper((uchar) c.latin1()) );
11780#endif
11781}
11782
11783static inline QChar::Direction direction( const QChar &c )
11784{
11785#ifndef QT_NO_UNICODETABLES
11786 const Q_UINT8 *rowp = direction_info[c.row()];
11787 if(!rowp) return QChar::DirL;
11788 return (QChar::Direction) ( *(rowp+c.cell()) & 0x1f );
11789#else
11790 return QChar::DirL;
11791#endif
11792}
11793
11794static inline bool mirrored( const QChar &c )
11795{
11796#ifndef QT_NO_UNICODETABLES
11797 const Q_UINT8 *rowp = direction_info[c.row()];
11798 if ( !rowp )
11799 return FALSE;
11800 return *(rowp+c.cell())>128;
11801#else
11802 return FALSE;
11803#endif
11804}
11805
11806#ifndef QT_NO_UNICODETABLES
11807static const Q_UINT16 symmetricPairs[] = {
11808 0x0028, 0x0029, 0x003C, 0x003E, 0x005B, 0x005D, 0x007B, 0x007D,
11809 0x00AB, 0x00BB, 0x2039, 0x203A, 0x2045, 0x2046, 0x207D, 0x207E,
11810 0x208D, 0x208E, 0x2208, 0x220B, 0x2209, 0x220C, 0x220A, 0x220D,
11811 0x2215, 0x29F5, 0x223C, 0x223D, 0x2243, 0x22CD, 0x2252, 0x2253,
11812 0x2254, 0x2255, 0x2264, 0x2265, 0x2266, 0x2267, 0x2268, 0x2269,
11813 0x226A, 0x226B, 0x226E, 0x226F, 0x2270, 0x2271, 0x2272, 0x2273,
11814 0x2274, 0x2275, 0x2276, 0x2277, 0x2278, 0x2279, 0x227A, 0x227B,
11815 0x227C, 0x227D, 0x227E, 0x227F, 0x2280, 0x2281, 0x2282, 0x2283,
11816 0x2284, 0x2285, 0x2286, 0x2287, 0x2288, 0x2289, 0x228A, 0x228B,
11817 0x228F, 0x2290, 0x2291, 0x2292, 0x2298, 0x29B8, 0x22A2, 0x22A3,
11818 0x22A6, 0x2ADE, 0x22A8, 0x2AE4, 0x22A9, 0x2AE3, 0x22AB, 0x2AE5,
11819 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x22B4, 0x22B5, 0x22B6, 0x22B7,
11820 0x22C9, 0x22CA, 0x22CB, 0x22CC, 0x22D0, 0x22D1, 0x22D6, 0x22D7,
11821 0x22D8, 0x22D9, 0x22DA, 0x22DB, 0x22DC, 0x22DD, 0x22DE, 0x22DF,
11822 0x22E0, 0x22E1, 0x22E2, 0x22E3, 0x22E4, 0x22E5, 0x22E6, 0x22E7,
11823 0x22E8, 0x22E9, 0x22EA, 0x22EB, 0x22EC, 0x22ED, 0x22F0, 0x22F1,
11824 0x22F2, 0x22FA, 0x22F3, 0x22FB, 0x22F4, 0x22FC, 0x22F6, 0x22FD,
11825 0x22F7, 0x22FE, 0x2308, 0x2309, 0x230A, 0x230B, 0x2329, 0x232A,
11826 0x2768, 0x2769, 0x276A, 0x276B, 0x276C, 0x276D, 0x276E, 0x276F,
11827 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, 0x2775, 0x27D5, 0x27D6,
11828 0x27DD, 0x27DE, 0x27E2, 0x27E3, 0x27E4, 0x27E5, 0x27E6, 0x27E7,
11829 0x27E8, 0x27E9, 0x27EA, 0x27EB, 0x2983, 0x2984, 0x2985, 0x2986,
11830 0x2987, 0x2988, 0x2989, 0x298A, 0x298B, 0x298C, 0x298D, 0x2990,
11831 0x298E, 0x298F, 0x2991, 0x2992, 0x2993, 0x2994, 0x2995, 0x2996,
11832 0x2997, 0x2998, 0x29C0, 0x29C1, 0x29C4, 0x29C5, 0x29CF, 0x29D0,
11833 0x29D1, 0x29D2, 0x29D4, 0x29D5, 0x29D8, 0x29D9, 0x29DA, 0x29DB,
11834 0x29F8, 0x29F9, 0x29FC, 0x29FD, 0x2A2B, 0x2A2C, 0x2A34, 0x2A35,
11835 0x2A3C, 0x2A3D, 0x2A64, 0x2A65, 0x2A79, 0x2A7A, 0x2A7D, 0x2A7E,
11836 0x2A7F, 0x2A80, 0x2A81, 0x2A82, 0x2A83, 0x2A84, 0x2A8B, 0x2A8C,
11837 0x2A91, 0x2A92, 0x2A93, 0x2A94, 0x2A95, 0x2A96, 0x2A97, 0x2A98,
11838 0x2A99, 0x2A9A, 0x2A9B, 0x2A9C, 0x2AA1, 0x2AA2, 0x2AA6, 0x2AA7,
11839 0x2AA8, 0x2AA9, 0x2AAA, 0x2AAB, 0x2AAC, 0x2AAD, 0x2AAF, 0x2AB0,
11840 0x2AB3, 0x2AB4, 0x2ABB, 0x2ABC, 0x2ABD, 0x2ABE, 0x2ABF, 0x2AC0,
11841 0x2AC1, 0x2AC2, 0x2AC3, 0x2AC4, 0x2AC5, 0x2AC6, 0x2ACD, 0x2ACE,
11842 0x2ACF, 0x2AD0, 0x2AD1, 0x2AD2, 0x2AD3, 0x2AD4, 0x2AD5, 0x2AD6,
11843 0x2AEC, 0x2AED, 0x2AF7, 0x2AF8, 0x2AF9, 0x2AFA, 0x3008, 0x3009,
11844 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3010, 0x3011,
11845 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x301A, 0x301B,
11846 0xFF08, 0xFF09, 0xFF1C, 0xFF1E, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D,
11847 0xFF5F, 0xFF60, 0xFF62, 0xFF63,
11848};
11849
11850// ### shouldn't this be const?
11851static const int symmetricPairsSize =
11852 sizeof(symmetricPairs)/sizeof(symmetricPairs[0]);
11853
11854/*
11855 * ----------------------------------------------------------------------
11856 * End of unicode tables
11857 * ----------------------------------------------------------------------
11858 */
11859
11860#endif
11861
11862static int ucstrcmp( const QString &as, const QString &bs )
11863{
11864 const QChar *a = as.unicode();
11865 const QChar *b = bs.unicode();
11866 if ( a == b )
11867 return 0;
11868 if ( a == 0 )
11869 return 1;
11870 if ( b == 0 )
11871 return -1;
11872 int l=QMIN(as.length(),bs.length());
11873 while ( l-- && *a == *b )
11874 a++,b++;
11875 if ( l==-1 )
11876 return ( as.length()-bs.length() );
11877 return a->unicode() - b->unicode();
11878}
11879
11880static int ucstrncmp( const QChar *a, const QChar *b, int l )
11881{
11882 while ( l-- && *a == *b )
11883 a++,b++;
11884 if ( l==-1 )
11885 return 0;
11886 return a->unicode() - b->unicode();
11887}
11888
11889static int ucstrnicmp( const QChar *a, const QChar *b, int l )
11890{
11891 while ( l-- && ::lower( *a ) == ::lower( *b ) )
11892 a++,b++;
11893 if ( l==-1 )
11894 return 0;
11895 return ::lower( *a ).unicode() - ::lower( *b ).unicode();
11896}
11897
11898static uint computeNewMax( uint len )
11899{
11900 uint newMax = 4;
11901 while ( newMax < len )
11902 newMax *= 2;
11903 // try to spare some memory
11904 if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) )
11905 newMax -= newMax >> 2;
11906 return newMax;
11907}
11908
11909/*!
11910 \class QCharRef qstring.h
11911 \reentrant
11912 \brief The QCharRef class is a helper class for QString.
11913
11914 \ingroup text
11915
11916 When you get an object of type QCharRef, if you can assign to it,
11917 the assignment will apply to the character in the string from
11918 which you got the reference. That is its whole purpose in life.
11919 The QCharRef becomes invalid once modifications are made to the
11920 string: if you want to keep the character, copy it into a QChar.
11921
11922 Most of the QChar member functions also exist in QCharRef.
11923 However, they are not explicitly documented here.
11924
11925 \sa QString::operator[]() QString::at() QChar
11926*/
11927
11928/*!
11929 \class QChar qstring.h
11930 \reentrant
11931 \brief The QChar class provides a lightweight Unicode character.
11932
11933 \ingroup text
11934
11935 Unicode characters are (so far) 16-bit entities without any markup
11936 or structure. This class represents such an entity. It is
11937 lightweight, so it can be used everywhere. Most compilers treat it
11938 like a "short int". (In a few years it may be necessary to make
11939 QChar 32-bit when more than 65536 Unicode code points have been
11940 defined and come into use.)
11941
11942 QChar provides a full complement of testing/classification
11943 functions, converting to and from other formats, converting from
11944 composed to decomposed Unicode, and trying to compare and
11945 case-convert if you ask it to.
11946
11947 The classification functions include functions like those in
11948 ctype.h, but operating on the full range of Unicode characters.
11949 They all return TRUE if the character is a certain type of
11950 character; otherwise they return FALSE. These classification
11951 functions are isNull() (returns TRUE if the character is U+0000),
11952 isPrint() (TRUE if the character is any sort of printable
11953 character, including whitespace), isPunct() (any sort of
11954 punctation), isMark() (Unicode Mark), isLetter (a letter),
11955 isNumber() (any sort of numeric character), isLetterOrNumber(),
11956 and isDigit() (decimal digits). All of these are wrappers around
11957 category() which return the Unicode-defined category of each
11958 character.
11959
11960 QChar further provides direction(), which indicates the "natural"
11961 writing direction of this character. The joining() function
11962 indicates how the character joins with its neighbors (needed
11963 mostly for Arabic) and finally mirrored(), which indicates whether
11964 the character needs to be mirrored when it is printed in its
11965 "unnatural" writing direction.
11966
11967 Composed Unicode characters (like &aring;) can be converted to
11968 decomposed Unicode ("a" followed by "ring above") by using
11969 decomposition().
11970
11971 In Unicode, comparison is not necessarily possible and case
11972 conversion is very difficult at best. Unicode, covering the
11973 "entire" world, also includes most of the world's case and sorting
11974 problems. Qt tries, but not very hard: operator==() and friends
11975 will do comparison based purely on the numeric Unicode value (code
11976 point) of the characters, and upper() and lower() will do case
11977 changes when the character has a well-defined upper/lower-case
11978 equivalent. There is no provision for locale-dependent case
11979 folding rules or comparison; these functions are meant to be fast
11980 so they can be used unambiguously in data structures. (See
11981 QString::localeAwareCompare() though.)
11982
11983 The conversion functions include unicode() (to a scalar), latin1()
11984 (to scalar, but converts all non-Latin1 characters to 0), row()
11985 (gives the Unicode row), cell() (gives the Unicode cell),
11986 digitValue() (gives the integer value of any of the numerous digit
11987 characters), and a host of constructors.
11988
11989 More information can be found in the document \link unicode.html
11990 About Unicode. \endlink
11991
11992 \sa QString QCharRef
11993*/
11994
11995/*!
11996 \enum QChar::Category
11997
11998 This enum maps the Unicode character categories.
11999
12000 The following characters are normative in Unicode:
12001
12002 \value Mark_NonSpacing Unicode class name Mn
12003
12004 \value Mark_SpacingCombining Unicode class name Mc
12005
12006 \value Mark_Enclosing Unicode class name Me
12007
12008 \value Number_DecimalDigit Unicode class name Nd
12009
12010 \value Number_Letter Unicode class name Nl
12011
12012 \value Number_Other Unicode class name No
12013
12014 \value Separator_Space Unicode class name Zs
12015
12016 \value Separator_Line Unicode class name Zl
12017
12018 \value Separator_Paragraph Unicode class name Zp
12019
12020 \value Other_Control Unicode class name Cc
12021
12022 \value Other_Format Unicode class name Cf
12023
12024 \value Other_Surrogate Unicode class name Cs
12025
12026 \value Other_PrivateUse Unicode class name Co
12027
12028 \value Other_NotAssigned Unicode class name Cn
12029
12030
12031 The following categories are informative in Unicode:
12032
12033 \value Letter_Uppercase Unicode class name Lu
12034
12035 \value Letter_Lowercase Unicode class name Ll
12036
12037 \value Letter_Titlecase Unicode class name Lt
12038
12039 \value Letter_Modifier Unicode class name Lm
12040
12041 \value Letter_Other Unicode class name Lo
12042
12043 \value Punctuation_Connector Unicode class name Pc
12044
12045 \value Punctuation_Dash Unicode class name Pd
12046
12047 \value Punctuation_Open Unicode class name Ps
12048
12049 \value Punctuation_Close Unicode class name Pe
12050
12051 \value Punctuation_InitialQuote Unicode class name Pi
12052
12053 \value Punctuation_FinalQuote Unicode class name Pf
12054
12055 \value Punctuation_Other Unicode class name Po
12056
12057 \value Symbol_Math Unicode class name Sm
12058
12059 \value Symbol_Currency Unicode class name Sc
12060
12061 \value Symbol_Modifier Unicode class name Sk
12062
12063 \value Symbol_Other Unicode class name So
12064
12065
12066 There are two categories that are specific to Qt:
12067
12068 \value NoCategory used when Qt is dazed and confused and cannot
12069 make sense of anything.
12070
12071 \value Punctuation_Dask old typo alias for Punctuation_Dash
12072
12073*/
12074
12075/*!
12076 \enum QChar::Direction
12077
12078 This enum type defines the Unicode direction attributes. See \link
12079 http://www.unicode.org/ the Unicode Standard\endlink for a
12080 description of the values.
12081
12082 In order to conform to C/C++ naming conventions "Dir" is prepended
12083 to the codes used in the Unicode Standard.
12084*/
12085
12086/*!
12087 \enum QChar::Decomposition
12088
12089 This enum type defines the Unicode decomposition attributes. See
12090 \link http://www.unicode.org/ the Unicode Standard\endlink for a
12091 description of the values.
12092*/
12093
12094/*!
12095 \enum QChar::Joining
12096
12097 This enum type defines the Unicode joining attributes. See \link
12098 http://www.unicode.org/ the Unicode Standard\endlink for a
12099 description of the values.
12100*/
12101
12102/*!
12103 \enum QChar::CombiningClass
12104
12105 This enum type defines names for some of the Unicode combining
12106 classes. See \link http://www.unicode.org/ the Unicode
12107 Standard\endlink for a description of the values.
12108*/
12109
12110/*!
12111 \fn void QChar::setCell( uchar cell )
12112 \internal
12113*/
12114
12115/*!
12116 \fn void QChar::setRow( uchar row )
12117 \internal
12118*/
12119
12120
12121/*!
12122 \fn QChar::QChar()
12123
12124 Constructs a null QChar (one that isNull()).
12125*/
12126
12127
12128/*!
12129 \fn QChar::QChar( char c )
12130
12131 Constructs a QChar corresponding to ASCII/Latin1 character \a c.
12132*/
12133
12134
12135/*!
12136 \fn QChar::QChar( uchar c )
12137
12138 Constructs a QChar corresponding to ASCII/Latin1 character \a c.
12139*/
12140
12141
12142/*!
12143 \fn QChar::QChar( uchar c, uchar r )
12144
12145 Constructs a QChar for Unicode cell \a c in row \a r.
12146*/
12147
12148
12149/*!
12150 \fn QChar::QChar( const QChar& c )
12151
12152 Constructs a copy of \a c. This is a deep copy, if such a
12153 lightweight object can be said to have deep copies.
12154*/
12155
12156
12157/*!
12158 \fn QChar::QChar( ushort rc )
12159
12160 Constructs a QChar for the character with Unicode code point \a rc.
12161*/
12162
12163
12164/*!
12165 \fn QChar::QChar( short rc )
12166
12167 Constructs a QChar for the character with Unicode code point \a rc.
12168*/
12169
12170
12171/*!
12172 \fn QChar::QChar( uint rc )
12173
12174 Constructs a QChar for the character with Unicode code point \a rc.
12175*/
12176
12177
12178/*!
12179 \fn QChar::QChar( int rc )
12180
12181 Constructs a QChar for the character with Unicode code point \a rc.
12182*/
12183
12184
12185/*!
12186 \fn bool QChar::networkOrdered ()
12187
12188 \obsolete
12189
12190 Returns TRUE if this character is in network byte order (MSB
12191 first); otherwise returns FALSE. This is platform dependent.
12192*/
12193
12194
12195/*!
12196 \fn bool QChar::isNull() const
12197
12198 Returns TRUE if the character is the Unicode character 0x0000,
12199 i.e. ASCII NUL; otherwise returns FALSE.
12200*/
12201
12202/*!
12203 \fn uchar QChar::cell () const
12204
12205 Returns the cell (least significant byte) of the Unicode
12206 character.
12207*/
12208
12209/*!
12210 \fn uchar QChar::row () const
12211
12212 Returns the row (most significant byte) of the Unicode character.
12213*/
12214
12215/*!
12216 Returns TRUE if the character is a printable character; otherwise
12217 returns FALSE. This is any character not of category Cc or Cn.
12218
12219 Note that this gives no indication of whether the character is
12220 available in a particular \link QFont font\endlink.
12221*/
12222bool QChar::isPrint() const
12223{
12224 Category c = ::category( *this );
12225 return !(c == Other_Control || c == Other_NotAssigned);
12226}
12227
12228/*!
12229 Returns TRUE if the character is a separator character
12230 (Separator_* categories); otherwise returns FALSE.
12231*/
12232bool QChar::isSpace() const
12233{
12234 if( ucs >= 9 && ucs <=13 ) return TRUE;
12235 Category c = ::category( *this );
12236 return c >= Separator_Space && c <= Separator_Paragraph;
12237}
12238
12239/*!
12240 Returns TRUE if the character is a mark (Mark_* categories);
12241 otherwise returns FALSE.
12242*/
12243bool QChar::isMark() const
12244{
12245 Category c = ::category( *this );
12246 return c >= Mark_NonSpacing && c <= Mark_Enclosing;
12247}
12248
12249/*!
12250 Returns TRUE if the character is a punctuation mark (Punctuation_*
12251 categories); otherwise returns FALSE.
12252*/
12253bool QChar::isPunct() const
12254{
12255 Category c = ::category( *this );
12256 return (c >= Punctuation_Connector && c <= Punctuation_Other);
12257}
12258
12259/*!
12260 Returns TRUE if the character is a letter (Letter_* categories);
12261 otherwise returns FALSE.
12262*/
12263bool QChar::isLetter() const
12264{
12265 Category c = ::category( *this );
12266 return (c >= Letter_Uppercase && c <= Letter_Other);
12267}
12268
12269/*!
12270 Returns TRUE if the character is a number (of any sort - Number_*
12271 categories); otherwise returns FALSE.
12272
12273 \sa isDigit()
12274*/
12275bool QChar::isNumber() const
12276{
12277 Category c = ::category( *this );
12278 return c >= Number_DecimalDigit && c <= Number_Other;
12279}
12280
12281/*!
12282 Returns TRUE if the character is a letter or number (Letter_* or
12283 Number_* categories); otherwise returns FALSE.
12284*/
12285bool QChar::isLetterOrNumber() const
12286{
12287 Category c = ::category( *this );
12288 return (c >= Letter_Uppercase && c <= Letter_Other)
12289 || (c >= Number_DecimalDigit && c <= Number_Other);
12290}
12291
12292
12293/*!
12294 Returns TRUE if the character is a decimal digit
12295 (Number_DecimalDigit); otherwise returns FALSE.
12296*/
12297bool QChar::isDigit() const
12298{
12299 return (::category( *this ) == Number_DecimalDigit);
12300}
12301
12302
12303/*!
12304 Returns TRUE if the character is a symbol (Symbol_* categories);
12305 otherwise returns FALSE.
12306*/
12307bool QChar::isSymbol() const
12308{
12309 Category c = ::category( *this );
12310 return c >= Symbol_Math && c <= Symbol_Other;
12311}
12312
12313/*!
12314 Returns the numeric value of the digit, or -1 if the character is
12315 not a digit.
12316*/
12317int QChar::digitValue() const
12318{
12319#ifndef QT_NO_UNICODETABLES
12320 const Q_INT8 *dec_row = decimal_info[row()];
12321 if( !dec_row )
12322 return -1;
12323 return dec_row[cell()];
12324#else
12325 // ##### just latin1
12326 if ( ucs < '0' || ucs > '9' )
12327 return -1;
12328 else
12329 return ucs - '0';
12330#endif
12331}
12332
12333/*!
12334 Returns the character category.
12335
12336 \sa Category
12337*/
12338QChar::Category QChar::category() const
12339{
12340 return ::category( *this );
12341}
12342
12343/*!
12344 Returns the character's direction.
12345
12346 \sa Direction
12347*/
12348QChar::Direction QChar::direction() const
12349{
12350 return ::direction( *this );
12351}
12352
12353/*!
12354 \warning This function is not supported (it may change to use
12355 Unicode character classes).
12356
12357 Returns information about the joining properties of the character
12358 (needed for example, for Arabic).
12359*/
12360QChar::Joining QChar::joining() const
12361{
12362#ifndef QT_NO_UNICODETABLES
12363 const Q_UINT8 *rowp = direction_info[row()];
12364 if ( !rowp )
12365 return QChar::OtherJoining;
12366 return (Joining) ((*(rowp+cell()) >> 5) &0x3);
12367#else
12368 return OtherJoining;
12369#endif
12370}
12371
12372
12373/*!
12374 Returns TRUE if the character is a mirrored character (one that
12375 should be reversed if the text direction is reversed); otherwise
12376 returns FALSE.
12377*/
12378bool QChar::mirrored() const
12379{
12380 return ::mirrored( *this );
12381}
12382
12383/*!
12384 Returns the mirrored character if this character is a mirrored
12385 character, otherwise returns the character itself.
12386*/
12387QChar QChar::mirroredChar() const
12388{
12389#ifndef QT_NO_UNICODETABLES
12390 if(!::mirrored( *this ))
12391 return *this;
12392
12393 int i;
12394 int c = unicode();
12395 for (i = 0; i < symmetricPairsSize; i ++) {
12396 if (symmetricPairs[i] == c)
12397 return symmetricPairs[(i%2) ? (i-1) : (i+1)];
12398 }
12399#endif
12400 return *this;
12401}
12402
12403#ifndef QT_NO_UNICODETABLES
12404// ### REMOVE ME 4.0
12405static QString shared_decomp;
12406#endif
12407/*!
12408 \nonreentrant
12409
12410 Decomposes a character into its parts. Returns QString::null if no
12411 decomposition exists.
12412*/
12413const QString &QChar::decomposition() const
12414{
12415#ifndef QT_NO_UNICODETABLES
12416 const Q_UINT16 *r = decomposition_info[row()];
12417 if(!r) return QString::null;
12418
12419 Q_UINT16 pos = r[cell()];
12420 if(!pos) return QString::null;
12421 pos+=2;
12422
12423 QString s;
12424 Q_UINT16 c;
12425 while((c = decomposition_map[pos++]) != 0) s += QChar(c);
12426 // ### In 4.0, return s, and not shared_decomp. shared_decomp
12427 // prevents this function from being reentrant.
12428 shared_decomp = s;
12429 return shared_decomp;
12430#else
12431 return QString::null;
12432#endif
12433}
12434
12435/*!
12436 Returns the tag defining the composition of the character. Returns
12437 QChar::Single if no decomposition exists.
12438*/
12439QChar::Decomposition QChar::decompositionTag() const
12440{
12441#ifndef QT_NO_UNICODETABLES
12442 const Q_UINT16 *r = decomposition_info[row()];
12443 if(!r) return QChar::Single;
12444
12445 Q_UINT16 pos = r[cell()];
12446 if(!pos) return QChar::Single;
12447
12448 return (QChar::Decomposition) decomposition_map[pos];
12449#else
12450 return Single; // ########### FIX eg. just latin1
12451#endif
12452}
12453
12454/*!
12455 Returns the combining class for the character as defined in the
12456 Unicode standard. This is mainly useful as a positioning hint for
12457 marks attached to a base character.
12458
12459 The Qt text rendering engine uses this information to correctly
12460 position non spacing marks around a base character.
12461*/
12462unsigned char QChar::combiningClass() const
12463{
12464#ifndef QT_NO_UNICODETABLES
12465 const Q_UINT8 *rowp = combining_info[row()];
12466 if ( !rowp )
12467 return 0;
12468 return *(rowp+cell());
12469#else
12470 return 0;
12471#endif
12472}
12473
12474
12475/*!
12476 Returns the lowercase equivalent if the character is uppercase;
12477 otherwise returns the character itself.
12478*/
12479QChar QChar::lower() const
12480{
12481 return ::lower( *this );
12482}
12483
12484/*!
12485 Returns the uppercase equivalent if the character is lowercase;
12486 otherwise returns the character itself.
12487*/
12488QChar QChar::upper() const
12489{
12490 return ::upper( *this );
12491}
12492
12493/*!
12494 \fn QChar::operator char() const
12495
12496 Returns the Latin1 character equivalent to the QChar, or 0. This
12497 is mainly useful for non-internationalized software.
12498
12499 \sa unicode()
12500*/
12501
12502/*!
12503 \fn ushort QChar::unicode() const
12504
12505 Returns the numeric Unicode value equal to the QChar. Normally,
12506 you should use QChar objects as they are equivalent, but for some
12507 low-level tasks (e.g. indexing into an array of Unicode
12508 information), this function is useful.
12509*/
12510
12511/*!
12512 \fn ushort & QChar::unicode()
12513
12514 \overload
12515
12516 Returns a reference to the numeric Unicode value equal to the
12517 QChar.
12518*/
12519
12520/*****************************************************************************
12521 Documentation of QChar related functions
12522 *****************************************************************************/
12523
12524/*!
12525 \fn bool operator==( QChar c1, QChar c2 )
12526
12527 \relates QChar
12528
12529 Returns TRUE if \a c1 and \a c2 are the same Unicode character;
12530 otherwise returns FALSE.
12531*/
12532
12533/*!
12534 \fn bool operator==( char ch, QChar c )
12535
12536 \overload
12537 \relates QChar
12538
12539 Returns TRUE if \a c is the ASCII/Latin1 character \a ch;
12540 otherwise returns FALSE.
12541*/
12542
12543/*!
12544 \fn bool operator==( QChar c, char ch )
12545
12546 \overload
12547 \relates QChar
12548
12549 Returns TRUE if \a c is the ASCII/Latin1 character \a ch;
12550 otherwise returns FALSE.
12551*/
12552
12553/*!
12554 \fn int operator!=( QChar c1, QChar c2 )
12555
12556 \relates QChar
12557
12558 Returns TRUE if \a c1 and \a c2 are not the same Unicode
12559 character; otherwise returns FALSE.
12560*/
12561
12562/*!
12563 \fn int operator!=( char ch, QChar c )
12564
12565 \overload
12566 \relates QChar
12567
12568 Returns TRUE if \a c is not the ASCII/Latin1 character \a ch;
12569 otherwise returns FALSE.
12570*/
12571
12572/*!
12573 \fn int operator!=( QChar c, char ch )
12574
12575 \overload
12576 \relates QChar
12577
12578 Returns TRUE if \a c is not the ASCII/Latin1 character \a ch;
12579 otherwise returns FALSE.
12580*/
12581
12582/*!
12583 \fn int operator<=( QChar c1, QChar c2 )
12584
12585 \relates QChar
12586
12587 Returns TRUE if the numeric Unicode value of \a c1 is less than
12588 that of \a c2, or they are the same Unicode character; otherwise
12589 returns FALSE.
12590*/
12591
12592/*!
12593 \fn int operator<=( QChar c, char ch )
12594
12595 \overload
12596 \relates QChar
12597
12598 Returns TRUE if the numeric Unicode value of \a c is less than or
12599 equal to that of the ASCII/Latin1 character \a ch; otherwise
12600 returns FALSE.
12601*/
12602
12603/*!
12604 \fn int operator<=( char ch, QChar c )
12605
12606 \overload
12607 \relates QChar
12608
12609 Returns TRUE if the numeric Unicode value of the ASCII/Latin1
12610 character \a ch is less than or equal to that of \a c; otherwise
12611 returns FALSE.
12612*/
12613
12614/*!
12615 \fn int operator>=( QChar c1, QChar c2 )
12616
12617 \relates QChar
12618
12619 Returns TRUE if the numeric Unicode value of \a c1 is greater than
12620 that of \a c2, or they are the same Unicode character; otherwise
12621 returns FALSE.
12622*/
12623
12624/*!
12625 \fn int operator>=( QChar c, char ch )
12626
12627 \overload
12628 \relates QChar
12629
12630 Returns TRUE if the numeric Unicode value of \a c is greater than
12631 or equal to that of the ASCII/Latin1 character \a ch; otherwise
12632 returns FALSE.
12633*/
12634
12635/*!
12636 \fn int operator>=( char ch, QChar c )
12637
12638 \overload
12639 \relates QChar
12640
12641 Returns TRUE if the numeric Unicode value of the ASCII/Latin1
12642 character \a ch is greater than or equal to that of \a c;
12643 otherwise returns FALSE.
12644*/
12645
12646/*!
12647 \fn int operator<( QChar c1, QChar c2 )
12648
12649 \relates QChar
12650
12651 Returns TRUE if the numeric Unicode value of \a c1 is less than
12652 that of \a c2; otherwise returns FALSE.
12653*/
12654
12655/*!
12656 \fn int operator<( QChar c, char ch )
12657
12658 \overload
12659 \relates QChar
12660
12661 Returns TRUE if the numeric Unicode value of \a c is less than that
12662 of the ASCII/Latin1 character \a ch; otherwise returns FALSE.
12663*/
12664
12665/*!
12666 \fn int operator<( char ch, QChar c )
12667
12668 \overload
12669 \relates QChar
12670
12671 Returns TRUE if the numeric Unicode value of the ASCII/Latin1
12672 character \a ch is less than that of \a c; otherwise returns
12673 FALSE.
12674*/
12675
12676/*!
12677 \fn int operator>( QChar c1, QChar c2 )
12678
12679 \relates QChar
12680
12681 Returns TRUE if the numeric Unicode value of \a c1 is greater than
12682 that of \a c2; otherwise returns FALSE.
12683*/
12684
12685/*!
12686 \fn int operator>( QChar c, char ch )
12687
12688 \overload
12689 \relates QChar
12690
12691 Returns TRUE if the numeric Unicode value of \a c is greater than
12692 that of the ASCII/Latin1 character \a ch; otherwise returns FALSE.
12693*/
12694
12695/*!
12696 \fn int operator>( char ch, QChar c )
12697
12698 \overload
12699 \relates QChar
12700
12701 Returns TRUE if the numeric Unicode value of the ASCII/Latin1
12702 character \a ch is greater than that of \a c; otherwise returns
12703 FALSE.
12704*/
12705
12706#ifndef QT_NO_UNICODETABLES
12707
12708// small class used internally in QString::Compose()
12709class QLigature
12710{
12711public:
12712 QLigature( QChar c );
12713
12714 Q_UINT16 first() { cur = ligatures; return cur ? *cur : 0; }
12715 Q_UINT16 next() { return cur && *cur ? *(cur++) : 0; }
12716 Q_UINT16 current() { return cur ? *cur : 0; }
12717
12718 int match(QString & str, unsigned int index);
12719 QChar head();
12720 QChar::Decomposition tag();
12721
12722private:
12723 Q_UINT16 *ligatures;
12724 Q_UINT16 *cur;
12725};
12726
12727QLigature::QLigature( QChar c )
12728{
12729 const Q_UINT16 *r = ligature_info[c.row()];
12730 if( !r )
12731 ligatures = 0;
12732 else
12733 {
12734 const Q_UINT16 pos = r[c.cell()];
12735 ligatures = (Q_UINT16 *)&(ligature_map[pos]);
12736 }
12737 cur = ligatures;
12738}
12739
12740QChar QLigature::head()
12741{
12742 if(current())
12743 return QChar(decomposition_map[current()+1]);
12744
12745 return QChar::null;
12746}
12747
12748QChar::Decomposition QLigature::tag()
12749{
12750 if(current())
12751 return (QChar::Decomposition) decomposition_map[current()];
12752
12753 return QChar::Canonical;
12754}
12755
12756int QLigature::match(QString & str, unsigned int index)
12757{
12758 unsigned int i=index;
12759
12760 if(!current()) return 0;
12761
12762 Q_UINT16 lig = current() + 2;
12763 Q_UINT16 ch;
12764
12765 while ((i < str.length()) && (ch = decomposition_map[lig])) {
12766 if (str[(int)i] != QChar(ch))
12767 return 0;
12768 i++;
12769 lig++;
12770 }
12771
12772 if (!decomposition_map[lig])
12773 {
12774 return i-index;
12775 }
12776 return 0;
12777}
12778
12779
12780// this function is just used in QString::compose()
12781static inline bool format(QChar::Decomposition tag, QString & str,
12782 int index, int len)
12783{
12784 unsigned int l = index + len;
12785 unsigned int r = index;
12786
12787 bool left = FALSE, right = FALSE;
12788
12789 left = ((l < str.length()) &&
12790 ((str[(int)l].joining() == QChar::Dual) ||
12791 (str[(int)l].joining() == QChar::Right)));
12792 if (r > 0) {
12793 r--;
12794 //printf("joining(right) = %d\n", str[(int)r].joining());
12795 right = (str[(int)r].joining() == QChar::Dual);
12796 }
12797
12798
12799 switch (tag) {
12800 case QChar::Medial:
12801 return (left & right);
12802 case QChar::Initial:
12803 return (left && !right);
12804 case QChar::Final:
12805 return (right);// && !left);
12806 case QChar::Isolated:
12807 default:
12808 return (!right && !left);
12809 }
12810} // format()
12811#endif
12812
12813/*
12814 QString::compose() and visual() were developed by Gordon Tisher
12815 <tisher@uniserve.ca>, with input from Lars Knoll <knoll@mpi-hd.mpg.de>,
12816 who developed the unicode data tables.
12817*/
12818/*!
12819 \warning This function is not supported in Qt 3.x. It is provided
12820 for experimental and illustrative purposes only. It is mainly of
12821 interest to those experimenting with Arabic and other
12822 composition-rich texts.
12823
12824 Applies possible ligatures to a QString. Useful when
12825 composition-rich text requires rendering with glyph-poor fonts,
12826 but it also makes compositions such as QChar(0x0041) ('A') and
12827 QChar(0x0308) (Unicode accent diaresis), giving QChar(0x00c4)
12828 (German A Umlaut).
12829*/
12830void QString::compose()
12831{
12832#ifndef QT_NO_UNICODETABLES
12833 unsigned int index=0, len;
12834 unsigned int cindex = 0;
12835
12836 QChar code, head;
12837
12838 QMemArray<QChar> dia;
12839
12840 QString composed = *this;
12841
12842 while (index < length()) {
12843 code = at(index);
12844 //printf("\n\nligature for 0x%x:\n", code.unicode());
12845 QLigature ligature(code);
12846 ligature.first();
12847 while(ligature.current()) {
12848 if ((len = ligature.match(*this, index)) != 0) {
12849 head = ligature.head();
12850 unsigned short code = head.unicode();
12851 // we exclude Arabic presentation forms A and a few
12852 // other ligatures, which are undefined in most fonts
12853 if(!(code > 0xfb50 && code < 0xfe80) &&
12854 !(code > 0xfb00 && code < 0xfb2a)) {
12855 // joining info is only needed for Arabic
12856 if (format(ligature.tag(), *this, index, len)) {
12857 //printf("using ligature 0x%x, len=%d\n",code,len);
12858 // replace letter
12859 composed.replace(cindex, len, QChar(head));
12860 index += len-1;
12861 // we continue searching in case we have a final
12862 // form because medial ones are preferred.
12863 if ( len != 1 || ligature.tag() !=QChar::Final )
12864 break;
12865 }
12866 }
12867 }
12868 ligature.next();
12869 }
12870 cindex++;
12871 index++;
12872 }
12873 *this = composed;
12874#endif
12875}
12876
12877
12878// These macros are used for efficient allocation of QChar strings.
12879// IMPORTANT! If you change these, make sure you also change the
12880// "delete unicode" statement in ~QStringData() in qstring.h correspondingly!
12881
12882#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ sizeof(QChar)*( N ) ]
12883#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P ))
12884
12885
12886/*!
12887 This utility function converts the 8-bit string \a ba to Unicode,
12888 returning the result.
12889
12890 The caller is responsible for deleting the return value with
12891 delete[].
12892*/
12893
12894QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len )
12895{
12896 if ( ba.isNull() ) {
12897 *len = 0;
12898 return 0;
12899 }
12900 int l = 0;
12901 while ( l < (int)ba.size() && ba[l] )
12902 l++;
12903 char* str = ba.data();
12904 QChar *uc = new QChar[ l ]; // Can't use macro, since function is public
12905 QChar *result = uc;
12906 if ( len )
12907 *len = l;
12908 while (l--)
12909 *uc++ = *str++;
12910 return result;
12911}
12912
12913static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len )
12914{
12915 if ( ba.isNull() ) {
12916 *len = 0;
12917 return 0;
12918 }
12919 int l = 0;
12920 while ( l < (int)ba.size() && ba[l] )
12921 l++;
12922 char* str = ba.data();
12923 QChar *uc = QT_ALLOC_QCHAR_VEC( l );
12924 QChar *result = uc;
12925 if ( len )
12926 *len = l;
12927 while (l--)
12928 *uc++ = *str++;
12929 return result;
12930}
12931
12932/*!
12933 \overload
12934
12935 This utility function converts the '\0'-terminated 8-bit string \a
12936 str to Unicode, returning the result and setting \a *len to the
12937 length of the Unicode string.
12938
12939 The caller is responsible for deleting the return value with
12940 delete[].
12941*/
12942
12943QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen )
12944{
12945 QChar* result = 0;
12946 uint l = 0;
12947 if ( str ) {
12948 if ( maxlen != (uint)-1 ) {
12949 while ( l < maxlen && str[l] )
12950 l++;
12951 } else {
12952 // Faster?
12953 l = qstrlen(str);
12954 }
12955 QChar *uc = new QChar[ l ]; // Can't use macro since function is public
12956 result = uc;
12957 uint i = l;
12958 while ( i-- )
12959 *uc++ = *str++;
12960 }
12961 if ( len )
12962 *len = l;
12963 return result;
12964}
12965
12966static QChar* internalAsciiToUnicode( const char *str, uint* len,
12967 uint maxlen = (uint)-1 )
12968{
12969 QChar* result = 0;
12970 uint l = 0;
12971 if ( str ) {
12972 if ( maxlen != (uint)-1 ) {
12973 while ( l < maxlen && str[l] )
12974 l++;
12975 } else {
12976 // Faster?
12977 l = qstrlen(str);
12978 }
12979 QChar *uc = QT_ALLOC_QCHAR_VEC( l );
12980 result = uc;
12981 uint i = l;
12982 while ( i-- )
12983 *uc++ = *str++;
12984 }
12985 if ( len )
12986 *len = l;
12987 return result;
12988}
12989
12990/*!
12991 This utility function converts \a l 16-bit characters from \a uc
12992 to ASCII, returning a '\0'-terminated string.
12993
12994 The caller is responsible for deleting the resultant string with
12995 delete[].
12996*/
12997char* QString::unicodeToAscii(const QChar *uc, uint l)
12998{
12999 if (!uc) {
13000 return 0;
13001 }
13002 char *a = new char[l+1];
13003 char *result = a;
13004 while (l--) {
13005 *a++ = (uc->unicode() > 0xff) ? '?' : (char)uc->unicode();
13006 uc++;
13007 }
13008 *a = '\0';
13009 return result;
13010}
13011
13012/*****************************************************************************
13013 QString member functions
13014 *****************************************************************************/
13015
13016/*!
13017 \class QString qstring.h
13018 \reentrant
13019
13020 \brief The QString class provides an abstraction of Unicode text
13021 and the classic C '\0'-terminated char array.
13022
13023 \ingroup tools
13024 \ingroup shared
13025 \ingroup text
13026 \mainclass
13027
13028 QString uses \link shclass.html implicit sharing\endlink, which
13029 makes it very efficient and easy to use.
13030
13031 In all of the QString methods that take \c {const char *}
13032 parameters, the \c {const char *} is interpreted as a classic
13033 C-style '\0'-terminated ASCII string. It is legal for the \c
13034 {const char *} parameter to be 0. If the \c {const char *} is not
13035 '\0'-terminated, the results are undefined. Functions that copy
13036 classic C strings into a QString will not copy the terminating
13037 '\0' character. The QChar array of the QString (as returned by
13038 unicode()) is generally not terminated by a '\0'. If you need to
13039 pass a QString to a function that requires a C '\0'-terminated
13040 string use latin1().
13041
13042 \keyword QString::null
13043 A QString that has not been assigned to anything is \e null, i.e.
13044 both the length and data pointer is 0. A QString that references
13045 the empty string ("", a single '\0' char) is \e empty. Both null
13046 and empty QStrings are legal parameters to the methods. Assigning
13047 \c{(const char *) 0} to QString gives a null QString. For
13048 convenience, \c QString::null is a null QString. When sorting,
13049 empty strings come first, followed by non-empty strings, followed
13050 by null strings. We recommend using \c{if ( !str.isNull() )} to
13051 check for a non-null string rather than \c{if ( !str )}; see \l
13052 operator!() for an explanation.
13053
13054 Note that if you find that you are mixing usage of \l QCString,
13055 QString, and \l QByteArray, this causes lots of unnecessary
13056 copying and might indicate that the true nature of the data you
13057 are dealing with is uncertain. If the data is '\0'-terminated 8-bit
13058 data, use \l QCString; if it is unterminated (i.e. contains '\0's)
13059 8-bit data, use \l QByteArray; if it is text, use QString.
13060
13061 Lists of strings are handled by the QStringList class. You can
13062 split a string into a list of strings using QStringList::split(),
13063 and join a list of strings into a single string with an optional
13064 separator using QStringList::join(). You can obtain a list of
13065 strings from a string list that contain a particular substring or
13066 that match a particular \link qregexp.html regex\endlink using
13067 QStringList::grep().
13068
13069 <b>Note for C programmers</b>
13070
13071 Due to C++'s type system and the fact that QString is implicitly
13072 shared, QStrings may be treated like ints or other simple base
13073 types. For example:
13074
13075 \code
13076 QString boolToString( bool b )
13077 {
13078 QString result;
13079 if ( b )
13080 result = "True";
13081 else
13082 result = "False";
13083 return result;
13084 }
13085 \endcode
13086
13087 The variable, result, is an auto variable allocated on the stack.
13088 When return is called, because we're returning by value, The copy
13089 constructor is called and a copy of the string is returned. (No
13090 actual copying takes place thanks to the implicit sharing, see
13091 below.)
13092
13093 Throughout Qt's source code you will encounter QString usages like
13094 this:
13095 \code
13096 QString func( const QString& input )
13097 {
13098 QString output = input;
13099 // process output
13100 return output;
13101 }
13102 \endcode
13103
13104 The 'copying' of input to output is almost as fast as copying a
13105 pointer because behind the scenes copying is achieved by
13106 incrementing a reference count. QString (like all Qt's implicitly
13107 shared classes) operates on a copy-on-write basis, only copying if
13108 an instance is actually changed.
13109
13110 If you wish to create a deep copy of a QString without losing any
13111 Unicode information then you should use QDeepCopy.
13112
13113 \sa QChar QCString QByteArray QConstString
13114*/
13115
13116/*! \enum Qt::ComparisonFlags
13117\internal
13118*/
13119/*!
13120 \enum Qt::StringComparisonMode
13121
13122 This enum type is used to set the string comparison mode when
13123 searching for an item. It is used by QListBox, QListView and
13124 QIconView, for example. We'll refer to the string being searched
13125 as the 'target' string.
13126
13127 \value CaseSensitive The strings must match case sensitively.
13128 \value ExactMatch The target and search strings must match exactly.
13129 \value BeginsWith The target string begins with the search string.
13130 \value EndsWith The target string ends with the search string.
13131 \value Contains The target string contains the search string.
13132
13133 If you OR these flags together (excluding \c CaseSensitive), the
13134 search criteria be applied in the following order: \c ExactMatch,
13135 \c BeginsWith, \c EndsWith, \c Contains.
13136
13137 Matching is case-insensitive unless \c CaseSensitive is set. \c
13138 CaseSensitive may be OR-ed with any combination of the other
13139 flags.
13140
13141*/
13142Q_EXPORT QStringData *QString::shared_null = 0;
13143QT_STATIC_CONST_IMPL QString QString::null;
13144QT_STATIC_CONST_IMPL QChar QChar::null;
13145QT_STATIC_CONST_IMPL QChar QChar::replacement((ushort)0xfffd);
13146QT_STATIC_CONST_IMPL QChar QChar::byteOrderMark((ushort)0xfeff);
13147QT_STATIC_CONST_IMPL QChar QChar::byteOrderSwapped((ushort)0xfffe);
13148QT_STATIC_CONST_IMPL QChar QChar::nbsp((ushort)0x00a0);
13149
13150QStringData* QString::makeSharedNull()
13151{
13152 QString::shared_null = new QStringData;
13153#if defined( Q_OS_MAC )
13154 QString *that = const_cast<QString *>(&QString::null);
13155 that->d = QString::shared_null;
13156#endif
13157 return QString::shared_null;
13158}
13159
13160// Uncomment this to get some useful statistics.
13161// #define Q2HELPER(x) x
13162
13163#ifdef Q2HELPER
13164static int stat_construct_charstar=0;
13165static int stat_construct_charstar_size=0;
13166static int stat_construct_null=0;
13167static int stat_construct_int=0;
13168static int stat_construct_int_size=0;
13169static int stat_construct_ba=0;
13170static int stat_get_ascii=0;
13171static int stat_get_ascii_size=0;
13172static int stat_copy_on_write=0;
13173static int stat_copy_on_write_size=0;
13174static int stat_fast_copy=0;
13175Q_EXPORT void qt_qstring_stats()
13176{
13177 qDebug("construct_charstar = %d (%d chars)", stat_construct_charstar, stat_construct_charstar_size);
13178 qDebug("construct_null = %d", stat_construct_null);
13179 qDebug("construct_int = %d (%d chars)", stat_construct_int, stat_construct_int_size);
13180 qDebug("construct_ba = %d", stat_construct_ba);
13181 qDebug("get_ascii = %d (%d chars)", stat_get_ascii, stat_get_ascii_size);
13182 qDebug("copy_on_write = %d (%d chars)", stat_copy_on_write, stat_copy_on_write_size);
13183 qDebug("fast_copy = %d", stat_fast_copy);
13184}
13185#else
13186#define Q2HELPER(x)
13187#endif
13188
13189/*!
13190 \fn QString::QString()
13191
13192 Constructs a null string, i.e. both the length and data pointer
13193 are 0.
13194
13195 \sa isNull()
13196*/
13197
13198/*!
13199 Constructs a string of length one, containing the character \a ch.
13200*/
13201QString::QString( QChar ch )
13202{
13203 d = new QStringData( QT_ALLOC_QCHAR_VEC( 1 ), 1, 1 );
13204 d->unicode[0] = ch;
13205}
13206
13207/*!
13208 Constructs an implicitly shared copy of \a s. This is very fast
13209 since it only involves incrementing a reference count.
13210*/
13211QString::QString( const QString &s ) :
13212 d(s.d)
13213{
13214 Q2HELPER(stat_fast_copy++)
13215 d->ref();
13216}
13217
13218/*!
13219 \internal
13220
13221 Private function.
13222
13223 Constructs a string with preallocated space for \a size characters.
13224
13225 The string is empty.
13226
13227 \sa isNull()
13228*/
13229
13230QString::QString( int size, bool /*dummy*/ )
13231{
13232 if ( size ) {
13233 Q2HELPER(stat_construct_int++)
13234 int l = size;
13235 Q2HELPER(stat_construct_int_size+=l)
13236 QChar* uc = QT_ALLOC_QCHAR_VEC( l );
13237 d = new QStringData( uc, 0, l );
13238 } else {
13239 Q2HELPER(stat_construct_null++)
13240 d = shared_null ? shared_null : (shared_null=new QStringData);
13241 d->ref();
13242 }
13243}
13244
13245/*!
13246 Constructs a string that is a deep copy of \a ba interpreted as a
13247 classic C string.
13248*/
13249
13250QString::QString( const QByteArray& ba )
13251{
13252 Q2HELPER(stat_construct_ba++)
13253 uint l;
13254 QChar *uc = internalAsciiToUnicode(ba,&l);
13255 d = new QStringData(uc,l,l);
13256}
13257
13258/*!
13259 Constructs a string that is a deep copy of the first \a length
13260 characters in the QChar array.
13261
13262 If \a unicode and \a length are 0, then a null string is created.
13263
13264 If only \a unicode is 0, the string is empty but has \a length
13265 characters of space preallocated: QString expands automatically
13266 anyway, but this may speed up some cases a little. We recommend
13267 using the plain constructor and setLength() for this purpose since
13268 it will result in more readable code.
13269
13270 \sa isNull() setLength()
13271*/
13272
13273QString::QString( const QChar* unicode, uint length )
13274{
13275 if ( !unicode && !length ) {
13276 d = shared_null ? shared_null : makeSharedNull();
13277 d->ref();
13278 } else {
13279 QChar* uc = QT_ALLOC_QCHAR_VEC( length );
13280 if ( unicode )
13281 memcpy(uc, unicode, length*sizeof(QChar));
13282 d = new QStringData(uc,unicode ? length : 0,length);
13283 }
13284}
13285
13286/*!
13287 Constructs a string that is a deep copy of \a str, interpreted as
13288 a classic C string.
13289
13290 If \a str is 0, then a null string is created.
13291
13292 This is a cast constructor, but it is perfectly safe: converting a
13293 Latin1 const char* to QString preserves all the information. You
13294 can disable this constructor by defining \c QT_NO_CAST_ASCII when
13295 you compile your applications. You can also make QString objects
13296 by using setLatin1(), fromLatin1(), fromLocal8Bit(), and
13297 fromUtf8(). Or whatever encoding is appropriate for the 8-bit data
13298 you have.
13299
13300 \sa isNull()
13301*/
13302
13303QString::QString( const char *str )
13304{
13305 Q2HELPER(stat_construct_charstar++)
13306 uint l;
13307 QChar *uc = internalAsciiToUnicode(str,&l);
13308 Q2HELPER(stat_construct_charstar_size+=l)
13309 d = new QStringData(uc,l,l);
13310}
13311
13312/*!
13313 \fn QString::~QString()
13314
13315 Destroys the string and frees the string's data if this is the
13316 last reference to the string.
13317*/
13318
13319
13320/*!
13321 Deallocates any space reserved solely by this QString.
13322
13323 If the string does not share its data with another QString
13324 instance, nothing happens; otherwise the function creates a new,
13325 unique copy of this string. This function is called whenever the
13326 string is modified.
13327*/
13328
13329void QString::real_detach()
13330{
13331 setLength( length() );
13332}
13333
13334void QString::deref()
13335{
13336 if ( d->deref() ) {
13337 if ( d != shared_null )
13338 delete d;
13339 d = 0; // helps debugging
13340 }
13341}
13342
13343void QStringData::deleteSelf()
13344{
13345 delete this;
13346}
13347
13348/*!
13349 \fn QString& QString::operator=( QChar c )
13350
13351 Sets the string to contain just the single character \a c.
13352*/
13353
13354/*!
13355 \fn QString& QString::operator=( char c )
13356
13357 \overload
13358
13359 Sets the string to contain just the single character \a c.
13360*/
13361
13362/*!
13363 \overload
13364
13365 Assigns a shallow copy of \a s to this string and returns a
13366 reference to this string. This is very fast because the string
13367 isn't actually copied.
13368*/
13369QString &QString::operator=( const QString &s )
13370{
13371 Q2HELPER(stat_fast_copy++)
13372 s.d->ref();
13373 deref();
13374 d = s.d;
13375 return *this;
13376}
13377
13378/*!
13379 \overload
13380
13381 Assigns a deep copy of \a cs, interpreted as a classic C string,
13382 to this string and returns a reference to this string.
13383*/
13384QString &QString::operator=( const QCString& cs )
13385{
13386 return setLatin1(cs);
13387}
13388
13389
13390/*!
13391 \overload
13392
13393 Assigns a deep copy of \a str, interpreted as a classic C string
13394 to this string and returns a reference to this string.
13395
13396 If \a str is 0, then a null string is created.
13397
13398 \sa isNull()
13399*/
13400QString &QString::operator=( const char *str )
13401{
13402 return setLatin1(str);
13403}
13404
13405
13406/*!
13407 \fn bool QString::isNull() const
13408
13409 Returns TRUE if the string is null; otherwise returns FALSE. A
13410 null string is always empty.
13411
13412 \code
13413 QString a; // a.unicode() == 0, a.length() == 0
13414 a.isNull(); // TRUE, because a.unicode() == 0
13415 a.isEmpty(); // TRUE
13416 \endcode
13417
13418 \sa isEmpty(), length()
13419*/
13420
13421/*!
13422 \fn bool QString::isEmpty() const
13423
13424 Returns TRUE if the string is empty, i.e. if length() == 0;
13425 otherwise returns FALSE. Null strings are also empty.
13426
13427 \code
13428 QString a( "" );
13429 a.isEmpty(); // TRUE
13430 a.isNull(); // FALSE
13431
13432 QString b;
13433 b.isEmpty(); // TRUE
13434 b.isNull(); // TRUE
13435 \endcode
13436
13437 \sa isNull(), length()
13438*/
13439
13440/*!
13441 \fn uint QString::length() const
13442
13443 Returns the length of the string.
13444
13445 Null strings and empty strings have zero length.
13446
13447 \sa isNull(), isEmpty()
13448*/
13449
13450/*!
13451 If \a newLen is less than the length of the string, then the
13452 string is truncated at position \a newLen. Otherwise nothing
13453 happens.
13454
13455 \code
13456 QString s = "truncate me";
13457 s.truncate( 5 ); // s == "trunc"
13458 \endcode
13459
13460 \sa setLength()
13461*/
13462
13463void QString::truncate( uint newLen )
13464{
13465 if ( newLen < d->len )
13466 setLength( newLen );
13467}
13468
13469/*!
13470 Ensures that at least \a newLen characters are allocated to the
13471 string, and sets the length of the string to \a newLen. Any new
13472 space allocated contains arbitrary data.
13473
13474 If \a newLen is 0, then the string becomes empty, unless the
13475 string is null, in which case it remains null.
13476
13477 If it is not possible to allocate enough memory, the string
13478 remains unchanged.
13479
13480 This function always detaches the string from other references to
13481 the same data.
13482
13483 This function is useful for code that needs to build up a long
13484 string and wants to avoid repeated reallocation. In this example,
13485 we want to add to the string until some condition is true, and
13486 we're fairly sure that size is big enough:
13487 \code
13488 QString result;
13489 int resultLength = 0;
13490 result.setLength( newLen ) // allocate some space
13491 while ( ... ) {
13492 result[resultLength++] = ... // fill (part of) the space with data
13493 }
13494 result.truncate[resultLength]; // and get rid of the undefined junk
13495 \endcode
13496
13497 If \a newLen is an underestimate, the worst that will happen is
13498 that the loop will slow down.
13499
13500 \sa truncate(), isNull(), isEmpty(), length()
13501*/
13502
13503void QString::setLength( uint newLen )
13504{
13505 if ( d->count != 1 || newLen > d->maxl ||
13506 ( newLen * 4 < d->maxl && d->maxl > 4 ) ) {
13507 // detach, grow or shrink
13508 Q2HELPER(stat_copy_on_write++)
13509 Q2HELPER(stat_copy_on_write_size+=d->len)
13510 uint newMax = computeNewMax( newLen );
13511 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
13512 if ( nd ) {
13513 uint len = QMIN( d->len, newLen );
13514 if ( d->unicode )
13515 memcpy( nd, d->unicode, sizeof(QChar)*len );
13516 deref();
13517 d = new QStringData( nd, newLen, newMax );
13518 }
13519 } else {
13520 d->len = newLen;
13521 d->setDirty();
13522 }
13523}
13524
13525/*!
13526 This function will return a string that replaces the lowest
13527 numbered occurrence of \c %1, \c %2, ..., \c %9 with \a a.
13528
13529 The \a fieldwidth value specifies the minimum amount of space that
13530 \a a is padded to. A positive value will produce right-aligned
13531 text, whereas a negative value will produce left-aligned text.
13532
13533 \code
13534 QString firstName( "Joe" );
13535 QString lastName( "Bloggs" );
13536 QString fullName;
13537 fullName = QString( "First name is '%1', last name is '%2'" )
13538 .arg( firstName )
13539 .arg( lastName );
13540
13541 // fullName == First name is 'Joe', last name is 'Bloggs'
13542 \endcode
13543
13544 Note that using arg() to construct sentences as we've done in the
13545 example above does not usually translate well into other languages
13546 because sentence structure and word order often differ between
13547 languages.
13548
13549 If there is no place marker (\c %1 or \c %2, etc.), a warning
13550 message (qWarning()) is output and the text is appended at the
13551 end of the string. We recommend that the correct number of place
13552 markers is always used in production code.
13553*/
13554QString QString::arg( const QString& a, int fieldwidth ) const
13555{
13556 int pos, len;
13557 QString r = *this;
13558
13559 if ( !findArg( pos, len ) ) {
13560 qWarning( "QString::arg(): Argument missing: %s, %s",
13561 latin1(), a.latin1() );
13562 // Make sure the text at least appears SOMEWHERE
13563 r += ' ';
13564 pos = r.length();
13565 len = 0;
13566 }
13567
13568 r.replace( pos, len, a );
13569 if ( fieldwidth < 0 ) {
13570 QString s;
13571 while ( (uint)-fieldwidth > a.length() ) {
13572 s += ' ';
13573 fieldwidth++;
13574 }
13575 r.insert( pos + a.length(), s );
13576 } else if ( fieldwidth ) {
13577 QString s;
13578 while ( (uint)fieldwidth > a.length() ) {
13579 s += ' ';
13580 fieldwidth--;
13581 }
13582 r.insert( pos, s );
13583 }
13584
13585 return r;
13586}
13587
13588
13589/*!
13590 \overload
13591
13592 The \a fieldwidth value specifies the minimum amount of space that
13593 \a a is padded to. A positive value will produce a right-aligned
13594 number, whereas a negative value will produce a left-aligned
13595 number.
13596
13597 \a a is expressed in base \a base, which is 10 by default and must
13598 be between 2 and 36.
13599
13600 \code
13601 QString str;
13602 str = QString( "Decimal 63 is %1 in hexadecimal" )
13603 .arg( 63, 0, 16 );
13604 // str == "Decimal 63 is 3f in hexadecimal"
13605 \endcode
13606*/
13607QString QString::arg( long a, int fieldwidth, int base ) const
13608{
13609 return arg( QString::number(a, base), fieldwidth );
13610}
13611
13612/*!
13613 \overload
13614
13615 \a a is expressed in base \a base, which is 10 by default and must
13616 be between 2 and 36.
13617*/
13618QString QString::arg( ulong a, int fieldwidth, int base ) const
13619{
13620 return arg( QString::number(a, base), fieldwidth );
13621}
13622
13623/*!
13624 \fn QString QString::arg( int a, int fieldwidth, int base ) const
13625
13626 \overload
13627
13628 \a a is expressed in base \a base, which is 10 by default and must
13629 be between 2 and 36.
13630*/
13631
13632/*!
13633 \fn QString QString::arg( uint a, int fieldwidth, int base ) const
13634
13635 \overload
13636
13637 \a a is expressed in base \a base, which is 10 by default and must
13638 be between 2 and 36.
13639*/
13640
13641/*!
13642 \fn QString QString::arg( short a, int fieldwidth, int base ) const
13643
13644 \overload
13645
13646 \a a is expressed in base \a base, which is 10 by default and must
13647 be between 2 and 36.
13648*/
13649
13650/*!
13651 \fn QString QString::arg( ushort a, int fieldwidth, int base ) const
13652
13653 \overload
13654
13655 \a a is expressed in base \a base, which is 10 by default and must
13656 be between 2 and 36.
13657*/
13658
13659
13660/*!
13661 \overload
13662
13663 \a a is assumed to be in the Latin1 character set.
13664*/
13665QString QString::arg( char a, int fieldwidth ) const
13666{
13667 QString c;
13668 c += a;
13669 return arg( c, fieldwidth );
13670}
13671
13672/*!
13673 \overload
13674*/
13675QString QString::arg( QChar a, int fieldwidth ) const
13676{
13677 QString c;
13678 c += a;
13679 return arg( c, fieldwidth );
13680}
13681
13682/*!
13683 \overload
13684
13685 \target arg-formats
13686
13687 Argument \a a is formatted according to the \a fmt format specified,
13688 which is 'g' by default and can be any of the following:
13689
13690 \table
13691 \header \i Format \i Meaning
13692 \row \i \c e \i format as [-]9.9e[+|-]999
13693 \row \i \c E \i format as [-]9.9E[+|-]999
13694 \row \i \c f \i format as [-]9.9
13695 \row \i \c g \i use \c e or \c f format, whichever is the most concise
13696 \row \i \c G \i use \c E or \c f format, whichever is the most concise
13697 \endtable
13698
13699 With 'e', 'E', and 'f', \a prec is the number of digits after the
13700 decimal point. With 'g' and 'G', \a prec is the maximum number of
13701 significant digits (trailing zeroes are omitted).
13702
13703 \code
13704 double d = 12.34;
13705 QString ds = QString( "'E' format, precision 3, gives %1" )
13706 .arg( d, 0, 'E', 3 );
13707 // ds == "1.234E+001"
13708 \endcode
13709*/
13710QString QString::arg( double a, int fieldwidth, char fmt, int prec ) const
13711{
13712 return arg( QString::number( a, fmt, prec ), fieldwidth );
13713}
13714
13715
13716/*
13717 Just 1-digit arguments.
13718*/
13719bool QString::findArg( int& pos, int& len ) const
13720{
13721 char lowest=0;
13722 register const QChar *uc = d->unicode;
13723 const uint l = length();
13724 for (uint i = 0; i < l; i++) {
13725 if ( uc[i] == '%' && i+1<l ) {
13726 QChar dig = uc[i+1];
13727 if ( dig >= '0' && dig <= '9' ) {
13728 if ( !lowest || dig < lowest ) {
13729 lowest = dig;
13730 pos = i;
13731 len = 2;
13732 }
13733 }
13734 }
13735 }
13736 return lowest != 0;
13737}
13738
13739/*!
13740 Safely builds a formatted string from the format string \a cformat
13741 and an arbitrary list of arguments. The format string supports all
13742 the escape sequences of printf() in the standard C library.
13743
13744 The %s escape sequence expects a utf8() encoded string. The format
13745 string \e cformat is expected to be in latin1. If you need a
13746 Unicode format string, use arg() instead. For typesafe string
13747 building, with full Unicode support, you can use QTextOStream like
13748 this:
13749
13750 \code
13751 QString str;
13752 QString s = ...;
13753 int x = ...;
13754 QTextOStream( &str ) << s << " : " << x;
13755 \endcode
13756
13757 For \link QObject::tr() translations,\endlink especially if the
13758 strings contains more than one escape sequence, you should
13759 consider using the arg() function instead. This allows the order
13760 of the replacements to be controlled by the translator, and has
13761 Unicode support.
13762
13763 \sa arg()
13764*/
13765
13766#ifndef QT_NO_SPRINTF
13767QString &QString::sprintf( const char* cformat, ... )
13768{
13769 va_list ap;
13770 va_start( ap, cformat );
13771
13772 if ( !cformat || !*cformat ) {
13773 // Qt 1.x compat
13774 *this = fromLatin1( "" );
13775 return *this;
13776 }
13777 QString format = fromLatin1( cformat );
13778
13779 QRegExp escape( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" );
13780 QString result;
13781 uint last = 0;
13782 int pos;
13783 int len = 0;
13784
13785 for (;;) {
13786 pos = escape.search( format, last );
13787 len = escape.matchedLength();
13788 // Non-escaped text
13789 if ( pos > (int)last )
13790 result += format.mid( last, pos - last );
13791 if ( pos < 0 ) {
13792 // The rest
13793 if ( last < format.length() )
13794 result += format.mid( last );
13795 break;
13796 }
13797 last = pos + len + 1;
13798
13799 // Escape
13800 QString f = format.mid( pos, len );
13801 uint width, decimals;
13802 int params = 0;
13803 int wpos = f.find('*');
13804 if ( wpos >= 0 ) {
13805 params++;
13806 width = va_arg( ap, int );
13807 if ( f.find('*', wpos + 1) >= 0 ) {
13808 decimals = va_arg( ap, int );
13809 params++;
13810 } else {
13811 decimals = 0;
13812 }
13813 } else {
13814 decimals = width = 0;
13815 }
13816 QString replacement;
13817 if ( format[pos + len] == 's' || format[pos + len] == 'S' ||
13818 format[pos + len] == 'c' )
13819 {
13820 bool rightjust = ( f.find('-') < 0 );
13821 // %-5s really means left adjust in sprintf
13822
13823 if ( wpos < 0 ) {
13824 QRegExp num( fromLatin1("[0-9]+") );
13825 int p = num.search( f );
13826 int nlen = num.matchedLength();
13827 int q = f.find( '.' );
13828 if ( q < 0 || (p < q && p >= 0) )
13829 width = f.mid( p, nlen ).toInt();
13830 if ( q >= 0 ) {
13831 p = num.search( f, q );
13832 // "decimals" is used to specify string truncation
13833 if ( p >= 0 )
13834 decimals = f.mid( p, nlen ).toInt();
13835 }
13836 }
13837
13838 if ( format[pos + len] == 's' ) {
13839 QString s = QString::fromUtf8( va_arg(ap, char*) );
13840 replacement = ( decimals <= 0 ) ? s : s.left( decimals );
13841 } else {
13842 int ch = va_arg(ap, int);
13843 replacement = QChar((ushort)ch);
13844 }
13845 if ( replacement.length() < width ) {
13846 replacement = rightjust
13847 ? replacement.rightJustify(width)
13848 : replacement.leftJustify(width);
13849 }
13850 } else if ( format[pos+len] == '%' ) {
13851 replacement = '%';
13852 } else if ( format[pos+len] == 'n' ) {
13853 int* n = va_arg(ap, int*);
13854 *n = result.length();
13855 } else {
13856 char in[64], out[330];
13857 strncpy(in,f.latin1(),63);
13858 out[0] = '\0';
13859 char fch = format[pos+len].latin1();
13860 in[f.length()] = fch;
13861 switch ( fch ) {
13862 case 'd':
13863 case 'i':
13864 case 'o':
13865 case 'u':
13866 case 'x':
13867 case 'X':
13868 {
13869 int value = va_arg( ap, int );
13870 switch ( params ) {
13871 case 0:
13872 ::sprintf( out, in, value );
13873 break;
13874 case 1:
13875 ::sprintf( out, in, width, value );
13876 break;
13877 case 2:
13878 ::sprintf( out, in, width, decimals, value );
13879 }
13880 }
13881 break;
13882 case 'e':
13883 case 'E':
13884 case 'f':
13885 case 'g':
13886 case 'G':
13887 {
13888 double value = va_arg( ap, double );
13889 switch ( params ) {
13890 case 0:
13891 ::sprintf( out, in, value );
13892 break;
13893 case 1:
13894 ::sprintf( out, in, width, value );
13895 break;
13896 case 2:
13897 ::sprintf( out, in, width, decimals, value );
13898 }
13899 }
13900 break;
13901 case 'p':
13902 {
13903 void* value = va_arg( ap, void * );
13904 switch ( params ) {
13905 case 0:
13906 ::sprintf( out, in, value );
13907 break;
13908 case 1:
13909 ::sprintf( out, in, width, value );
13910 break;
13911 case 2:
13912 ::sprintf( out, in, width, decimals, value );
13913 }
13914 }
13915 }
13916 replacement = fromLatin1( out );
13917 }
13918 result += replacement;
13919 }
13920 *this = result;
13921
13922 va_end( ap );
13923 return *this;
13924}
13925#endif
13926
13927/*!
13928 Fills the string with \a len characters of value \a c, and returns
13929 a reference to the string.
13930
13931 If \a len is negative (the default), the current string length is
13932 used.
13933
13934 \code
13935 QString str;
13936 str.fill( 'g', 5 ); // string == "ggggg"
13937 \endcode
13938*/
13939
13940QString& QString::fill( QChar c, int len )
13941{
13942 if ( len < 0 )
13943 len = length();
13944 if ( len == 0 ) {
13945 *this = "";
13946 } else {
13947 deref();
13948 QChar * nd = QT_ALLOC_QCHAR_VEC( len );
13949 d = new QStringData(nd,len,len);
13950 while (len--) *nd++ = c;
13951 }
13952 return *this;
13953}
13954
13955
13956/*!
13957 \fn QString QString::copy() const
13958
13959 \obsolete
13960
13961 In Qt 2.0 and later, all calls to this function are needless. Just
13962 remove them.
13963*/
13964
13965/*!
13966 \overload
13967
13968 Finds the first occurrence of the character \a c, starting at
13969 position \a index. If \a index is -1, the search starts at the
13970 last character; if -2, at the next to last character and so on.
13971 (See findRev() for searching backwards.)
13972
13973 If \a cs is TRUE, the search is case sensitive; otherwise the
13974 search is case insensitive.
13975
13976 Returns the position of \a c or -1 if \a c could not be found.
13977*/
13978
13979int QString::find( QChar c, int index, bool cs ) const
13980{
13981 const uint l = length();
13982 if ( index < 0 )
13983 index += l;
13984 if ( (uint)index >= l )
13985 return -1;
13986 register const QChar *uc = unicode()+index;
13987 const QChar *end = unicode() + l;
13988 if ( cs ) {
13989 while ( uc < end && *uc != c )
13990 uc++;
13991 } else {
13992 c = ::lower( c );
13993 while ( uc < end && ::lower( *uc ) != c )
13994 uc++;
13995 }
13996 if ( uint(uc - unicode()) >= l )
13997 return -1;
13998 return (int)(uc - unicode());
13999}
14000
14001/* an implementation of the Boyer-Moore search algorithm
14002*/
14003
14004/* initializes the skiptable to know haw far ahead we can skip on a wrong match
14005*/
14006static void bm_init_skiptable( const QString &pattern, uint *skiptable, bool cs )
14007{
14008 int i = 0;
14009 register uint *st = skiptable;
14010 int l = pattern.length();
14011 while ( i++ < 0x100/8 ) {
14012 *(st++) = l;
14013 *(st++) = l;
14014 *(st++) = l;
14015 *(st++) = l;
14016 *(st++) = l;
14017 *(st++) = l;
14018 *(st++) = l;
14019 *(st++) = l;
14020 }
14021 const QChar *uc = pattern.unicode();
14022 if ( cs ) {
14023 while( l-- ) {
14024 skiptable[ uc->cell() ] = l;
14025 uc++;
14026 }
14027 } else {
14028 while( l-- ) {
14029 skiptable[ ::lower( *uc ).cell() ] = l;
14030 uc++;
14031 }
14032 }
14033}
14034
14035static int bm_find( const QString &str, int index, const QString &pattern, uint *skiptable, bool cs )
14036{
14037 const uint l = str.length();
14038 if ( pattern.isEmpty() )
14039 return index > (int)l ? -1 : index;
14040
14041 const QChar *uc = str.unicode();
14042 const QChar *puc = pattern.unicode();
14043 const uint pl = pattern.length();
14044 const uint pl_minus_one = pl - 1;
14045
14046 register const QChar *current = uc + index + pl_minus_one;
14047 const QChar *end = uc + l;
14048 if ( cs ) {
14049 while( current < end ) {
14050 uint skip = skiptable[ current->cell() ];
14051 if ( !skip ) {
14052 // possible match
14053 while( skip < pl ) {
14054 if ( *(current - skip ) != puc[pl_minus_one-skip] )
14055 break;
14056 skip++;
14057 }
14058 if ( skip > pl_minus_one ) { // we have a match
14059 return (current - uc) - skip + 1;
14060 }
14061 // in case we don't have a match we are a bit inefficient as we only skip by one
14062 // when we have the non matching char in the string.
14063 if ( skiptable[ (current-skip)->cell() ] == pl )
14064 skip = pl - skip;
14065 else
14066 skip = 1;
14067 }
14068 current += skip;
14069 }
14070 } else {
14071 while( current < end ) {
14072 uint skip = skiptable[ ::lower( *current ).cell() ];
14073 if ( !skip ) {
14074 // possible match
14075 while( skip < pl ) {
14076 if ( ::lower( *(current - skip) ) != ::lower( puc[pl_minus_one-skip] ) )
14077 break;
14078 skip++;
14079 }
14080 if ( skip > pl_minus_one ) // we have a match
14081 return (current - uc) - skip + 1;
14082 // in case we don't have a match we are a bit inefficient as we only skip by one
14083 // when we have the non matching char in the string.
14084 if ( skiptable[ ::lower( (current - skip)->cell() ) ] == pl )
14085 skip = pl - skip;
14086 else
14087 skip = 1;
14088 }
14089 current += skip;
14090 }
14091 }
14092 // not found
14093 return -1;
14094}
14095
14096
14097#define REHASH( a ) \
14098 if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
14099 hashHaystack -= (a) << sl_minus_1; \
14100 hashHaystack <<= 1
14101
14102/*!
14103 \overload
14104
14105 Finds the first occurrence of the string \a str, starting at
14106 position \a index. If \a index is -1, the search starts at the
14107 last character, if it is -2, at the next to last character and so
14108 on. (See findRev() for searching backwards.)
14109
14110 If \a cs is TRUE, the search is case sensitive; otherwise the
14111 search is case insensitive.
14112
14113 Returns the position of \a str or -1 if \a str could not be found.
14114*/
14115
14116int QString::find( const QString& str, int index, bool cs ) const
14117{
14118 const uint l = length();
14119 const uint sl = str.length();
14120 if ( index < 0 )
14121 index += l;
14122 if ( sl + index > l )
14123 return -1;
14124 if ( !sl )
14125 return index;
14126
14127 if ( sl == 1 )
14128 return find( *str.unicode(), index, cs );
14129
14130 // we use the Boyer-Moore algorithm in cases where the overhead
14131 // for the hash table should pay off, otherwise we use a simple
14132 // hash function
14133 if ( l > 500 && sl > 5 ) {
14134 uint skiptable[0x100];
14135 bm_init_skiptable( str, skiptable, cs );
14136 return bm_find( *this, index, str, skiptable, cs );
14137 }
14138
14139 /*
14140 We use some hashing for efficiency's sake. Instead of
14141 comparing strings, we compare the hash value of str with that of
14142 a part of this QString. Only if that matches, we call ucstrncmp
14143 or ucstrnicmp.
14144 */
14145 const QChar* needle = str.unicode();
14146 const QChar* haystack = unicode() + index;
14147 const QChar* end = unicode() + (l-sl);
14148 const uint sl_minus_1 = sl-1;
14149 uint hashNeedle = 0, hashHaystack = 0, i;
14150
14151 if ( cs ) {
14152 for ( i = 0; i < sl; ++i ) {
14153 hashNeedle = ((hashNeedle<<1) + needle[i].unicode() );
14154 hashHaystack = ((hashHaystack<<1) + haystack[i].unicode() );
14155 }
14156 hashHaystack -= (haystack+sl_minus_1)->unicode();
14157
14158 while ( haystack <= end ) {
14159 hashHaystack += (haystack+sl_minus_1)->unicode();
14160 if ( hashHaystack == hashNeedle
14161 && ucstrncmp( needle, haystack, sl ) == 0 )
14162 return haystack-unicode();
14163
14164 REHASH( haystack->unicode() );
14165 ++haystack;
14166 }
14167 } else {
14168 for ( i = 0; i < sl; ++i ) {
14169 hashNeedle = ((hashNeedle<<1) +
14170 ::lower( needle[i].unicode() ).unicode() );
14171 hashHaystack = ((hashHaystack<<1) +
14172 ::lower( haystack[i].unicode() ).unicode() );
14173 }
14174
14175 hashHaystack -= ::lower(*(haystack+sl_minus_1)).unicode();
14176 while ( haystack <= end ) {
14177 hashHaystack += ::lower(*(haystack+sl_minus_1)).unicode();
14178 if ( hashHaystack == hashNeedle
14179 && ucstrnicmp( needle, haystack, sl ) == 0 )
14180 return haystack-unicode();
14181
14182 REHASH( ::lower(*haystack).unicode() );
14183 ++haystack;
14184 }
14185 }
14186 return -1;
14187}
14188
14189/*!
14190 \fn int QString::findRev( const char* str, int index ) const
14191
14192 Equivalent to findRev(QString(\a str), \a index).
14193*/
14194
14195/*!
14196 \fn int QString::find( const char* str, int index ) const
14197
14198 \overload
14199
14200 Equivalent to find(QString(\a str), \a index).
14201*/
14202
14203/*!
14204 \overload
14205
14206 Finds the first occurrence of the character \a c, starting at
14207 position \a index and searching backwards. If the index is -1, the
14208 search starts at the last character, if it is -2, at the next to
14209 last character and so on.
14210
14211 Returns the position of \a c or -1 if \a c could not be found.
14212
14213 If \a cs is TRUE, the search is case sensitive; otherwise the
14214 search is case insensitive.
14215
14216 \code
14217 QString string( "bananas" );
14218 int i = string.findRev( 'a' ); // i == 5
14219 \endcode
14220*/
14221
14222int QString::findRev( QChar c, int index, bool cs ) const
14223{
14224 const uint l = length();
14225 if ( index < 0 )
14226 index += l;
14227 if ( (uint)index >= l )
14228 return -1;
14229 const QChar *end = unicode();
14230 register const QChar *uc = end + index;
14231 if ( cs ) {
14232 while ( uc >= end && *uc != c )
14233 uc--;
14234 } else {
14235 c = ::lower( c );
14236 while ( uc >= end && ::lower( *uc ) != c )
14237 uc--;
14238 }
14239 return uc - end;
14240}
14241
14242/*!
14243 \overload
14244
14245 Finds the first occurrence of the string \a str, starting at
14246 position \a index and searching backwards. If the index is -1, the
14247 search starts at the last character, if it is -2, at the next to
14248 last character and so on.
14249
14250 Returns the position of \a str or -1 if \a str could not be found.
14251
14252 If \a cs is TRUE, the search is case sensitive; otherwise the
14253 search is case insensitive.
14254
14255 \code
14256 QString string("bananas");
14257 int i = string.findRev( "ana" ); // i == 3
14258 \endcode
14259*/
14260
14261int QString::findRev( const QString& str, int index, bool cs ) const
14262{
14263 /*
14264 See QString::find() for explanations.
14265 */
14266 const uint l = length();
14267 if ( index < 0 )
14268 index += l;
14269 const uint sl = str.length();
14270 int delta = l-sl;
14271 if ( index < 0 || index > (int)l || delta < 0 )
14272 return -1;
14273 if ( index > delta )
14274 index = delta;
14275
14276 if ( sl == 1 )
14277 return findRev( *str.unicode(), index, cs );
14278
14279 const QChar* needle = str.unicode();
14280 const QChar* haystack = unicode() + index;
14281 const QChar* end = unicode();
14282 const uint sl_minus_1 = sl-1;
14283 const QChar* n = needle+sl_minus_1;
14284 const QChar* h = haystack+sl_minus_1;
14285 uint hashNeedle = 0, hashHaystack = 0, i;
14286
14287 if ( cs ) {
14288 for ( i = 0; i < sl; ++i ) {
14289 hashNeedle = ((hashNeedle<<1) + (n-i)->unicode() );
14290 hashHaystack = ((hashHaystack<<1) + (h-i)->unicode() );
14291 }
14292 hashHaystack -= haystack->unicode();
14293
14294 while ( haystack >= end ) {
14295 hashHaystack += haystack->unicode();
14296 if ( hashHaystack == hashNeedle
14297 && ucstrncmp( needle, haystack, sl ) == 0 )
14298 return haystack-unicode();
14299 --haystack;
14300 REHASH( (haystack+sl)->unicode() );
14301 }
14302 } else {
14303 for ( i = 0; i < sl; ++i ) {
14304 hashNeedle = ((hashNeedle<<1)
14305 + ::lower( (n-i)->unicode() ).unicode() );
14306 hashHaystack = ((hashHaystack<<1)
14307 + ::lower( (h-i)->unicode() ).unicode() );
14308 }
14309 hashHaystack -= ::lower(*haystack).unicode();
14310
14311 while ( haystack >= end ) {
14312 hashHaystack += ::lower(*haystack).unicode();
14313 if ( hashHaystack == hashNeedle
14314 && ucstrnicmp( needle, haystack, sl ) == 0 )
14315 return haystack-unicode();
14316 --haystack;
14317 REHASH( ::lower(*(haystack+sl)).unicode() );
14318 }
14319 }
14320 return -1;
14321}
14322
14323#undef REHASH
14324
14325/*!
14326 \enum QString::SectionFlags
14327
14328 \value SectionDefault Empty fields are counted, leading and
14329 trailing separators are not included, and the separator is
14330 compared case sensitively.
14331
14332 \value SectionSkipEmpty Treat empty fields as if they don't exist,
14333 i.e. they are not considered as far as \e start and \e end are
14334 concerned.
14335
14336 \value SectionIncludeLeadingSep Include the leading separator (if
14337 any) in the result string.
14338
14339 \value SectionIncludeTrailingSep Include the trailing separator
14340 (if any) in the result string.
14341
14342 \value SectionCaseInsensitiveSeps Compare the separator
14343 case-insensitively.
14344
14345 Any of the last four values can be OR-ed together to form a flag.
14346
14347 \sa section()
14348*/
14349
14350/*!
14351 \fn QString QString::section( QChar sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const
14352
14353 This function returns a section of the string.
14354
14355 This string is treated as a sequence of fields separated by the
14356 character, \a sep. The returned string consists of the fields from
14357 position \a start to position \a end inclusive. If \a end is not
14358 specified, all fields from position \a start to the end of the
14359 string are included. Fields are numbered 0, 1, 2, etc., counting
14360 from the left, and -1, -2, etc., counting from right to left.
14361
14362 The \a flags argument can be used to affect some aspects of the
14363 function's behaviour, e.g. whether to be case sensitive, whether
14364 to skip empty fields and how to deal with leading and trailing
14365 separators; see \l{SectionFlags}.
14366
14367 \code
14368 QString csv( "forename,middlename,surname,phone" );
14369 QString s = csv.section( ',', 2, 2 ); // s == "surname"
14370
14371 QString path( "/usr/local/bin/myapp" ); // First field is empty
14372 QString s = path.section( '/', 3, 4 ); // s == "bin/myapp"
14373 QString s = path.section( '/', 3, 3, SectionSkipEmpty ); // s == "myapp"
14374 \endcode
14375
14376 If \a start or \a end is negative, we count fields from the right
14377 of the string, the right-most field being -1, the one from
14378 right-most field being -2, and so on.
14379
14380 \code
14381 QString csv( "forename,middlename,surname,phone" );
14382 QString s = csv.section( ',', -3, -2 ); // s == "middlename,surname"
14383
14384 QString path( "/usr/local/bin/myapp" ); // First field is empty
14385 QString s = path.section( '/', -1 ); // s == "myapp"
14386 \endcode
14387
14388 \sa QStringList::split()
14389*/
14390
14391/*!
14392 \overload
14393
14394 This function returns a section of the string.
14395
14396 This string is treated as a sequence of fields separated by the
14397 string, \a sep. The returned string consists of the fields from
14398 position \a start to position \a end inclusive. If \a end is not
14399 specified, all fields from position \a start to the end of the
14400 string are included. Fields are numbered 0, 1, 2, etc., counting
14401 from the left, and -1, -2, etc., counting from right to left.
14402
14403 The \a flags argument can be used to affect some aspects of the
14404 function's behaviour, e.g. whether to be case sensitive, whether
14405 to skip empty fields and how to deal with leading and trailing
14406 separators; see \l{SectionFlags}.
14407
14408 \code
14409 QString data( "forename**middlename**surname**phone" );
14410 QString s = data.section( "**", 2, 2 ); // s == "surname"
14411 \endcode
14412
14413 If \a start or \a end is negative, we count fields from the right
14414 of the string, the right-most field being -1, the one from
14415 right-most field being -2, and so on.
14416
14417 \code
14418 QString data( "forename**middlename**surname**phone" );
14419 QString s = data.section( "**", -3, -2 ); // s == "middlename**surname"
14420 \endcode
14421
14422 \sa QStringList::split()
14423*/
14424
14425QString QString::section( const QString &sep, int start, int end, int flags ) const
14426{
14427 const QChar *uc = unicode();
14428 if ( !uc )
14429 return QString();
14430 QString _sep = (flags & SectionCaseInsensitiveSeps) ? sep.lower() : sep;
14431 const QChar *uc_sep = _sep.unicode();
14432 if(!uc_sep)
14433 return QString();
14434 bool match = FALSE, last_match = TRUE;
14435
14436 //find start
14437 int n = length(), sep_len = _sep.length();
14438 const QChar *begin = start < 0 ? uc + n : uc;
14439 while(start) {
14440 match = FALSE;
14441 int c = 0;
14442 for(const QChar *tmp = start < 0 ? begin - sep_len : begin;
14443 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
14444 if(flags & SectionCaseInsensitiveSeps) {
14445 if( ::lower( *tmp ) != *(uc_sep + c))
14446 break;
14447 } else {
14448 if( *tmp != *(uc_sep + c) )
14449 break;
14450 }
14451 if(c == sep_len - 1) {
14452 match = TRUE;
14453 break;
14454 }
14455 }
14456 if(start > 0 && (flags & SectionSkipEmpty) && match && last_match)
14457 match = FALSE;
14458 last_match = match;
14459
14460 if(start < 0) {
14461 if(match) {
14462 begin -= sep_len;
14463 if(!++start)
14464 break;
14465 } else {
14466 if(start == -1 && begin == uc)
14467 break;
14468 begin--;
14469 }
14470 } else {
14471 if(match) {
14472 if(!--start)
14473 break;
14474 begin += sep_len;
14475 } else {
14476 if(start == 1 && begin == uc + n)
14477 break;
14478 begin++;
14479 }
14480 }
14481 if(begin > uc + n || begin < uc)
14482 return QString();
14483 }
14484 if(match && !(flags & SectionIncludeLeadingSep))
14485 begin+=sep_len;
14486 if(begin > uc + n || begin < uc)
14487 return QString();
14488
14489 //now find last
14490 match = FALSE;
14491 const QChar *last = end < 0 ? uc + n : uc;
14492 if(end == -1) {
14493 int c = 0;
14494 for(const QChar *tmp = end < 0 ? last - sep_len : last;
14495 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
14496 if(flags & SectionCaseInsensitiveSeps) {
14497 if( ::lower( *tmp ) != *(uc_sep + c))
14498 break;
14499 } else {
14500 if( *tmp != *(uc_sep + c) )
14501 break;
14502 }
14503 if(c == sep_len - 1) {
14504 match = TRUE;
14505 break;
14506 }
14507 }
14508 } else {
14509 end++;
14510 last_match = TRUE;
14511 while(end) {
14512 match = FALSE;
14513 int c = 0;
14514 for(const QChar *tmp = end < 0 ? last - sep_len : last;
14515 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
14516 if(flags & SectionCaseInsensitiveSeps) {
14517 if( ::lower( *tmp ) != *(uc_sep + c))
14518 break;
14519 } else {
14520 if( *tmp != *(uc_sep + c) )
14521 break;
14522 }
14523 if(c == sep_len - 1) {
14524 match = TRUE;
14525 break;
14526 }
14527 }
14528 if(end > 0 && (flags & SectionSkipEmpty) && match && last_match)
14529 match = FALSE;
14530 last_match = match;
14531
14532 if(end < 0) {
14533 if(match) {
14534 if(!++end)
14535 break;
14536 last -= sep_len;
14537 } else {
14538 last--;
14539 }
14540 } else {
14541 if(match) {
14542 last += sep_len;
14543 if(!--end)
14544 break;
14545 } else {
14546 last++;
14547 }
14548 }
14549 if(last >= uc + n) {
14550 last = uc + n;
14551 break;
14552 } else if(last < uc) {
14553 return QString();
14554 }
14555 }
14556 }
14557 if(match && !(flags & SectionIncludeTrailingSep))
14558 last -= sep_len;
14559 if(last < uc || last > uc + n || begin >= last)
14560 return QString();
14561
14562 //done
14563 return QString(begin, last - begin);
14564}
14565
14566#ifndef QT_NO_REGEXP
14567class section_chunk {
14568public:
14569 section_chunk(int l, QString s) { length = l; string = s; }
14570 int length;
14571 QString string;
14572};
14573/*!
14574 \overload
14575
14576 This function returns a section of the string.
14577
14578 This string is treated as a sequence of fields separated by the
14579 regular expression, \a reg. The returned string consists of the
14580 fields from position \a start to position \a end inclusive. If \a
14581 end is not specified, all fields from position \a start to the end
14582 of the string are included. Fields are numbered 0, 1, 2, etc., counting
14583 from the left, and -1, -2, etc., counting from right to left.
14584
14585 The \a flags argument can be used to affect some aspects of the
14586 function's behaviour, e.g. whether to be case sensitive, whether
14587 to skip empty fields and how to deal with leading and trailing
14588 separators; see \l{SectionFlags}.
14589
14590 \code
14591 QString line( "forename\tmiddlename surname \t \t phone" );
14592 QRegExp sep( "\s+" );
14593 QString s = line.section( sep, 2, 2 ); // s == "surname"
14594 \endcode
14595
14596 If \a start or \a end is negative, we count fields from the right
14597 of the string, the right-most field being -1, the one from
14598 right-most field being -2, and so on.
14599
14600 \code
14601 QString line( "forename\tmiddlename surname \t \t phone" );
14602 QRegExp sep( "\\s+" );
14603 QString s = line.section( sep, -3, -2 ); // s == "middlename surname"
14604 \endcode
14605
14606 \warning Using this QRegExp version is much more expensive than
14607 the overloaded string and character versions.
14608
14609 \sa QStringList::split() simplifyWhiteSpace()
14610*/
14611
14612QString QString::section( const QRegExp &reg, int start, int end, int flags ) const
14613{
14614 const QChar *uc = unicode();
14615 if(!uc)
14616 return QString();
14617
14618 QRegExp sep(reg);
14619 sep.setCaseSensitive(!(flags & SectionCaseInsensitiveSeps));
14620
14621 QPtrList<section_chunk> l;
14622 l.setAutoDelete(TRUE);
14623 int n = length(), m = 0, last_m = 0, last = 0, last_len = 0;
14624
14625 while( ( m = sep.search( *this, m ) ) != -1 ) {
14626 l.append(new section_chunk(last_len, QString(uc + last_m, m - last_m)));
14627 last_m = m;
14628 last_len = sep.matchedLength();
14629 if((m += sep.matchedLength()) >= n) {
14630 last = 1;
14631 break;
14632 }
14633 }
14634 if(!last)
14635 l.append(new section_chunk(last_len, QString(uc + last_m, n - last_m)));
14636
14637 if(start < 0)
14638 start = l.count() + start;
14639 if(end == -1)
14640 end = l.count();
14641 else if(end < 0)
14642 end = l.count() + end;
14643
14644 int i = 0;
14645 QString ret;
14646 for ( section_chunk *chk=l.first(); chk; chk=l.next(), i++ ) {
14647 if((flags & SectionSkipEmpty) && chk->length == (int)chk->string.length()) {
14648 if(i <= start)
14649 start++;
14650 end++;
14651 }
14652 if(i == start) {
14653 ret = (flags & SectionIncludeLeadingSep) ? chk->string : chk->string.mid(chk->length);
14654 } else if(i > start) {
14655 ret += chk->string;
14656 }
14657 if(i == end) {
14658 if((chk=l.next()) && flags & SectionIncludeTrailingSep)
14659 ret += chk->string.left(chk->length);
14660 break;
14661 }
14662 }
14663 return ret;
14664}
14665#endif
14666
14667/*!
14668 \fn QString QString::section( char sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const
14669
14670 \overload
14671*/
14672
14673/*!
14674 \fn QString QString::section( const char *sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const
14675
14676 \overload
14677*/
14678
14679
14680/*!
14681 Returns the number of times the character \a c occurs in the
14682 string.
14683
14684 If \a cs is TRUE, the search is case sensitive; otherwise the
14685 search is case insensitive.
14686
14687 \code
14688 QString string( "Trolltech and Qt" );
14689 int i = string.contains( 't', FALSE ); // i == 3
14690 \endcode
14691*/
14692
14693int QString::contains( QChar c, bool cs ) const
14694{
14695 int count = 0;
14696 const QChar *uc = unicode();
14697 if ( !uc )
14698 return 0;
14699 int n = length();
14700 if ( cs ) {
14701 while ( n-- )
14702 if ( *uc++ == c )
14703 count++;
14704 } else {
14705 c = ::lower( c );
14706 while ( n-- ) {
14707 if ( ::lower( *uc ) == c )
14708 count++;
14709 uc++;
14710 }
14711 }
14712 return count;
14713}
14714
14715/*!
14716 \overload
14717
14718 Returns the number of times the string \a str occurs in the string.
14719
14720 If \a cs is TRUE, the search is case sensitive; otherwise the
14721 search is case insensitive.
14722*/
14723int QString::contains( const char* str, bool cs ) const
14724{
14725 return contains( QString(str), cs );
14726}
14727
14728/*!
14729 \fn int QString::contains( char c, bool cs ) const
14730
14731 \overload
14732*/
14733
14734/*!
14735 \fn int QString::find( char c, int index, bool cs ) const
14736
14737 \overload
14738
14739 Find character \a c starting from position \a index.
14740
14741 If \a cs is TRUE, the search is case sensitive; otherwise the
14742 search is case insensitive.
14743*/
14744
14745/*!
14746 \fn int QString::findRev( char c, int index, bool cs ) const
14747
14748 \overload
14749
14750 Find character \a c starting from position \a index and working
14751 backwards.
14752
14753 If \a cs is TRUE, the search is case sensitive; otherwise the
14754 search is case insensitive.
14755*/
14756
14757/*!
14758 \overload
14759
14760 Returns the number of times \a str occurs in the string.
14761
14762 If \a cs is TRUE, the search is case sensitive; otherwise the
14763 search is case insensitive.
14764
14765 This function counts overlapping strings, so in the example below,
14766 there are two instances of "ana" in "bananas".
14767
14768 \code
14769 QString str( "bananas" );
14770 int i = str.contains( "ana" ); // i == 2
14771 \endcode
14772
14773 \sa findRev()
14774*/
14775
14776int QString::contains( const QString &str, bool cs ) const
14777{
14778 if ( isNull() )
14779 return 0;
14780 int count = 0;
14781 uint skiptable[0x100];
14782 bm_init_skiptable( str, skiptable, cs );
14783 int i = -1;
14784 // use boyer-moore for the ultimate speed experience
14785 while ( ( i = bm_find( *this, i+1, str, skiptable, cs ) ) != -1 )
14786 count++;
14787 return count;
14788}
14789
14790/*!
14791 Returns a substring that contains the \a len leftmost characters
14792 of the string.
14793
14794 The whole string is returned if \a len exceeds the length of the
14795 string.
14796
14797 \code
14798 QString s = "Pineapple";
14799 QString t = s.left( 4 ); // t == "Pine"
14800 \endcode
14801
14802 \sa right(), mid(), isEmpty()
14803*/
14804
14805QString QString::left( uint len ) const
14806{
14807 if ( isEmpty() ) {
14808 return QString();
14809 } else if ( len == 0 ) { // ## just for 1.x compat:
14810 return fromLatin1( "" );
14811 } else if ( len >= length() ) {
14812 return *this;
14813 } else {
14814 QString s( len, TRUE );
14815 memcpy( s.d->unicode, d->unicode, len * sizeof(QChar) );
14816 s.d->len = len;
14817 return s;
14818 }
14819}
14820
14821/*!
14822 Returns a string that contains the \a len rightmost characters of
14823 the string.
14824
14825 If \a len is greater than the length of the string then the whole
14826 string is returned.
14827
14828 \code
14829 QString string( "Pineapple" );
14830 QString t = string.right( 5 ); // t == "apple"
14831 \endcode
14832
14833 \sa left(), mid(), isEmpty()
14834*/
14835
14836QString QString::right( uint len ) const
14837{
14838 if ( isEmpty() ) {
14839 return QString();
14840 } else if ( len == 0 ) { // ## just for 1.x compat:
14841 return fromLatin1( "" );
14842 } else {
14843 uint l = length();
14844 if ( len >= l )
14845 return *this;
14846 QString s( len, TRUE );
14847 memcpy( s.d->unicode, d->unicode+(l-len), len*sizeof(QChar) );
14848 s.d->len = len;
14849 return s;
14850 }
14851}
14852
14853/*!
14854 Returns a string that contains the \a len characters of this
14855 string, starting at position \a index.
14856
14857 Returns a null string if the string is empty or \a index is out of
14858 range. Returns the whole string from \a index if \a index + \a len
14859 exceeds the length of the string.
14860
14861 \code
14862 QString s( "Five pineapples" );
14863 QString t = s.mid( 5, 4 ); // t == "pine"
14864 \endcode
14865
14866 \sa left(), right()
14867*/
14868
14869QString QString::mid( uint index, uint len ) const
14870{
14871 uint slen = length();
14872 if ( isEmpty() || index >= slen ) {
14873 return QString();
14874 } else if ( len == 0 ) { // ## just for 1.x compat:
14875 return fromLatin1( "" );
14876 } else {
14877 if ( len > slen-index )
14878 len = slen - index;
14879 if ( index == 0 && len == slen )
14880 return *this;
14881 register const QChar *p = unicode()+index;
14882 QString s( len, TRUE );
14883 memcpy( s.d->unicode, p, len * sizeof(QChar) );
14884 s.d->len = len;
14885 return s;
14886 }
14887}
14888
14889/*!
14890 Returns a string of length \a width that contains this string
14891 padded by the \a fill character.
14892
14893 If \a truncate is FALSE and the length of the string is more than
14894 \a width, then the returned string is a copy of the string.
14895
14896 If \a truncate is TRUE and the length of the string is more than
14897 \a width, then any characters in a copy of the string after length
14898 \a width are removed, and the copy is returned.
14899
14900 \code
14901 QString s( "apple" );
14902 QString t = s.leftJustify( 8, '.' ); // t == "apple..."
14903 \endcode
14904
14905 \sa rightJustify()
14906*/
14907
14908QString QString::leftJustify( uint width, QChar fill, bool truncate ) const
14909{
14910 QString result;
14911 int len = length();
14912 int padlen = width - len;
14913 if ( padlen > 0 ) {
14914 result.setLength(len+padlen);
14915 if ( len )
14916 memcpy( result.d->unicode, unicode(), sizeof(QChar)*len );
14917 QChar* uc = result.d->unicode + len;
14918 while (padlen--)
14919 *uc++ = fill;
14920 } else {
14921 if ( truncate )
14922 result = left( width );
14923 else
14924 result = *this;
14925 }
14926 return result;
14927}
14928
14929/*!
14930 Returns a string of length \a width that contains the \a fill
14931 character followed by the string.
14932
14933 If \a truncate is FALSE and the length of the string is more than
14934 \a width, then the returned string is a copy of the string.
14935
14936 If \a truncate is TRUE and the length of the string is more than
14937 \a width, then the resulting string is truncated at position \a
14938 width.
14939
14940 \code
14941 QString string( "apple" );
14942 QString t = string.rightJustify( 8, '.' ); // t == "...apple"
14943 \endcode
14944
14945 \sa leftJustify()
14946*/
14947
14948QString QString::rightJustify( uint width, QChar fill, bool truncate ) const
14949{
14950 QString result;
14951 int len = length();
14952 int padlen = width - len;
14953 if ( padlen > 0 ) {
14954 result.setLength( len+padlen );
14955 QChar* uc = result.d->unicode;
14956 while (padlen--)
14957 *uc++ = fill;
14958 if ( len )
14959 memcpy( uc, unicode(), sizeof(QChar)*len );
14960 } else {
14961 if ( truncate )
14962 result = left( width );
14963 else
14964 result = *this;
14965 }
14966 return result;
14967}
14968
14969/*!
14970 Returns a lowercase copy of the string.
14971
14972 \code
14973 QString string( "TROlltECH" );
14974 str = string.lower(); // str == "trolltech"
14975 \endcode
14976
14977 \sa upper()
14978*/
14979
14980QString QString::lower() const
14981{
14982 QString s(*this);
14983 int l=length();
14984 if ( l ) {
14985 s.real_detach(); // could do this only when we find a change
14986 register QChar *p=s.d->unicode;
14987 if ( p ) {
14988 while ( l-- ) {
14989 *p = ::lower( *p );
14990 p++;
14991 }
14992 }
14993 }
14994 return s;
14995}
14996
14997/*!
14998 Returns an uppercase copy of the string.
14999
15000 \code
15001 QString string( "TeXt" );
15002 str = string.upper(); // t == "TEXT"
15003 \endcode
15004
15005 \sa lower()
15006*/
15007
15008QString QString::upper() const
15009{
15010 QString s(*this);
15011 int l=length();
15012 if ( l ) {
15013 s.real_detach(); // could do this only when we find a change
15014 register QChar *p=s.d->unicode;
15015 if ( p ) {
15016 while ( l-- ) {
15017 *p = ::upper( *p );
15018 p++;
15019 }
15020 }
15021 }
15022 return s;
15023}
15024
15025
15026/*!
15027 Returns a string that has whitespace removed from the start and
15028 the end.
15029
15030 Whitespace means any character for which QChar::isSpace() returns
15031 TRUE. This includes Unicode characters with decimal values 9
15032 (TAB), 10 (LF), 11 (VT), 12 (FF), 13 (CR) and 32 (Space), and may
15033 also include other Unicode characters.
15034
15035 \code
15036 QString string = " white space ";
15037 QString s = string.stripWhiteSpace(); // s == "white space"
15038 \endcode
15039
15040 \sa simplifyWhiteSpace()
15041*/
15042
15043QString QString::stripWhiteSpace() const
15044{
15045 if ( isEmpty() ) // nothing to do
15046 return *this;
15047 register const QChar *s = unicode();
15048 if ( !s->isSpace() && !s[length()-1].isSpace() )
15049 return *this;
15050
15051 int start = 0;
15052 int end = length() - 1;
15053 while ( start<=end && s[start].isSpace() ) // skip white space from start
15054 start++;
15055 if ( start <= end ) { // only white space
15056 while ( end && s[end].isSpace() ) // skip white space from end
15057 end--;
15058 }
15059 int l = end - start + 1;
15060 if ( l <= 0 )
15061 return QString::fromLatin1("");
15062
15063 QString result( l, TRUE );
15064 memcpy( result.d->unicode, &s[start], sizeof(QChar)*l );
15065 result.d->len = l;
15066 return result;
15067}
15068
15069
15070/*!
15071 Returns a string that has whitespace removed from the start and
15072 the end, and which has each sequence of internal whitespace
15073 replaced with a single space.
15074
15075 Whitespace means any character for which QChar::isSpace() returns
15076 TRUE. This includes Unicode characters with decimal values 9
15077 (TAB), 10 (LF), 11 (VT), 12 (FF), 13 (CR), and 32 (Space).
15078
15079 \code
15080 QString string = " lots\t of\nwhite space ";
15081 QString t = string.simplifyWhiteSpace();
15082 // t == "lots of white space"
15083 \endcode
15084
15085 \sa stripWhiteSpace()
15086*/
15087
15088QString QString::simplifyWhiteSpace() const
15089{
15090 if ( isEmpty() )
15091 return *this;
15092 QString result;
15093 result.setLength( length() );
15094 const QChar *from = unicode();
15095 const QChar *fromend = from+length();
15096 int outc=0;
15097 QChar *to = result.d->unicode;
15098 for (;;) {
15099 while ( from!=fromend && from->isSpace() )
15100 from++;
15101 while ( from!=fromend && !from->isSpace() )
15102 to[outc++] = *from++;
15103 if ( from!=fromend )
15104 to[outc++] = ' ';
15105 else
15106 break;
15107 }
15108 if ( outc > 0 && to[outc-1] == ' ' )
15109 outc--;
15110 result.truncate( outc );
15111 return result;
15112}
15113
15114
15115/*!
15116 Inserts \a s into the string at position \a index.
15117
15118 If \a index is beyond the end of the string, the string is
15119 extended with spaces to length \a index and \a s is then appended
15120 and returns a reference to the string.
15121
15122 \code
15123 QString string( "I like fish" );
15124 str = string.insert( 2, "don't " );
15125 // str == "I don't like fish"
15126 \endcode
15127
15128 \sa remove(), replace()
15129*/
15130
15131QString &QString::insert( uint index, const QString &s )
15132{
15133 // the sub function takes care of &s == this case.
15134 return insert( index, s.unicode(), s.length() );
15135}
15136
15137/*!
15138 \overload
15139
15140 Inserts the character in \a s into the string at position \a index
15141 \a len number of times and returns a reference to the string.
15142*/
15143
15144QString &QString::insert( uint index, const QChar* s, uint len )
15145{
15146 if ( len == 0 )
15147 return *this;
15148 uint olen = length();
15149 int nlen = olen + len;
15150
15151 if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
15152 // Part of me - take a copy.
15153 QChar *tmp = QT_ALLOC_QCHAR_VEC( len );
15154 memcpy(tmp,s,len*sizeof(QChar));
15155 insert(index,tmp,len);
15156 QT_DELETE_QCHAR_VEC( tmp );
15157 return *this;
15158 }
15159
15160 if ( index >= olen ) { // insert after end of string
15161 setLength( len + index );
15162 int n = index - olen;
15163 QChar* uc = d->unicode+olen;
15164 while (n--)
15165 *uc++ = ' ';
15166 memcpy( d->unicode+index, s, sizeof(QChar)*len );
15167 } else { // normal insert
15168 setLength( nlen );
15169 memmove( d->unicode + index + len, unicode() + index,
15170 sizeof(QChar) * (olen - index) );
15171 memcpy( d->unicode + index, s, sizeof(QChar) * len );
15172 }
15173 return *this;
15174}
15175
15176/*!
15177 \overload
15178
15179 Insert \a c into the string at position \a index and returns a
15180 reference to the string.
15181
15182 If \a index is beyond the end of the string, the string is
15183 extended with spaces (ASCII 32) to length \a index and \a c is
15184 then appended.
15185*/
15186
15187QString &QString::insert( uint index, QChar c ) // insert char
15188{
15189 QString s( c );
15190 return insert( index, s );
15191}
15192
15193/*!
15194 \fn QString& QString::insert( uint index, char c )
15195
15196 \overload
15197
15198 Insert character \a c at position \a index.
15199*/
15200
15201/*!
15202 \fn QString &QString::prepend( const QString &s )
15203
15204 Inserts \a s at the beginning of the string and returns a
15205 reference to the string.
15206
15207 Equivalent to insert(0, \a s).
15208
15209 \code
15210 QString string = "42";
15211 string.prepend( "The answer is " );
15212 // string == "The answer is 42"
15213 \endcode
15214
15215 \sa insert()
15216*/
15217
15218/*!
15219 \fn QString& QString::prepend( char ch )
15220
15221 \overload
15222
15223 Inserts \a ch at the beginning of the string and returns a
15224 reference to the string.
15225
15226 Equivalent to insert(0, \a ch).
15227
15228 \sa insert()
15229*/
15230
15231/*!
15232 \fn QString& QString::prepend( QChar ch )
15233
15234 \overload
15235
15236 Inserts \a ch at the beginning of the string and returns a
15237 reference to the string.
15238
15239 Equivalent to insert(0, \a ch).
15240
15241 \sa insert()
15242*/
15243
15244/*! \fn QString& QString::prepend( const QByteArray &s )
15245 \overload
15246
15247 Inserts \a s at the beginning of the string and returns a reference to the string.
15248
15249 Equivalent to insert(0, \a s).
15250
15251 \sa insert()
15252 */
15253
15254/*!
15255 \overload
15256
15257 Inserts \a s at the beginning of the string and returns a reference to the string.
15258
15259 Equivalent to insert(0, \a s).
15260
15261 \sa insert()
15262 */
15263QString &QString::prepend( const char *s )
15264{
15265 return insert( 0, QString(s) );
15266}
15267
15268/*!
15269 Removes \a len characters from the string starting at position \a
15270 index, and returns a reference to the string.
15271
15272 If \a index is beyond the length of the string, nothing happens.
15273 If \a index is within the string, but \a index + \a len is beyond
15274 the end of the string, the string is truncated at position \a
15275 index.
15276
15277 \code
15278 QString string( "Montreal" );
15279 string.remove( 1, 4 ); // string == "Meal"
15280 \endcode
15281
15282 \sa insert(), replace()
15283*/
15284
15285QString &QString::remove( uint index, uint len )
15286{
15287 uint olen = length();
15288 if ( index >= olen ) {
15289 // range problems
15290 } else if ( index + len >= olen ) { // index ok
15291 setLength( index );
15292 } else if ( len != 0 ) {
15293 real_detach();
15294 memmove( d->unicode+index, d->unicode+index+len,
15295 sizeof(QChar)*(olen-index-len) );
15296 setLength( olen-len );
15297 }
15298 return *this;
15299}
15300
15301/*! \overload
15302
15303 Removes every occurrence of the character \a c in the string.
15304 Returns a reference to the string.
15305
15306 This is the same as replace(\a c, "").
15307*/
15308QString &QString::remove( QChar c )
15309{
15310 int i = 0;
15311 while ( i < (int) length() ) {
15312 if ( constref(i) == c ) {
15313 remove( i, 1 );
15314 } else {
15315 i++;
15316 }
15317 }
15318 return *this;
15319}
15320
15321/*! \overload
15322
15323 \fn QString &QString::remove( char c )
15324
15325 Removes every occurrence of the character \a c in the string.
15326 Returns a reference to the string.
15327
15328 This is the same as replace(\a c, "").
15329*/
15330
15331/*! \overload
15332
15333 Removes every occurrence of \a str in the string. Returns a
15334 reference to the string.
15335
15336 This is the same as replace(\a str, "").
15337*/
15338QString &QString::remove( const QString & str )
15339{
15340 int index = 0;
15341 if ( !str.isEmpty() ) {
15342 while ( (index = find(str, index)) != -1 )
15343 remove( index, str.length() );
15344 }
15345 return *this;
15346}
15347
15348/*! \overload
15349
15350 Replaces every occurrence of \a c1 with the char \a c2.
15351 Returns a reference to the string.
15352*/
15353QString &QString::replace( QChar c1, QChar c2 )
15354{
15355 real_detach();
15356 uint i = 0;
15357 while ( i < d->len ) {
15358 if ( d->unicode[i] == c1 )
15359 d->unicode[i] = c2;
15360 i++;
15361 }
15362 return *this;
15363}
15364
15365
15366#ifndef QT_NO_REGEXP_CAPTURE
15367
15368/*! \overload
15369
15370 Removes every occurrence of the regular expression \a rx in the
15371 string. Returns a reference to the string.
15372
15373 This is the same as replace(\a rx, "").
15374*/
15375
15376QString &QString::remove( const QRegExp & rx )
15377{
15378 return replace( rx, QString::null );
15379}
15380
15381#endif
15382
15383/*! \overload
15384
15385 Removes every occurrence of \a str in the string. Returns a
15386 reference to the string.
15387*/
15388QString &QString::remove( const char *str )
15389{
15390 return remove( QString::fromLatin1(str) );
15391}
15392
15393/*!
15394 Replaces \a len characters from the string with \a s, starting at
15395 position \a index, and returns a reference to the string.
15396
15397 If \a index is beyond the length of the string, nothing is deleted
15398 and \a s is appended at the end of the string. If \a index is
15399 valid, but \a index + \a len is beyond the end of the string,
15400 the string is truncated at position \a index, then \a s is
15401 appended at the end.
15402
15403 \code
15404 QString string( "Say yes!" );
15405 string = string.replace( 4, 3, "NO" );
15406 // string == "Say NO!"
15407 \endcode
15408
15409 \sa insert(), remove()
15410*/
15411
15412QString &QString::replace( uint index, uint len, const QString &s )
15413{
15414 return replace( index, len, s.unicode(), s.length() );
15415}
15416
15417/*! \overload
15418
15419 This is the same as replace(\a index, \a len, QString(\a c)).
15420*/
15421QString &QString::replace( uint index, uint len, QChar c )
15422{
15423 return replace( index, len, &c, 1 );
15424}
15425
15426/*! \overload
15427 \fn QString &QString::replace( uint index, uint len, char c )
15428
15429 This is the same as replace(\a index, \a len, QChar(\a c)).
15430*/
15431
15432/*!
15433 \overload
15434
15435 Replaces \a len characters with \a slen characters of QChar data
15436 from \a s, starting at position \a index, and returns a reference
15437 to the string.
15438
15439 \sa insert(), remove()
15440*/
15441
15442QString &QString::replace( uint index, uint len, const QChar* s, uint slen )
15443{
15444 real_detach();
15445 if ( len == slen && index + len <= length() ) {
15446 // Optimized common case: replace without size change
15447 memcpy( d->unicode+index, s, len * sizeof(QChar) );
15448 } else if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
15449 // Part of me - take a copy.
15450 QChar *tmp = QT_ALLOC_QCHAR_VEC( slen );
15451 memcpy( tmp, s, slen * sizeof(QChar) );
15452 replace( index, len, tmp, slen );
15453 QT_DELETE_QCHAR_VEC( tmp );
15454 } else {
15455 remove( index, len );
15456 insert( index, s, slen );
15457 }
15458 return *this;
15459}
15460
15461/*! \overload
15462
15463 Replaces every occurrence of the character \a c in the string
15464 with \a after. Returns a reference to the string.
15465
15466 Example:
15467 \code
15468 QString s = "a,b,c";
15469 s.replace( QChar(','), " or " );
15470 // s == "a or b or c"
15471 \endcode
15472*/
15473QString &QString::replace( QChar c, const QString & after )
15474{
15475 return replace( QString( c ), after );
15476}
15477
15478/*! \overload
15479 \fn QString &QString::replace( char c, const QString & after )
15480
15481 Replaces every occurrence of the character \a c in the string
15482 with \a after. Returns a reference to the string.
15483*/
15484
15485/*! \overload
15486
15487 Replaces every occurrence of the string \a before in the string
15488 with the string \a after. Returns a reference to the string.
15489
15490 Example:
15491 \code
15492 QString s = "Greek is Greek";
15493 s.replace( "Greek", "English" );
15494 // s == "English is English"
15495 \endcode
15496*/
15497QString &QString::replace( const QString & before, const QString & after )
15498{
15499 if ( before == after || isNull() )
15500 return *this;
15501
15502 real_detach();
15503
15504 int index = 0;
15505 uint skiptable[256];
15506 bm_init_skiptable( before, skiptable, TRUE );
15507 const int bl = before.length();
15508 const int al = after.length();
15509
15510 if ( bl == al ) {
15511 if ( bl ) {
15512 const QChar *auc = after.unicode();
15513 while( (index = bm_find(*this, index, before, skiptable, TRUE) ) != -1 ) {
15514 memcpy( d->unicode+index, auc, al*sizeof(QChar) );
15515 index += bl;
15516 }
15517 }
15518 } else if ( al < bl ) {
15519 const QChar *auc = after.unicode();
15520 uint to = 0;
15521 uint movestart = 0;
15522 uint num = 0;
15523 while( (index = bm_find(*this, index, before, skiptable, TRUE) ) != -1 ) {
15524 if ( num ) {
15525 int msize = index - movestart;
15526 if ( msize > 0 ) {
15527 memmove( d->unicode + to, d->unicode + movestart, msize*sizeof(QChar) );
15528 to += msize;
15529 }
15530 } else {
15531 to = index;
15532 }
15533 if ( al ) {
15534 memcpy( d->unicode+to, auc, al*sizeof(QChar) );
15535 to += al;
15536 }
15537 index += bl;
15538 movestart = index;
15539 num++;
15540 }
15541 if ( num ) {
15542 int msize = d->len - movestart;
15543 if ( msize > 0 )
15544 memmove( d->unicode + to, d->unicode + movestart, msize*sizeof(QChar) );
15545 setLength( d->len - num*(bl-al) );
15546 }
15547 } else {
15548 // the most complex case. We don't want to loose performance by doing repeated
15549 // copies and reallocs of the string.
15550 while( index != -1 ) {
15551 uint indices[4096];
15552 uint pos = 0;
15553 while( pos < 4095 ) {
15554 index = bm_find(*this, index, before, skiptable, TRUE);
15555 if ( index == -1 )
15556 break;
15557 indices[pos++] = index;
15558 index += bl;
15559 // avoid infinite loop
15560 if ( !bl )
15561 index++;
15562 }
15563 if ( !pos )
15564 break;
15565
15566 // we have a table of replacement positions, use them for fast replacing
15567 int adjust = pos*(al-bl);
15568 // index has to be adjusted in case we get back into the loop above.
15569 if ( index != -1 )
15570 index += adjust;
15571 uint newlen = d->len + adjust;
15572 int moveend = d->len;
15573 if ( newlen > d->len )
15574 setLength( newlen );
15575
15576 while( pos ) {
15577 pos--;
15578 int movestart = indices[pos] + bl;
15579 int insertstart = indices[pos] + pos*(al-bl);
15580 int moveto = insertstart + al;
15581 memmove( d->unicode + moveto, d->unicode + movestart, (moveend - movestart)*sizeof(QChar) );
15582 memcpy( d->unicode + insertstart, after.unicode(), al*sizeof(QChar) );
15583 moveend = movestart-bl;
15584 }
15585 }
15586 }
15587 return *this;
15588}
15589
15590#ifndef QT_NO_REGEXP_CAPTURE
15591/*! \overload
15592
15593 Replaces every occurrence of the regexp \a rx in the string with \a str.
15594 Returns a reference to the string. For example:
15595 \code
15596 QString s = "banana";
15597 s.replace( QRegExp("an"), "" );
15598 // s == "ba"
15599 \endcode
15600
15601 For regexps containing \link qregexp.html#capturing-text capturing
15602 parentheses \endlink, occurrences of <b>\\1</b>, <b>\\2</b>, ...,
15603 in \a str are replaced with \a{rx}.cap(1), cap(2), ...
15604
15605 \code
15606 QString t = "A <i>bon mot</i>.";
15607 t.replace( QRegExp("<i>([^<]*)</i>"), "\\emph{\\1}" );
15608 // t == "A \\emph{bon mot}."
15609 \endcode
15610
15611 \sa find(), findRev(), QRegExp::cap()
15612*/
15613
15614QString &QString::replace( const QRegExp &rx, const QString &str )
15615{
15616 if ( isNull() )
15617 return *this;
15618
15619 real_detach();
15620
15621 QRegExp rx2 = rx;
15622 int index = 0;
15623 int numCaptures = rx2.numCaptures();
15624 int al = str.length();
15625 QRegExp::CaretMode caretMode = QRegExp::CaretAtZero;
15626
15627 if ( numCaptures > 0 ) {
15628 if ( numCaptures > 9 )
15629 numCaptures = 9;
15630
15631 const QChar *uc = str.unicode();
15632 int numBackRefs = 0;
15633
15634 for ( int i = 0; i < al - 1; i++ ) {
15635 if ( uc[i] == '\\' ) {
15636 int no = uc[i + 1].digitValue();
15637 if ( no > 0 && no <= numCaptures )
15638 numBackRefs++;
15639 }
15640 }
15641
15642 /*
15643 This is the harder case where we have back-references. We
15644 don't try to optimize it.
15645 */
15646 if ( numBackRefs > 0 ) {
15647 int *capturePositions = new int[numBackRefs];
15648 int *captureNumbers = new int[numBackRefs];
15649 int j = 0;
15650
15651 for ( int i = 0; i < al - 1; i++ ) {
15652 if ( uc[i] == '\\' ) {
15653 int no = uc[i + 1].digitValue();
15654 if ( no > 0 && no <= numCaptures ) {
15655 capturePositions[j] = i;
15656 captureNumbers[j] = no;
15657 j++;
15658 }
15659 }
15660 }
15661
15662 while ( index <= (int)length() ) {
15663 index = rx2.search( *this, index, caretMode );
15664 if ( index == -1 )
15665 break;
15666
15667 QString str2 = str;
15668 for ( j = numBackRefs - 1; j >= 0; j-- )
15669 str2.replace( capturePositions[j], 2,
15670 rx2.cap(captureNumbers[j]) );
15671
15672 replace( index, rx2.matchedLength(), str2 );
15673 index += str2.length();
15674
15675 if ( rx2.matchedLength() == 0 ) {
15676 // avoid infinite loop on 0-length matches (e.g., [a-z]*)
15677 index++;
15678 } else if ( index == 0 ) {
15679 caretMode = QRegExp::CaretWontMatch;
15680 }
15681 }
15682 delete[] capturePositions;
15683 delete[] captureNumbers;
15684 return *this;
15685 }
15686 }
15687
15688 /*
15689 This is the simple and optimized case where we don't have
15690 back-references.
15691 */
15692 while ( index != -1 ) {
15693 struct {
15694 int pos;
15695 int length;
15696 } replacements[2048];
15697
15698 uint pos = 0;
15699 int adjust = 0;
15700 while( pos < 2047 ) {
15701 index = rx2.search( *this, index, caretMode );
15702 if ( index == -1 )
15703 break;
15704 int ml = rx2.matchedLength();
15705 replacements[pos].pos = index;
15706 replacements[pos++].length = ml;
15707 index += ml;
15708 adjust += al - ml;
15709 // avoid infinite loop
15710 if ( !ml )
15711 index++;
15712 }
15713 if ( !pos )
15714 break;
15715 replacements[pos].pos = d->len;
15716 uint newlen = d->len + adjust;
15717
15718 // to continue searching at the right position after we did
15719 // the first round of replacements
15720 if ( index != -1 )
15721 index += adjust;
15722 QChar *newuc = QT_ALLOC_QCHAR_VEC( newlen + 1 );
15723 QChar *uc = newuc;
15724 int copystart = 0;
15725 uint i = 0;
15726 while( i < pos ) {
15727 int copyend = replacements[i].pos;
15728 int size = copyend - copystart;
15729 memcpy( uc, d->unicode + copystart, size*sizeof(QChar) );
15730 uc += size;
15731 memcpy( uc, str.unicode(), al*sizeof( QChar ) );
15732 uc += al;
15733 copystart = copyend + replacements[i].length;
15734 i++;
15735 }
15736 memcpy( uc, d->unicode + copystart,
15737 (d->len - copystart) * sizeof(QChar) );
15738 QT_DELETE_QCHAR_VEC( d->unicode );
15739 d->unicode = newuc;
15740 d->len = newlen;
15741 d->maxl = newlen + 1;
15742 d->setDirty();
15743 caretMode = QRegExp::CaretWontMatch;
15744 }
15745 return *this;
15746}
15747#endif
15748
15749#ifndef QT_NO_REGEXP
15750/*!
15751 Finds the first match of the regular expression \a rx, starting
15752 from position \a index. If \a index is -1, the search starts at
15753 the last character; if -2, at the next to last character and so
15754 on. (See findRev() for searching backwards.)
15755
15756 Returns the position of the first match of \a rx or -1 if no match
15757 was found.
15758
15759 \code
15760 QString string( "bananas" );
15761 int i = string.find( QRegExp("an"), 0 ); // i == 1
15762 \endcode
15763
15764 \sa findRev() replace() contains()
15765*/
15766
15767int QString::find( const QRegExp &rx, int index ) const
15768{
15769 return rx.search( *this, index );
15770}
15771
15772/*!
15773 \overload
15774
15775 Finds the first match of the regexp \a rx, starting at position \a
15776 index and searching backwards. If the index is -1, the search
15777 starts at the last character, if it is -2, at the next to last
15778 character and so on. (See findRev() for searching backwards.)
15779
15780 Returns the position of the match or -1 if no match was found.
15781
15782 \code
15783 QString string( "bananas" );
15784 int i = string.findRev( QRegExp("an") ); // i == 3
15785 \endcode
15786
15787 \sa find()
15788*/
15789
15790int QString::findRev( const QRegExp &rx, int index ) const
15791{
15792 return rx.searchRev( *this, index );
15793}
15794
15795/*!
15796 \overload
15797
15798 Returns the number of times the regexp, \a rx, matches in the
15799 string.
15800
15801 This function counts overlapping matches, so in the example below,
15802 there are four instances of "ana" or "ama".
15803
15804 \code
15805 QString str = "banana and panama";
15806 QRegExp rxp = QRegExp( "a[nm]a", TRUE, FALSE );
15807 int i = str.contains( rxp ); // i == 4
15808 \endcode
15809
15810 \sa find() findRev()
15811*/
15812
15813int QString::contains( const QRegExp &rx ) const
15814{
15815 int count = 0;
15816 int index = -1;
15817 int len = length();
15818 while ( index < len - 1 ) { // count overlapping matches
15819 index = rx.search( *this, index + 1 );
15820 if ( index == -1 )
15821 break;
15822 count++;
15823 }
15824 return count;
15825}
15826
15827#endif //QT_NO_REGEXP
15828
15829static bool ok_in_base( QChar c, int base )
15830{
15831 if ( base <= 10 )
15832 return c.isDigit() && c.digitValue() < base;
15833 else
15834 return c.isDigit() || (c >= 'a' && c < char('a'+base-10))
15835 || (c >= 'A' && c < char('A'+base-10));
15836}
15837
15838/*!
15839 Returns the string converted to a \c long value to the base \a
15840 base, which is 10 by default and must be between 2 and 36.
15841
15842 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
15843 FALSE; otherwise \a *ok is set to TRUE.
15844
15845 \sa number()
15846*/
15847
15848long QString::toLong( bool *ok, int base ) const
15849{
15850 const QChar *p = unicode();
15851 long val = 0;
15852 int l = length();
15853 const long max_mult = INT_MAX / base;
15854 bool is_ok = FALSE;
15855 int neg = 0;
15856 if ( !p )
15857 goto bye;
15858 while ( l && p->isSpace() ) // skip leading space
15859 l--,p++;
15860 if ( !l )
15861 goto bye;
15862 if ( *p == '-' ) {
15863 l--;
15864 p++;
15865 neg = 1;
15866 } else if ( *p == '+' ) {
15867 l--;
15868 p++;
15869 }
15870
15871 // NOTE: toULong() code is similar
15872 if ( !l || !ok_in_base(*p,base) )
15873 goto bye;
15874 while ( l && ok_in_base(*p,base) ) {
15875 l--;
15876 int dv;
15877 if ( p->isDigit() ) {
15878 dv = p->digitValue();
15879 } else {
15880 if ( *p >= 'a' && *p <= 'z' )
15881 dv = *p - 'a' + 10;
15882 else
15883 dv = *p - 'A' + 10;
15884 }
15885 if ( val > max_mult ||
15886 (val == max_mult && dv > (INT_MAX % base) + neg) )
15887 goto bye;
15888 val = base * val + dv;
15889 p++;
15890 }
15891 if ( neg )
15892 val = -val;
15893 while ( l && p->isSpace() ) // skip trailing space
15894 l--,p++;
15895 if ( !l )
15896 is_ok = TRUE;
15897bye:
15898 if ( ok )
15899 *ok = is_ok;
15900 return is_ok ? val : 0;
15901}
15902
15903/*!
15904 Returns the string converted to an \c {unsigned long} value to the
15905 base \a base, which is 10 by default and must be between 2 and 36.
15906
15907 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
15908 FALSE; otherwise \a *ok is set to TRUE.
15909
15910 \sa number()
15911*/
15912
15913ulong QString::toULong( bool *ok, int base ) const
15914{
15915 const QChar *p = unicode();
15916 ulong val = 0;
15917 int l = length();
15918 const ulong max_mult = UINT_MAX / base;
15919 bool is_ok = FALSE;
15920 if ( !p )
15921 goto bye;
15922 while ( l && p->isSpace() ) // skip leading space
15923 l--,p++;
15924 if ( !l )
15925 goto bye;
15926 if ( *p == '+' )
15927 l--,p++;
15928
15929 // NOTE: toLong() code is similar
15930 if ( !l || !ok_in_base(*p,base) )
15931 goto bye;
15932 while ( l && ok_in_base(*p,base) ) {
15933 l--;
15934 uint dv;
15935 if ( p->isDigit() ) {
15936 dv = p->digitValue();
15937 } else {
15938 if ( *p >= 'a' && *p <= 'z' )
15939 dv = *p - 'a' + 10;
15940 else
15941 dv = *p - 'A' + 10;
15942 }
15943 if ( val > max_mult || (val == max_mult && dv > UINT_MAX % base) )
15944 goto bye;
15945 val = base * val + dv;
15946 p++;
15947 }
15948
15949 while ( l && p->isSpace() ) // skip trailing space
15950 l--,p++;
15951 if ( !l )
15952 is_ok = TRUE;
15953bye:
15954 if ( ok )
15955 *ok = is_ok;
15956 return is_ok ? val : 0;
15957}
15958
15959/*!
15960 Returns the string converted to a \c short value to the base \a
15961 base, which is 10 by default and must be between 2 and 36.
15962
15963 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
15964 FALSE; otherwise \a *ok is set to TRUE.
15965*/
15966
15967short QString::toShort( bool *ok, int base ) const
15968{
15969 long v = toLong( ok, base );
15970 if ( ok && *ok && (v < -32768 || v > 32767) ) {
15971 *ok = FALSE;
15972 v = 0;
15973 }
15974 return (short)v;
15975}
15976
15977/*!
15978 Returns the string converted to an \c {unsigned short} value to
15979 the base \a base, which is 10 by default and must be between 2 and
15980 36.
15981
15982 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
15983 FALSE; otherwise \a *ok is set to TRUE.
15984*/
15985
15986ushort QString::toUShort( bool *ok, int base ) const
15987{
15988 ulong v = toULong( ok, base );
15989 if ( ok && *ok && (v > 65535) ) {
15990 *ok = FALSE;
15991 v = 0;
15992 }
15993 return (ushort)v;
15994}
15995
15996
15997/*!
15998 Returns the string converted to an \c int value to the base \a
15999 base, which is 10 by default and must be between 2 and 36.
16000
16001 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
16002 FALSE; otherwise \a *ok is set to TRUE.
16003
16004 \code
16005 QString str( "FF" );
16006 bool ok;
16007 int hex = str.toInt( &ok, 16 ); // hex == 255, ok == TRUE
16008 int dec = str.toInt( &ok, 10 ); // dec == 0, ok == FALSE
16009 \endcode
16010
16011 \sa number()
16012*/
16013
16014int QString::toInt( bool *ok, int base ) const
16015{
16016 return (int)toLong( ok, base );
16017}
16018
16019/*!
16020 Returns the string converted to an \c{unsigned int} value to the
16021 base \a base, which is 10 by default and must be between 2 and 36.
16022
16023 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
16024 FALSE; otherwise \a *ok is set to TRUE.
16025
16026 \sa number()
16027*/
16028
16029uint QString::toUInt( bool *ok, int base ) const
16030{
16031 return (uint)toULong( ok, base );
16032}
16033
16034/*!
16035 Returns the string converted to a \c double value.
16036
16037 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
16038 FALSE; otherwise \a *ok is set to TRUE.
16039
16040 \code
16041 QString string( "1234.56" );
16042 double a = string.toDouble(); // a == 1234.56
16043 \endcode
16044
16045 \sa number()
16046*/
16047
16048double QString::toDouble( bool *ok ) const
16049{
16050 char *end;
16051
16052 const char *a = latin1();
16053 double val = strtod( a ? a : "", &end );
16054 if ( ok )
16055 *ok = ( a && *a && (end == 0 || (end - a) == (int)length()) );
16056 return val;
16057}
16058
16059/*!
16060 Returns the string converted to a \c float value.
16061
16062 If \a ok is not 0: if a conversion error occurs, \a *ok is set to
16063 FALSE; otherwise \a *ok is set to TRUE.
16064
16065 \sa number()
16066*/
16067
16068float QString::toFloat( bool *ok ) const
16069{
16070 return (float)toDouble( ok );
16071}
16072
16073
16074/*!
16075 Sets the string to the printed value of \a n in base \a base and
16076 returns a reference to the string.
16077
16078 The base is 10 by default and must be between 2 and 36.
16079
16080 \code
16081 QString string;
16082 string = string.setNum( 1234 ); // string == "1234"
16083 \endcode
16084*/
16085
16086QString &QString::setNum( long n, int base )
16087{
16088#if defined(QT_CHECK_RANGE)
16089 if ( base < 2 || base > 36 ) {
16090 qWarning( "QString::setNum: Invalid base %d", base );
16091 base = 10;
16092 }
16093#endif
16094 char charbuf[65*sizeof(QChar)];
16095 QChar *buf = (QChar*)charbuf;
16096 QChar *p = &buf[64];
16097 int len = 0;
16098 bool neg;
16099 if ( n < 0 ) {
16100 neg = TRUE;
16101 if ( n == INT_MIN ) {
16102 // Cannot always negate this special case
16103 QString s1, s2;
16104 s1.setNum(n/base);
16105 s2.setNum((-(n+base))%base);
16106 *this = s1 + s2;
16107 return *this;
16108 }
16109 n = -n;
16110 } else {
16111 neg = FALSE;
16112 }
16113 do {
16114 *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
16115 n /= base;
16116 ++len;
16117 } while ( n );
16118 if ( neg ) {
16119 *--p = '-';
16120 ++len;
16121 }
16122 return setUnicode( p, len );
16123}
16124
16125/*!
16126 \overload
16127
16128 Sets the string to the printed value of \a n in base \a base and
16129 returns a reference to the string.
16130
16131 The base is 10 by default and must be between 2 and 36.
16132*/
16133
16134QString &QString::setNum( ulong n, int base )
16135{
16136#if defined(QT_CHECK_RANGE)
16137 if ( base < 2 || base > 36 ) {
16138 qWarning( "QString::setNum: Invalid base %d", base );
16139 base = 10;
16140 }
16141#endif
16142 char charbuf[65*sizeof(QChar)];
16143 QChar *buf = (QChar*)charbuf;
16144 QChar *p = &buf[64];
16145 int len = 0;
16146 do {
16147 *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
16148 n /= base;
16149 len++;
16150 } while ( n );
16151 return setUnicode(p,len);
16152}
16153
16154/*!
16155 \fn QString &QString::setNum( int n, int base )
16156
16157 \overload
16158
16159 Sets the string to the printed value of \a n in base \a base and
16160 returns a reference to the string.
16161
16162 The base is 10 by default and must be between 2 and 36.
16163*/
16164
16165/*!
16166 \fn QString &QString::setNum( uint n, int base )
16167
16168 \overload
16169
16170 Sets the string to the printed value of \a n in base \a base and
16171 returns a reference to the string.
16172
16173 The base is 10 by default and must be between 2 and 36.
16174*/
16175
16176/*!
16177 \fn QString &QString::setNum( short n, int base )
16178
16179 \overload
16180
16181 Sets the string to the printed value of \a n in base \a base and
16182 returns a reference to the string.
16183
16184 The base is 10 by default and must be between 2 and 36.
16185*/
16186
16187/*!
16188 \fn QString &QString::setNum( ushort n, int base )
16189
16190 \overload
16191
16192 Sets the string to the printed value of \a n in base \a base and
16193 returns a reference to the string.
16194
16195 The base is 10 by default and must be between 2 and 36.
16196*/
16197
16198/*!
16199 \overload
16200
16201 Sets the string to the printed value of \a n, formatted in format
16202 \a f with precision \a prec, and returns a reference to the
16203 string.
16204
16205 The format \a f can be 'f', 'F', 'e', 'E', 'g' or 'G'. See \link
16206 #arg-formats arg \endlink() for an explanation of the formats.
16207*/
16208
16209QString &QString::setNum( double n, char f, int prec )
16210{
16211#if defined(QT_CHECK_RANGE)
16212 if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') ) {
16213 qWarning( "QString::setNum: Invalid format char '%c'", f );
16214 f = 'f';
16215 }
16216#endif
16217 char format[20];
16218 char *fs = format; // generate format string: %.<prec>l<f>
16219 *fs++ = '%';
16220 if ( prec >= 0 ) {
16221 if ( prec > 99 ) // rather than crash in sprintf()
16222 prec = 99;
16223 *fs++ = '.';
16224 if ( prec >= 10 ) {
16225 *fs++ = prec / 10 + '0';
16226 *fs++ = prec % 10 + '0';
16227 } else {
16228 *fs++ = prec + '0';
16229 }
16230 }
16231 *fs++ = 'l';
16232 *fs++ = f;
16233 *fs = '\0';
16234#ifndef QT_NO_SPRINTF
16235 sprintf( format, n );
16236 return *this;
16237#else
16238 char buf[512];
16239 ::sprintf( buf, format, n ); // snprintf is unfortunately not portable
16240 return setLatin1(buf);
16241#endif
16242}
16243
16244/*!
16245 \fn QString &QString::setNum( float n, char f, int prec )
16246
16247 \overload
16248
16249 Sets the string to the printed value of \a n, formatted in format
16250 \a f with precision \a prec, and returns a reference to the
16251 string.
16252
16253 The format \a f can be 'f', 'F', 'e', 'E', 'g' or 'G'. See \link
16254 #arg-formats arg \endlink() for an explanation of the formats.
16255*/
16256
16257
16258/*!
16259 A convenience function that returns a string equivalent of the
16260 number \a n to base \a base, which is 10 by default and must be
16261 between 2 and 36.
16262
16263 \code
16264 long a = 63;
16265 QString str = QString::number( a, 16 ); // str == "3f"
16266 QString str = QString::number( a, 16 ).upper(); // str == "3F"
16267 \endcode
16268
16269 \sa setNum()
16270*/
16271QString QString::number( long n, int base )
16272{
16273 QString s;
16274 s.setNum( n, base );
16275 return s;
16276}
16277
16278/*!
16279 \overload
16280
16281 \sa setNum()
16282*/
16283QString QString::number( ulong n, int base )
16284{
16285 QString s;
16286 s.setNum( n, base );
16287 return s;
16288}
16289
16290/*!
16291 \overload
16292
16293 \sa setNum()
16294*/
16295QString QString::number( int n, int base )
16296{
16297 QString s;
16298 s.setNum( n, base );
16299 return s;
16300}
16301
16302/*!
16303 \overload
16304
16305 A convenience factory function that returns a string
16306 representation of the number \a n to the base \a base, which is 10
16307 by default and must be between 2 and 36.
16308
16309 \sa setNum()
16310*/
16311QString QString::number( uint n, int base )
16312{
16313 QString s;
16314 s.setNum( n, base );
16315 return s;
16316}
16317
16318/*!
16319 \overload
16320
16321 Argument \a n is formatted according to the \a f format specified,
16322 which is \c g by default, and can be any of the following:
16323
16324 \table
16325 \header \i Format \i Meaning
16326 \row \i \c e \i format as [-]9.9e[+|-]999
16327 \row \i \c E \i format as [-]9.9E[+|-]999
16328 \row \i \c f \i format as [-]9.9
16329 \row \i \c g \i use \c e or \c f format, whichever is the most concise
16330 \row \i \c G \i use \c E or \c f format, whichever is the most concise
16331 \endtable
16332
16333 With 'e', 'E', and 'f', \a prec is the number of digits after the
16334 decimal point. With 'g' and 'G', \a prec is the maximum number of
16335 significant digits (trailing zeroes are omitted).
16336
16337 \code
16338 double d = 12.34;
16339 QString ds = QString( "'E' format, precision 3, gives %1" )
16340 .arg( d, 0, 'E', 3 );
16341 // ds == "1.234E+001"
16342 \endcode
16343
16344 \sa setNum()
16345 */
16346QString QString::number( double n, char f, int prec )
16347{
16348 QString s;
16349 s.setNum( n, f, prec );
16350 return s;
16351}
16352
16353
16354/*! \obsolete
16355
16356 Sets the character at position \a index to \a c and expands the
16357 string if necessary, filling with spaces.
16358
16359 This method is redundant in Qt 3.x, because operator[] will expand
16360 the string as necessary.
16361*/
16362
16363void QString::setExpand( uint index, QChar c )
16364{
16365 int spaces = index - d->len;
16366 at(index) = c;
16367 while (spaces-->0)
16368 d->unicode[--index]=' ';
16369}
16370
16371
16372/*!
16373 \fn const char* QString::data() const
16374
16375 \obsolete
16376
16377 Returns a pointer to a '\0'-terminated classic C string.
16378
16379 In Qt 1.x, this returned a char* allowing direct manipulation of the
16380 string as a sequence of bytes. In Qt 2.x where QString is a Unicode
16381 string, char* conversion constructs a temporary string, and hence
16382 direct character operations are meaningless.
16383*/
16384
16385/*!
16386 \fn bool QString::operator!() const
16387
16388 Returns TRUE if this is a null string; otherwise returns FALSE.
16389
16390 \code
16391 QString name = getName();
16392 if ( !name )
16393 name = "Rodney";
16394 \endcode
16395
16396 Note that if you say
16397
16398 \code
16399 QString name = getName();
16400 if ( name )
16401 doSomethingWith(name);
16402 \endcode
16403
16404 It will call "operator const char*()", which is inefficent; you
16405 may wish to define the macro \c QT_NO_ASCII_CAST when writing code
16406 which you wish to remain Unicode-clean.
16407
16408 When you want the above semantics, use:
16409
16410 \code
16411 QString name = getName();
16412 if ( !name.isNull() )
16413 doSomethingWith(name);
16414 \endcode
16415
16416 \sa isEmpty()
16417*/
16418
16419
16420/*!
16421 \fn QString& QString::append( const QString& str )
16422
16423 Appends \a str to the string and returns a reference to the
16424 result.
16425
16426 \code
16427 string = "Test";
16428 string.append( "ing" ); // string == "Testing"
16429 \endcode
16430
16431 Equivalent to operator+=().
16432*/
16433
16434/*!
16435 \fn QString& QString::append( char ch )
16436
16437 \overload
16438
16439 Appends character \a ch to the string and returns a reference to
16440 the result.
16441
16442 Equivalent to operator+=().
16443*/
16444
16445/*!
16446 \fn QString& QString::append( QChar ch )
16447
16448 \overload
16449
16450 Appends character \a ch to the string and returns a reference to
16451 the result.
16452
16453 Equivalent to operator+=().
16454*/
16455
16456/*! \fn QString& QString::append( const QByteArray &str )
16457 \overload
16458
16459 Appends \a str to the string and returns a reference to the result.
16460
16461 Equivalent to operator+=().
16462 */
16463
16464/*! \fn QString& QString::append( const char *str )
16465 \overload
16466
16467 Appends \a str to the string and returns a reference to the result.
16468
16469 Equivalent to operator+=().
16470 */
16471
16472/*!
16473 Appends \a str to the string and returns a reference to the string.
16474*/
16475QString& QString::operator+=( const QString &str )
16476{
16477 uint len1 = length();
16478 uint len2 = str.length();
16479 if ( len2 ) {
16480 setLength(len1+len2);
16481 memcpy( d->unicode+len1, str.unicode(), sizeof(QChar)*len2 );
16482 } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
16483 *this = fromLatin1( "" );
16484 }
16485 return *this;
16486}
16487
16488/*!
16489 \overload
16490
16491 Appends \a str to the string and returns a reference to the string.
16492*/
16493QString& QString::operator+=( const char *str )
16494{
16495 if ( str ) {
16496 uint len1 = length();
16497 uint len2 = strlen( str );
16498 if ( len2 ) {
16499 setLength(len1+len2);
16500 uint i = 0;
16501 while( i < len2 ) {
16502 d->unicode[len1+i] = str[i];
16503 i++;
16504 }
16505 } else if ( isNull() ) { // ## just for 1.x compat:
16506 *this = fromLatin1( "" );
16507 }
16508 }
16509 return *this;
16510}
16511
16512/*! \overload
16513
16514 Appends \a c to the string and returns a reference to the string.
16515*/
16516
16517QString &QString::operator+=( QChar c )
16518{
16519 setLength(length()+1);
16520 d->unicode[length()-1] = c;
16521 return *this;
16522}
16523
16524/*!
16525 \overload
16526
16527 Appends \a c to the string and returns a reference to the string.
16528*/
16529
16530QString &QString::operator+=( char c )
16531{
16532 setLength(length()+1);
16533 d->unicode[length()-1] = c;
16534 return *this;
16535}
16536
16537/*!
16538 \fn QString &QString::operator+=( const QByteArray &str )
16539 \overload
16540
16541 Appends \a str to the string and returns a reference to the string.
16542*/
16543
16544
16545
16546/*!
16547 \fn char QChar::latin1() const
16548
16549 Returns a latin-1 copy of this character, if this character is in
16550 the latin-1 character set. If not, this function returns 0.
16551*/
16552
16553
16554/*!
16555 Returns a Latin-1 representation of the string. Note that the
16556 returned value is undefined if the string contains non-Latin-1
16557 characters. If you want to convert strings into formats other than
16558 Unicode, see the QTextCodec classes.
16559
16560 This function is mainly useful for boot-strapping legacy code to
16561 use Unicode.
16562
16563 The result remains valid so long as one unmodified copy of the
16564 source string exists.
16565
16566 \sa utf8(), local8Bit()
16567*/
16568const char* QString::latin1() const
16569{
16570 if ( !d->ascii ) {
16571 Q2HELPER(stat_get_ascii++)
16572 Q2HELPER(stat_get_ascii_size+=d->len)
16573 d->ascii = unicodeToAscii( d->unicode, d->len );
16574 }
16575 return d->ascii;
16576}
16577
16578/*!
16579 \fn const char* QString::ascii() const
16580 \obsolete
16581
16582 This function simply calls latin1() and returns the result.
16583*/
16584
16585/*!
16586 Returns the string encoded in UTF8 format.
16587
16588 See QTextCodec for more diverse coding/decoding of Unicode strings.
16589
16590 \sa QString::fromUtf8(), local8Bit(), latin1()
16591*/
16592QCString QString::utf8() const
16593{
16594 int l = length();
16595 int rlen = l*3+1;
16596 QCString rstr(rlen);
16597 uchar* cursor = (uchar*)rstr.data();
16598 const QChar *ch = d->unicode;
16599 for (int i=0; i<l; i++) {
16600 ushort u = ch->unicode();
16601 if ( u < 0x80 ) {
16602 *cursor++ = (uchar)u;
16603 } else {
16604 if ( u < 0x0800 ) {
16605 *cursor++ = 0xc0 | ((uchar) (u >> 6));
16606 } else {
16607 *cursor++ = 0xe0 | ((uchar) (u >> 12));
16608 *cursor++ = 0x80 | ( ((uchar) (u >> 6)) & 0x3f);
16609 }
16610 *cursor++ = 0x80 | ((uchar) (u&0x3f));
16611 }
16612 ch++;
16613 }
16614 rstr.truncate( cursor - (uchar*)rstr.data() );
16615 return rstr;
16616}
16617
16618/*!
16619 Returns the Unicode string decoded from the first \a len
16620 characters of \a utf8, ignoring the rest of \a utf8. If \a len is
16621 -1 then the length of \a utf8 is used. If \a len is bigger than
16622 the length of \a utf8 then it will use the length of \a utf8.
16623
16624 \code
16625 QString str = QString::fromUtf8( "123456789", 5 );
16626 // str == "12345"
16627 \endcode
16628
16629 See QTextCodec for more diverse coding/decoding of Unicode strings.
16630*/
16631QString QString::fromUtf8( const char* utf8, int len )
16632{
16633 if ( !utf8 )
16634 return QString::null;
16635
16636 if ( len < 0 ) len = qstrlen( utf8 );
16637 QString result;
16638 result.setLength( len ); // worst case
16639 QChar *qch = (QChar *)result.unicode();
16640 ushort uc = 0;
16641 int need = 0;
16642 for (int i=0; i<len; i++) {
16643 uchar ch = utf8[i];
16644 if (need) {
16645 if ( (ch&0xc0) == 0x80 ) {
16646 uc = (uc << 6) | (ch & 0x3f);
16647 need--;
16648 if ( !need ) {
16649 *qch = uc;
16650 qch++;
16651 }
16652 } else {
16653 // error
16654 *qch = QChar::replacement;
16655 qch++;
16656 need = 0;
16657 }
16658 } else {
16659 if ( ch < 128 ) {
16660 *qch = ch;
16661 qch++;
16662 } else if ( (ch&0xe0) == 0xc0 ) {
16663 uc = ch &0x1f;
16664 need = 1;
16665 } else if ( (ch&0xf0) == 0xe0 ) {
16666 uc = ch &0x0f;
16667 need = 2;
16668 }
16669 }
16670 }
16671 result.truncate( qch - result.unicode() );
16672 return result;
16673}
16674
16675/*!
16676 Returns the Unicode string decoded from the first \a len
16677 characters of \a chars, ignoring the rest of \a chars. If \a len
16678 is -1 then the length of \a chars is used. If \a len is bigger
16679 than the length of \a chars then it will use the length of \a
16680 chars.
16681
16682 This is the same as the QString(const char*) constructor, but you
16683 can make that constructor invisible if you compile with the define
16684 \c QT_NO_CAST_ASCII, in which case you can explicitly create a
16685 QString from Latin-1 text using this function.
16686
16687 \code
16688 QString str = QString::fromLatin1( "123456789", 5 );
16689 // str == "12345"
16690 \endcode
16691*/
16692QString QString::fromLatin1( const char* chars, int len )
16693{
16694 uint l;
16695 QChar *uc;
16696 if ( len < 0 )
16697 len = -1;
16698 uc = internalAsciiToUnicode( chars, &l, len );
16699 return QString( new QStringData(uc, l, l), TRUE );
16700}
16701
16702/*!
16703 \fn const QChar* QString::unicode() const
16704
16705 Returns the Unicode representation of the string. The result
16706 remains valid until the string is modified.
16707*/
16708
16709/*!
16710 Returns the string encoded in a locale-specific format. On X11,
16711 this is the QTextCodec::codecForLocale(). On Windows, it is a
16712 system-defined encoding. On Mac OS X, this always uses utf8 as the
16713 encoding.
16714
16715 See QTextCodec for more diverse coding/decoding of Unicode
16716 strings.
16717
16718 \sa QString::fromLocal8Bit(), latin1(), utf8()
16719*/
16720
16721
16722QCString QString::local8Bit() const
16723{
16724#ifdef QT_NO_TEXTCODEC
16725 return latin1();
16726#else
16727#ifdef Q_WS_X11
16728 QTextCodec* codec = QTextCodec::codecForLocale();
16729 return codec
16730 ? codec->fromUnicode(*this)
16731 : QCString(latin1());
16732#endif
16733#if defined( Q_WS_MACX )
16734 return utf8();
16735#endif
16736#if defined( Q_WS_MAC9 )
16737 return QCString(latin1()); //I'm evil..
16738#endif
16739#ifdef Q_WS_WIN
16740 return qt_winQString2MB( *this );
16741#endif
16742#ifdef Q_WS_QWS
16743 return utf8(); // ##### if there is ANY 8 bit format supported?
16744#endif
16745#endif
16746}
16747
16748/*!
16749 Returns the Unicode string decoded from the first \a len
16750 characters of \a local8Bit, ignoring the rest of \a local8Bit. If
16751 \a len is -1 then the length of \a local8Bit is used. If \a len is
16752 bigger than the length of \a local8Bit then it will use the length
16753 of \a local8Bit.
16754
16755 \code
16756 QString str = QString::fromLocal8Bit( "123456789", 5 );
16757 // str == "12345"
16758 \endcode
16759
16760 \a local8Bit is assumed to be encoded in a locale-specific format.
16761
16762 See QTextCodec for more diverse coding/decoding of Unicode strings.
16763*/
16764QString QString::fromLocal8Bit( const char* local8Bit, int len )
16765{
16766#ifdef QT_NO_TEXTCODEC
16767 return fromLatin1( local8Bit, len );
16768#else
16769
16770 if ( !local8Bit )
16771 return QString::null;
16772#ifdef Q_WS_X11
16773 QTextCodec* codec = QTextCodec::codecForLocale();
16774 if ( len < 0 ) len = qstrlen(local8Bit);
16775 return codec
16776 ? codec->toUnicode( local8Bit, len )
16777 : fromLatin1( local8Bit, len );
16778#endif
16779#if defined( Q_WS_MAC )
16780 return fromUtf8(local8Bit,len);
16781#endif
16782// Should this be OS_WIN32?
16783#ifdef Q_WS_WIN
16784 if ( len >= 0 ) {
16785 QCString s(local8Bit,len+1);
16786 return qt_winMB2QString(s);
16787 }
16788 return qt_winMB2QString( local8Bit );
16789#endif
16790#ifdef Q_WS_QWS
16791 return fromUtf8(local8Bit,len);
16792#endif
16793#endif // QT_NO_TEXTCODEC
16794}
16795
16796/*!
16797 \fn QString::operator const char *() const
16798
16799 Returns latin1(). Be sure to see the warnings documented in the
16800 latin1() function. Note that for new code which you wish to be
16801 strictly Unicode-clean, you can define the macro \c
16802 QT_NO_ASCII_CAST when compiling your code to hide this function so
16803 that automatic casts are not done. This has the added advantage
16804 that you catch the programming error described in operator!().
16805*/
16806
16807
16808/*!
16809 Returns the QString as a zero terminated array of unsigned shorts
16810 if the string is not null; otherwise returns zero.
16811
16812 The result remains valid so long as one unmodified
16813 copy of the source string exists.
16814*/
16815const unsigned short *QString::ucs2() const
16816{
16817 if ( ! d->unicode )
16818 return 0;
16819 unsigned int len = d->len;
16820 if ( d->maxl < len + 1 ) {
16821 // detach, grow or shrink
16822 Q2HELPER(stat_copy_on_write++)
16823 Q2HELPER(stat_copy_on_write_size += len)
16824 uint newMax = computeNewMax( len + 1 );
16825 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
16826 if ( nd ) {
16827 if ( d->unicode )
16828 memcpy( nd, d->unicode, sizeof(QChar)*len );
16829 ((QString *)this)->deref();
16830 ((QString *)this)->d = new QStringData( nd, len, newMax );
16831 }
16832 }
16833 d->unicode[len] = 0;
16834 return (unsigned short *) d->unicode;
16835}
16836
16837/*!
16838 Constructs a string that is a deep copy of \a str, interpreted as a
16839 UCS2 encoded, zero terminated, Unicode string.
16840
16841 If \a str is 0, then a null string is created.
16842
16843 \sa isNull()
16844*/
16845QString QString::fromUcs2( const unsigned short *str )
16846{
16847 if ( !str ) {
16848 return QString::null;
16849 } else {
16850 int length = 0;
16851 while( str[length] != 0 )
16852 length++;
16853 QChar* uc = QT_ALLOC_QCHAR_VEC( length );
16854 memcpy( uc, str, length*sizeof(QChar) );
16855 return QString( new QStringData( uc, length, length ), TRUE );
16856 }
16857}
16858
16859/*!
16860 \fn QChar QString::at( uint ) const
16861
16862 Returns the character at index \a i, or 0 if \a i is beyond the
16863 length of the string.
16864
16865 \code
16866 const QString string( "abcdefgh" );
16867 QChar ch = string.at( 4 );
16868 // ch == 'e'
16869 \endcode
16870
16871 If the QString is not const (i.e. const QString) or const& (i.e.
16872 const QString &), then the non-const overload of at() will be used
16873 instead.
16874*/
16875
16876/*!
16877 \fn QChar QString::constref(uint i) const
16878
16879 Returns the QChar at index \a i by value.
16880
16881 Equivalent to at(\a i).
16882
16883 \sa ref()
16884*/
16885
16886/*!
16887 \fn QChar& QString::ref(uint i)
16888
16889 Returns the QChar at index \a i by reference, expanding the string
16890 with QChar::null if necessary. The resulting reference can be
16891 assigned to, or otherwise used immediately, but becomes invalid
16892 once furher modifications are made to the string.
16893
16894 \code
16895 QString string("ABCDEF");
16896 QChar ch = string.ref( 3 ); // ch == 'D'
16897 \endcode
16898
16899 \sa constref()
16900*/
16901
16902/*!
16903 \fn QChar QString::operator[]( int ) const
16904
16905 Returns the character at index \a i, or QChar::null if \a i is
16906 beyond the length of the string.
16907
16908 If the QString is not const (i.e., const QString) or const\&
16909 (i.e., const QString\&), then the non-const overload of operator[]
16910 will be used instead.
16911*/
16912
16913/*!
16914 \fn QCharRef QString::operator[]( int )
16915
16916 \overload
16917
16918 The function returns a reference to the character at index \a i.
16919 The resulting reference can then be assigned to, or used
16920 immediately, but it will become invalid once further modifications
16921 are made to the original string.
16922
16923 If \a i is beyond the length of the string then the string is
16924 expanded with QChar::nulls, so that the QCharRef references a
16925 valid (null) character in the string.
16926
16927 The QCharRef internal class can be used much like a constant
16928 QChar, but if you assign to it, you change the original string
16929 (which will detach itself because of QString's copy-on-write
16930 semantics). You will get compilation errors if you try to use the
16931 result as anything but a QChar.
16932*/
16933
16934/*!
16935 \fn QCharRef QString::at( uint i )
16936
16937 \overload
16938
16939 The function returns a reference to the character at index \a i.
16940 The resulting reference can then be assigned to, or used
16941 immediately, but it will become invalid once further modifications
16942 are made to the original string.
16943
16944 If \a i is beyond the length of the string then the string is
16945 expanded with QChar::null.
16946*/
16947
16948/*
16949 Internal chunk of code to handle the
16950 uncommon cases of at() above.
16951*/
16952void QString::subat( uint i )
16953{
16954 uint olen = d->len;
16955 if ( i >= olen ) {
16956 setLength( i+1 ); // i is index; i+1 is needed length
16957 for ( uint j=olen; j<=i; j++ )
16958 d->unicode[j] = QChar::null;
16959 } else {
16960 // Just be sure to detach
16961 real_detach();
16962 }
16963}
16964
16965
16966/*!
16967 Resizes the string to \a len characters and copies \a unicode into
16968 the string. If \a unicode is 0, nothing is copied, but the
16969 string is still resized to \a len. If \a len is zero, then the
16970 string becomes a \link isNull() null\endlink string.
16971
16972 \sa setLatin1(), isNull()
16973*/
16974
16975QString& QString::setUnicode( const QChar *unicode, uint len )
16976{
16977 if ( len == 0 ) { // set to null string
16978 if ( d != shared_null ) { // beware of nullstring being set to nullstring
16979 deref();
16980 d = shared_null ? shared_null : makeSharedNull();
16981 d->ref();
16982 }
16983 } else if ( d->count != 1 || len > d->maxl ||
16984 ( len * 4 < d->maxl && d->maxl > 4 ) ) {
16985 // detach, grown or shrink
16986 Q2HELPER(stat_copy_on_write++)
16987 Q2HELPER(stat_copy_on_write_size+=d->len)
16988 uint newMax = computeNewMax( len );
16989 QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
16990 if ( unicode )
16991 memcpy( nd, unicode, sizeof(QChar)*len );
16992 deref();
16993 d = new QStringData( nd, len, newMax );
16994 } else {
16995 d->len = len;
16996 d->setDirty();
16997 if ( unicode )
16998 memcpy( d->unicode, unicode, sizeof(QChar)*len );
16999 }
17000 return *this;
17001}
17002
17003/*!
17004 Resizes the string to \a len characters and copies \a
17005 unicode_as_ushorts into the string (on some X11 client platforms
17006 this will involve a byte-swapping pass).
17007
17008 If \a unicode_as_ushorts is 0, nothing is copied, but the string
17009 is still resized to \a len. If \a len is zero, the string becomes
17010 a \link isNull() null\endlink string.
17011
17012 \sa setLatin1(), isNull()
17013*/
17014QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len )
17015{
17016 return setUnicode((const QChar*)unicode_as_ushorts, len);
17017}
17018
17019
17020/*!
17021 Sets this string to \a str, interpreted as a classic Latin1 C
17022 string. If \a len is -1 (the default), then it is set to
17023 strlen(str).
17024
17025 If \a str is 0 a null string is created. If \a str is "", an empty
17026 string is created.
17027
17028 \sa isNull(), isEmpty()
17029*/
17030
17031QString &QString::setLatin1( const char *str, int len )
17032{
17033 if ( str == 0 )
17034 return setUnicode(0,0);
17035 if ( len < 0 )
17036 len = qstrlen(str);
17037 if ( len == 0 ) { // won't make a null string
17038 *this = QString::fromLatin1( "" );
17039 } else {
17040 setUnicode( 0, len ); // resize but not copy
17041 QChar *p = d->unicode;
17042 while ( len-- )
17043 *p++ = *str++;
17044 }
17045 return *this;
17046}
17047
17048/*! \internal
17049 */
17050void QString::checkSimpleText() const
17051{
17052 QChar *p = d->unicode;
17053 QChar *end = p + d->len;
17054 d->simpletext = 1;
17055 while( p < end ) {
17056 ushort uc = p->unicode();
17057 // sort out regions of complex text formatting
17058 if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) {
17059 d->simpletext = 0;
17060 return;
17061 }
17062 p++;
17063 }
17064}
17065
17066/*! \fn bool QString::simpleText() const
17067 \internal
17068*/
17069
17070/*! \internal
17071 */
17072bool QString::isRightToLeft() const
17073{
17074 int len = length();
17075 QChar *p = d->unicode;
17076 while( len-- ) {
17077 switch( ::direction( *p ) )
17078 {
17079 case QChar::DirL:
17080 case QChar::DirLRO:
17081 case QChar::DirLRE:
17082 return FALSE;
17083 case QChar::DirR:
17084 case QChar::DirAL:
17085 case QChar::DirRLO:
17086 case QChar::DirRLE:
17087 return TRUE;
17088 default:
17089 break;
17090 }
17091 ++p;
17092 }
17093 return FALSE;
17094}
17095
17096
17097/*!
17098 \fn int QString::compare( const QString & s1, const QString & s2 )
17099
17100 Lexically compares \a s1 with \a s2 and returns an integer less
17101 than, equal to, or greater than zero if \a s1 is less than, equal
17102 to, or greater than \a s2.
17103
17104 The comparison is based exclusively on the numeric Unicode values
17105 of the characters and is very fast, but is not what a human would
17106 expect. Consider sorting user-interface strings with
17107 QString::localeAwareCompare().
17108
17109 \code
17110 int a = QString::compare( "def", "abc" ); // a > 0
17111 int b = QString::compare( "abc", "def" ); // b < 0
17112 int c = QString::compare(" abc", "abc" ); // c == 0
17113 \endcode
17114*/
17115
17116/*!
17117 \overload
17118
17119 Lexically compares this string with \a s and returns an integer
17120 less than, equal to, or greater than zero if it is less than, equal
17121 to, or greater than \a s.
17122*/
17123int QString::compare( const QString& s ) const
17124{
17125 return ucstrcmp( *this, s );
17126}
17127
17128/*!
17129 \fn int QString::localeAwareCompare( const QString & s1, const QString & s2 )
17130
17131 Compares \a s1 with \a s2 and returns an integer less than, equal
17132 to, or greater than zero if \a s1 is less than, equal to, or
17133 greater than \a s2.
17134
17135 The comparison is performed in a locale- and also
17136 platform-dependent manner. Use this function to present sorted
17137 lists of strings to the user.
17138
17139 \sa QString::compare() QTextCodec::locale()
17140*/
17141
17142/*!
17143 \overload
17144
17145 Compares this string with \a s.
17146*/
17147
17148#if !defined(CSTR_LESS_THAN)
17149#define CSTR_LESS_THAN 1
17150#define CSTR_EQUAL 2
17151#define CSTR_GREATER_THAN 3
17152#endif
17153
17154int QString::localeAwareCompare( const QString& s ) const
17155{
17156 // do the right thing for null and empty
17157 if ( isEmpty() || s.isEmpty() )
17158 return compare( s );
17159
17160#if defined(Q_WS_WIN)
17161 int res;
17162 QT_WA( {
17163 const TCHAR* s1 = (TCHAR*)ucs2();
17164 const TCHAR* s2 = (TCHAR*)s.ucs2();
17165 res = CompareStringW( LOCALE_USER_DEFAULT, 0, s1, length(), s2, s.length() );
17166 } , {
17167 QCString s1 = local8Bit();
17168 QCString s2 = s.local8Bit();
17169 res = CompareStringA( LOCALE_USER_DEFAULT, 0, s1.data(), s1.length(), s2.data(), s2.length() );
17170 } );
17171
17172 switch ( res ) {
17173 case CSTR_LESS_THAN:
17174 return -1;
17175 case CSTR_GREATER_THAN:
17176 return 1;
17177 default:
17178 return 0;
17179 }
17180#elif defined(Q_WS_X11)
17181 // declared in <string.h>
17182 int delta = strcoll( local8Bit(), s.local8Bit() );
17183 if ( delta == 0 )
17184 delta = ucstrcmp( *this, s );
17185 return delta;
17186#else
17187 return ucstrcmp( *this, s );
17188#endif
17189}
17190
17191bool operator==( const QString &s1, const QString &s2 )
17192{
17193 if ( s1.unicode() == s2.unicode() )
17194 return TRUE;
17195 return (s1.length() == s2.length()) && s1.isNull() == s2.isNull() &&
17196 (memcmp((char*)s1.unicode(),(char*)s2.unicode(),
17197 s1.length()*sizeof(QChar)) == 0 );
17198}
17199
17200bool operator!=( const QString &s1, const QString &s2 )
17201{ return !(s1==s2); }
17202
17203bool operator<( const QString &s1, const QString &s2 )
17204{ return ucstrcmp(s1,s2) < 0; }
17205
17206bool operator<=( const QString &s1, const QString &s2 )
17207{ return ucstrcmp(s1,s2) <= 0; }
17208
17209bool operator>( const QString &s1, const QString &s2 )
17210{ return ucstrcmp(s1,s2) > 0; }
17211
17212bool operator>=( const QString &s1, const QString &s2 )
17213{ return ucstrcmp(s1,s2) >= 0; }
17214
17215
17216bool operator==( const QString &s1, const char *s2 )
17217{
17218 if ( !s2 )
17219 return s1.isNull();
17220
17221 int len = s1.length();
17222 const QChar *uc = s1.unicode();
17223 while ( len ) {
17224 if ( !(*s2) || uc->unicode() != (uchar) *s2 )
17225 return FALSE;
17226 ++uc;
17227 ++s2;
17228 --len;
17229 }
17230 return !*s2;
17231}
17232
17233bool operator==( const char *s1, const QString &s2 )
17234{ return (s2 == s1); }
17235
17236bool operator!=( const QString &s1, const char *s2 )
17237{ return !(s1==s2); }
17238
17239bool operator!=( const char *s1, const QString &s2 )
17240{ return !(s1==s2); }
17241
17242bool operator<( const QString &s1, const char *s2 )
17243{ return ucstrcmp(s1,s2) < 0; }
17244
17245bool operator<( const char *s1, const QString &s2 )
17246{ return ucstrcmp(s1,s2) < 0; }
17247
17248bool operator<=( const QString &s1, const char *s2 )
17249{ return ucstrcmp(s1,s2) <= 0; }
17250
17251bool operator<=( const char *s1, const QString &s2 )
17252{ return ucstrcmp(s1,s2) <= 0; }
17253
17254bool operator>( const QString &s1, const char *s2 )
17255{ return ucstrcmp(s1,s2) > 0; }
17256
17257bool operator>( const char *s1, const QString &s2 )
17258{ return ucstrcmp(s1,s2) > 0; }
17259
17260bool operator>=( const QString &s1, const char *s2 )
17261{ return ucstrcmp(s1,s2) >= 0; }
17262
17263bool operator>=( const char *s1, const QString &s2 )
17264{ return ucstrcmp(s1,s2) >= 0; }
17265
17266
17267/*****************************************************************************
17268 Documentation for QString related functions
17269 *****************************************************************************/
17270
17271/*!
17272 \fn bool operator==( const QString &s1, const QString &s2 )
17273
17274 \relates QString
17275
17276 Returns TRUE if \a s1 is equal to \a s2; otherwise returns FALSE.
17277 Note that a null string is not equal to a not-null empty string.
17278
17279 Equivalent to compare(\a s1, \a s2) != 0.
17280
17281 \sa isNull(), isEmpty()
17282*/
17283
17284/*!
17285 \fn bool operator==( const QString &s1, const char *s2 )
17286
17287 \overload
17288 \relates QString
17289
17290 Returns TRUE if \a s1 is equal to \a s2; otherwise returns FALSE.
17291 Note that a null string is not equal to a not-null empty string.
17292
17293 Equivalent to compare(\a s1, \a s2) == 0.
17294
17295 \sa isNull(), isEmpty()
17296*/
17297
17298/*!
17299 \fn bool operator==( const char *s1, const QString &s2 )
17300
17301 \overload
17302 \relates QString
17303
17304 Returns TRUE if \a s1 is equal to \a s2; otherwise returns FALSE.
17305 Note that a null string is not equal to a not-null empty string.
17306
17307 Equivalent to compare(\a s1, \a s2) == 0.
17308
17309 \sa isNull(), isEmpty()
17310*/
17311
17312/*!
17313 \fn bool operator!=( const QString &s1, const QString &s2 )
17314
17315 \relates QString
17316
17317 Returns TRUE if \a s1 is not equal to \a s2; otherwise returns FALSE.
17318 Note that a null string is not equal to a not-null empty string.
17319
17320 Equivalent to compare(\a s1, \a s2) != 0.
17321
17322 \sa isNull(), isEmpty()
17323*/
17324
17325/*!
17326 \fn bool operator!=( const QString &s1, const char *s2 )
17327
17328 \overload
17329 \relates QString
17330
17331 Returns TRUE if \a s1 is not equal to \a s2; otherwise returns FALSE.
17332 Note that a null string is not equal to a not-null empty string.
17333
17334 Equivalent to compare(\a s1, \a s2) != 0.
17335
17336 \sa isNull(), isEmpty()
17337*/
17338
17339/*!
17340 \fn bool operator!=( const char *s1, const QString &s2 )
17341
17342 \overload
17343 \relates QString
17344
17345 Returns TRUE if \a s1 is not equal to \a s2; otherwise returns FALSE.
17346 Note that a null string is not equal to a not-null empty string.
17347
17348 Equivalent to compare(\a s1, \a s2) != 0.
17349
17350 \sa isNull(), isEmpty()
17351*/
17352
17353/*!
17354 \fn bool operator<( const QString &s1, const char *s2 )
17355
17356 \relates QString
17357
17358 Returns TRUE if \a s1 is lexically less than \a s2; otherwise returns FALSE.
17359 The comparison is case sensitive.
17360
17361 Equivalent to compare(\a s1, \a s2) \< 0.
17362*/
17363
17364/*!
17365 \fn bool operator<( const char *s1, const QString &s2 )
17366
17367 \overload
17368 \relates QString
17369
17370 Returns TRUE if \a s1 is lexically less than \a s2; otherwise returns FALSE.
17371 The comparison is case sensitive.
17372
17373 Equivalent to compare(\a s1, \a s2) \< 0.
17374*/
17375
17376/*!
17377 \fn bool operator<=( const QString &s1, const char *s2 )
17378
17379 \relates QString
17380
17381 Returns TRUE if \a s1 is lexically less than or equal to \a s2;
17382 otherwise returns FALSE.
17383 The comparison is case sensitive.
17384 Note that a null string is not equal to a not-null empty string.
17385
17386 Equivalent to compare(\a s1,\a s2) \<= 0.
17387
17388 \sa isNull(), isEmpty()
17389*/
17390
17391/*!
17392 \fn bool operator<=( const char *s1, const QString &s2 )
17393
17394 \overload
17395 \relates QString
17396
17397 Returns TRUE if \a s1 is lexically less than or equal to \a s2;
17398 otherwise returns FALSE.
17399 The comparison is case sensitive.
17400 Note that a null string is not equal to a not-null empty string.
17401
17402 Equivalent to compare(\a s1, \a s2) \<= 0.
17403
17404 \sa isNull(), isEmpty()
17405*/
17406
17407/*!
17408 \fn bool operator>( const QString &s1, const char *s2 )
17409
17410 \relates QString
17411
17412 Returns TRUE if \a s1 is lexically greater than \a s2; otherwise
17413 returns FALSE.
17414 The comparison is case sensitive.
17415
17416 Equivalent to compare(\a s1, \a s2) \> 0.
17417*/
17418
17419/*!
17420 \fn bool operator>( const char *s1, const QString &s2 )
17421
17422 \overload
17423 \relates QString
17424
17425 Returns TRUE if \a s1 is lexically greater than \a s2; otherwise
17426 returns FALSE.
17427 The comparison is case sensitive.
17428
17429 Equivalent to compare(\a s1, \a s2) \> 0.
17430*/
17431
17432/*!
17433 \fn bool operator>=( const QString &s1, const char *s2 )
17434
17435 \relates QString
17436
17437 Returns TRUE if \a s1 is lexically greater than or equal to \a s2;
17438 otherwise returns FALSE.
17439 The comparison is case sensitive.
17440 Note that a null string is not equal to a not-null empty string.
17441
17442 Equivalent to compare(\a s1, \a s2) \>= 0.
17443
17444 \sa isNull(), isEmpty()
17445*/
17446
17447/*!
17448 \fn bool operator>=( const char *s1, const QString &s2 )
17449
17450 \overload
17451 \relates QString
17452
17453 Returns TRUE if \a s1 is lexically greater than or equal to \a s2;
17454 otherwise returns FALSE.
17455 The comparison is case sensitive.
17456 Note that a null string is not equal to a not-null empty string.
17457
17458 Equivalent to compare(\a s1, \a s2) \>= 0.
17459
17460 \sa isNull(), isEmpty()
17461*/
17462
17463/*!
17464 \fn const QString operator+( const QString &s1, const QString &s2 )
17465
17466 \relates QString
17467
17468 Returns a string which is the result of concatenating the string
17469 \a s1 and the string \a s2.
17470
17471 Equivalent to \a {s1}.append(\a s2).
17472*/
17473
17474/*!
17475 \fn const QString operator+( const QString &s1, const char *s2 )
17476
17477 \overload
17478 \relates QString
17479
17480 Returns a string which is the result of concatenating the string
17481 \a s1 and character \a s2.
17482
17483 Equivalent to \a {s1}.append(\a s2).
17484*/
17485
17486/*!
17487 \fn const QString operator+( const char *s1, const QString &s2 )
17488
17489 \overload
17490 \relates QString
17491
17492 Returns a string which is the result of concatenating the
17493 character \a s1 and string \a s2.
17494*/
17495
17496/*!
17497 \fn const QString operator+( const QString &s, char c )
17498
17499 \overload
17500 \relates QString
17501
17502 Returns a string which is the result of concatenating the string
17503 \a s and character \a c.
17504
17505 Equivalent to \a {s}.append(\a c).
17506*/
17507
17508/*!
17509 \fn const QString operator+( char c, const QString &s )
17510
17511 \overload
17512 \relates QString
17513
17514 Returns a string which is the result of concatenating the
17515 character \a c and string \a s.
17516
17517 Equivalent to \a {s}.prepend(\a c).
17518*/
17519
17520
17521/*****************************************************************************
17522 QString stream functions
17523 *****************************************************************************/
17524#ifndef QT_NO_DATASTREAM
17525/*!
17526 \relates QString
17527
17528 Writes the string \a str to the stream \a s.
17529
17530 See also \link datastreamformat.html Format of the QDataStream operators \endlink
17531*/
17532
17533QDataStream &operator<<( QDataStream &s, const QString &str )
17534{
17535 if ( s.version() == 1 ) {
17536 QCString l( str.latin1() );
17537 s << l;
17538 }
17539 else {
17540 int byteOrder = s.byteOrder();
17541 const QChar* ub = str.unicode();
17542 if ( ub || s.version() < 3 ) {
17543 static const uint auto_size = 1024;
17544 char t[auto_size];
17545 char *b;
17546 if ( str.length()*sizeof(QChar) > auto_size ) {
17547 b = new char[str.length()*sizeof(QChar)];
17548 } else {
17549 b = t;
17550 }
17551 int l = str.length();
17552 char *c=b;
17553 while ( l-- ) {
17554 if ( byteOrder == QDataStream::BigEndian ) {
17555 *c++ = (char)ub->row();
17556 *c++ = (char)ub->cell();
17557 } else {
17558 *c++ = (char)ub->cell();
17559 *c++ = (char)ub->row();
17560 }
17561 ub++;
17562 }
17563 s.writeBytes( b, sizeof(QChar)*str.length() );
17564 if ( str.length()*sizeof(QChar) > auto_size )
17565 delete [] b;
17566 } else {
17567 // write null marker
17568 s << (Q_UINT32)0xffffffff;
17569 }
17570 }
17571 return s;
17572}
17573
17574/*!
17575 \relates QString
17576
17577 Reads a string from the stream \a s into string \a str.
17578
17579 See also \link datastreamformat.html Format of the QDataStream operators \endlink
17580*/
17581
17582QDataStream &operator>>( QDataStream &s, QString &str )
17583{
17584#ifdef QT_QSTRING_UCS_4
17585#if defined(Q_CC_GNU)
17586#warning "operator>> not working properly"
17587#endif
17588#endif
17589 if ( s.version() == 1 ) {
17590 QCString l;
17591 s >> l;
17592 str = QString( l );
17593 }
17594 else {
17595 Q_UINT32 bytes;
17596 s >> bytes; // read size of string
17597 if ( bytes == 0xffffffff ) { // null string
17598 str = QString::null;
17599 } else if ( bytes > 0 ) { // not empty
17600 int byteOrder = s.byteOrder();
17601 str.setLength( bytes/2 );
17602 QChar* ch = str.d->unicode;
17603 static const uint auto_size = 1024;
17604 char t[auto_size];
17605 char *b;
17606 if ( bytes > auto_size ) {
17607 b = new char[bytes];
17608 } else {
17609 b = t;
17610 }
17611 s.readRawBytes( b, bytes );
17612 int bt = bytes/2;
17613 char *oldb = b;
17614 while ( bt-- ) {
17615 if ( byteOrder == QDataStream::BigEndian )
17616 *ch++ = (ushort) (((ushort)b[0])<<8) | (uchar)b[1];
17617 else
17618 *ch++ = (ushort) (((ushort)b[1])<<8) | (uchar)b[0];
17619 b += 2;
17620 }
17621 if ( bytes > auto_size )
17622 delete [] oldb;
17623 } else {
17624 str = "";
17625 }
17626 }
17627 return s;
17628}
17629#endif // QT_NO_DATASTREAM
17630
17631/*****************************************************************************
17632 QConstString member functions
17633 *****************************************************************************/
17634
17635/*!
17636 \class QConstString qstring.h
17637 \reentrant
17638 \ingroup text
17639 \brief The QConstString class provides string objects using constant Unicode data.
17640
17641 In order to minimize copying, highly optimized applications can
17642 use QConstString to provide a QString-compatible object from
17643 existing Unicode data. It is then the programmer's responsibility
17644 to ensure that the Unicode data exists for the entire lifetime of
17645 the QConstString object.
17646
17647 A QConstString is created with the QConstString constructor. The
17648 string held by the object can be obtained by calling string().
17649*/
17650
17651/*!
17652 Constructs a QConstString that uses the first \a length Unicode
17653 characters in the array \a unicode. Any attempt to modify copies
17654 of the string will cause it to create a copy of the data, thus it
17655 remains forever unmodified.
17656
17657 The data in \a unicode is not copied. The caller must be able to
17658 guarantee that \a unicode will not be deleted or modified.
17659*/
17660QConstString::QConstString( const QChar* unicode, uint length ) :
17661 QString( new QStringData( (QChar*)unicode, length, length ), TRUE )
17662{
17663}
17664
17665/*!
17666 Destroys the QConstString, creating a copy of the data if other
17667 strings are still using it.
17668*/
17669QConstString::~QConstString()
17670{
17671 if ( d->count > 1 ) {
17672 QChar* cp = QT_ALLOC_QCHAR_VEC( d->len );
17673 memcpy( cp, d->unicode, d->len*sizeof(QChar) );
17674 d->unicode = cp;
17675 } else {
17676 d->unicode = 0;
17677 }
17678
17679 // The original d->unicode is now unlinked.
17680}
17681
17682/*!
17683 \fn const QString& QConstString::string() const
17684
17685 Returns a constant string referencing the data passed during
17686 construction.
17687*/
17688
17689/*!
17690 Returns TRUE if the string starts with \a s; otherwise returns
17691 FALSE.
17692
17693 \code
17694 QString string("Bananas");
17695 bool a = string.startsWith("Ban"); // a == TRUE
17696 \endcode
17697
17698 \sa endsWith()
17699*/
17700bool QString::startsWith( const QString& s ) const
17701{
17702 if ( isNull() )
17703 return s.isNull();
17704 if ( s.length() > length() )
17705 return FALSE;
17706 for ( int i =0; i < (int) s.length(); i++ ) {
17707 if ( d->unicode[i] != s[i] )
17708 return FALSE;
17709 }
17710 return TRUE;
17711}
17712
17713/*!
17714 Returns TRUE if the string ends with \a s; otherwise returns
17715 FALSE.
17716
17717 \sa startsWith()
17718*/
17719bool QString::endsWith( const QString& s ) const
17720{
17721 if ( isNull() )
17722 return s.isNull();
17723 int pos = length() - s.length();
17724 if ( pos < 0 )
17725 return FALSE;
17726 for ( uint i = 0; i < s.length(); i++ ) {
17727 if ( d->unicode[pos+i] != s[(int)i] )
17728 return FALSE;
17729 }
17730 return TRUE;
17731}
17732
17733/*! \fn void QString::detach()
17734 If the string does not share its data with another QString instance,
17735 nothing happens; otherwise the function creates a new, unique copy of
17736 this string. This function is called whenever the map is modified. The
17737 implicit sharing mechanism is implemented this way.
17738*/
17739
17740#if defined(Q_OS_WIN32)
17741
17742#include <windows.h>
17743
17744/*!
17745 \obsolete
17746
17747 Returns a static Windows TCHAR* from a QString, adding NUL if \a
17748 addnul is TRUE.
17749
17750 The lifetime of the return value is until the next call to this function,
17751 or until the last copy of str is deleted, whatever comes first.
17752
17753 Use ucs2() instead.
17754*/
17755const void* qt_winTchar(const QString& str, bool)
17756{
17757 // So that the return value lives long enough.
17758 static QString str_cache;
17759 str_cache = str;
17760#ifdef UNICODE
17761 return str_cache.ucs2();
17762#else
17763 return str_cache.latin1();
17764#endif
17765}
17766
17767/*!
17768 Makes a new '\0'-terminated Windows TCHAR* from a QString.
17769*/
17770void* qt_winTchar_new(const QString& str)
17771{
17772 if ( str.isNull() )
17773 return 0;
17774 int l = str.length()+1;
17775 TCHAR *tc = new TCHAR[ l ];
17776#ifdef UNICODE
17777 memcpy( tc, str.ucs2(), sizeof(TCHAR)*l );
17778#else
17779 memcpy( tc, str.latin1(), sizeof(TCHAR)*l );
17780#endif
17781 return tc;
17782}
17783
17784/*!
17785 Makes a QString from a Windows TCHAR*.
17786*/
17787QString qt_winQString(void* tc)
17788{
17789#ifdef UNICODE
17790 return QString::fromUcs2( (ushort*)tc );
17791#else
17792 return QString::fromLatin1( (TCHAR *)tc );
17793#endif
17794}
17795
17796QCString qt_winQString2MB( const QString& s, int uclen )
17797{
17798 if ( uclen < 0 )
17799 uclen = s.length();
17800 if ( s.isNull() )
17801 return QCString();
17802 if ( uclen == 0 )
17803 return QCString("");
17804 BOOL used_def;
17805 QCString mb(4096);
17806 int len;
17807 while ( !(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)s.unicode(), uclen,
17808 mb.data(), mb.size()-1, 0, &used_def)) )
17809 {
17810 int r = GetLastError();
17811 if ( r == ERROR_INSUFFICIENT_BUFFER ) {
17812 mb.resize(1+WideCharToMultiByte( CP_ACP, 0,
17813 (const WCHAR*)s.unicode(), uclen,
17814 0, 0, 0, &used_def));
17815 // and try again...
17816 } else {
17817#ifndef QT_NO_DEBUG
17818 // Fail.
17819 qWarning("WideCharToMultiByte cannot convert multibyte text (error %d): %s (UTF8)",
17820 r, s.utf8().data());
17821#endif
17822 break;
17823 }
17824 }
17825 mb[len]='\0';
17826 return mb;
17827}
17828
17829// WATCH OUT: mblen must include the NUL (or just use -1)
17830QString qt_winMB2QString( const char* mb, int mblen )
17831{
17832 if ( !mb || !mblen )
17833 return QString::null;
17834 const int wclen_auto = 4096;
17835 WCHAR wc_auto[wclen_auto];
17836 int wclen = wclen_auto;
17837 WCHAR *wc = wc_auto;
17838 int len;
17839 while ( !(len=MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
17840 mb, mblen, wc, wclen )) )
17841 {
17842 int r = GetLastError();
17843 if ( r == ERROR_INSUFFICIENT_BUFFER ) {
17844 if ( wc != wc_auto ) {
17845 qWarning("Size changed in MultiByteToWideChar");
17846 break;
17847 } else {
17848 wclen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
17849 mb, mblen, 0, 0 );
17850 wc = new WCHAR[wclen];
17851 // and try again...
17852 }
17853 } else {
17854 // Fail.
17855 qWarning("MultiByteToWideChar cannot convert multibyte text");
17856 break;
17857 }
17858 }
17859 if ( len <= 0 )
17860 return QString::null;
17861 QString s( (QChar*)wc, len - 1 ); // len - 1: we don't want terminator
17862 if ( wc != wc_auto )
17863 delete [] wc;
17864 return s;
17865}
17866
17867#endif // Q_OS_WIN32
diff --git a/qmake/tools/qstringlist.cpp b/qmake/tools/qstringlist.cpp
new file mode 100644
index 0000000..0720e7f
--- a/dev/null
+++ b/qmake/tools/qstringlist.cpp
@@ -0,0 +1,376 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QStringList
5**
6** Created : 990406
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qstringlist.h"
39
40#ifndef QT_NO_STRINGLIST
41#include "qregexp.h"
42#include "qstrlist.h"
43#include "qdatastream.h"
44#include "qtl.h"
45
46/*!
47 \class QStringList qstringlist.h
48 \reentrant
49 \brief The QStringList class provides a list of strings.
50
51 \ingroup tools
52 \ingroup shared
53 \ingroup text
54 \mainclass
55
56 It is used to store and manipulate strings that logically belong
57 together. Essentially QStringList is a QValueList of QString
58 objects. Unlike QStrList, which stores pointers to characters,
59 QStringList holds real QString objects. It is the class of choice
60 whenever you work with Unicode strings. QStringList is part of the
61 \link qtl.html Qt Template Library\endlink.
62
63 Like QString itself, QStringList objects are implicitly shared.
64 Passing them around as value-parameters is both fast and safe.
65
66 Strings can be added to a list using append(), operator+=() or
67 operator<<(), e.g.
68 \code
69 QStringList fonts;
70 fonts.append( "Times" );
71 fonts += "Courier";
72 fonts += "Courier New";
73 fonts << "Helvetica [Cronyx]" << "Helvetica [Adobe]";
74 \endcode
75
76 String lists have an iterator, QStringList::Iterator(), e.g.
77 \code
78 for ( QStringList::Iterator it = fonts.begin(); it != fonts.end(); ++it ) {
79 cout << *it << ":";
80 }
81 cout << endl;
82 // Output:
83 //Times:Courier:Courier New:Helvetica [Cronyx]:Helvetica [Adobe]:
84 \endcode
85
86 Many Qt functions return const string lists; to iterate over these
87 you should make a copy and iterate over the copy.
88
89 You can concatenate all the strings in a string list into a single
90 string (with an optional separator) using join(), e.g.
91 \code
92 QString allFonts = fonts.join( ", " );
93 cout << allFonts << endl;
94 // Output:
95 //Times, Courier, Courier New, Helvetica [Cronyx], Helvetica [Adobe]
96 \endcode
97
98 You can sort the list with sort(), and extract a new list which
99 contains only those strings which contain a particular substring
100 (or match a particular regular expression) using the grep()
101 functions, e.g.
102 \code
103 fonts.sort();
104 cout << fonts.join( ", " ) << endl;
105 // Output:
106 //Courier, Courier New, Helvetica [Adobe], Helvetica [Cronyx], Times
107
108 QStringList helveticas = fonts.grep( "Helvetica" );
109 cout << helveticas.join( ", " ) << endl;
110 // Output:
111 //Helvetica [Adobe], Helvetica [Cronyx]
112 \endcode
113
114 Existing strings can be split into string lists with character,
115 string or regular expression separators, e.g.
116 \code
117 QString s = "Red\tGreen\tBlue";
118 QStringList colors = QStringList::split( "\t", s );
119 cout << colors.join( ", " ) << endl;
120 // Output:
121 //Red, Green, Blue
122 \endcode
123*/
124
125/*!
126 \fn QStringList::QStringList()
127
128 Creates an empty string list.
129*/
130
131/*!
132 \fn QStringList::QStringList( const QStringList& l )
133
134 Creates a copy of the list \a l. This function is very fast
135 because QStringList is implicitly shared. In most situations this
136 acts like a deep copy, for example, if this list or the original
137 one or some other list referencing the same shared data is
138 modified, the modifying list first makes a copy, i.e.
139 copy-on-write.
140 In a threaded environment you may require a real deep copy
141 \omit see \l QDeepCopy\endomit.
142*/
143
144/*!
145 \fn QStringList::QStringList (const QString & i)
146
147 Constructs a string list consisting of the single string \a i.
148 Longer lists are easily created as follows:
149
150 \code
151 QStringList items;
152 items << "Buy" << "Sell" << "Update" << "Value";
153 \endcode
154*/
155
156/*!
157 \fn QStringList::QStringList (const char* i)
158
159 Constructs a string list consisting of the single latin-1 string \a i.
160*/
161
162/*!
163 \fn QStringList::QStringList( const QValueList<QString>& l )
164
165 Constructs a new string list that is a copy of \a l.
166*/
167
168/*!
169 Sorts the list of strings in ascending case-sensitive order.
170
171 Sorting is very fast. It uses the \link qtl.html Qt Template
172 Library's\endlink efficient HeapSort implementation that has a
173 time complexity of O(n*log n).
174
175 If you want to sort your strings in an arbitrary order consider
176 using a QMap. For example you could use a QMap\<QString,QString\>
177 to create a case-insensitive ordering (e.g. mapping the lowercase
178 text to the text), or a QMap\<int,QString\> to sort the strings by
179 some integer index, etc.
180*/
181void QStringList::sort()
182{
183 qHeapSort( *this );
184}
185
186/*!
187 \overload
188
189 This version of the function uses a QChar as separator, rather
190 than a regular expression.
191
192 \sa join() QString::section()
193*/
194
195QStringList QStringList::split( const QChar &sep, const QString &str,
196 bool allowEmptyEntries )
197{
198 return split( QString(sep), str, allowEmptyEntries );
199}
200
201/*!
202 \overload
203
204 This version of the function uses a QString as separator, rather
205 than a regular expression.
206
207 If \a sep is an empty string, the return value is a list of
208 one-character strings: split( QString( "" ), "four" ) returns the
209 four-item list, "f", "o", "u", "r".
210
211 If \a allowEmptyEntries is TRUE, an empty string is inserted in
212 the list wherever the separator matches twice without intervening
213 text.
214
215 \sa join() QString::section()
216*/
217
218QStringList QStringList::split( const QString &sep, const QString &str,
219 bool allowEmptyEntries )
220{
221 QStringList lst;
222
223 int j = 0;
224 int i = str.find( sep, j );
225
226 while ( i != -1 ) {
227 if ( i > j && i <= (int)str.length() )
228 lst << str.mid( j, i - j );
229 else if ( allowEmptyEntries )
230 lst << QString::null;
231 j = i + sep.length();
232 i = str.find( sep, sep.length() > 0 ? j : j+1 );
233 }
234
235 int l = str.length() - 1;
236 if ( str.mid( j, l - j + 1 ).length() > 0 )
237 lst << str.mid( j, l - j + 1 );
238 else if ( allowEmptyEntries )
239 lst << QString::null;
240
241 return lst;
242}
243
244#ifndef QT_NO_REGEXP
245/*!
246 Splits the string \a str into strings wherever the regular
247 expression \a sep occurs, and returns the list of those strings.
248
249 If \a allowEmptyEntries is TRUE, an empty string is inserted in
250 the list wherever the separator matches twice without intervening
251 text.
252
253 For example, if you split the string "a,,b,c" on commas, split()
254 returns the three-item list "a", "b", "c" if \a allowEmptyEntries
255 is FALSE (the default), and the four-item list "a", "", "b", "c"
256 if \a allowEmptyEntries is TRUE.
257
258 If \a sep does not match anywhere in \a str, split() returns a
259 list consisting of the single string \a str.
260
261 \sa join() QString::section()
262*/
263
264QStringList QStringList::split( const QRegExp &sep, const QString &str,
265 bool allowEmptyEntries )
266{
267 QStringList lst;
268
269 QRegExp tep = sep;
270
271 int j = 0;
272 int i = tep.search( str, j );
273
274 while ( i != -1 ) {
275 if ( str.mid( j, i - j ).length() > 0 )
276 lst << str.mid( j, i - j );
277 else if ( allowEmptyEntries )
278 lst << QString::null;
279 if ( tep.matchedLength() == 0 )
280 j = i + 1;
281 else
282 j = i + tep.matchedLength();
283 i = tep.search( str, j );
284 }
285
286 int l = str.length() - 1;
287 if ( str.mid( j, l - j + 1 ).length() > 0 )
288 lst << str.mid( j, l - j + 1 );
289 else if ( allowEmptyEntries )
290 lst << QString::null;
291
292 return lst;
293}
294#endif
295
296/*!
297 Returns a list of all strings containing the substring \a str.
298
299 If \a cs is TRUE, the grep is done case-sensitively; otherwise
300 case is ignored.
301*/
302
303QStringList QStringList::grep( const QString &str, bool cs ) const
304{
305 QStringList res;
306 for ( QStringList::ConstIterator it = begin(); it != end(); ++it )
307 if ( (*it).contains(str, cs) )
308 res << *it;
309
310 return res;
311}
312
313#ifndef QT_NO_REGEXP
314/*!
315 \overload
316
317 Returns a list of all the strings that match the regular
318 expression \a expr.
319*/
320
321QStringList QStringList::grep( const QRegExp &expr ) const
322{
323 QStringList res;
324 for ( QStringList::ConstIterator it = begin(); it != end(); ++it )
325 if ( (*it).contains(expr) )
326 res << *it;
327
328 return res;
329}
330#endif
331
332/*!
333 Joins the string list into a single string with each element
334 separated by the string \a sep (which can be empty).
335
336 \sa split()
337*/
338QString QStringList::join( const QString &sep ) const
339{
340 QString res;
341 bool alredy = FALSE;
342 for ( QStringList::ConstIterator it = begin(); it != end(); ++it ) {
343 if ( alredy )
344 res += sep;
345 alredy = TRUE;
346 res += *it;
347 }
348
349 return res;
350}
351
352#ifndef QT_NO_DATASTREAM
353Q_EXPORT QDataStream &operator>>( QDataStream & s, QStringList& l )
354{
355 return s >> (QValueList<QString>&)l;
356}
357
358Q_EXPORT QDataStream &operator<<( QDataStream & s, const QStringList& l )
359{
360 return s << (const QValueList<QString>&)l;
361}
362#endif
363
364/*!
365 Converts from an ASCII-QStrList \a ascii to a QStringList (Unicode).
366*/
367QStringList QStringList::fromStrList(const QStrList& ascii)
368{
369 QStringList res;
370 const char * s;
371 for ( QStrListIterator it(ascii); (s=it.current()); ++it )
372 res << s;
373 return res;
374}
375
376#endif //QT_NO_STRINGLIST
diff --git a/qmake/tools/qtextstream.cpp b/qmake/tools/qtextstream.cpp
new file mode 100644
index 0000000..75c6531
--- a/dev/null
+++ b/qmake/tools/qtextstream.cpp
@@ -0,0 +1,2593 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QTextStream class
5**
6** Created : 940922
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qtextstream.h"
39
40#ifndef QT_NO_TEXTSTREAM
41#include "qtextcodec.h"
42#include "qregexp.h"
43#include "qbuffer.h"
44#include "qfile.h"
45#include <stdio.h>
46#include <ctype.h>
47#include <stdlib.h>
48
49#if defined(Q_OS_WIN32)
50#include <windows.h>
51#endif
52
53/*!
54 \class QTextStream qtextstream.h
55 \reentrant
56 \brief The QTextStream class provides basic functions for reading
57 and writing text using a QIODevice.
58
59 \ingroup io
60 \ingroup text
61 \mainclass
62
63 The text stream class has a functional interface that is very
64 similar to that of the standard C++ iostream class.
65
66 Qt provides several global functions similar to the ones in iostream:
67 \table
68 \header \i Function \i Meaning
69 \row \i bin \i sets the QTextStream to read/write binary numbers
70 \row \i oct \i sets the QTextStream to read/write octal numbers
71 \row \i dec \i sets the QTextStream to read/write decimal numbers
72 \row \i hex \i sets the QTextStream to read/write hexadecimal numbers
73 \row \i endl \i forces a line break
74 \row \i flush \i forces the QIODevice to flush any buffered data
75 \row \i ws \i eats any available whitespace (on input)
76 \row \i reset \i resets the QTextStream to its default mode (see reset())
77 \row \i qSetW(int) \i sets the \link width() field width \endlink
78 to the given argument
79 \row \i qSetFill(int) \i sets the \link fill() fill character
80 \endlink to the given argument
81 \row \i qSetPrecision(int) \i sets the \link precision() precision
82 \endlink to the given argument
83 \endtable
84
85 \warning By default QTextStream will automatically detect whether
86 integers in the stream are in decimal, octal, hexadecimal or
87 binary format when reading from the stream. In particular, a
88 leading '0' signifies octal, i.e. the sequence "0100" will be
89 interpreted as 64.
90
91 The QTextStream class reads and writes text; it is not appropriate
92 for dealing with binary data (but QDataStream is).
93
94 By default, output of Unicode text (i.e. QString) is done using
95 the local 8-bit encoding. This can be changed using the
96 setEncoding() method. For input, the QTextStream will auto-detect
97 standard Unicode "byte order marked" text files; otherwise the
98 local 8-bit encoding is used.
99
100 The QIODevice is set in the constructor, or later using
101 setDevice(). If the end of the input is reached atEnd() returns
102 TRUE. Data can be read into variables of the appropriate type
103 using the operator>>() overloads, or read in its entirety into a
104 single string using read(), or read a line at a time using
105 readLine(). Whitespace can be skipped over using skipWhiteSpace().
106 You can set flags for the stream using flags() or setf(). The
107 stream also supports width(), precision() and fill(); use reset()
108 to reset the defaults.
109
110 \sa QDataStream
111*/
112
113/*!
114 \enum QTextStream::Encoding
115
116 \value Locale
117 \value Latin1
118 \value Unicode
119 \value UnicodeNetworkOrder
120 \value UnicodeReverse
121 \value RawUnicode
122 \value UnicodeUTF8
123
124 See setEncoding() for an explanation of the encodings.
125*/
126
127/*
128 \class QTSManip
129
130 \brief The QTSManip class is an internal helper class for the
131 QTextStream.
132
133 It is generally a very bad idea to use this class directly in
134 application programs.
135
136 \internal
137
138 This class makes it possible to give the QTextStream function objects
139 with arguments, like this:
140 \code
141 QTextStream cout( stdout, IO_WriteOnly );
142 cout << setprecision( 8 ); // QTSManip used here!
143 cout << 3.14159265358979323846;
144 \endcode
145
146 The setprecision() function returns a QTSManip object.
147 The QTSManip object contains a pointer to a member function in
148 QTextStream and an integer argument.
149 When serializing a QTSManip into a QTextStream, the function
150 is executed with the argument.
151*/
152
153/*! \fn QTSManip::QTSManip( QTSMFI m, int a )
154
155 Constructs a QTSManip object which will call \a m (a member function
156 in QTextStream which accepts a single int) with argument \a a when
157 QTSManip::exec() is called. Used internally in e.g. endl:
158
159 \code
160 s << "some text" << endl << "more text";
161 \endcode
162*/
163
164/*! \fn void QTSManip::exec( QTextStream& s )
165
166 Calls the member function specified in the constructor, for object
167 \a s. Used internally in e.g. endl:
168
169 \code
170 s << "some text" << endl << "more text";
171 \endcode
172*/
173
174
175/*****************************************************************************
176 QTextStream member functions
177 *****************************************************************************/
178
179#if defined(QT_CHECK_STATE)
180#undef CHECK_STREAM_PRECOND
181 #define CHECK_STREAM_PRECOND if ( !dev ) { \
182 qWarning( "QTextStream: No device" );\
183 return *this; }
184#else
185#define CHECK_STREAM_PRECOND
186#endif
187
188
189 #define I_SHORT 0x0010
190 #define I_INT 0x0020
191 #define I_LONG 0x0030
192 #define I_TYPE_MASK0x00f0
193
194 #define I_BASE_2QTS::bin
195 #define I_BASE_8QTS::oct
196 #define I_BASE_10QTS::dec
197 #define I_BASE_16QTS::hex
198 #define I_BASE_MASK(QTS::bin | QTS::oct | QTS::dec | QTS::hex)
199
200 #define I_SIGNED0x0100
201 #define I_UNSIGNED0x0200
202 #define I_SIGN_MASK0x0f00
203
204
205static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.
206static const uint getline_buf_size = 256; // bufsize used by ts_getline()
207
208const int QTextStream::basefield = I_BASE_MASK;
209const int QTextStream::adjustfield = ( QTextStream::left |
210 QTextStream::right |
211 QTextStream::internal );
212const int QTextStream::floatfield = ( QTextStream::scientific |
213 QTextStream::fixed );
214
215
216class QTextStreamPrivate {
217public:
218#ifndef QT_NO_TEXTCODEC
219 QTextStreamPrivate()
220 : decoder( 0 ), encoder( 0 ), sourceType( NotSet ) { }
221 ~QTextStreamPrivate() {
222 delete decoder;
223 delete encoder;
224 }
225 QTextDecoder *decoder;
226 QTextEncoder *encoder;
227#else
228 QTextStreamPrivate() : sourceType( NotSet ) { }
229 ~QTextStreamPrivate() { }
230#endif
231 QString ungetcBuf;
232
233 enum SourceType { NotSet, IODevice, String, ByteArray, File };
234 SourceType sourceType;
235};
236
237
238// skips whitespace and returns the first non-whitespace character
239QChar QTextStream::eat_ws()
240{
241 QChar c;
242 do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );
243 return c;
244}
245
246void QTextStream::init()
247{
248 // ### ungetcBuf = QEOF;
249 dev = 0;
250 owndev = FALSE;
251 mapper = 0;
252 d = new QTextStreamPrivate;
253 doUnicodeHeader = TRUE; // autodetect
254 latin1 = TRUE; // should use locale?
255 internalOrder = QChar::networkOrdered();
256 networkOrder = TRUE;
257}
258
259/*!
260 Constructs a data stream that has no IO device.
261*/
262
263QTextStream::QTextStream()
264{
265 init();
266 setEncoding( Locale ); //###
267 reset();
268 d->sourceType = QTextStreamPrivate::NotSet;
269}
270
271/*!
272 Constructs a text stream that uses the IO device \a iod.
273*/
274
275QTextStream::QTextStream( QIODevice *iod )
276{
277 init();
278 setEncoding( Locale ); //###
279 dev = iod;
280 reset();
281 d->sourceType = QTextStreamPrivate::IODevice;
282}
283
284// TODO: use special-case handling of this case in QTextStream, and
285 // simplify this class to only deal with QChar or QString data.
286class QStringBuffer : public QIODevice {
287public:
288 QStringBuffer( QString* str );
289 ~QStringBuffer();
290 bool open( int m );
291 void close();
292 void flush();
293 Offset size() const;
294 Offset at() const;
295 bool at( Offset pos );
296 Q_LONG readBlock( char *p, Q_ULONG len );
297 Q_LONG writeBlock( const char *p, Q_ULONG len );
298 int getch();
299 int putch( int ch );
300 int ungetch( int ch );
301protected:
302 QString* s;
303
304private: // Disabled copy constructor and operator=
305 QStringBuffer( const QStringBuffer & );
306 QStringBuffer &operator=( const QStringBuffer & );
307};
308
309
310QStringBuffer::QStringBuffer( QString* str )
311{
312 s = str;
313}
314
315QStringBuffer::~QStringBuffer()
316{
317}
318
319
320bool QStringBuffer::open( int m )
321{
322 if ( !s ) {
323#if defined(QT_CHECK_STATE)
324 qWarning( "QStringBuffer::open: No string" );
325#endif
326 return FALSE;
327 }
328 if ( isOpen() ) { // buffer already open
329#if defined(QT_CHECK_STATE)
330 qWarning( "QStringBuffer::open: Buffer already open" );
331#endif
332 return FALSE;
333 }
334 setMode( m );
335 if ( m & IO_Truncate ) { // truncate buffer
336 s->truncate( 0 );
337 }
338 if ( m & IO_Append ) { // append to end of buffer
339 ioIndex = s->length()*sizeof(QChar);
340 } else {
341 ioIndex = 0;
342 }
343 setState( IO_Open );
344 setStatus( 0 );
345 return TRUE;
346}
347
348void QStringBuffer::close()
349{
350 if ( isOpen() ) {
351 setFlags( IO_Direct );
352 ioIndex = 0;
353 }
354}
355
356void QStringBuffer::flush()
357{
358}
359
360QIODevice::Offset QStringBuffer::size() const
361{
362 return s ? s->length()*sizeof(QChar) : 0;
363}
364
365QIODevice::Offset QStringBuffer::at() const
366{
367 return ioIndex;
368}
369
370bool QStringBuffer::at( Offset pos )
371{
372#if defined(QT_CHECK_STATE)
373 if ( !isOpen() ) {
374 qWarning( "QStringBuffer::at: Buffer is not open" );
375 return FALSE;
376 }
377#endif
378 if ( pos >= s->length()*2 ) {
379#if defined(QT_CHECK_RANGE)
380#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
381 qWarning( "QStringBuffer::at: Index %llu out of range", pos );
382#else
383 qWarning( "QStringBuffer::at: Index %lu out of range", pos );
384#endif
385#endif
386 return FALSE;
387 }
388 ioIndex = pos;
389 return TRUE;
390}
391
392
393Q_LONG QStringBuffer::readBlock( char *p, Q_ULONG len )
394{
395#if defined(QT_CHECK_STATE)
396 Q_CHECK_PTR( p );
397 if ( !isOpen() ) { // buffer not open
398 qWarning( "QStringBuffer::readBlock: Buffer not open" );
399 return -1;
400 }
401 if ( !isReadable() ) { // reading not permitted
402 qWarning( "QStringBuffer::readBlock: Read operation not permitted" );
403 return -1;
404 }
405#endif
406 if ( ioIndex + len > s->length()*sizeof(QChar) ) {
407 // overflow
408 if ( (uint)ioIndex >= s->length()*sizeof(QChar) ) {
409 setStatus( IO_ReadError );
410 return -1;
411 } else {
412 len = s->length()*2 - (uint)ioIndex;
413 }
414 }
415 memcpy( p, ((const char*)(s->unicode()))+ioIndex, len );
416 ioIndex += len;
417 return len;
418}
419
420Q_LONG QStringBuffer::writeBlock( const char *p, Q_ULONG len )
421{
422#if defined(QT_CHECK_NULL)
423 if ( p == 0 && len != 0 )
424 qWarning( "QStringBuffer::writeBlock: Null pointer error" );
425#endif
426#if defined(QT_CHECK_STATE)
427 if ( !isOpen() ) { // buffer not open
428 qWarning( "QStringBuffer::writeBlock: Buffer not open" );
429 return -1;
430 }
431 if ( !isWritable() ) { // writing not permitted
432 qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );
433 return -1;
434 }
435 if ( ioIndex&1 ) {
436 qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );
437 return -1;
438 }
439 if ( len&1 ) {
440 qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );
441 return -1;
442 }
443#endif
444 s->replace(ioIndex/2, len/2, (QChar*)p, len/2);
445 ioIndex += len;
446 return len;
447}
448
449int QStringBuffer::getch()
450{
451#if defined(QT_CHECK_STATE)
452 if ( !isOpen() ) { // buffer not open
453 qWarning( "QStringBuffer::getch: Buffer not open" );
454 return -1;
455 }
456 if ( !isReadable() ) { // reading not permitted
457 qWarning( "QStringBuffer::getch: Read operation not permitted" );
458 return -1;
459 }
460#endif
461 if ( (uint)ioIndex >= s->length()*2 ) { // overflow
462 setStatus( IO_ReadError );
463 return -1;
464 }
465 return (int) *( (const char *) s->unicode() + ioIndex++ );
466}
467
468int QStringBuffer::putch( int ch )
469{
470 char c = ch;
471 if ( writeBlock(&c,1) < 0 )
472 return -1;
473 else
474 return ch;
475}
476
477int QStringBuffer::ungetch( int ch )
478{
479#if defined(QT_CHECK_STATE)
480 if ( !isOpen() ) { // buffer not open
481 qWarning( "QStringBuffer::ungetch: Buffer not open" );
482 return -1;
483 }
484 if ( !isReadable() ) { // reading not permitted
485 qWarning( "QStringBuffer::ungetch: Read operation not permitted" );
486 return -1;
487 }
488#endif
489 if ( ch != -1 ) { // something to do with eof
490 if ( ioIndex )
491 ioIndex--;
492 else
493 ch = -1;
494 }
495 return ch;
496}
497
498
499/*!
500 Constructs a text stream that operates on the Unicode QString, \a
501 str, through an internal device. The \a filemode argument is
502 passed to the device's open() function; see \l{QIODevice::mode()}.
503
504 If you set an encoding or codec with setEncoding() or setCodec(),
505 this setting is ignored for text streams that operate on QString.
506
507 Example:
508 \code
509 QString str;
510 QTextStream ts( &str, IO_WriteOnly );
511 ts << "pi = " << 3.14; // str == "pi = 3.14"
512 \endcode
513
514 Writing data to the text stream will modify the contents of the
515 string. The string will be expanded when data is written beyond
516 the end of the string. Note that the string will not be truncated:
517 \code
518 QString str = "pi = 3.14";
519 QTextStream ts( &str, IO_WriteOnly );
520 ts << "2+2 = " << 2+2; // str == "2+2 = 414"
521 \endcode
522
523 Note that because QString is Unicode, you should not use
524 readRawBytes() or writeRawBytes() on such a stream.
525*/
526
527QTextStream::QTextStream( QString* str, int filemode )
528{
529 // TODO: optimize for this case as it becomes more common
530 // (see QStringBuffer above)
531 init();
532 dev = new QStringBuffer( str );
533 ((QStringBuffer *)dev)->open( filemode );
534 owndev = TRUE;
535 setEncoding(RawUnicode);
536 reset();
537 d->sourceType = QTextStreamPrivate::String;
538}
539
540/*! \obsolete
541
542 This constructor is equivalent to the constructor taking a QString*
543 parameter.
544*/
545
546QTextStream::QTextStream( QString& str, int filemode )
547{
548 init();
549 dev = new QStringBuffer( &str );
550 ((QStringBuffer *)dev)->open( filemode );
551 owndev = TRUE;
552 setEncoding(RawUnicode);
553 reset();
554 d->sourceType = QTextStreamPrivate::String;
555}
556
557/*!
558 Constructs a text stream that operates on the byte array, \a a,
559 through an internal QBuffer device. The \a mode argument is passed
560 to the device's open() function; see \l{QIODevice::mode()}.
561
562 Example:
563 \code
564 QByteArray array;
565 QTextStream ts( array, IO_WriteOnly );
566 ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
567 \endcode
568
569 Writing data to the text stream will modify the contents of the
570 array. The array will be expanded when data is written beyond the
571 end of the string.
572
573 Same example, using a QBuffer:
574 \code
575 QByteArray array;
576 QBuffer buf( array );
577 buf.open( IO_WriteOnly );
578 QTextStream ts( &buf );
579 ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
580 buf.close();
581 \endcode
582*/
583
584QTextStream::QTextStream( QByteArray a, int mode )
585{
586 init();
587 dev = new QBuffer( a );
588 ((QBuffer *)dev)->open( mode );
589 owndev = TRUE;
590 setEncoding( Latin1 ); //### Locale???
591 reset();
592 d->sourceType = QTextStreamPrivate::ByteArray;
593}
594
595/*!
596 Constructs a text stream that operates on an existing file handle
597 \a fh through an internal QFile device. The \a mode argument is
598 passed to the device's open() function; see \l{QIODevice::mode()}.
599
600 Note that if you create a QTextStream \c cout or another name that
601 is also used for another variable of a different type, some
602 linkers may confuse the two variables, which will often cause
603 crashes.
604*/
605
606QTextStream::QTextStream( FILE *fh, int mode )
607{
608 init();
609 setEncoding( Locale ); //###
610 dev = new QFile;
611 ((QFile *)dev)->open( mode, fh );
612 owndev = TRUE;
613 reset();
614 d->sourceType = QTextStreamPrivate::File;
615}
616
617/*!
618 Destroys the text stream.
619
620 The destructor does not affect the current IO device.
621*/
622
623QTextStream::~QTextStream()
624{
625 if ( owndev )
626 delete dev;
627 delete d;
628}
629
630/*!
631 Positions the read pointer at the first non-whitespace character.
632*/
633void QTextStream::skipWhiteSpace()
634{
635 ts_ungetc( eat_ws() );
636}
637
638
639/*!
640 Tries to read \a len characters from the stream and stores them in
641 \a buf. Returns the number of characters really read.
642
643 \warning There will no QEOF appended if the read reaches the end
644 of the file. EOF is reached when the return value does not equal
645 \a len.
646*/
647uint QTextStream::ts_getbuf( QChar* buf, uint len )
648{
649 if( len < 1 )
650 return 0;
651
652 uint rnum=0; // the number of QChars really read
653
654 if ( d && d->ungetcBuf.length() ) {
655 while( rnum < len && rnum < d->ungetcBuf.length() ) {
656 *buf = d->ungetcBuf.constref( rnum );
657 buf++;
658 rnum++;
659 }
660 d->ungetcBuf = d->ungetcBuf.mid( rnum );
661 if ( rnum >= len )
662 return rnum;
663 }
664
665 // we use dev->ungetch() for one of the bytes of the unicode
666 // byte-order mark, but a local unget hack for the other byte:
667 int ungetHack = EOF;
668
669 if ( doUnicodeHeader ) {
670 doUnicodeHeader = FALSE; // only at the top
671 int c1 = dev->getch();
672 if ( c1 == EOF )
673 return rnum;
674 int c2 = dev->getch();
675 if ( c1 == 0xfe && c2 == 0xff ) {
676 mapper = 0;
677 latin1 = FALSE;
678 internalOrder = QChar::networkOrdered();
679 networkOrder = TRUE;
680 } else if ( c1 == 0xff && c2 == 0xfe ) {
681 mapper = 0;
682 latin1 = FALSE;
683 internalOrder = !QChar::networkOrdered();
684 networkOrder = FALSE;
685 } else {
686 if ( c2 != EOF ) {
687 dev->ungetch( c2 );
688 ungetHack = c1;
689 } else {
690 /*
691 A small bug might hide here. If only the first byte
692 of a file has made it so far, and that first byte
693 is half of the byte-order mark, then the utfness
694 will not be detected.
695 */
696 dev->ungetch( c1 );
697 }
698 }
699 }
700
701#ifndef QT_NO_TEXTCODEC
702 if ( mapper ) {
703 bool shortRead = FALSE;
704 if ( !d->decoder )
705 d->decoder = mapper->makeDecoder();
706 while( rnum < len ) {
707 QString s;
708 bool readBlock = !( len == 1+rnum );
709 for (;;) {
710 // for efficiency: normally read a whole block
711 if ( readBlock ) {
712 // guess buffersize; this may be wrong (too small or too
713 // big). But we can handle this (either iterate reading
714 // or use ungetcBuf).
715 // Note that this might cause problems for codecs where
716 // one byte can result in >1 Unicode Characters if bytes
717 // are written to the stream in the meantime (loss of
718 // synchronicity).
719 uint rlen = len - rnum;
720 char *cbuf = new char[ rlen ];
721 if ( ungetHack != EOF ) {
722 rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
723 cbuf[0] = (char)ungetHack;
724 ungetHack = EOF;
725 } else {
726 rlen = dev->readBlock( cbuf, rlen );
727 }
728 s += d->decoder->toUnicode( cbuf, rlen );
729 delete[] cbuf;
730 // use buffered reading only for the first time, because we
731 // have to get the stream synchronous again (this is easier
732 // with single character reading)
733 readBlock = FALSE;
734 }
735 // get stream (and codec) in sync
736 int c;
737 if ( ungetHack == EOF ) {
738 c = dev->getch();
739 } else {
740 c = ungetHack;
741 ungetHack = EOF;
742 }
743 if ( c == EOF ) {
744 shortRead = TRUE;
745 break;
746 }
747 char b = c;
748 uint lengthBefore = s.length();
749 s += d->decoder->toUnicode( &b, 1 );
750 if ( s.length() > lengthBefore )
751 break; // it seems we are in sync now
752 }
753 uint i = 0;
754 uint end = QMIN( len-rnum, s.length() );
755 while( i < end ) {
756 *buf = s.constref(i++);
757 buf++;
758 }
759 rnum += end;
760 if ( s.length() > i )
761 // could be = but append is clearer
762 d->ungetcBuf.append( s.mid( i ) );
763 if ( shortRead )
764 return rnum;
765 }
766 } else
767#endif
768 if ( latin1 ) {
769 if ( len == 1+rnum ) {
770 // use this method for one character because it is more efficient
771 // (arnt doubts whether it makes a difference, but lets it stand)
772 int c = (ungetHack == EOF) ? dev->getch() : ungetHack;
773 if ( c != EOF ) {
774 *buf = (char)c;
775 buf++;
776 rnum++;
777 }
778 } else {
779 if ( ungetHack != EOF ) {
780 *buf = (char)ungetHack;
781 buf++;
782 rnum++;
783 ungetHack = EOF;
784 }
785 char *cbuf = new char[len - rnum];
786 while ( !dev->atEnd() && rnum < len ) {
787 uint rlen = len - rnum;
788 rlen = dev->readBlock( cbuf, rlen );
789 char *it = cbuf;
790 char *end = cbuf + rlen;
791 while ( it < end ) {
792 *buf = *it;
793 buf++;
794 it++;
795 }
796 rnum += rlen;
797 }
798 delete[] cbuf;
799 }
800 } else { // UCS-2 or UTF-16
801 if ( len == 1+rnum ) {
802 int c1 = (ungetHack == EOF) ? dev->getch() : ungetHack;
803 if ( c1 == EOF )
804 return rnum;
805 int c2 = dev->getch();
806 if ( c2 == EOF )
807 return rnum;
808
809 if ( networkOrder ) {
810 *buf = QChar( c2, c1 );
811 } else {
812 *buf = QChar( c1, c2 );
813 }
814 buf++;
815 rnum++;
816 } else {
817 char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
818 while ( !dev->atEnd() && rnum < len ) {
819 uint rlen = 2 * ( len-rnum );
820 if ( ungetHack != EOF ) {
821 rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
822 cbuf[0] = (char)ungetHack;
823 ungetHack = EOF;
824 } else {
825 rlen = dev->readBlock( cbuf, rlen );
826 }
827 // We can't use an odd number of bytes, so put it back. But
828 // do it only if we are capable of reading more -- normally
829 // there should not be an odd number, but the file might be
830 // truncated or not in UTF-16...
831 if ( (rlen & 1) == 1 )
832 if ( !dev->atEnd() )
833 dev->ungetch( cbuf[--rlen] );
834 uint i = 0;
835 if ( networkOrder ) {
836 while( i < rlen ) {
837 *buf = QChar( cbuf[i+1], cbuf[i] );
838 buf++;
839 i+=2;
840 }
841 } else {
842 while( i < rlen ) {
843 *buf = QChar( cbuf[i], cbuf[i+1] );
844 buf++;
845 i+=2;
846 }
847 }
848 rnum += i/2;
849 }
850 delete[] cbuf;
851 }
852 }
853 return rnum;
854}
855
856/*!
857 Tries to read one line, but at most len characters from the stream
858 and stores them in \a buf.
859
860 Returns the number of characters really read. Newlines are not
861 stripped.
862
863 There will be a QEOF appended if the read reaches the end of file;
864 this is different to ts_getbuf().
865
866 This function works only if a newline (as byte) is also a newline
867 (as resulting character) since it uses QIODevice::readLine(). So
868 use it only for such codecs where this is true!
869
870 This function is (almost) a no-op for UTF 16. Don't use it if
871 doUnicodeHeader is TRUE!
872*/
873uint QTextStream::ts_getline( QChar* buf )
874{
875 uint rnum=0; // the number of QChars really read
876 char cbuf[ getline_buf_size+1 ];
877
878 if ( d && d->ungetcBuf.length() ) {
879 while( rnum < getline_buf_size && rnum < d->ungetcBuf.length() ) {
880 buf[rnum] = d->ungetcBuf.constref(rnum);
881 rnum++;
882 }
883 d->ungetcBuf = d->ungetcBuf.mid( rnum );
884 if ( rnum >= getline_buf_size )
885 return rnum;
886 }
887
888#ifndef QT_NO_TEXTCODEC
889 if ( mapper ) {
890 if ( !d->decoder )
891 d->decoder = mapper->makeDecoder();
892 QString s;
893 bool readBlock = TRUE;
894 for (;;) {
895 // for efficiency: try to read a line
896 if ( readBlock ) {
897 int rlen = getline_buf_size - rnum;
898 rlen = dev->readLine( cbuf, rlen+1 );
899 if ( rlen == -1 )
900 rlen = 0;
901 s += d->decoder->toUnicode( cbuf, rlen );
902 readBlock = FALSE;
903 }
904 if ( dev->atEnd()
905 || s.at( s.length()-1 ) == '\n'
906 || s.at( s.length()-1 ) == '\r'
907 ) {
908 break;
909 } else {
910 // get stream (and codec) in sync
911 int c;
912 c = dev->getch();
913 if ( c == EOF ) {
914 break;
915 }
916 char b = c;
917 uint lengthBefore = s.length();
918 s += d->decoder->toUnicode( &b, 1 );
919 if ( s.length() > lengthBefore )
920 break; // it seems we are in sync now
921 }
922 }
923 uint i = 0;
924 while( rnum < getline_buf_size && i < s.length() )
925 buf[rnum++] = s.constref(i++);
926 if ( s.length() > i )
927 // could be = but append is clearer
928 d->ungetcBuf.append( s.mid( i ) );
929 if ( rnum < getline_buf_size && dev->atEnd() )
930 buf[rnum++] = QEOF;
931 } else
932#endif
933 if ( latin1 ) {
934 int rlen = getline_buf_size - rnum;
935 rlen = dev->readLine( cbuf, rlen+1 );
936 if ( rlen == -1 )
937 rlen = 0;
938 char *end = cbuf+rlen;
939 char *it = cbuf;
940 buf +=rnum;
941 while ( it != end ) {
942 buf->setCell( *(it++) );
943 buf->setRow( 0 );
944 buf++;
945 }
946 rnum += rlen;
947 if ( rnum < getline_buf_size && dev->atEnd() )
948 buf[1] = QEOF;
949 }
950 return rnum;
951}
952
953
954/*!
955 Puts one character into the stream.
956*/
957void QTextStream::ts_putc( QChar c )
958{
959#ifndef QT_NO_TEXTCODEC
960 if ( mapper ) {
961 if ( !d->encoder )
962 d->encoder = mapper->makeEncoder();
963 int len = 1;
964 QString s = c;
965 QCString block = d->encoder->fromUnicode( s, len );
966 dev->writeBlock( block, len );
967 } else
968#endif
969 if ( latin1 ) {
970 if ( c.row() )
971 dev->putch( '?' ); // unknown character
972 else
973 dev->putch( c.cell() );
974 } else {
975 if ( doUnicodeHeader ) {
976 doUnicodeHeader = FALSE;
977 ts_putc( QChar::byteOrderMark );
978 }
979 if ( internalOrder ) {
980 // this case is needed by QStringBuffer
981 dev->writeBlock( (char*)&c, sizeof(QChar) );
982 } else if ( networkOrder ) {
983 dev->putch( c.row() );
984 dev->putch( c.cell() );
985 } else {
986 dev->putch( c.cell() );
987 dev->putch( c.row() );
988 }
989 }
990}
991
992/*!
993 Puts one character into the stream.
994*/
995void QTextStream::ts_putc( int ch )
996{
997 ts_putc( QChar((ushort)ch) );
998}
999
1000bool QTextStream::ts_isdigit( QChar c )
1001{
1002 return c.isDigit();
1003}
1004
1005bool QTextStream::ts_isspace( QChar c )
1006{
1007 return c.isSpace();
1008}
1009
1010void QTextStream::ts_ungetc( QChar c )
1011{
1012 if ( c.unicode() == 0xffff )
1013 return;
1014
1015 d->ungetcBuf.prepend( c );
1016}
1017
1018
1019
1020/*!
1021 Reads \a len bytes from the stream into \a s and returns a
1022 reference to the stream.
1023
1024 The buffer \a s must be preallocated.
1025
1026 Note that no encoding is done by this function.
1027
1028 \warning The behavior of this function is undefined unless the
1029 stream's encoding is set to Unicode or Latin1.
1030
1031 \sa QIODevice::readBlock()
1032*/
1033
1034QTextStream &QTextStream::readRawBytes( char *s, uint len )
1035{
1036 dev->readBlock( s, len );
1037 return *this;
1038}
1039
1040/*!
1041 Writes the \a len bytes from \a s to the stream and returns a
1042 reference to the stream.
1043
1044 Note that no encoding is done by this function.
1045
1046 \sa QIODevice::writeBlock()
1047*/
1048
1049QTextStream &QTextStream::writeRawBytes( const char* s, uint len )
1050{
1051 dev->writeBlock( s, len );
1052 return *this;
1053}
1054
1055
1056QTextStream &QTextStream::writeBlock( const char* p, uint len )
1057{
1058 if ( doUnicodeHeader ) {
1059 doUnicodeHeader = FALSE;
1060 if ( !mapper && !latin1 )
1061 ts_putc( QChar::byteOrderMark );
1062 }
1063 // QCString and const char * are treated as Latin-1
1064 if ( !mapper && latin1 ) {
1065 dev->writeBlock( p, len );
1066 } else if ( !mapper && internalOrder ) {
1067 QChar *u = new QChar[len];
1068 for ( uint i = 0; i < len; i++ )
1069 u[i] = p[i];
1070 dev->writeBlock( (char*)u, len * sizeof(QChar) );
1071 delete [] u;
1072 } else {
1073 for ( uint i = 0; i < len; i++ )
1074 ts_putc( (uchar)p[i] );
1075 }
1076 return *this;
1077}
1078
1079QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
1080{
1081#ifndef QT_NO_TEXTCODEC
1082 if ( mapper ) {
1083 if ( !d->encoder )
1084 d->encoder = mapper->makeEncoder();
1085 QConstString s( p, len );
1086 int l = len;
1087 QCString block = d->encoder->fromUnicode( s.string(), l );
1088 dev->writeBlock( block, l );
1089 } else
1090#endif
1091 if ( latin1 ) {
1092 char *str = QString::unicodeToAscii( p, len );
1093 dev->writeBlock( str, len );
1094 delete [] str;
1095 } else if ( internalOrder ) {
1096 if ( doUnicodeHeader ) {
1097 doUnicodeHeader = FALSE;
1098 ts_putc( QChar::byteOrderMark );
1099 }
1100 dev->writeBlock( (char*)p, sizeof(QChar)*len );
1101 } else {
1102 for (uint i=0; i<len; i++)
1103 ts_putc( p[i] );
1104 }
1105 return *this;
1106}
1107
1108/*!
1109 Resets the text stream.
1110
1111 \list
1112 \i All flags are set to 0.
1113 \i The field width is set to 0.
1114 \i The fill character is set to ' ' (Space).
1115 \i The precision is set to 6.
1116 \endlist
1117
1118 \sa setf(), width(), fill(), precision()
1119*/
1120
1121void QTextStream::reset()
1122{
1123 fflags = 0;
1124 fwidth = 0;
1125 fillchar = ' ';
1126 fprec = 6;
1127}
1128
1129/*!
1130 \fn QIODevice *QTextStream::device() const
1131
1132 Returns the IO device currently set.
1133
1134 \sa setDevice(), unsetDevice()
1135*/
1136
1137/*!
1138 Sets the IO device to \a iod.
1139
1140 \sa device(), unsetDevice()
1141*/
1142
1143void QTextStream::setDevice( QIODevice *iod )
1144{
1145 if ( owndev ) {
1146 delete dev;
1147 owndev = FALSE;
1148 }
1149 dev = iod;
1150 d->sourceType = QTextStreamPrivate::IODevice;
1151}
1152
1153/*!
1154 Unsets the IO device. Equivalent to setDevice( 0 ).
1155
1156 \sa device(), setDevice()
1157*/
1158
1159void QTextStream::unsetDevice()
1160{
1161 setDevice( 0 );
1162 d->sourceType = QTextStreamPrivate::NotSet;
1163}
1164
1165/*!
1166 \fn bool QTextStream::atEnd() const
1167
1168 Returns TRUE if the IO device has reached the end position (end of
1169 the stream or file) or if there is no IO device set; otherwise
1170 returns FALSE.
1171
1172 \sa QIODevice::atEnd()
1173*/
1174
1175/*!\fn bool QTextStream::eof() const
1176
1177 \obsolete
1178
1179 This function has been renamed to atEnd().
1180
1181 \sa QIODevice::atEnd()
1182*/
1183
1184/*****************************************************************************
1185 QTextStream read functions
1186 *****************************************************************************/
1187
1188
1189/*!
1190 \overload
1191
1192 Reads a char \a c from the stream and returns a reference to the
1193 stream. Note that whitespace is skipped.
1194*/
1195
1196QTextStream &QTextStream::operator>>( char &c )
1197{
1198 CHECK_STREAM_PRECOND
1199 c = eat_ws();
1200 return *this;
1201}
1202
1203/*!
1204 Reads a char \a c from the stream and returns a reference to the
1205 stream. Note that whitespace is \e not skipped.
1206*/
1207
1208QTextStream &QTextStream::operator>>( QChar &c )
1209{
1210 CHECK_STREAM_PRECOND
1211 c = ts_getc();
1212 return *this;
1213}
1214
1215
1216ulong QTextStream::input_bin()
1217{
1218 ulong val = 0;
1219 QChar ch = eat_ws();
1220 int dv = ch.digitValue();
1221 while ( dv == 0 || dv == 1 ) {
1222 val = ( val << 1 ) + dv;
1223 ch = ts_getc();
1224 dv = ch.digitValue();
1225 }
1226 if ( ch != QEOF )
1227 ts_ungetc( ch );
1228 return val;
1229}
1230
1231ulong QTextStream::input_oct()
1232{
1233 ulong val = 0;
1234 QChar ch = eat_ws();
1235 int dv = ch.digitValue();
1236 while ( dv >= 0 && dv <= 7 ) {
1237 val = ( val << 3 ) + dv;
1238 ch = ts_getc();
1239 dv = ch.digitValue();
1240 }
1241 if ( dv == 8 || dv == 9 ) {
1242 while ( ts_isdigit(ch) )
1243 ch = ts_getc();
1244 }
1245 if ( ch != QEOF )
1246 ts_ungetc( ch );
1247 return val;
1248}
1249
1250ulong QTextStream::input_dec()
1251{
1252 ulong val = 0;
1253 QChar ch = eat_ws();
1254 int dv = ch.digitValue();
1255 while ( ts_isdigit(ch) ) {
1256 val = val * 10 + dv;
1257 ch = ts_getc();
1258 dv = ch.digitValue();
1259 }
1260 if ( ch != QEOF )
1261 ts_ungetc( ch );
1262 return val;
1263}
1264
1265ulong QTextStream::input_hex()
1266{
1267 ulong val = 0;
1268 QChar ch = eat_ws();
1269 char c = ch;
1270 while ( isxdigit((uchar) c) ) {
1271 val <<= 4;
1272 if ( ts_isdigit(c) )
1273 val += c - '0';
1274 else
1275 val += 10 + tolower( (uchar) c ) - 'a';
1276 c = ch = ts_getc();
1277 }
1278 if ( ch != QEOF )
1279 ts_ungetc( ch );
1280 return val;
1281}
1282
1283long QTextStream::input_int()
1284{
1285 long val;
1286 QChar ch;
1287 char c;
1288 switch ( flags() & basefield ) {
1289 case bin:
1290 val = (long)input_bin();
1291 break;
1292 case oct:
1293 val = (long)input_oct();
1294 break;
1295 case dec:
1296 c = ch = eat_ws();
1297 if ( ch == QEOF ) {
1298 val = 0;
1299 } else {
1300 if ( !(c == '-' || c == '+') )
1301 ts_ungetc( ch );
1302 if ( c == '-' ) {
1303 ulong v = input_dec();
1304 if ( v ) { // ensure that LONG_MIN can be read
1305 v--;
1306 val = -((long)v) - 1;
1307 } else {
1308 val = 0;
1309 }
1310 } else {
1311 val = (long)input_dec();
1312 }
1313 }
1314 break;
1315 case hex:
1316 val = (long)input_hex();
1317 break;
1318 default:
1319 val = 0;
1320 c = ch = eat_ws();
1321 if ( c == '0' ) { // bin, oct or hex
1322 c = ch = ts_getc();
1323 if ( tolower((uchar) c) == 'x' )
1324 val = (long)input_hex();
1325 else if ( tolower((uchar) c) == 'b' )
1326 val = (long)input_bin();
1327 else { // octal
1328 ts_ungetc( ch );
1329 if ( c >= '0' && c <= '7' ) {
1330 val = (long)input_oct();
1331 } else {
1332 val = 0;
1333 }
1334 }
1335 } else if ( ts_isdigit(ch) ) {
1336 ts_ungetc( ch );
1337 val = (long)input_dec();
1338 } else if ( c == '-' || c == '+' ) {
1339 ulong v = input_dec();
1340 if ( c == '-' ) {
1341 if ( v ) { // ensure that LONG_MIN can be read
1342 v--;
1343 val = -((long)v) - 1;
1344 } else {
1345 val = 0;
1346 }
1347 } else {
1348 val = (long)v;
1349 }
1350 }
1351 }
1352 return val;
1353}
1354
1355//
1356// We use a table-driven FSM to parse floating point numbers
1357// strtod() cannot be used directly since we're reading from a QIODevice
1358//
1359
1360double QTextStream::input_double()
1361{
1362 const int Init = 0; // states
1363 const int Sign = 1;
1364 const int Mantissa = 2;
1365 const int Dot = 3;
1366 const int Abscissa = 4;
1367 const int ExpMark = 5;
1368 const int ExpSign = 6;
1369 const int Exponent = 7;
1370 const int Done = 8;
1371
1372 const int InputSign = 1; // input tokens
1373 const int InputDigit = 2;
1374 const int InputDot = 3;
1375 const int InputExp = 4;
1376
1377 static const uchar table[8][5] = {
1378 /* None InputSign InputDigit InputDot InputExp */
1379 { 0, Sign, Mantissa, Dot, 0, }, // Init
1380 { 0, 0, Mantissa, Dot, 0, }, // Sign
1381 { Done, Done, Mantissa, Dot, ExpMark,}, // Mantissa
1382 { 0, 0, Abscissa, 0, 0, }, // Dot
1383 { Done, Done, Abscissa, Done, ExpMark,}, // Abscissa
1384 { 0, ExpSign, Exponent, 0, 0, }, // ExpMark
1385 { 0, 0, Exponent, 0, 0, }, // ExpSign
1386 { Done, Done, Exponent, Done, Done } // Exponent
1387 };
1388
1389 int state = Init; // parse state
1390 int input; // input token
1391
1392 char buf[256];
1393 int i = 0;
1394 QChar c = eat_ws();
1395
1396 for (;;) {
1397
1398 switch ( c ) {
1399 case '+':
1400 case '-':
1401 input = InputSign;
1402 break;
1403 case '0': case '1': case '2': case '3': case '4':
1404 case '5': case '6': case '7': case '8': case '9':
1405 input = InputDigit;
1406 break;
1407 case '.':
1408 input = InputDot;
1409 break;
1410 case 'e':
1411 case 'E':
1412 input = InputExp;
1413 break;
1414 default:
1415 input = 0;
1416 break;
1417 }
1418
1419 state = table[state][input];
1420
1421 if ( state == 0 || state == Done || i > 250 ) {
1422 if ( i > 250 ) { // ignore rest of digits
1423 do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) );
1424 }
1425 if ( c != QEOF )
1426 ts_ungetc( c );
1427 buf[i] = '\0';
1428 char *end;
1429 return strtod( buf, &end );
1430 }
1431
1432 buf[i++] = c;
1433 c = ts_getc();
1434 }
1435
1436#if !defined(Q_CC_EDG)
1437 return 0.0;
1438#endif
1439}
1440
1441
1442/*!
1443 \overload
1444
1445 Reads a signed \c short integer \a i from the stream and returns a
1446 reference to the stream. See flags() for an explanation of the
1447 expected input format.
1448*/
1449
1450QTextStream &QTextStream::operator>>( signed short &i )
1451{
1452 CHECK_STREAM_PRECOND
1453 i = (signed short)input_int();
1454 return *this;
1455}
1456
1457
1458/*!
1459 \overload
1460
1461 Reads an unsigned \c short integer \a i from the stream and
1462 returns a reference to the stream. See flags() for an explanation
1463 of the expected input format.
1464*/
1465
1466QTextStream &QTextStream::operator>>( unsigned short &i )
1467{
1468 CHECK_STREAM_PRECOND
1469 i = (unsigned short)input_int();
1470 return *this;
1471}
1472
1473
1474/*!
1475 \overload
1476
1477 Reads a signed \c int \a i from the stream and returns a reference
1478 to the stream. See flags() for an explanation of the expected
1479 input format.
1480*/
1481
1482QTextStream &QTextStream::operator>>( signed int &i )
1483{
1484 CHECK_STREAM_PRECOND
1485 i = (signed int)input_int();
1486 return *this;
1487}
1488
1489
1490/*!
1491 \overload
1492
1493 Reads an unsigned \c int \a i from the stream and returns a
1494 reference to the stream. See flags() for an explanation of the
1495 expected input format.
1496*/
1497
1498QTextStream &QTextStream::operator>>( unsigned int &i )
1499{
1500 CHECK_STREAM_PRECOND
1501 i = (unsigned int)input_int();
1502 return *this;
1503}
1504
1505
1506/*!
1507 \overload
1508
1509 Reads a signed \c long int \a i from the stream and returns a
1510 reference to the stream. See flags() for an explanation of the
1511 expected input format.
1512*/
1513
1514QTextStream &QTextStream::operator>>( signed long &i )
1515{
1516 CHECK_STREAM_PRECOND
1517 i = (signed long)input_int();
1518 return *this;
1519}
1520
1521
1522/*!
1523 \overload
1524
1525 Reads an unsigned \c long int \a i from the stream and returns a
1526 reference to the stream. See flags() for an explanation of the
1527 expected input format.
1528*/
1529
1530QTextStream &QTextStream::operator>>( unsigned long &i )
1531{
1532 CHECK_STREAM_PRECOND
1533 i = (unsigned long)input_int();
1534 return *this;
1535}
1536
1537
1538/*!
1539 \overload
1540
1541 Reads a \c float \a f from the stream and returns a reference to
1542 the stream. See flags() for an explanation of the expected input
1543 format.
1544*/
1545
1546QTextStream &QTextStream::operator>>( float &f )
1547{
1548 CHECK_STREAM_PRECOND
1549 f = (float)input_double();
1550 return *this;
1551}
1552
1553
1554/*!
1555 \overload
1556
1557 Reads a \c double \a f from the stream and returns a reference to
1558 the stream. See flags() for an explanation of the expected input
1559 format.
1560*/
1561
1562QTextStream &QTextStream::operator>>( double &f )
1563{
1564 CHECK_STREAM_PRECOND
1565 f = input_double();
1566 return *this;
1567}
1568
1569
1570/*!
1571 \overload
1572
1573 Reads a "word" from the stream into \a s and returns a reference
1574 to the stream.
1575
1576 A word consists of characters for which isspace() returns FALSE.
1577*/
1578
1579QTextStream &QTextStream::operator>>( char *s )
1580{
1581 CHECK_STREAM_PRECOND
1582 int maxlen = width( 0 );
1583 QChar c = eat_ws();
1584 if ( !maxlen )
1585 maxlen = -1;
1586 while ( c != QEOF ) {
1587 if ( ts_isspace(c) || maxlen-- == 0 ) {
1588 ts_ungetc( c );
1589 break;
1590 }
1591 *s++ = c;
1592 c = ts_getc();
1593 }
1594
1595 *s = '\0';
1596 return *this;
1597}
1598
1599/*!
1600 \overload
1601
1602 Reads a "word" from the stream into \a str and returns a reference
1603 to the stream.
1604
1605 A word consists of characters for which isspace() returns FALSE.
1606*/
1607
1608QTextStream &QTextStream::operator>>( QString &str )
1609{
1610 CHECK_STREAM_PRECOND
1611 str=QString::fromLatin1("");
1612 QCharc = eat_ws();
1613
1614 while ( c != QEOF ) {
1615 if ( ts_isspace(c) ) {
1616 ts_ungetc( c );
1617 break;
1618 }
1619 str += c;
1620 c = ts_getc();
1621 }
1622 return *this;
1623}
1624
1625/*!
1626 \overload
1627
1628 Reads a "word" from the stream into \a str and returns a reference
1629 to the stream.
1630
1631 A word consists of characters for which isspace() returns FALSE.
1632*/
1633
1634QTextStream &QTextStream::operator>>( QCString &str )
1635{
1636 CHECK_STREAM_PRECOND
1637 QCString *dynbuf = 0;
1638 const int buflen = 256;
1639 char buffer[buflen];
1640 char *s = buffer;
1641 int i = 0;
1642 QChar c = eat_ws();
1643
1644 while ( c != QEOF ) {
1645 if ( ts_isspace(c) ) {
1646 ts_ungetc( c );
1647 break;
1648 }
1649 if ( i >= buflen-1 ) {
1650 if ( !dynbuf ) { // create dynamic buffer
1651 dynbuf = new QCString(buflen*2);
1652 memcpy( dynbuf->data(), s, i );// copy old data
1653 } else if ( i >= (int)dynbuf->size()-1 ) {
1654 dynbuf->resize( dynbuf->size()*2 );
1655 }
1656 s = dynbuf->data();
1657 }
1658 s[i++] = c;
1659 c = ts_getc();
1660 }
1661 str.resize( i+1 );
1662 memcpy( str.data(), s, i );
1663 delete dynbuf;
1664 return *this;
1665}
1666
1667
1668/*!
1669 Reads a line from the stream and returns a string containing the
1670 text.
1671
1672 The returned string does not contain any trailing newline or
1673 carriage return. Note that this is different from
1674 QIODevice::readLine(), which does not strip the newline at the end
1675 of the line.
1676
1677 On EOF you will get a QString that is null. On reading an empty
1678 line the returned QString is empty but not null.
1679
1680 \sa QIODevice::readLine()
1681*/
1682
1683QString QTextStream::readLine()
1684{
1685#if defined(QT_CHECK_STATE)
1686 if ( !dev ) {
1687 qWarning( "QTextStream::readLine: No device" );
1688 return QString::null;
1689 }
1690#endif
1691 bool readCharByChar = TRUE;
1692 QString result;
1693#if 0
1694 if ( !doUnicodeHeader && (
1695 (latin1) ||
1696 (mapper != 0 && mapper->mibEnum() == 106 ) // UTF 8
1697 ) ) {
1698 readCharByChar = FALSE;
1699 // use optimized read line
1700 QChar c[getline_buf_size];
1701 int pos = 0;
1702 bool eof = FALSE;
1703
1704 for (;;) {
1705 pos = ts_getline( c );
1706 if ( pos == 0 ) {
1707 // something went wrong; try fallback
1708 readCharByChar = TRUE;
1709 //dev->resetStatus();
1710 break;
1711 }
1712 if ( c[pos-1] == QEOF || c[pos-1] == '\n' ) {
1713 if ( pos>2 && c[pos-1]==QEOF && c[pos-2]=='\n' ) {
1714 result += QString( c, pos-2 );
1715 } else if ( pos > 1 ) {
1716 result += QString( c, pos-1 );
1717 }
1718 if ( pos == 1 && c[pos-1] == QEOF )
1719 eof = TRUE;
1720 break;
1721 } else {
1722 result += QString( c, pos );
1723 }
1724 }
1725 if ( eof && result.isEmpty() )
1726 return QString::null;
1727 }
1728#endif
1729 if ( readCharByChar ) {
1730 // read character by character
1731 const int buf_size = 256;
1732 QChar c[buf_size];
1733 int pos = 0;
1734
1735 c[pos] = ts_getc();
1736 if ( c[pos] == QEOF ) {
1737 return QString::null;
1738 }
1739
1740 while ( c[pos] != QEOF && c[pos] != '\n' ) {
1741 if ( c[pos] == '\r' ) { // ( handle mac and dos )
1742 QChar nextc = ts_getc();
1743 if ( nextc != '\n' )
1744 ts_ungetc( nextc );
1745 break;
1746 }
1747 pos++;
1748 if ( pos >= buf_size ) {
1749 result += QString( c, pos );
1750 pos = 0;
1751 }
1752 c[pos] = ts_getc();
1753 }
1754 result += QString( c, pos );
1755 }
1756
1757 return result;
1758}
1759
1760
1761/*!
1762 Reads the entire stream and returns a string containing the text.
1763
1764 \sa QIODevice::readLine()
1765*/
1766
1767QString QTextStream::read()
1768{
1769#if defined(QT_CHECK_STATE)
1770 if ( !dev ) {
1771 qWarning( "QTextStream::read: No device" );
1772 return QString::null;
1773 }
1774#endif
1775 QString result;
1776 const uint bufsize = 512;
1777 QChar buf[bufsize];
1778 uint i, num, start;
1779 bool skipped_cr = FALSE;
1780
1781 for (;;) {
1782 num = ts_getbuf(buf,bufsize);
1783 // convert dos (\r\n) and mac (\r) style eol to unix style (\n)
1784 start = 0;
1785 for ( i=0; i<num; i++ ) {
1786 if ( buf[i] == '\r' ) {
1787 // Only skip single cr's preceding lf's
1788 if ( skipped_cr ) {
1789 result += buf[i];
1790 start++;
1791 } else {
1792 result += QString( &buf[start], i-start );
1793 start = i+1;
1794 skipped_cr = TRUE;
1795 }
1796 } else {
1797 if ( skipped_cr ) {
1798 if ( buf[i] != '\n' ) {
1799 // Should not have skipped it
1800 result += '\n';
1801 }
1802 skipped_cr = FALSE;
1803 }
1804 }
1805 }
1806 if ( start < num )
1807 result += QString( &buf[start], i-start );
1808 if ( num != bufsize ) // if ( EOF )
1809 break;
1810 }
1811 return result;
1812}
1813
1814
1815
1816/*****************************************************************************
1817 QTextStream write functions
1818 *****************************************************************************/
1819
1820/*!
1821 Writes character \c char to the stream and returns a reference to
1822 the stream.
1823
1824 The character \a c is assumed to be Latin1 encoded independent of
1825 the Encoding set for the QTextStream.
1826*/
1827QTextStream &QTextStream::operator<<( QChar c )
1828{
1829 CHECK_STREAM_PRECOND
1830 ts_putc( c );
1831 return *this;
1832}
1833
1834/*!
1835 \overload
1836
1837 Writes character \a c to the stream and returns a reference to the
1838 stream.
1839*/
1840QTextStream &QTextStream::operator<<( char c )
1841{
1842 CHECK_STREAM_PRECOND
1843 unsigned char uc = (unsigned char) c;
1844 ts_putc( uc );
1845 return *this;
1846}
1847
1848QTextStream &QTextStream::output_int( int format, ulong n, bool neg )
1849{
1850 static const char hexdigits_lower[] = "0123456789abcdef";
1851 static const char hexdigits_upper[] = "0123456789ABCDEF";
1852 CHECK_STREAM_PRECOND
1853 char buf[76];
1854 register char *p;
1855 int len;
1856 const char *hexdigits;
1857
1858 switch ( flags() & I_BASE_MASK ) {
1859
1860 case I_BASE_2: // output binary number
1861 switch ( format & I_TYPE_MASK ) {
1862 case I_SHORT: len=16; break;
1863 case I_INT: len=sizeof(int)*8; break;
1864 case I_LONG: len=32; break;
1865 default: len = 0;
1866 }
1867 p = &buf[74]; // go reverse order
1868 *p = '\0';
1869 while ( len-- ) {
1870 *--p = (char)(n&1) + '0';
1871 n >>= 1;
1872 if ( !n )
1873 break;
1874 }
1875 if ( flags() & showbase ) { // show base
1876 *--p = (flags() & uppercase) ? 'B' : 'b';
1877 *--p = '0';
1878 }
1879 break;
1880
1881 case I_BASE_8: // output octal number
1882 p = &buf[74];
1883 *p = '\0';
1884 do {
1885 *--p = (char)(n&7) + '0';
1886 n >>= 3;
1887 } while ( n );
1888 if ( flags() & showbase )
1889 *--p = '0';
1890 break;
1891
1892 case I_BASE_16: // output hexadecimal number
1893 p = &buf[74];
1894 *p = '\0';
1895 hexdigits = (flags() & uppercase) ?
1896 hexdigits_upper : hexdigits_lower;
1897 do {
1898 *--p = hexdigits[(int)n&0xf];
1899 n >>= 4;
1900 } while ( n );
1901 if ( flags() & showbase ) {
1902 *--p = (flags() & uppercase) ? 'X' : 'x';
1903 *--p = '0';
1904 }
1905 break;
1906
1907 default: // decimal base is default
1908 p = &buf[74];
1909 *p = '\0';
1910 if ( neg )
1911 n = (ulong)(-(long)n);
1912 do {
1913 *--p = ((int)(n%10)) + '0';
1914 n /= 10;
1915 } while ( n );
1916 if ( neg )
1917 *--p = '-';
1918 else if ( flags() & showpos )
1919 *--p = '+';
1920 if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {
1921 ts_putc( *p ); // special case for internal
1922 ++p; // padding
1923 fwidth--;
1924 return *this << (const char*)p;
1925 }
1926 }
1927 if ( fwidth ) { // adjustment required
1928 if ( !(flags() & left) ) { // but NOT left adjustment
1929 len = qstrlen(p);
1930 int padlen = fwidth - len;
1931 if ( padlen <= 0 ) { // no padding required
1932 writeBlock( p, len );
1933 } else if ( padlen < (int)(p-buf) ) { // speeds up padding
1934 memset( p-padlen, (char)fillchar, padlen );
1935 writeBlock( p-padlen, padlen+len );
1936 }
1937 else // standard padding
1938 *this << (const char*)p;
1939 }
1940 else
1941 *this << (const char*)p;
1942 fwidth = 0; // reset field width
1943 }
1944 else
1945 writeBlock( p, qstrlen(p) );
1946 return *this;
1947}
1948
1949
1950/*!
1951 \overload
1952
1953 Writes a \c short integer \a i to the stream and returns a
1954 reference to the stream.
1955*/
1956
1957QTextStream &QTextStream::operator<<( signed short i )
1958{
1959 return output_int( I_SHORT | I_SIGNED, i, i < 0 );
1960}
1961
1962
1963/*!
1964 \overload
1965
1966 Writes an \c unsigned \c short integer \a i to the stream and
1967 returns a reference to the stream.
1968*/
1969
1970QTextStream &QTextStream::operator<<( unsigned short i )
1971{
1972 return output_int( I_SHORT | I_UNSIGNED, i, FALSE );
1973}
1974
1975
1976/*!
1977 \overload
1978
1979 Writes an \c int \a i to the stream and returns a reference to the
1980 stream.
1981*/
1982
1983QTextStream &QTextStream::operator<<( signed int i )
1984{
1985 return output_int( I_INT | I_SIGNED, i, i < 0 );
1986}
1987
1988
1989/*!
1990 \overload
1991
1992 Writes an \c unsigned \c int \a i to the stream and returns a
1993 reference to the stream.
1994*/
1995
1996QTextStream &QTextStream::operator<<( unsigned int i )
1997{
1998 return output_int( I_INT | I_UNSIGNED, i, FALSE );
1999}
2000
2001
2002/*!
2003 \overload
2004
2005 Writes a \c long \c int \a i to the stream and returns a reference
2006 to the stream.
2007*/
2008
2009QTextStream &QTextStream::operator<<( signed long i )
2010{
2011 return output_int( I_LONG | I_SIGNED, i, i < 0 );
2012}
2013
2014
2015/*!
2016 \overload
2017
2018 Writes an \c unsigned \c long \c int \a i to the stream and
2019 returns a reference to the stream.
2020*/
2021
2022QTextStream &QTextStream::operator<<( unsigned long i )
2023{
2024 return output_int( I_LONG | I_UNSIGNED, i, FALSE );
2025}
2026
2027
2028/*!
2029 \overload
2030
2031 Writes a \c float \a f to the stream and returns a reference to
2032 the stream.
2033*/
2034
2035QTextStream &QTextStream::operator<<( float f )
2036{
2037 return *this << (double)f;
2038}
2039
2040
2041/*!
2042 \overload
2043
2044 Writes a \c double \a f to the stream and returns a reference to
2045 the stream.
2046*/
2047
2048QTextStream &QTextStream::operator<<( double f )
2049{
2050 CHECK_STREAM_PRECOND
2051 char buf[64];
2052 char f_char;
2053 char format[16];
2054 if ( (flags()&floatfield) == fixed )
2055 f_char = 'f';
2056 else if ( (flags()&floatfield) == scientific )
2057 f_char = (flags() & uppercase) ? 'E' : 'e';
2058 else
2059 f_char = (flags() & uppercase) ? 'G' : 'g';
2060 register char *fs = format; // generate format string
2061 *fs++ = '%'; // "%.<prec>l<f_char>"
2062 *fs++ = '.';
2063 int prec = precision();
2064 if ( prec > 99 )
2065 prec = 99;
2066 if ( prec >= 10 ) {
2067 *fs++ = prec / 10 + '0';
2068 *fs++ = prec % 10 + '0';
2069 } else {
2070 *fs++ = prec + '0';
2071 }
2072 *fs++ = 'l';
2073 *fs++ = f_char;
2074 *fs = '\0';
2075 sprintf( buf, format, f ); // convert to text
2076 if ( fwidth ) // padding
2077 *this << (const char*)buf;
2078 else // just write it
2079 writeBlock( buf, qstrlen(buf) );
2080 return *this;
2081}
2082
2083
2084/*!
2085 \overload
2086
2087 Writes a string to the stream and returns a reference to the
2088 stream.
2089
2090 The string \a s is assumed to be Latin1 encoded independent of the
2091 Encoding set for the QTextStream.
2092*/
2093
2094QTextStream &QTextStream::operator<<( const char* s )
2095{
2096 CHECK_STREAM_PRECOND
2097 char padbuf[48];
2098 uint len = qstrlen( s ); // don't write null terminator
2099 if ( fwidth ) { // field width set
2100 int padlen = fwidth - len;
2101 fwidth = 0; // reset width
2102 if ( padlen > 0 ) {
2103 char *ppad;
2104 if ( padlen > 46 ) { // create extra big fill buffer
2105 ppad = new char[padlen];
2106 Q_CHECK_PTR( ppad );
2107 } else {
2108 ppad = padbuf;
2109 }
2110 memset( ppad, (char)fillchar, padlen );// fill with fillchar
2111 if ( !(flags() & left) ) {
2112 writeBlock( ppad, padlen );
2113 padlen = 0;
2114 }
2115 writeBlock( s, len );
2116 if ( padlen )
2117 writeBlock( ppad, padlen );
2118 if ( ppad != padbuf ) // delete extra big fill buf
2119 delete[] ppad;
2120 return *this;
2121 }
2122 }
2123 writeBlock( s, len );
2124 return *this;
2125}
2126
2127/*!
2128 \overload
2129
2130 Writes \a s to the stream and returns a reference to the stream.
2131
2132 The string \a s is assumed to be Latin1 encoded independent of the
2133 Encoding set for the QTextStream.
2134*/
2135
2136QTextStream &QTextStream::operator<<( const QCString & s )
2137{
2138 return operator<<(s.data());
2139}
2140
2141/*!
2142 \overload
2143
2144 Writes \a s to the stream and returns a reference to the stream.
2145*/
2146
2147QTextStream &QTextStream::operator<<( const QString& s )
2148{
2149 if ( !mapper && latin1 )
2150 return operator<<(s.latin1());
2151 CHECK_STREAM_PRECOND
2152 QString s1 = s;
2153 if ( fwidth ) { // field width set
2154 if ( !(flags() & left) ) {
2155 s1 = s.rightJustify(fwidth, (char)fillchar);
2156 } else {
2157 s1 = s.leftJustify(fwidth, (char)fillchar);
2158 }
2159 fwidth = 0; // reset width
2160 }
2161 writeBlock( s1.unicode(), s1.length() );
2162 return *this;
2163}
2164
2165
2166/*!
2167 \overload
2168
2169 Writes a pointer to the stream and returns a reference to the
2170 stream.
2171
2172 The \a ptr is output as an unsigned long hexadecimal integer.
2173*/
2174
2175QTextStream &QTextStream::operator<<( void *ptr )
2176{
2177 int f = flags();
2178 setf( hex, basefield );
2179 setf( showbase );
2180 unsetf( uppercase );
2181 output_int( I_LONG | I_UNSIGNED, (ulong)ptr, FALSE );
2182 flags( f );
2183 return *this;
2184}
2185
2186
2187/*!
2188 \fn int QTextStream::flags() const
2189
2190 Returns the current stream flags. The default value is 0.
2191
2192 \table
2193 \header \i Flag \i Meaning
2194 \row \i \c skipws \i Not currently used; whitespace always skipped
2195 \row \i \c left \i Numeric fields are left-aligned
2196 \row \i \c right
2197 \i Not currently used (by default, numerics are right-aligned)
2198 \row \i \c internal \i Puts any padding spaces between +/- and value
2199 \row \i \c bin \i Output \e and input only in binary
2200 \row \i \c oct \i Output \e and input only in octal
2201 \row \i \c dec \i Output \e and input only in decimal
2202 \row \i \c hex \i Output \e and input only in hexadecimal
2203 \row \i \c showbase
2204 \i Annotates numeric outputs with 0b, 0, or 0x if in \c bin,
2205 \c oct, or \c hex format
2206 \row \i \c showpoint \i Not currently used
2207 \row \i \c uppercase \i Uses 0B and 0X rather than 0b and 0x
2208 \row \i \c showpos \i Shows + for positive numeric values
2209 \row \i \c scientific \i Uses scientific notation for floating point values
2210 \row \i \c fixed \i Uses fixed-point notation for floating point values
2211 \endtable
2212
2213 Note that unless \c bin, \c oct, \c dec, or \c hex is set, the
2214 input base is octal if the value starts with 0, hexadecimal if it
2215 starts with 0x, binary if it starts with 0b, and decimal
2216 otherwise.
2217
2218 \sa setf(), unsetf()
2219*/
2220
2221/*!
2222 \fn int QTextStream::flags( int f )
2223
2224 \overload
2225
2226 Sets the stream flags to \a f. Returns the previous stream flags.
2227
2228 \sa setf(), unsetf(), flags()
2229*/
2230
2231/*!
2232 \fn int QTextStream::setf( int bits )
2233
2234 Sets the stream flag bits \a bits. Returns the previous stream
2235 flags.
2236
2237 Equivalent to \c{flags( flags() | bits )}.
2238
2239 \sa setf(), unsetf()
2240*/
2241
2242/*!
2243 \fn int QTextStream::setf( int bits, int mask )
2244
2245 \overload
2246
2247 Sets the stream flag bits \a bits with a bit mask \a mask. Returns
2248 the previous stream flags.
2249
2250 Equivalent to \c{flags( (flags() & ~mask) | (bits & mask) )}.
2251
2252 \sa setf(), unsetf()
2253*/
2254
2255/*!
2256 \fn int QTextStream::unsetf( int bits )
2257
2258 Clears the stream flag bits \a bits. Returns the previous stream
2259 flags.
2260
2261 Equivalent to \c{flags( flags() & ~mask )}.
2262
2263 \sa setf()
2264*/
2265
2266/*!
2267 \fn int QTextStream::width() const
2268
2269 Returns the field width. The default value is 0.
2270*/
2271
2272/*!
2273 \fn int QTextStream::width( int w )
2274
2275 \overload
2276
2277 Sets the field width to \a w. Returns the previous field width.
2278*/
2279
2280/*!
2281 \fn int QTextStream::fill() const
2282
2283 Returns the fill character. The default value is ' ' (space).
2284*/
2285
2286/*!
2287 \overload int QTextStream::fill( int f )
2288
2289 Sets the fill character to \a f. Returns the previous fill character.
2290*/
2291
2292/*!
2293 \fn int QTextStream::precision() const
2294
2295 Returns the precision. The default value is 6.
2296*/
2297
2298/*!
2299 \fn int QTextStream::precision( int p )
2300
2301 \overload
2302
2303 Sets the precision to \a p. Returns the previous precision setting.
2304*/
2305
2306
2307 /*****************************************************************************
2308 QTextStream manipulators
2309 *****************************************************************************/
2310
2311QTextStream &bin( QTextStream &s )
2312{
2313 s.setf(QTS::bin,QTS::basefield);
2314 return s;
2315}
2316
2317QTextStream &oct( QTextStream &s )
2318{
2319 s.setf(QTS::oct,QTS::basefield);
2320 return s;
2321}
2322
2323QTextStream &dec( QTextStream &s )
2324{
2325 s.setf(QTS::dec,QTS::basefield);
2326 return s;
2327}
2328
2329QTextStream &hex( QTextStream &s )
2330{
2331 s.setf(QTS::hex,QTS::basefield);
2332 return s;
2333}
2334
2335QTextStream &endl( QTextStream &s )
2336{
2337 return s << '\n';
2338}
2339
2340QTextStream &flush( QTextStream &s )
2341{
2342 if ( s.device() )
2343 s.device()->flush();
2344 return s;
2345}
2346
2347QTextStream &ws( QTextStream &s )
2348{
2349 s.skipWhiteSpace();
2350 return s;
2351}
2352
2353QTextStream &reset( QTextStream &s )
2354{
2355 s.reset();
2356 return s;
2357}
2358
2359
2360/*!
2361 \class QTextIStream qtextstream.h
2362 \reentrant
2363 \brief The QTextIStream class is a convenience class for input streams.
2364
2365 \ingroup io
2366 \ingroup text
2367
2368 This class provides a shorthand for creating simple input
2369 \l{QTextStream}s without having to pass a \e mode argument to the
2370 constructor.
2371
2372 This class makes it easy, for example, to write things like this:
2373 \code
2374 QString data = "123 456";
2375 int a, b;
2376 QTextIStream(&data) >> a >> b;
2377 \endcode
2378
2379 \sa QTextOStream
2380*/
2381
2382/*!
2383 \fn QTextIStream::QTextIStream( const QString *s )
2384
2385 Constructs a stream to read from the string \a s.
2386*/
2387/*!
2388 \fn QTextIStream::QTextIStream( QByteArray ba )
2389
2390 Constructs a stream to read from the array \a ba.
2391*/
2392/*!
2393 \fn QTextIStream::QTextIStream( FILE *f )
2394
2395 Constructs a stream to read from the file \a f.
2396*/
2397
2398
2399/*!
2400 \class QTextOStream
2401 \reentrant
2402 \brief The QTextOStream class is a convenience class for output streams.
2403
2404 \ingroup io
2405 \ingroup text
2406
2407 This class provides a shorthand for creating simple output
2408 \l{QTextStream}s without having to pass a \e mode argument to the
2409 constructor.
2410
2411 This makes it easy for example, to write things like this:
2412 \code
2413 QString result;
2414 QTextOStream(&result) << "pi = " << 3.14;
2415 \endcode
2416*/
2417
2418/*!
2419 \fn QTextOStream::QTextOStream( QString *s )
2420
2421 Constructs a stream to write to string \a s.
2422*/
2423/*!
2424 \fn QTextOStream::QTextOStream( QByteArray ba )
2425
2426 Constructs a stream to write to the array \a ba.
2427*/
2428/*!
2429 \fn QTextOStream::QTextOStream( FILE *f )
2430
2431 Constructs a stream to write to the file \a f.
2432*/
2433
2434
2435
2436/*!
2437 Sets the encoding of this stream to \a e, where \a e is one of the
2438 following values:
2439 \table
2440 \header \i Encoding \i Meaning
2441 \row \i Locale
2442 \i Uses local file format (Latin1 if locale is not set), but
2443 autodetecting Unicode(utf16) on input.
2444 \row \i Unicode
2445 \i Uses Unicode(utf16) for input and output. Output will be
2446 written in the order most efficient for the current platform
2447 (i.e. the order used internally in QString).
2448 \row \i UnicodeUTF8
2449 \i Using Unicode(utf8) for input and output. If you use it for
2450 input it will autodetect utf16 and use it instead of utf8.
2451 \row \i Latin1
2452 \i ISO-8859-1. Will not autodetect utf16.
2453 \row \i UnicodeNetworkOrder
2454 \i Uses network order Unicode(utf16) for input and output.
2455 Useful when reading Unicode data that does not start with the
2456 byte order marker.
2457 \row \i UnicodeReverse
2458 \i Uses reverse network order Unicode(utf16) for input and
2459 output. Useful when reading Unicode data that does not start
2460 with the byte order marker or when writing data that should be
2461 read by buggy Windows applications.
2462 \row \i RawUnicode
2463 \i Like Unicode, but does not write the byte order marker nor
2464 does it auto-detect the byte order. Useful only when writing to
2465 non-persistent storage used by a single process.
2466 \endtable
2467
2468 \c Locale and all Unicode encodings, except \c RawUnicode, will look
2469 at the first two bytes in an input stream to determine the byte
2470 order. The initial byte order marker will be stripped off before
2471 data is read.
2472
2473 Note that this function should be called before any data is read to
2474 or written from the stream.
2475
2476 \sa setCodec()
2477*/
2478
2479void QTextStream::setEncoding( Encoding e )
2480{
2481 if ( d->sourceType == QTextStreamPrivate::String )
2482 return;
2483
2484 switch ( e ) {
2485 case Unicode:
2486 mapper = 0;
2487 latin1 = FALSE;
2488 doUnicodeHeader = TRUE;
2489 internalOrder = TRUE;
2490 networkOrder = QChar::networkOrdered();
2491 break;
2492 case UnicodeUTF8:
2493#ifndef QT_NO_TEXTCODEC
2494 mapper = QTextCodec::codecForMib( 106 );
2495 latin1 = FALSE;
2496 doUnicodeHeader = TRUE;
2497 internalOrder = TRUE;
2498 networkOrder = QChar::networkOrdered();
2499#else
2500 mapper = 0;
2501 latin1 = TRUE;
2502 doUnicodeHeader = TRUE;
2503#endif
2504 break;
2505 case UnicodeNetworkOrder:
2506 mapper = 0;
2507 latin1 = FALSE;
2508 doUnicodeHeader = TRUE;
2509 internalOrder = QChar::networkOrdered();
2510 networkOrder = TRUE;
2511 break;
2512 case UnicodeReverse:
2513 mapper = 0;
2514 latin1 = FALSE;
2515 doUnicodeHeader = TRUE;
2516 internalOrder = !QChar::networkOrdered();
2517 networkOrder = FALSE;
2518 break;
2519 case RawUnicode:
2520 mapper = 0;
2521 latin1 = FALSE;
2522 doUnicodeHeader = FALSE;
2523 internalOrder = TRUE;
2524 networkOrder = QChar::networkOrdered();
2525 break;
2526 case Locale:
2527 latin1 = TRUE; // fallback to Latin-1
2528#ifndef QT_NO_TEXTCODEC
2529 mapper = QTextCodec::codecForLocale();
2530 // optimized Latin-1 processing
2531#if defined(Q_OS_WIN32)
2532 if ( GetACP() == 1252 )
2533 mapper = 0;
2534#endif
2535 if ( mapper && mapper->mibEnum() == 4 )
2536#endif
2537 mapper = 0;
2538
2539 doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
2540 break;
2541 case Latin1:
2542 mapper = 0;
2543 doUnicodeHeader = FALSE;
2544 latin1 = TRUE;
2545 break;
2546 }
2547}
2548
2549
2550#ifndef QT_NO_TEXTCODEC
2551/*!
2552 Sets the codec for this stream to \a codec. Will not try to
2553 autodetect Unicode.
2554
2555 Note that this function should be called before any data is read
2556 to/written from the stream.
2557
2558 \sa setEncoding(), codec()
2559*/
2560
2561void QTextStream::setCodec( QTextCodec *codec )
2562{
2563 if ( d->sourceType == QTextStreamPrivate::String )
2564 return; // QString does not need any codec
2565 mapper = codec;
2566 latin1 = ( codec->mibEnum() == 4 );
2567 if ( latin1 )
2568 mapper = 0;
2569 doUnicodeHeader = FALSE;
2570}
2571
2572/*!
2573 Returns the codec actually used for this stream.
2574
2575 If Unicode is automatically detected in input, a codec with \link
2576 QTextCodec::name() name() \endlink "ISO-10646-UCS-2" is returned.
2577
2578 \sa setCodec()
2579*/
2580
2581QTextCodec *QTextStream::codec()
2582{
2583 if ( mapper ) {
2584 return mapper;
2585 } else {
2586 // 4 is "ISO 8859-1", 1000 is "ISO-10646-UCS-2"
2587 return QTextCodec::codecForMib( latin1 ? 4 : 1000 );
2588 }
2589}
2590
2591#endif
2592
2593#endif // QT_NO_TEXTSTREAM
diff --git a/qmake/tools/qucom.cpp b/qmake/tools/qucom.cpp
new file mode 100644
index 0000000..6086a79
--- a/dev/null
+++ b/qmake/tools/qucom.cpp
@@ -0,0 +1,668 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of the QUcom classes
5**
6** Created : 990101
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qucom_p.h"
39
40// Standard types
41
42// {DE56510E-4E9F-4b76-A3C2-D1E2EF42F1AC}
43const QUuid TID_QUType_Null( 0xde56510e, 0x4e9f, 0x4b76, 0xa3, 0xc2, 0xd1, 0xe2, 0xef, 0x42, 0xf1, 0xac );
44const QUuid *QUType_Null::uuid() const { return &TID_QUType_Null; }
45const char *QUType_Null::desc() const { return "null"; }
46bool QUType_Null::canConvertFrom( QUObject *, QUType * ) { return FALSE; }
47bool QUType_Null::canConvertTo( QUObject *, QUType * ) { return FALSE; }
48bool QUType_Null::convertFrom( QUObject *, QUType * ) { return FALSE; }
49bool QUType_Null::convertTo( QUObject *, QUType * ) { return FALSE; }
50void QUType_Null::clear( QUObject *) {};
51int QUType_Null::serializeTo( QUObject *, QUBuffer * ) { return 0; }
52int QUType_Null::serializeFrom( QUObject *, QUBuffer * ) { return 0; };
53QUType_Null static_QUType_Null;
54
55
56// {7EE17B08-5419-47e2-9776-8EEA112DCAEC}
57const QUuid TID_QUType_enum( 0x7ee17b08, 0x5419, 0x47e2, 0x97, 0x76, 0x8e, 0xea, 0x11, 0x2d, 0xca, 0xec );
58QUType_enum static_QUType_enum;
59const QUuid *QUType_enum::uuid() const { return &TID_QUType_enum; }
60const char *QUType_enum::desc() const { return "enum"; }
61void QUType_enum::set( QUObject *o, int v )
62{
63 o->payload.i = v;
64 o->type = this;
65}
66
67bool QUType_enum::canConvertFrom( QUObject *o, QUType *t )
68{
69 if ( isEqual( t, &static_QUType_int ) ) // ## todo unsigned int?
70 return TRUE;
71
72 return t->canConvertTo( o, this );
73}
74
75bool QUType_enum::canConvertTo( QUObject * /*o*/, QUType *t )
76{
77 return isEqual( t, &static_QUType_int );
78}
79
80bool QUType_enum::convertFrom( QUObject *o, QUType *t )
81{
82 if ( isEqual( t, &static_QUType_int ) ) // ## todo unsigned int?
83 ;
84 else
85 return t->convertTo( o, this );
86
87 o->type = this;
88 return TRUE;
89}
90
91bool QUType_enum::convertTo( QUObject *o, QUType *t )
92{
93 if ( isEqual( t, &static_QUType_int ) ) {
94 o->type = &static_QUType_int;
95 return TRUE;
96 }
97 return FALSE;
98}
99
100int QUType_enum::serializeTo( QUObject *, QUBuffer * )
101{
102 return 0;
103}
104
105int QUType_enum::serializeFrom( QUObject *, QUBuffer * )
106{
107 return 0;
108}
109
110// {8AC26448-5AB4-49eb-968C-8F30AB13D732}
111const QUuid TID_QUType_ptr( 0x8ac26448, 0x5ab4, 0x49eb, 0x96, 0x8c, 0x8f, 0x30, 0xab, 0x13, 0xd7, 0x32 );
112QUType_ptr static_QUType_ptr;
113const QUuid *QUType_ptr::uuid() const { return &TID_QUType_ptr; }
114const char *QUType_ptr::desc() const { return "ptr"; }
115
116void QUType_ptr::set( QUObject *o, const void* v )
117{
118 o->payload.ptr = (void*) v;
119 o->type = this;
120}
121
122bool QUType_ptr::canConvertFrom( QUObject *o, QUType *t )
123{
124 return t->canConvertTo( o, this );
125}
126
127bool QUType_ptr::canConvertTo( QUObject *, QUType * )
128{
129 return FALSE;
130}
131
132bool QUType_ptr::convertFrom( QUObject *o, QUType *t )
133{
134 return t->convertTo( o, this );
135}
136
137bool QUType_ptr::convertTo( QUObject *, QUType * )
138{
139 return FALSE;
140}
141
142int QUType_ptr::serializeTo( QUObject *, QUBuffer * )
143{
144 return 0;
145}
146
147int QUType_ptr::serializeFrom( QUObject *, QUBuffer * )
148{
149 return 0;
150}
151
152// {97A2594D-6496-4402-A11E-55AEF2D4D25C}
153const QUuid TID_QUType_iface( 0x97a2594d, 0x6496, 0x4402, 0xa1, 0x1e, 0x55, 0xae, 0xf2, 0xd4, 0xd2, 0x5c );
154QUType_iface static_QUType_iface;
155const QUuid *QUType_iface::uuid() const { return &TID_QUType_iface; }
156const char *QUType_iface::desc() const { return "UnknownInterface"; }
157
158void QUType_iface::set( QUObject *o, QUnknownInterface* iface )
159{
160 o->payload.iface = iface;
161 o->type = this;
162}
163
164bool QUType_iface::canConvertFrom( QUObject *o, QUType *t )
165{
166 return t->canConvertTo( o, this );
167}
168
169bool QUType_iface::canConvertTo( QUObject *, QUType * )
170{
171 return FALSE;
172}
173
174bool QUType_iface::convertFrom( QUObject *o, QUType *t )
175{
176 return t->convertTo( o, this );
177}
178
179bool QUType_iface::convertTo( QUObject *, QUType * )
180{
181 return FALSE;
182}
183
184int QUType_iface::serializeTo( QUObject *, QUBuffer * )
185{
186 return 0;
187}
188
189int QUType_iface::serializeFrom( QUObject *, QUBuffer * )
190{
191 return 0;
192}
193
194// {2F358164-E28F-4bf4-9FA9-4E0CDCABA50B}
195const QUuid TID_QUType_idisp( 0x2f358164, 0xe28f, 0x4bf4, 0x9f, 0xa9, 0x4e, 0xc, 0xdc, 0xab, 0xa5, 0xb );
196QUType_idisp static_QUType_idisp;
197const QUuid *QUType_idisp::uuid() const { return &TID_QUType_idisp; }
198const char *QUType_idisp::desc() const { return "DispatchInterface"; }
199
200void QUType_idisp::set( QUObject *o, QDispatchInterface* idisp )
201{
202 o->payload.idisp = idisp;
203 o->type = this;
204}
205
206bool QUType_idisp::canConvertFrom( QUObject *o, QUType *t )
207{
208 return t->canConvertTo( o, this );
209}
210
211bool QUType_idisp::canConvertTo( QUObject * /*o*/, QUType *t )
212{
213 return isEqual( t, &static_QUType_iface );
214}
215
216bool QUType_idisp::convertFrom( QUObject *o, QUType *t )
217{
218 return t->convertTo( o, this );
219}
220
221bool QUType_idisp::convertTo( QUObject *o, QUType *t )
222{
223#ifndef QT_NO_COMPONENT
224 if ( isEqual( t, &static_QUType_iface ) ) {
225 o->payload.iface = (QUnknownInterface*)o->payload.idisp;
226 o->type = &static_QUType_iface;
227 return TRUE;
228 }
229#endif
230 return FALSE;
231}
232
233int QUType_idisp::serializeTo( QUObject *, QUBuffer * )
234{
235 return 0;
236}
237
238int QUType_idisp::serializeFrom( QUObject *, QUBuffer * )
239{
240 return 0;
241}
242
243// {CA42115D-13D0-456c-82B5-FC10187F313E}
244const QUuid TID_QUType_bool( 0xca42115d, 0x13d0, 0x456c, 0x82, 0xb5, 0xfc, 0x10, 0x18, 0x7f, 0x31, 0x3e );
245QUType_bool static_QUType_bool;
246const QUuid *QUType_bool::uuid() const { return &TID_QUType_bool; }
247const char *QUType_bool::desc() const { return "bool"; }
248
249void QUType_bool::set( QUObject *o, bool v )
250{
251 o->payload.b = v;
252 o->type = this;
253}
254
255bool QUType_bool::canConvertFrom( QUObject *o, QUType *t )
256{
257 return t->canConvertTo( o, this );
258}
259
260bool QUType_bool::canConvertTo( QUObject *, QUType * )
261{
262 return FALSE;
263}
264
265bool QUType_bool::convertFrom( QUObject *o, QUType *t )
266{
267 return t->convertTo( o, this );
268}
269
270bool QUType_bool::convertTo( QUObject *, QUType * )
271{
272 return FALSE;
273}
274
275int QUType_bool::serializeTo( QUObject *, QUBuffer * )
276{
277 return 0;
278}
279
280int QUType_bool::serializeFrom( QUObject *, QUBuffer * )
281{
282 return 0;
283}
284
285// {53C1F3BE-73C3-4c7d-9E05-CCF09EB676B5}
286const QUuid TID_QUType_int( 0x53c1f3be, 0x73c3, 0x4c7d, 0x9e, 0x5, 0xcc, 0xf0, 0x9e, 0xb6, 0x76, 0xb5 );
287QUType_int static_QUType_int;
288const QUuid *QUType_int::uuid() const { return &TID_QUType_int; }
289const char *QUType_int::desc() const { return "int"; }
290
291void QUType_int::set( QUObject *o, int v )
292{
293 o->payload.i = v;
294 o->type = this;
295}
296
297bool QUType_int::canConvertFrom( QUObject *o, QUType *t )
298{
299 if ( isEqual( t, &static_QUType_double ) ||
300 isEqual( t, &static_QUType_float ) )
301 return TRUE;
302
303 return t->canConvertTo( o, this );
304}
305
306bool QUType_int::canConvertTo( QUObject * /*o*/, QUType *t )
307{
308 return isEqual( t, &static_QUType_double ) ||
309 isEqual( t, &static_QUType_float );
310}
311
312bool QUType_int::convertFrom( QUObject *o, QUType *t )
313{
314 if ( isEqual( t, &static_QUType_double ) )
315 o->payload.i = (long)o->payload.d;
316 else if ( isEqual( t, &static_QUType_float ) )
317 o->payload.i = (long)o->payload.f;
318 else
319 return t->convertTo( o, this );
320
321 o->type = this;
322 return TRUE;
323}
324
325bool QUType_int::convertTo( QUObject *o, QUType *t )
326{
327 if ( isEqual( t, &static_QUType_double ) ) {
328 o->payload.d = (double)o->payload.i;
329 o->type = &static_QUType_double;
330 } else if ( isEqual( t, &static_QUType_float ) ) {
331 o->payload.f = (float)o->payload.i;
332 o->type = &static_QUType_float;
333 } else
334 return FALSE;
335 return TRUE;
336}
337
338int QUType_int::serializeTo( QUObject *, QUBuffer * )
339{
340 return 0;
341}
342
343int QUType_int::serializeFrom( QUObject *, QUBuffer * )
344{
345 return 0;
346}
347
348// {5938712A-C496-11D5-8CB2-00C0F03BC0F3}
349const QUuid TID_QUType_uint( 0x5938712a, 0xc496, 0x11d5, 0x8c, 0xb2, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3);
350QUType_uint static_QUType_uint;
351const QUuid *QUType_uint::uuid() const { return &TID_QUType_uint; }
352const char *QUType_uint::desc() const { return "uint"; }
353
354void QUType_uint::set( QUObject *o, uint v )
355{
356 o->payload.ui = v;
357 o->type = this;
358}
359
360bool QUType_uint::canConvertFrom( QUObject *o, QUType *t )
361{
362 return t->canConvertTo( o, this );
363}
364
365bool QUType_uint::canConvertTo( QUObject * /*o*/, QUType * /*t*/ )
366{
367 return FALSE;
368}
369
370bool QUType_uint::convertFrom( QUObject *o, QUType *t )
371{
372 return t->convertTo( o, this );
373}
374
375bool QUType_uint::convertTo( QUObject * /*o*/, QUType * /*t*/ )
376{
377 return FALSE;
378}
379
380int QUType_uint::serializeTo( QUObject *, QUBuffer * )
381{
382 return 0;
383}
384
385int QUType_uint::serializeFrom( QUObject *, QUBuffer * )
386{
387 return 0;
388}
389
390// {2D0974E5-0BA6-4ec2-8837-C198972CB48C}
391const QUuid TID_QUType_double( 0x2d0974e5, 0xba6, 0x4ec2, 0x88, 0x37, 0xc1, 0x98, 0x97, 0x2c, 0xb4, 0x8c );
392QUType_double static_QUType_double;
393const QUuid *QUType_double::uuid() const { return &TID_QUType_double; }
394const char *QUType_double::desc() const {return "double"; }
395
396void QUType_double::set( QUObject *o, double v )
397{
398 o->payload.d = v;
399 o->type = this;
400}
401
402bool QUType_double::canConvertFrom( QUObject *o, QUType *t )
403{
404 if ( isEqual( t, &static_QUType_int ) ||
405 isEqual( t, &static_QUType_float) )
406 return TRUE;
407
408 return t->canConvertTo( o, this );
409}
410
411bool QUType_double::canConvertTo( QUObject * /*o*/, QUType *t )
412{
413 return isEqual( t, &static_QUType_int ) ||
414 isEqual( t, &static_QUType_float );
415}
416
417bool QUType_double::convertFrom( QUObject *o, QUType *t )
418{
419 if ( isEqual( t, &static_QUType_int ) )
420 o->payload.d = (double)o->payload.i;
421 else if ( isEqual( t, &static_QUType_float ) )
422 o->payload.d = (double)o->payload.f;
423 else
424 return t->convertTo( o, this );
425
426 o->type = this;
427 return TRUE;
428}
429
430bool QUType_double::convertTo( QUObject *o, QUType *t )
431{
432 if ( isEqual( t, &static_QUType_int ) ) {
433 o->payload.i = (int) o->payload.d;
434 o->type = &static_QUType_int;
435 } else if ( isEqual( t, &static_QUType_double ) ) {
436 o->payload.d = (double) o->payload.f;
437 o->type = &static_QUType_double;
438 } else
439 return FALSE;
440 return TRUE;
441}
442
443int QUType_double::serializeTo( QUObject *, QUBuffer * )
444{
445 return 0;
446}
447
448int QUType_double::serializeFrom( QUObject *, QUBuffer * )
449{
450 return 0;
451}
452
453
454// {544C5175-6993-4486-B04D-CEC4D21BF4B9 }
455const QUuid TID_QUType_float( 0x544c5175, 0x6993, 0x4486, 0xb0, 0x4d, 0xce, 0xc4, 0xd2, 0x1b, 0xf4, 0xb9 );
456QUType_float static_QUType_float;
457const QUuid *QUType_float::uuid() const { return &TID_QUType_float; }
458const char *QUType_float::desc() const {return "float"; }
459
460void QUType_float::set( QUObject *o, float v )
461{
462 o->payload.f = v;
463 o->type = this;
464}
465
466bool QUType_float::canConvertFrom( QUObject *o, QUType *t )
467{
468 if ( isEqual( t, &static_QUType_int ) ||
469 isEqual( t, &static_QUType_double ) )
470 return TRUE;
471
472 return t->canConvertTo( o, this );
473}
474
475bool QUType_float::canConvertTo( QUObject * /*o*/, QUType *t )
476{
477 return isEqual( t, &static_QUType_int ) ||
478 isEqual( t, &static_QUType_double );
479}
480
481bool QUType_float::convertFrom( QUObject *o, QUType *t )
482{
483 if ( isEqual( t, &static_QUType_int ) )
484 o->payload.f = (float)o->payload.i;
485 else if ( isEqual( t, &static_QUType_double ) )
486 o->payload.f = (float)o->payload.d;
487 else
488 return t->convertTo( o, this );
489
490 o->type = this;
491 return TRUE;
492}
493
494bool QUType_float::convertTo( QUObject *o, QUType *t )
495{
496 if ( isEqual( t, &static_QUType_int ) ) {
497 o->payload.i = (int) o->payload.f;
498 o->type = &static_QUType_int;
499 } else if ( isEqual( t, &static_QUType_double ) ) {
500 o->payload.d = (double) o->payload.f;
501 o->type = &static_QUType_double;
502 } else
503 return FALSE;
504 return TRUE;
505}
506
507int QUType_float::serializeTo( QUObject *, QUBuffer * )
508{
509 return 0;
510}
511
512int QUType_float::serializeFrom( QUObject *, QUBuffer * )
513{
514 return 0;
515}
516
517// {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9}
518const QUuid TID_QUType_charstar( 0xefcdd1d4, 0x77a3, 0x4b8e, 0x8d, 0x46, 0xdc, 0x14, 0xb8, 0xd3, 0x93, 0xe9 );
519QUType_charstar static_QUType_charstar;
520const QUuid *QUType_charstar::uuid() const { return &TID_QUType_charstar; }
521const char *QUType_charstar::desc() const { return "char*"; }
522
523void QUType_charstar::set( QUObject *o, const char* v, bool take )
524{
525 if ( take ) {
526 if ( v ) {
527 o->payload.charstar.ptr = new char[ strlen(v) + 1 ];
528 strcpy( o->payload.charstar.ptr, v );
529 } else {
530 o->payload.charstar.ptr = 0;
531 }
532 o->payload.charstar.owner = TRUE;
533 } else {
534 o->payload.charstar.ptr = (char*) v;
535 o->payload.charstar.owner = FALSE;
536 }
537 o->type = this;
538}
539
540bool QUType_charstar::canConvertFrom( QUObject *o, QUType *t )
541{
542 return t->canConvertTo( o, this );
543}
544
545bool QUType_charstar::canConvertTo( QUObject *, QUType * )
546{
547 return FALSE;
548}
549
550bool QUType_charstar::convertFrom( QUObject *o, QUType *t )
551{
552 return t->convertTo( o, this );
553}
554
555bool QUType_charstar::convertTo( QUObject *, QUType * )
556{
557 return FALSE;
558}
559
560void QUType_charstar::clear( QUObject *o )
561{
562 if ( o->payload.charstar.owner )
563 delete [] o->payload.charstar.ptr;
564 o->payload.charstar.ptr = 0;
565}
566
567int QUType_charstar::serializeTo( QUObject *, QUBuffer * )
568{
569 return 0;
570}
571
572int QUType_charstar::serializeFrom( QUObject *, QUBuffer * )
573{
574 return 0;
575}
576
577
578// Qt specific types
579
580// {44C2A547-01E7-4e56-8559-35AF9D2F42B7}
581const QUuid TID_QUType_QString( 0x44c2a547, 0x1e7, 0x4e56, 0x85, 0x59, 0x35, 0xaf, 0x9d, 0x2f, 0x42, 0xb7 );
582QUType_QString static_QUType_QString;
583const QUuid *QUType_QString::uuid() const { return &TID_QUType_QString; }
584const char *QUType_QString::desc() const { return "QString"; }
585
586void QUType_QString::set( QUObject *o, const QString& v )
587{
588 o->payload.ptr = new QString( v );
589 o->type = this;
590}
591
592bool QUType_QString::canConvertFrom( QUObject *o, QUType *t )
593{
594 if ( isEqual( t, &static_QUType_charstar ) ||
595 isEqual( t, &static_QUType_double ) ||
596 isEqual( t, &static_QUType_float ) ||
597 isEqual( t, &static_QUType_int ) )
598 return TRUE;
599
600 return t->canConvertTo( o, this );
601}
602
603bool QUType_QString::canConvertTo( QUObject * /*o*/, QUType *t )
604{
605 return isEqual( t, &static_QUType_charstar ) ||
606 isEqual( t, &static_QUType_int ) ||
607 isEqual( t, &static_QUType_double ) ||
608 isEqual( t, &static_QUType_float );
609}
610
611bool QUType_QString::convertFrom( QUObject *o, QUType *t )
612{
613 QString *str = 0;
614 if ( isEqual( t, &static_QUType_charstar ) )
615 str = new QString( o->payload.charstar.ptr );
616 else if ( isEqual( t, &static_QUType_double ) )
617 str = new QString( QString::number( o->payload.d ) );
618 else if ( isEqual( t, &static_QUType_float ) )
619 str = new QString( QString::number( o->payload.f ) );
620 else if ( isEqual( t, &static_QUType_int ) )
621 str = new QString( QString::number( o->payload.i ) );
622 else
623 return t->convertTo( o, this );
624
625 o->type->clear( o );
626 o->payload.ptr = str;
627 o->type = this;
628 return TRUE;
629}
630
631bool QUType_QString::convertTo( QUObject *o, QUType *t )
632{
633 QString *str = (QString *)o->payload.ptr;
634 if ( isEqual( t, &static_QUType_charstar ) ) {
635 o->payload.charstar.ptr = qstrdup( str->local8Bit().data() );
636 o->payload.charstar.owner = TRUE;
637 o->type = &static_QUType_charstar;
638 } else if ( isEqual( t, &static_QUType_int ) ) {
639 o->payload.l = str->toLong();
640 o->type = &static_QUType_int;
641 } else if ( isEqual( t, &static_QUType_double ) ) {
642 o->payload.d = str->toDouble();
643 o->type = &static_QUType_double;
644 } else if ( isEqual( t, &static_QUType_float ) ) {
645 o->payload.d = str->toFloat();
646 o->type = &static_QUType_float;
647 } else {
648 return FALSE;
649 }
650 delete str;
651 return TRUE;
652}
653
654int QUType_QString::serializeTo( QUObject *, QUBuffer * )
655{
656 return 0;
657}
658
659int QUType_QString::serializeFrom( QUObject *, QUBuffer * )
660{
661 return 0;
662}
663
664void QUType_QString::clear( QUObject *o )
665{
666 delete (QString*)o->payload.ptr;
667 o->payload.ptr = 0;
668}
diff --git a/qmake/tools/quuid.cpp b/qmake/tools/quuid.cpp
new file mode 100644
index 0000000..fd99abf
--- a/dev/null
+++ b/qmake/tools/quuid.cpp
@@ -0,0 +1,230 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QUuid class
5**
6** Copyright (C) 2000-2001 Trolltech AS. All rights reserved.
7**
8** This file is part of the tools module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "quuid.h"
37
38#include <qdatastream.h>
39
40/*!
41 \class QUuid quuid.h
42 \reentrant
43 \brief The QUuid class defines a Universally Unique Identifier (UUID).
44
45 \internal
46
47 For objects or declarations that need to be identified uniquely, UUIDs (also known as GUIDs) are widely
48 used in order to assign a fixed and easy to compare value to this object or declaration. The 128bit value
49 of an UUID is generated by an algorithm that guarantees a value that is unique in time and space.
50
51 In Qt, UUIDs are wrapped by the QUuid struct which provides convenience functions for comparing and coping
52 this value. The QUuid struct is used in Qt's component model to identify interfaces. Most platforms provide a tool to
53 generate new UUIDs (uuidgen, guidgen), and the Qt distribution includes a graphical tool \e quuidgen that generates
54 the UUIDs in a programmer friendly format.
55
56 \sa QUnknownInterface
57*/
58
59/*!
60 \fn QUuid::QUuid()
61
62 Creates the null UUID {00000000-0000-0000-0000-000000000000}.
63*/
64
65/*!
66 \fn QUuid::QUuid( uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8 )
67
68 Creates an UUID with the value specified by the parameters, \a l, \a
69 w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a b8.
70
71 Example:
72 \code
73 // {67C8770B-44F1-410A-AB9A-F9B5446F13EE}
74 QUuid IID_MyInterface( 0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee )
75 \endcode
76*/
77
78/*!
79 \fn QUuid::QUuid( const QUuid &orig )
80
81 Creates a copy of the QUuid \a orig.
82*/
83#ifndef QT_NO_QUUID_STRING
84/*!
85 Creates a QUuid object from the string \a text. Right now, the function
86 can only convert the format {12345678-1234-1234-1234-123456789ABC} and
87 will create the null UUID when the conversion fails.
88*/
89QUuid::QUuid( const QString &text )
90{
91 bool ok;
92 QString temp = text.upper();
93
94 data1 = temp.mid( 1, 8 ).toULong( &ok, 16 );
95 if ( !ok ) {
96 *this = QUuid();
97 return;
98 }
99
100 data2 = temp.mid( 10, 4 ).toUInt( &ok, 16 );
101 if ( !ok ) {
102 *this = QUuid();
103 return;
104 }
105 data3 = temp.mid( 15, 4 ).toUInt( &ok, 16 );
106 if ( !ok ) {
107 *this = QUuid();
108 return;
109 }
110 data4[0] = temp.mid( 20, 2 ).toUInt( &ok, 16 );
111 if ( !ok ) {
112 *this = QUuid();
113 return;
114 }
115 data4[1] = temp.mid( 22, 2 ).toUInt( &ok, 16 );
116 if ( !ok ) {
117 *this = QUuid();
118 return;
119 }
120 for ( int i = 2; i<8; i++ ) {
121 data4[i] = temp.mid( 25 + (i-2)*2, 2 ).toUShort( &ok, 16 );
122 if ( !ok ) {
123 *this = QUuid();
124 return;
125 }
126 }
127}
128
129/*!
130 \overload
131*/
132QUuid::QUuid( const char *text )
133{
134 *this = QUuid( QString(text) );
135}
136#endif
137/*!
138 \fn QUuid QUuid::operator=(const QUuid &uuid )
139
140 Assigns the value of \a uuid to this QUuid object.
141*/
142
143/*!
144 \fn bool QUuid::operator==(const QUuid &other) const
145
146 Returns TRUE if this QUuid and the \a other QUuid are identical, otherwise returns FALSE.
147*/
148
149/*!
150 \fn bool QUuid::operator!=(const QUuid &other) const
151
152 Returns TRUE if this QUuid and the \a other QUuid are different, otherwise returns FALSE.
153*/
154#ifndef QT_NO_QUUID_STRING
155/*!
156 \fn QUuid::operator QString() const
157
158 Returns the string representation of the uuid.
159
160 \sa toString()
161*/
162
163/*!
164 QString QUuid::toString() const
165
166 Returns the string representation of the uuid.
167*/
168QString QUuid::toString() const
169{
170 QString result;
171
172 result = "{" + QString::number( data1, 16 ).rightJustify( 8, '0' ) + "-";
173 result += QString::number( (int)data2, 16 ).rightJustify( 4, '0' ) + "-";
174 result += QString::number( (int)data3, 16 ).rightJustify( 4, '0' ) + "-";
175 result += QString::number( (int)data4[0], 16 ).rightJustify( 2, '0' );
176 result += QString::number( (int)data4[1], 16 ).rightJustify( 2, '0' ) + "-";
177 for ( int i = 2; i < 8; i++ )
178 result += QString::number( (int)data4[i], 16 ).rightJustify( 2, '0' );
179
180 return result + "}";
181}
182#endif
183
184#ifndef QT_NO_DATASTREAM
185/*!
186 \relates QUuid
187 Writes the \a id to the datastream \a s.
188*/
189QDataStream &operator<<( QDataStream &s, const QUuid &id )
190{
191 s << (Q_UINT32)id.data1;
192 s << (Q_UINT16)id.data2;
193 s << (Q_UINT16)id.data3;
194 for (int i = 0; i < 8; i++ )
195 s << (Q_UINT8)id.data4[i];
196 return s;
197}
198
199/*!
200 \relates QUuid
201 Reads a universally unique id from from the stream \a s into \a id.
202*/
203QDataStream &operator>>( QDataStream &s, QUuid &id )
204{
205 Q_UINT32 u32;
206 Q_UINT16 u16;
207 Q_UINT8 u8;
208 s >> u32;
209 id.data1 = u32;
210 s >> u16;
211 id.data2 = u16;
212 s >> u16;
213 id.data3 = u16;
214 for (int i = 0; i < 8; i++ ) {
215 s >> u8;
216 id.data4[i] = u8;
217 }
218 return s;
219}
220#endif
221
222/*!
223 Returns TRUE if this is the null UUID {00000000-0000-0000-0000-000000000000}, otherwise returns FALSE.
224*/
225bool QUuid::isNull() const
226{
227 return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
228 data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
229 data1 == 0 && data2 == 0 && data3 == 0;
230}
diff --git a/qmake/tools/qwaitcondition_unix.cpp b/qmake/tools/qwaitcondition_unix.cpp
new file mode 100644
index 0000000..99c1014
--- a/dev/null
+++ b/qmake/tools/qwaitcondition_unix.cpp
@@ -0,0 +1,310 @@
1/****************************************************************************
2** $Id$
3**
4** QWaitCondition class for Unix
5**
6** Created : 20010725
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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
14** LICENSE.QPL included in the packaging of this file.
15**
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
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
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.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#if defined(QT_THREAD_SUPPORT)
39
40#include "qplatformdefs.h"
41
42typedef pthread_mutex_t Q_MUTEX_T;
43
44#include "qwaitcondition.h"
45#include "qmutex.h"
46#include "qmutex_p.h"
47
48#include <errno.h>
49#include <string.h>
50
51
52struct QWaitConditionPrivate {
53 pthread_cond_t cond;
54};
55
56
57/*!
58 \class QWaitCondition qwaitcondition.h
59 \threadsafe
60 \brief The QWaitCondition class allows waiting/waking for conditions between threads.
61
62 \ingroup thread
63 \ingroup environment
64
65 QWaitConditions allow a thread to tell other threads that some
66 sort of condition has been met; one or many threads can block
67 waiting for a QWaitCondition to set a condition with wakeOne() or
68 wakeAll(). Use wakeOne() to wake one randomly selected event or
69 wakeAll() to wake them all. For example, say we have three tasks
70 that should be performed every time the user presses a key; each
71 task could be split into a thread, each of which would have a
72 run() body like this:
73
74 \code
75 QWaitCondition key_pressed;
76
77 for (;;) {
78 key_pressed.wait(); // This is a QWaitCondition global variable
79 // Key was pressed, do something interesting
80 do_something();
81 }
82 \endcode
83
84 A fourth thread would read key presses and wake the other three
85 threads up every time it receives one, like this:
86
87 \code
88 QWaitCondition key_pressed;
89
90 for (;;) {
91 getchar();
92 // Causes any thread in key_pressed.wait() to return from
93 // that method and continue processing
94 key_pressed.wakeAll();
95 }
96 \endcode
97
98 Note that the order the three threads are woken up in is
99 undefined, and that if some or all of the threads are still in
100 do_something() when the key is pressed, they won't be woken up
101 (since they're not waiting on the condition variable) and so the
102 task will not be performed for that key press. This can be
103 avoided by, for example, doing something like this:
104
105 \code
106 QMutex mymutex;
107 QWaitCondition key_pressed;
108 int mycount=0;
109
110 // Worker thread code
111 for (;;) {
112 key_pressed.wait(); // This is a QWaitCondition global variable
113 mymutex.lock();
114 mycount++;
115 mymutex.unlock();
116 do_something();
117 mymutex.lock();
118 mycount--;
119 mymutex.unlock();
120 }
121
122 // Key reading thread code
123 for (;;) {
124 getchar();
125 mymutex.lock();
126 // Sleep until there are no busy worker threads
127 while( count > 0 ) {
128 mymutex.unlock();
129 sleep( 1 );
130 mymutex.lock();
131 }
132 mymutex.unlock();
133 key_pressed.wakeAll();
134 }
135 \endcode
136
137 The mutexes are necessary because the results of two threads
138 attempting to change the value of the same variable simultaneously
139 are unpredictable.
140*/
141
142/*!
143 Constructs a new event signalling, i.e. wait condition, object.
144*/
145QWaitCondition::QWaitCondition()
146{
147 d = new QWaitConditionPrivate;
148
149 int ret = pthread_cond_init(&d->cond, NULL);
150
151#ifdef QT_CHECK_RANGE
152 if (ret)
153 qWarning( "Wait condition init failure: %s", strerror( ret ) );
154#endif
155}
156
157
158/*!
159 Deletes the event signalling, i.e. wait condition, object.
160*/
161QWaitCondition::~QWaitCondition()
162{
163 int ret = pthread_cond_destroy(&d->cond);
164
165 if (ret) {
166#ifdef QT_CHECK_RANGE
167 qWarning( "Wait condition destroy failure: %s", strerror( ret ) );
168#endif
169
170 // seems we have threads waiting on us, lets wake them up
171 pthread_cond_broadcast(&d->cond);
172 }
173
174 delete d;
175}
176
177/*!
178 This wakes one thread waiting on the QWaitCondition. The thread
179 that is woken up depends on the operating system's scheduling
180 policies, and cannot be controlled or predicted.
181
182 \sa wakeAll()
183*/
184void QWaitCondition::wakeOne()
185{
186 int ret = pthread_cond_signal(&d->cond);
187
188#ifdef QT_CHECK_RANGE
189 if (ret)
190 qWarning("Wait condition wakeOne failure: %s", strerror(ret));
191#endif
192}
193
194/*!
195 This wakes all threads waiting on the QWaitCondition. The order in
196 which the threads are woken up depends on the operating system's
197 scheduling policies, and cannot be controlled or predicted.
198
199 \sa wakeOne()
200*/
201void QWaitCondition::wakeAll()
202{
203 int ret = pthread_cond_broadcast(&d->cond);
204
205#ifdef QT_CHECK_RANGE
206 if (ret)
207 qWarning("Wait condition wakeAll failure: %s", strerror(ret));
208#endif
209}
210
211/*!
212 Wait on the thread event object. The thread calling this will
213 block until either of these conditions is met:
214 \list
215 \i Another thread signals it using wakeOne() or wakeAll(). This
216 function will return TRUE in this case.
217 \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
218 default), then the wait will never timeout (the event must be
219 signalled). This function will return FALSE if the wait timed
220 out.
221 \endlist
222
223 \sa wakeOne(), wakeAll()
224*/
225bool QWaitCondition::wait(unsigned long time)
226{
227 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
228
229 int ret;
230 if (time != ULONG_MAX) {
231 struct timeval tv;
232 gettimeofday(&tv, 0);
233
234 timespec ti;
235 ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000;
236 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
237 ti.tv_nsec %= 1000000000;
238
239 ret = pthread_cond_timedwait(&d->cond, &mutex, &ti);
240 } else
241 ret = pthread_cond_wait(&d->cond, &mutex);
242
243#ifdef QT_CHECK_RANGE
244 if (ret && ret != ETIMEDOUT)
245 qWarning("Wait condition wait failure: %s",strerror(ret));
246#endif
247
248 return (ret == 0);
249}
250
251/*!
252 \overload
253
254 Release the locked \a mutex and wait on the thread event object.
255 The \a mutex must be initially locked by the calling thread. If \a
256 mutex is not in a locked state, this function returns immediately.
257 If \a mutex is a recursive mutex, this function returns
258 immediately. The \a mutex will be unlocked, and the calling thread
259 will block until either of these conditions is met:
260 \list
261 \i Another thread signals it using wakeOne() or wakeAll(). This
262 function will return TRUE in this case.
263 \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
264 default), then the wait will never timeout (the event must be
265 signalled). This function will return FALSE if the wait timed
266 out.
267 \endlist
268
269 The mutex will be returned to the same locked state. This function
270 is provided to allow the atomic transition from the locked state
271 to the wait state.
272
273 \sa wakeOne(), wakeAll()
274*/
275bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
276{
277 if (! mutex)
278 return FALSE;
279
280 if (mutex->d->type() == Q_MUTEX_RECURSIVE) {
281#ifdef QT_CHECK_RANGE
282 qWarning("Wait condition warning: using recursive mutexes with\n"
283 " wait conditions is undefined!");
284#endif
285 return FALSE;
286 }
287
288 int ret;
289 if (time != ULONG_MAX) {
290 struct timeval tv;
291 gettimeofday(&tv, 0);
292
293 timespec ti;
294 ti.tv_nsec = (tv.tv_usec * 1000) + (time % 1000) * 1000;
295 ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
296 ti.tv_nsec %= 1000000000;
297
298 ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti);
299 } else
300 ret = pthread_cond_wait(&d->cond, &mutex->d->handle);
301
302#ifdef QT_CHECK_RANGE
303 if (ret && ret != ETIMEDOUT)
304 qWarning("Wait condition wait failure: %s",strerror(ret));
305#endif
306
307 return (ret == 0);
308}
309
310#endif // QT_THREAD_SUPPORT