summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/CHANGES40
-rw-r--r--qmake/LICENSE.GPL349
-rw-r--r--qmake/Makefile173
-rw-r--r--qmake/generators/mac/metrowerks_xml.cpp822
-rw-r--r--qmake/generators/mac/metrowerks_xml.h69
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp983
-rw-r--r--qmake/generators/mac/pbuilder_pbx.h68
-rw-r--r--qmake/generators/unix/unixmake.cpp520
-rw-r--r--qmake/generators/unix/unixmake.h71
-rw-r--r--qmake/generators/unix/unixmake2.cpp1048
-rw-r--r--qmake/generators/win32/borland_bmake.cpp477
-rw-r--r--qmake/generators/win32/borland_bmake.h59
-rw-r--r--qmake/generators/win32/msvc_dsp.cpp955
-rw-r--r--qmake/generators/win32/msvc_dsp.h73
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp488
-rw-r--r--qmake/generators/win32/msvc_nmake.h59
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp1955
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h775
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp1050
-rw-r--r--qmake/generators/win32/msvc_vcproj.h129
-rw-r--r--qmake/generators/win32/winmakefile.cpp360
-rw-r--r--qmake/generators/win32/winmakefile.h72
-rw-r--r--qmake/include/private/qapplication_p.h87
-rw-r--r--qmake/include/private/qcolor_p.h63
-rw-r--r--qmake/include/private/qcom_p.h337
-rw-r--r--qmake/include/private/qcomlibrary_p.h79
-rw-r--r--qmake/include/private/qcomplextext_p.h123
-rw-r--r--qmake/include/private/qcomponentfactory_p.h73
-rw-r--r--qmake/include/private/qcriticalsection_p.h80
-rw-r--r--qmake/include/private/qdir_p.h78
-rw-r--r--qmake/include/private/qeffects_p.h78
-rw-r--r--qmake/include/private/qeventloop_p.h74
-rw-r--r--qmake/include/private/qfiledefs_p.h64
-rw-r--r--qmake/include/private/qfontcodecs_p.h368
-rw-r--r--qmake/include/private/qfontdata_p.h479
-rw-r--r--qmake/include/private/qgfxdriverinterface_p.h56
-rw-r--r--qmake/include/private/qgpluginmanager_p.h107
-rw-r--r--qmake/include/private/qimageformatinterface_p.h75
-rw-r--r--qmake/include/private/qinputcontext_p.h121
-rw-r--r--qmake/include/private/qinternal_p.h157
-rw-r--r--qmake/include/private/qkbddriverinterface_p.h56
-rw-r--r--qmake/include/private/qlayoutengine_p.h128
-rw-r--r--qmake/include/private/qlibrary_p.h84
-rw-r--r--qmake/include/private/qmousedriverinterface_p.h56
-rw-r--r--qmake/include/private/qmutex_p.h70
-rw-r--r--qmake/include/private/qmutexpool_p.h39
-rw-r--r--qmake/include/private/qpainter_p.h63
-rw-r--r--qmake/include/private/qpluginmanager_p.h73
-rw-r--r--qmake/include/private/qpsprinter_p.h89
-rw-r--r--qmake/include/private/qrichtext_p.h2133
-rw-r--r--qmake/include/private/qsettings_p.h133
-rw-r--r--qmake/include/private/qsharedmemory_p.h84
-rw-r--r--qmake/include/private/qsqldriverinterface_p.h69
-rw-r--r--qmake/include/private/qsqlextension_p.h101
-rw-r--r--qmake/include/private/qsqlmanager_p.h159
-rw-r--r--qmake/include/private/qstyleinterface_p.h61
-rw-r--r--qmake/include/private/qsvgdevice_p.h134
-rw-r--r--qmake/include/private/qtextcodecinterface_p.h79
-rw-r--r--qmake/include/private/qtitlebar_p.h136
-rw-r--r--qmake/include/private/qucom_p.h499
-rw-r--r--qmake/include/private/qucomextra_p.h93
-rw-r--r--qmake/include/private/qwidget_p.h61
-rw-r--r--qmake/include/private/qwidgetinterface_p.h111
-rw-r--r--qmake/include/private/qwidgetresizehandler_p.h113
-rw-r--r--qmake/include/qasciidict.h118
-rw-r--r--qmake/include/qbitarray.h166
-rw-r--r--qmake/include/qbuffer.h100
-rw-r--r--qmake/include/qcache.h118
-rw-r--r--qmake/include/qcleanuphandler.h127
-rw-r--r--qmake/include/qcstring.h391
-rw-r--r--qmake/include/qdatastream.h173
-rw-r--r--qmake/include/qdatetime.h250
-rw-r--r--qmake/include/qdict.h118
-rw-r--r--qmake/include/qdir.h241
-rw-r--r--qmake/include/qfeatures.h959
-rw-r--r--qmake/include/qfile.h124
-rw-r--r--qmake/include/qfileinfo.h150
-rw-r--r--qmake/include/qgarray.h121
-rw-r--r--qmake/include/qgcache.h128
-rw-r--r--qmake/include/qgdict.h222
-rw-r--r--qmake/include/qglist.h252
-rw-r--r--qmake/include/qglobal.h1006
-rw-r--r--qmake/include/qgvector.h121
-rw-r--r--qmake/include/qintdict.h114
-rw-r--r--qmake/include/qiodevice.h161
-rw-r--r--qmake/include/qmap.h883
-rw-r--r--qmake/include/qmemarray.h122
-rw-r--r--qmake/include/qnamespace.h843
-rw-r--r--qmake/include/qpair.h96
-rw-r--r--qmake/include/qptrcollection.h76
-rw-r--r--qmake/include/qptrlist.h160
-rw-r--r--qmake/include/qptrvector.h113
-rw-r--r--qmake/include/qregexp.h115
-rw-r--r--qmake/include/qshared.h55
-rw-r--r--qmake/include/qstring.h950
-rw-r--r--qmake/include/qstringlist.h86
-rw-r--r--qmake/include/qstrlist.h112
-rw-r--r--qmake/include/qtextcodec.h114
-rw-r--r--qmake/include/qtextstream.h335
-rw-r--r--qmake/include/qtl.h321
-rw-r--r--qmake/include/quuid.h168
-rw-r--r--qmake/include/qvaluelist.h665
-rw-r--r--qmake/include/qvaluestack.h64
-rw-r--r--qmake/main.cpp153
-rw-r--r--qmake/option.cpp449
-rw-r--r--qmake/option.h122
-rw-r--r--qmake/project.cpp987
-rw-r--r--qmake/project.h114
-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
147 files changed, 78867 insertions, 0 deletions
diff --git a/qmake/CHANGES b/qmake/CHANGES
new file mode 100644
index 0000000..995c16e
--- a/dev/null
+++ b/qmake/CHANGES
@@ -0,0 +1,40 @@
11.04a -
2
3 subdirs supports multiple project files in a single directory.
4
51.03a -
6
7 New function $$system() to extract the value of a shell call.
8
91.02a -
10
11 Dependancy / Mocable caching. qmake can cache these expensive operations with qmake_cache
12 CONFIG.
13
14 The parser has been improved to cover more error cases, as well as more forgiving
15
16 qmake now includes a special else scope to invert the previous test
17
18 Ability to add user defined targets to UnixMakefiles.
19
201.01a -
21
22 New system for library linking. This system allows a user several different features:
23
24 1) libtool like library dependancies to static libraries build with qmake
25 2) library dependencies, when on .pro depends on another library - it will
26 automatically build that other library (unix makefiles only)
27 3) automatic detection of configurations for Qt, if CONFIG qt is specified
28 it will find the settings for the most recent Qt itself.
29
30 Project Builder for Mac OS X is now a supported backend for qmake.
31
32 qmake now offers a 'make uninstall' feature, to reverse the actions of a 'make install'.
33
34 qmake can now do recursive searches in project-file mode (-r option).
35
361.00a -
37
38 First release, shipped with Qt 3.0.
39
40 qmake ships with support for Unix make, MSVC (both dsp and nmake), Borland make.
diff --git a/qmake/LICENSE.GPL b/qmake/LICENSE.GPL
new file mode 100644
index 0000000..1700eb1
--- a/dev/null
+++ b/qmake/LICENSE.GPL
@@ -0,0 +1,349 @@
1
2 The Qt GUI Toolkit is Copyright (C) 1994-2000 Trolltech AS.
3
4 You may use, distribute and copy the Qt GUI Toolkit under the terms of
5 GNU General Public License version 2, which is displayed below.
6
7-------------------------------------------------------------------------
8
9 GNU GENERAL PUBLIC LICENSE
10 Version 2, June 1991
11
12 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
13 675 Mass Ave, Cambridge, MA 02139, USA
14 Everyone is permitted to copy and distribute verbatim copies
15 of this license document, but changing it is not allowed.
16
17 Preamble
18
19 The licenses for most software are designed to take away your
20freedom to share and change it. By contrast, the GNU General Public
21License is intended to guarantee your freedom to share and change free
22software--to make sure the software is free for all its users. This
23General Public License applies to most of the Free Software
24Foundation's software and to any other program whose authors commit to
25using it. (Some other Free Software Foundation software is covered by
26the GNU Library General Public License instead.) You can apply it to
27your programs, too.
28
29 When we speak of free software, we are referring to freedom, not
30price. Our General Public Licenses are designed to make sure that you
31have the freedom to distribute copies of free software (and charge for
32this service if you wish), that you receive source code or can get it
33if you want it, that you can change the software or use pieces of it
34in new free programs; and that you know you can do these things.
35
36 To protect your rights, we need to make restrictions that forbid
37anyone to deny you these rights or to ask you to surrender the rights.
38These restrictions translate to certain responsibilities for you if you
39distribute copies of the software, or if you modify it.
40
41 For example, if you distribute copies of such a program, whether
42gratis or for a fee, you must give the recipients all the rights that
43you have. You must make sure that they, too, receive or can get the
44source code. And you must show them these terms so they know their
45rights.
46
47 We protect your rights with two steps: (1) copyright the software, and
48(2) offer you this license which gives you legal permission to copy,
49distribute and/or modify the software.
50
51 Also, for each author's protection and ours, we want to make certain
52that everyone understands that there is no warranty for this free
53software. If the software is modified by someone else and passed on, we
54want its recipients to know that what they have is not the original, so
55that any problems introduced by others will not reflect on the original
56authors' reputations.
57
58 Finally, any free program is threatened constantly by software
59patents. We wish to avoid the danger that redistributors of a free
60program will individually obtain patent licenses, in effect making the
61program proprietary. To prevent this, we have made it clear that any
62patent must be licensed for everyone's free use or not licensed at all.
63
64 The precise terms and conditions for copying, distribution and
65modification follow.
66
67 GNU GENERAL PUBLIC LICENSE
68 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
69
70 0. This License applies to any program or other work which contains
71a notice placed by the copyright holder saying it may be distributed
72under the terms of this General Public License. The "Program", below,
73refers to any such program or work, and a "work based on the Program"
74means either the Program or any derivative work under copyright law:
75that is to say, a work containing the Program or a portion of it,
76either verbatim or with modifications and/or translated into another
77language. (Hereinafter, translation is included without limitation in
78the term "modification".) Each licensee is addressed as "you".
79
80Activities other than copying, distribution and modification are not
81covered by this License; they are outside its scope. The act of
82running the Program is not restricted, and the output from the Program
83is covered only if its contents constitute a work based on the
84Program (independent of having been made by running the Program).
85Whether that is true depends on what the Program does.
86
87 1. You may copy and distribute verbatim copies of the Program's
88source code as you receive it, in any medium, provided that you
89conspicuously and appropriately publish on each copy an appropriate
90copyright notice and disclaimer of warranty; keep intact all the
91notices that refer to this License and to the absence of any warranty;
92and give any other recipients of the Program a copy of this License
93along with the Program.
94
95You may charge a fee for the physical act of transferring a copy, and
96you may at your option offer warranty protection in exchange for a fee.
97
98 2. You may modify your copy or copies of the Program or any portion
99of it, thus forming a work based on the Program, and copy and
100distribute such modifications or work under the terms of Section 1
101above, provided that you also meet all of these conditions:
102
103 a) You must cause the modified files to carry prominent notices
104 stating that you changed the files and the date of any change.
105
106 b) You must cause any work that you distribute or publish, that in
107 whole or in part contains or is derived from the Program or any
108 part thereof, to be licensed as a whole at no charge to all third
109 parties under the terms of this License.
110
111 c) If the modified program normally reads commands interactively
112 when run, you must cause it, when started running for such
113 interactive use in the most ordinary way, to print or display an
114 announcement including an appropriate copyright notice and a
115 notice that there is no warranty (or else, saying that you provide
116 a warranty) and that users may redistribute the program under
117 these conditions, and telling the user how to view a copy of this
118 License. (Exception: if the Program itself is interactive but
119 does not normally print such an announcement, your work based on
120 the Program is not required to print an announcement.)
121
122These requirements apply to the modified work as a whole. If
123identifiable sections of that work are not derived from the Program,
124and can be reasonably considered independent and separate works in
125themselves, then this License, and its terms, do not apply to those
126sections when you distribute them as separate works. But when you
127distribute the same sections as part of a whole which is a work based
128on the Program, the distribution of the whole must be on the terms of
129this License, whose permissions for other licensees extend to the
130entire whole, and thus to each and every part regardless of who wrote it.
131
132Thus, it is not the intent of this section to claim rights or contest
133your rights to work written entirely by you; rather, the intent is to
134exercise the right to control the distribution of derivative or
135collective works based on the Program.
136
137In addition, mere aggregation of another work not based on the Program
138with the Program (or with a work based on the Program) on a volume of
139a storage or distribution medium does not bring the other work under
140the scope of this License.
141
142 3. You may copy and distribute the Program (or a work based on it,
143under Section 2) in object code or executable form under the terms of
144Sections 1 and 2 above provided that you also do one of the following:
145
146 a) Accompany it with the complete corresponding machine-readable
147 source code, which must be distributed under the terms of Sections
148 1 and 2 above on a medium customarily used for software interchange; or,
149
150 b) Accompany it with a written offer, valid for at least three
151 years, to give any third party, for a charge no more than your
152 cost of physically performing source distribution, a complete
153 machine-readable copy of the corresponding source code, to be
154 distributed under the terms of Sections 1 and 2 above on a medium
155 customarily used for software interchange; or,
156
157 c) Accompany it with the information you received as to the offer
158 to distribute corresponding source code. (This alternative is
159 allowed only for noncommercial distribution and only if you
160 received the program in object code or executable form with such
161 an offer, in accord with Subsection b above.)
162
163The source code for a work means the preferred form of the work for
164making modifications to it. For an executable work, complete source
165code means all the source code for all modules it contains, plus any
166associated interface definition files, plus the scripts used to
167control compilation and installation of the executable. However, as a
168special exception, the source code distributed need not include
169anything that is normally distributed (in either source or binary
170form) with the major components (compiler, kernel, and so on) of the
171operating system on which the executable runs, unless that component
172itself accompanies the executable.
173
174If distribution of executable or object code is made by offering
175access to copy from a designated place, then offering equivalent
176access to copy the source code from the same place counts as
177distribution of the source code, even though third parties are not
178compelled to copy the source along with the object code.
179
180 4. You may not copy, modify, sublicense, or distribute the Program
181except as expressly provided under this License. Any attempt
182otherwise to copy, modify, sublicense or distribute the Program is
183void, and will automatically terminate your rights under this License.
184However, parties who have received copies, or rights, from you under
185this License will not have their licenses terminated so long as such
186parties remain in full compliance.
187
188 5. You are not required to accept this License, since you have not
189signed it. However, nothing else grants you permission to modify or
190distribute the Program or its derivative works. These actions are
191prohibited by law if you do not accept this License. Therefore, by
192modifying or distributing the Program (or any work based on the
193Program), you indicate your acceptance of this License to do so, and
194all its terms and conditions for copying, distributing or modifying
195the Program or works based on it.
196
197 6. Each time you redistribute the Program (or any work based on the
198Program), the recipient automatically receives a license from the
199original licensor to copy, distribute or modify the Program subject to
200these terms and conditions. You may not impose any further
201restrictions on the recipients' exercise of the rights granted herein.
202You are not responsible for enforcing compliance by third parties to
203this License.
204
205 7. If, as a consequence of a court judgment or allegation of patent
206infringement or for any other reason (not limited to patent issues),
207conditions are imposed on you (whether by court order, agreement or
208otherwise) that contradict the conditions of this License, they do not
209excuse you from the conditions of this License. If you cannot
210distribute so as to satisfy simultaneously your obligations under this
211License and any other pertinent obligations, then as a consequence you
212may not distribute the Program at all. For example, if a patent
213license would not permit royalty-free redistribution of the Program by
214all those who receive copies directly or indirectly through you, then
215the only way you could satisfy both it and this License would be to
216refrain entirely from distribution of the Program.
217
218If any portion of this section is held invalid or unenforceable under
219any particular circumstance, the balance of the section is intended to
220apply and the section as a whole is intended to apply in other
221circumstances.
222
223It is not the purpose of this section to induce you to infringe any
224patents or other property right claims or to contest validity of any
225such claims; this section has the sole purpose of protecting the
226integrity of the free software distribution system, which is
227implemented by public license practices. Many people have made
228generous contributions to the wide range of software distributed
229through that system in reliance on consistent application of that
230system; it is up to the author/donor to decide if he or she is willing
231to distribute software through any other system and a licensee cannot
232impose that choice.
233
234This section is intended to make thoroughly clear what is believed to
235be a consequence of the rest of this License.
236
237 8. If the distribution and/or use of the Program is restricted in
238certain countries either by patents or by copyrighted interfaces, the
239original copyright holder who places the Program under this License
240may add an explicit geographical distribution limitation excluding
241those countries, so that distribution is permitted only in or among
242countries not thus excluded. In such case, this License incorporates
243the limitation as if written in the body of this License.
244
245 9. The Free Software Foundation may publish revised and/or new versions
246of the General Public License from time to time. Such new versions will
247be similar in spirit to the present version, but may differ in detail to
248address new problems or concerns.
249
250Each version is given a distinguishing version number. If the Program
251specifies a version number of this License which applies to it and "any
252later version", you have the option of following the terms and conditions
253either of that version or of any later version published by the Free
254Software Foundation. If the Program does not specify a version number of
255this License, you may choose any version ever published by the Free Software
256Foundation.
257
258 10. If you wish to incorporate parts of the Program into other free
259programs whose distribution conditions are different, write to the author
260to ask for permission. For software which is copyrighted by the Free
261Software Foundation, write to the Free Software Foundation; we sometimes
262make exceptions for this. Our decision will be guided by the two goals
263of preserving the free status of all derivatives of our free software and
264of promoting the sharing and reuse of software generally.
265
266 NO WARRANTY
267
268 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
269FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
270OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
271PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
272OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
273MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
274TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
275PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
276REPAIR OR CORRECTION.
277
278 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
279WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
280REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
281INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
282OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
283TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
284YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
285PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
286POSSIBILITY OF SUCH DAMAGES.
287
288 END OF TERMS AND CONDITIONS
289
290 Appendix: How to Apply These Terms to Your New Programs
291
292 If you develop a new program, and you want it to be of the greatest
293possible use to the public, the best way to achieve this is to make it
294free software which everyone can redistribute and change under these terms.
295
296 To do so, attach the following notices to the program. It is safest
297to attach them to the start of each source file to most effectively
298convey the exclusion of warranty; and each file should have at least
299the "copyright" line and a pointer to where the full notice is found.
300
301 <one line to give the program's name and a brief idea of what it does.>
302 Copyright (C) 19yy <name of author>
303
304 This program is free software; you can redistribute it and/or modify
305 it under the terms of the GNU General Public License as published by
306 the Free Software Foundation; either version 2 of the License, or
307 (at your option) any later version.
308
309 This program is distributed in the hope that it will be useful,
310 but WITHOUT ANY WARRANTY; without even the implied warranty of
311 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
312 GNU General Public License for more details.
313
314 You should have received a copy of the GNU General Public License
315 along with this program; if not, write to the Free Software
316 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
317
318Also add information on how to contact you by electronic and paper mail.
319
320If the program is interactive, make it output a short notice like this
321when it starts in an interactive mode:
322
323 Gnomovision version 69, Copyright (C) 19yy name of author
324 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
325 This is free software, and you are welcome to redistribute it
326 under certain conditions; type `show c' for details.
327
328The hypothetical commands `show w' and `show c' should show the appropriate
329parts of the General Public License. Of course, the commands you use may
330be called something other than `show w' and `show c'; they could even be
331mouse-clicks or menu items--whatever suits your program.
332
333You should also get your employer (if you work as a programmer) or your
334school, if any, to sign a "copyright disclaimer" for the program, if
335necessary. Here is a sample; alter the names:
336
337 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
338 `Gnomovision' (which makes passes at compilers) written by James Hacker.
339
340 <signature of Ty Coon>, 1 April 1989
341 Ty Coon, President of Vice
342
343This General Public License does not permit incorporating your program into
344proprietary programs. If your program is a subroutine library, you may
345consider it more useful to permit linking proprietary applications with the
346library. If this is what you want to do, use the GNU Library General
347Public License instead of this License.
348
349-------------------------------------------------------------------------
diff --git a/qmake/Makefile b/qmake/Makefile
new file mode 100644
index 0000000..104cc44
--- a/dev/null
+++ b/qmake/Makefile
@@ -0,0 +1,173 @@
1TOPDIR=$(shell pwd)
2QMAKESPECSDIR=$(OPIEDIR)
3
4########################################################################
5## This file was autogenerated by configure, all changes will be lost ##
6########################################################################
7 CC = gcc
8 CXX = g++
9
10#qmake code
11OBJS=project.o main.o makefile.o unixmake2.o unixmake.o borland_bmake.o \
12 msvc_nmake.o msvc_dsp.o msvc_vcproj.o option.o winmakefile.o \
13 projectgenerator.o metrowerks_xml.o pbuilder_pbx.o msvc_objectmodel.o
14
15#qt code
16QOBJS=qstring.o qtextstream.o qiodevice.o qglobal.o qgdict.o qcstring.o \
17 qdatastream.o qgarray.o qbuffer.o qglist.o qptrcollection.o qfile.o \
18 qfile_unix.o qregexp.o qgvector.o qgcache.o qbitarray.o qdir.o \
19 qfileinfo_unix.o qdir_unix.o qfileinfo.o qdatetime.o qstringlist.o qmap.o \
20 qconfig.o
21
22CFLAGS= \
23 -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac \
24 -I$(TOPDIR)/include -I$(TOPDIR)/include/qmake -I$(QMAKESPECSDIR)/default \
25 -I$(TOPDIR)/include/private \
26 -DQT_NO_TEXTCODEC -DQT_LITE_COMPONENT -DQT_NO_STL -DQT_NO_COMPRESS -I$(QMAKESPECDIR)/qws/linux-x86-g++
27CXXFLAGS= $(CFLAGS)
28LFLAGS=
29
30qmake: $(OBJS) $(QOBJS)
31 $(CXX) -o $@ $(OBJS) $(QOBJS) $(LFLAGS)
32 $(if $(OPIEDIR),rm -f $(OPIEDIR)/bin/$@)
33 $(if $(OPIEDIR),ln -s ../qmake/$@ $(OPIEDIR)/bin/$@)
34
35install: qmake
36 [ -d $(INSTALL_ROOT)$(QTDIR)/bin ] || mkdir -p $(INSTALL_ROOT)$(QTDIR)/bin
37 -cp -f $(QTDIR)/bin/qmake $(INSTALL_ROOT)$(QTDIR)/bin
38 [ -d $(INSTALL_ROOT)$(QTDIR) ] || mkdir -p $(INSTALL_ROOT)$(QTDIR)
39 -cp -r -f $(QMAKESPECDIR) $(INSTALL_ROOT)$(QTDIR)
40
41clean::
42 rm -f $(OBJS) $(QOBJS)
43
44distclean:: clean
45 rm -rf qmake .deps
46
47# don't use optimization for these
48qtextstream.o: $(TOPDIR)/tools/qtextstream.cpp
49 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qtextstream.cpp
50
51qiodevice.o: $(TOPDIR)/tools/qiodevice.cpp
52 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qiodevice.cpp
53
54qglobal.o: $(TOPDIR)/tools/qglobal.cpp
55 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qglobal.cpp
56
57qgdict.o: $(TOPDIR)/tools/qgdict.cpp
58 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qgdict.cpp
59
60qcstring.o: $(TOPDIR)/tools/qcstring.cpp
61 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qcstring.cpp
62
63qstring.o: $(TOPDIR)/tools/qstring.cpp
64 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qstring.cpp
65
66qdatastream.o: $(TOPDIR)/tools/qdatastream.cpp
67 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qdatastream.cpp
68
69qgarray.o: $(TOPDIR)/tools/qgarray.cpp
70 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qgarray.cpp
71
72qbuffer.o: $(TOPDIR)/tools/qbuffer.cpp
73 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qbuffer.cpp
74
75qglist.o: $(TOPDIR)/tools/qglist.cpp
76 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qglist.cpp
77
78qptrcollection.o: $(TOPDIR)/tools/qptrcollection.cpp
79 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qptrcollection.cpp
80
81qfile.o: $(TOPDIR)/tools/qfile.cpp
82 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qfile.cpp
83
84qfile_unix.o: $(TOPDIR)/tools/qfile_unix.cpp
85 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qfile_unix.cpp
86
87qregexp.o: $(TOPDIR)/tools/qregexp.cpp
88 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qregexp.cpp
89
90qgvector.o: $(TOPDIR)/tools/qgvector.cpp
91 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qgvector.cpp
92
93qgcache.o: $(TOPDIR)/tools/qgcache.cpp
94 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qgcache.cpp
95
96qbitarray.o: $(TOPDIR)/tools/qbitarray.cpp
97 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qbitarray.cpp
98
99qdir.o: $(TOPDIR)/tools/qdir.cpp
100 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qdir.cpp
101
102qfileinfo_unix.o: $(TOPDIR)/tools/qfileinfo_unix.cpp
103 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qfileinfo_unix.cpp
104
105qdir_unix.o: $(TOPDIR)/tools/qdir_unix.cpp
106 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qdir_unix.cpp
107
108qfileinfo.o: $(TOPDIR)/tools/qfileinfo.cpp
109 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qfileinfo.cpp
110
111qdatetime.o: $(TOPDIR)/tools/qdatetime.cpp
112 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qdatetime.cpp
113
114qstringlist.o: $(TOPDIR)/tools/qstringlist.cpp
115 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qstringlist.cpp
116
117qmap.o: $(TOPDIR)/tools/qmap.cpp
118 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qmap.cpp
119
120qconfig.o: $(TOPDIR)/tools/qconfig.cpp
121 $(CXX) -c -o $@ $(CXXFLAGS) $(TOPDIR)/tools/qconfig.cpp
122
123winmakefile.o: generators/win32/winmakefile.cpp
124 $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/winmakefile.cpp
125
126project.o: project.cpp project.h option.h
127 $(CXX) -c -o $@ $(CXXFLAGS) project.cpp
128
129main.o: main.cpp project.h
130 $(CXX) -c -o $@ $(CXXFLAGS) main.cpp
131
132option.o: option.cpp option.h
133 $(CXX) -c -o $@ $(CXXFLAGS) option.cpp
134
135makefile.o: generators/makefile.cpp
136 $(CXX) -c -o $@ $(CXXFLAGS) generators/makefile.cpp
137
138unixmake.o: generators/unix/unixmake.cpp
139 $(CXX) -c -o $@ $(CXXFLAGS) generators/unix/unixmake.cpp
140
141unixmake2.o: generators/unix/unixmake2.cpp
142 $(CXX) -c -o $@ $(CXXFLAGS) generators/unix/unixmake2.cpp
143
144borland_bmake.o: generators/win32/borland_bmake.cpp
145 $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/borland_bmake.cpp
146
147msvc_objectmodel.o: generators/win32/msvc_objectmodel.cpp
148 $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp
149
150msvc_vcproj.o: generators/win32/msvc_vcproj.cpp
151 $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_vcproj.cpp
152
153msvc_nmake.o: generators/win32/msvc_nmake.cpp
154 $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_nmake.cpp
155
156metrowerks_xml.o: generators/mac/metrowerks_xml.cpp
157 $(CXX) -c -o $@ $(CXXFLAGS) generators/mac/metrowerks_xml.cpp
158
159pbuilder_pbx.o: generators/mac/pbuilder_pbx.cpp
160 $(CXX) -c -o $@ $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp
161
162msvc_dsp.o: generators/win32/msvc_dsp.cpp
163 $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_dsp.cpp
164
165projectgenerator.o: generators/projectgenerator.cpp
166 $(CXX) -c -o $@ $(CXXFLAGS) generators/projectgenerator.cpp
167
168#default rules
169.c.o:
170 $(CC) -c -o $@ $(CFLAGS) $<
171
172.cpp.o:
173 $(CXX) -c -o $@ $(CXXFLAGS) $<
diff --git a/qmake/generators/mac/metrowerks_xml.cpp b/qmake/generators/mac/metrowerks_xml.cpp
new file mode 100644
index 0000000..125749d
--- a/dev/null
+++ b/qmake/generators/mac/metrowerks_xml.cpp
@@ -0,0 +1,822 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "metrowerks_xml.h"
39#include "option.h"
40#include <qdir.h>
41#include <qdict.h>
42#include <qregexp.h>
43#include <stdlib.h>
44#include <time.h>
45#ifdef Q_OS_MAC
46#include <Carbon/Carbon.h>
47#include <sys/types.h>
48#include <sys/stat.h>
49#endif
50
51
52MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE)
53{
54
55}
56
57bool
58MetrowerksMakefileGenerator::writeMakefile(QTextStream &t)
59{
60 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
61 /* for now just dump, I need to generated an empty xml or something.. */
62 fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
63 var("QMAKE_FAILED_REQUIREMENTS").latin1());
64 return TRUE;
65 }
66
67 if(project->first("TEMPLATE") == "app" ||
68 project->first("TEMPLATE") == "lib") {
69 return writeMakeParts(t);
70 }
71 else if(project->first("TEMPLATE") == "subdirs") {
72 writeHeader(t);
73 qDebug("Not supported!");
74 return TRUE;
75 }
76 return FALSE;
77}
78
79bool
80MetrowerksMakefileGenerator::writeMakeParts(QTextStream &t)
81{
82 //..grrr.. libs!
83 QStringList extra_objs;
84 bool do_libs = TRUE;
85 if(project->first("TEMPLATE") == "app")
86 extra_objs += project->variables()["QMAKE_CRT_OBJECTS"];
87 else if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib"))
88 do_libs = FALSE;
89 if(do_libs)
90 extra_objs += project->variables()["QMAKE_LIBS"];
91 for(QStringList::Iterator val_it = extra_objs.begin();
92 val_it != extra_objs.end(); ++val_it) {
93 if((*val_it).startsWith("-L")) {
94 QString dir((*val_it).right((*val_it).length() - 2));
95 fixEnvVariables(dir);
96 if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 &&
97 project->variables()["INCLUDEPATH"].findIndex(dir) == -1)
98 project->variables()["INCLUDEPATH"].append(dir);
99 } else if((*val_it).startsWith("-l")) {
100 QString lib("lib" + (*val_it).right((*val_it).length() - 2) + "." +
101 project->first("QMAKE_EXTENSION_SHLIB"));
102 if(project->variables()["LIBRARIES"].findIndex(lib) == -1)
103 project->variables()["LIBRARIES"].append(lib);
104 } else
105 if((*val_it) == "-framework") {
106 ++val_it;
107 if(val_it == extra_objs.end())
108 break;
109 QString frmwrk = (*val_it) + ".framework";
110 if(project->variables()["FRAMEWORKS"].findIndex(frmwrk) == -1)
111 project->variables()["FRAMEWORKS"].append(frmwrk);
112 } else if((*val_it).left(1) != "-") {
113 QString lib=(*val_it);
114 int s = lib.findRev('/');
115 if(s != -1) {
116 QString dir = lib.left(s);
117 lib = lib.right(lib.length() - s - 1);
118 fixEnvVariables(dir);
119 if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 &&
120 project->variables()["INCLUDEPATH"].findIndex(dir) == -1)
121 project->variables()["INCLUDEPATH"].append(dir);
122 }
123 project->variables()["LIBRARIES"].append(lib);
124 }
125 }
126 //let metrowerks find the files & set the files to the type I expect
127 QDict<void> seen(293);
128 QString paths[] = { QString("SRCMOC"), QString("FORMS"), QString("UICDECLS"),
129 QString("UICIMPLS"), QString("SOURCES"),QString("HEADERS"),
130 QString::null };
131 for(int y = 0; paths[y] != QString::null; y++) {
132 QStringList &l = project->variables()[paths[y]];
133 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
134 //establish file types
135 seen.insert((*val_it), (void *)1);
136 createFork((*val_it)); //the file itself
137 QStringList &d = findDependencies((*val_it)); //depends
138 for(QStringList::Iterator dep_it = d.begin(); dep_it != d.end(); ++dep_it) {
139 if(!seen.find((*dep_it))) {
140 seen.insert((*dep_it), (void *)1);
141 createFork((*dep_it));
142 }
143 }
144 //now chop it
145 int s = (*val_it).findRev('/');
146 if(s != -1) {
147 QString dir = (*val_it).left(s);
148 (*val_it) = (*val_it).right((*val_it).length() - s - 1);
149 QString tmpd=dir, tmpv;
150 if(fixifyToMacPath(tmpd, tmpv)) {
151 bool add_in = TRUE;
152 QString deps[] = { QString("DEPENDPATH"),
153 QString("INCLUDEPATH"), QString::null },
154 dd, dv;
155 for(int yy = 0; deps[yy] != QString::null; yy++) {
156 QStringList &l2 = project->variables()[deps[yy]];
157 for(QStringList::Iterator val_it2 = l2.begin();
158 val_it2 != l2.end(); ++val_it2) {
159 QString dd= (*val_it2), dv;
160 if(!fixifyToMacPath(dd, dv))
161 continue;
162 if(dd == tmpd && tmpv == dv) {
163 add_in = FALSE;
164 break;
165 }
166 }
167 }
168 if(add_in)
169 project->variables()["INCLUDEPATH"].append(dir);
170 }
171 }
172 }
173 }
174 //need a defines file
175 if(!project->isEmpty("DEFINES")) {
176 QString pre_pref = project->first("TARGET_STEM");
177 if(project->first("TEMPLATE") == "lib")
178 pre_pref += project->isActiveConfig("staticlib") ? "_static" : "_shared";
179 project->variables()["CODEWARRIOR_PREFIX_HEADER"].append(pre_pref + "_prefix.h");
180 }
181
182 QString xmlfile = findTemplate(project->first("QMAKE_XML_TEMPLATE"));
183 QFile file(xmlfile);
184 if(!file.open(IO_ReadOnly )) {
185 fprintf(stderr, "Cannot open XML file: %s\n",
186 project->first("QMAKE_XML_TEMPLATE").latin1());
187 return FALSE;
188 }
189 QTextStream xml(&file);
190 createFork(Option::output.name());
191
192 int rep;
193 QString line;
194 while ( !xml.eof() ) {
195 line = xml.readLine();
196 while((rep = line.find(QRegExp("\\$\\$[!a-zA-Z0-9_-]*"))) != -1) {
197 QString torep = line.mid(rep, line.find(QRegExp("[^\\$!a-zA-Z0-9_-]"), rep) - rep);
198 QString variable = torep.right(torep.length()-2);
199
200 t << line.left(rep); //output the left side
201 line = line.right(line.length() - (rep + torep.length())); //now past the variable
202 if(variable == "CODEWARRIOR_HEADERS" || variable == "CODEWARRIOR_SOURCES" ||
203 variable == "CODEWARRIOR_LIBRARIES" || variable == "CODEWARRIOR_QPREPROCESS" ||
204 variable == "CODEWARRIOR_QPREPROCESSOUT") {
205 QString outcmd=variable.right(variable.length() - variable.findRev('_') - 1);
206 QStringList args;
207 if(outcmd == "QPREPROCESS")
208 args << "UICS" << "MOCS";
209 else if(outcmd == "QPREPROCESSOUT")
210 args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
211 else
212 args << outcmd;
213 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
214 QString arg = (*arit);
215 QString kind = "Text";
216 if(arg == "LIBRARIES")
217 kind = "Library";
218 if(!project->variables()[arg].isEmpty()) {
219 QStringList &list = project->variables()[arg];
220 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
221 QString flag;
222 if(project->isActiveConfig("debug")) {
223 bool debug = TRUE;
224 if(outcmd == "QPREPROCESS") {
225 debug = FALSE;
226 } else {
227 for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) {
228 if((*it).endsWith((*hit))) {
229 debug = FALSE;
230 break;
231 }
232 }
233 }
234 if(debug)
235 flag = "Debug";
236 }
237 t << "\t\t\t\t<FILE>" << endl
238 << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
239 << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
240 << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
241 << "\t\t\t\t\t<FILEKIND>" << kind << "</FILEKIND>" << endl
242 << "\t\t\t\t\t<FILEFLAGS>" << flag << "</FILEFLAGS>" << endl
243 << "\t\t\t\t</FILE>" << endl;
244 }
245 }
246 }
247 } else if(variable == "CODEWARRIOR_SOURCES_LINKORDER" ||
248 variable == "CODEWARRIOR_HEADERS_LINKORDER" ||
249 variable == "CODEWARRIOR_LIBRARIES_LINKORDER" ||
250 variable == "CODEWARRIOR_QPREPROCESS_LINKORDER" ||
251 variable == "CODEWARRIOR_QPREPROCESSOUT_LINKORDER") {
252 QString outcmd=variable.mid(variable.find('_')+1,
253 variable.findRev('_')-(variable.find('_')+1));
254 QStringList args;
255 if(outcmd == "QPREPROCESS")
256 args << "UICS" << "MOCS";
257 else if(outcmd == "QPREPROCESSOUT")
258 args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
259 else
260 args << outcmd;
261 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
262 QString arg = (*arit);
263 if(!project->variables()[arg].isEmpty()) {
264 QStringList &list = project->variables()[arg];
265 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
266 t << "\t\t\t\t<FILEREF>" << endl
267 << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
268 << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
269 << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
270 << "\t\t\t\t</FILEREF>" << endl;
271 }
272 }
273 }
274 } else if(variable == "CODEWARRIOR_HEADERS_GROUP" ||
275 variable == "CODEWARRIOR_SOURCES_GROUP" ||
276 variable == "CODEWARRIOR_LIBRARIES_GROUP" ||
277 variable == "CODEWARRIOR_QPREPROCESS_GROUP" ||
278 variable == "CODEWARRIOR_QPREPROCESSOUT_GROUP") {
279 QString outcmd = variable.mid(variable.find('_')+1,
280 variable.findRev('_')-(variable.find('_')+1));
281 QStringList args;
282 if(outcmd == "QPREPROCESS")
283 args << "UICS" << "MOCS";
284 else if(outcmd == "QPREPROCESSOUT")
285 args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
286 else
287 args << outcmd;
288 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
289 QString arg = (*arit);
290 if(!project->variables()[arg].isEmpty()) {
291 QStringList &list = project->variables()[arg];
292 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
293 t << "\t\t\t\t<FILEREF>" << endl
294 << "\t\t\t\t\t<TARGETNAME>" << var("TARGET_STEM") << "</TARGETNAME>"
295 << endl
296 << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
297 << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
298 << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
299 << "\t\t\t\t</FILEREF>" << endl;
300 }
301 }
302 }
303 } else if(variable == "CODEWARRIOR_FRAMEWORKS") {
304 if(!project->isEmpty("FRAMEWORKS")) {
305 QStringList &list = project->variables()["FRAMEWORKS"];
306 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
307 t << "\t\t\t\t<FRAMEWORK>" << endl
308 << "\t\t\t\t\t<FILEREF>" << endl
309 << "\t\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
310 << "\t\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
311 << "\t\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
312 << "\t\t\t\t\t</FILEREF>" << endl
313 << "\t\t\t\t</FRAMEWORK>" << endl;
314 }
315 }
316 } else if(variable == "CODEWARRIOR_DEPENDPATH" || variable == "CODEWARRIOR_INCLUDEPATH" ||
317 variable == "CODEWARRIOR_FRAMEWORKPATH") {
318 QString arg=variable.right(variable.length()-variable.find('_')-1);
319 QStringList list;
320 if(arg == "INCLUDEPATH") {
321 list = project->variables()[arg];
322 list << Option::mkfile::qmakespec;
323 list << QDir::current().currentDirPath();
324
325 QStringList &l = project->variables()["QMAKE_LIBS_PATH"];
326 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
327 QString p = (*val_it), v;
328 if(!fixifyToMacPath(p, v))
329 continue;
330
331 t << "\t\t\t\t\t<SETTING>" << endl
332 << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl
333 << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>"
334 << "<VALUE>" << p << "</VALUE></SETTING>" << endl
335 << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
336 << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING>" << endl
337 << "\t\t\t\t\t\t</SETTING>" << endl
338 << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING>" << endl
339 << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl
340 << "\t\t\t\t\t</SETTING>" << endl;
341 }
342 } else if(variable == "DEPENDPATH") {
343 QStringList &l = project->variables()[arg];
344 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it)
345 {
346 //apparently tmake used colon separation...
347 QStringList damn = QStringList::split(':', (*val_it));
348 if(!damn.isEmpty())
349 list += damn;
350 else
351 list.append((*val_it));
352 }
353 } else {
354 list = project->variables()[arg];
355 }
356 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
357 QString p = (*it), v, recursive = "false", framework = "false";
358 if(p.startsWith("recursive--")) {
359 p = p.right(p.length() - 11);
360 recursive = "true";
361 }
362 if(!fixifyToMacPath(p, v))
363 continue;
364 if(arg == "FRAMEWORKPATH")
365 framework = "true";
366
367 t << "\t\t\t\t\t<SETTING>" << endl
368 << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl
369 << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>"
370 << "<VALUE>" << p << "</VALUE></SETTING>" << endl
371 << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
372 << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << v << "</VALUE></SETTING>" << endl
373 << "\t\t\t\t\t\t</SETTING>" << endl
374 << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>" << recursive << "</VALUE></SETTING>" << endl
375 << "\t\t\t\t\t\t<SETTING><NAME>FrameworkPath</NAME><VALUE>" << framework << "</VALUE></SETTING>" << endl
376 << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl
377 << "\t\t\t\t\t</SETTING>" << endl;
378 }
379 } else if(variable == "CODEWARRIOR_WARNING" || variable == "!CODEWARRIOR_WARNING") {
380 bool b = ((!project->isActiveConfig("warn_off")) &&
381 project->isActiveConfig("warn_on"));
382 if(variable.startsWith("!"))
383 b = !b;
384 t << (int)b;
385 } else if(variable == "CODEWARRIOR_TEMPLATE") {
386 if(project->first("TEMPLATE") == "app" ) {
387 t << "Executable";
388 } else if(project->first("TEMPLATE") == "lib") {
389 if(project->isActiveConfig("staticlib"))
390 t << "Library";
391 else
392 t << "SharedLibrary";
393 }
394 } else if(variable == "CODEWARRIOR_OUTPUT_DIR") {
395 QString outdir = "{Project}/", volume;
396 if(!project->isEmpty("DESTDIR"))
397 outdir = project->first("DESTDIR");
398 if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console"))
399 outdir += var("TARGET") + ".app/Contents/MacOS/";
400 if(fixifyToMacPath(outdir, volume, FALSE)) {
401 t << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir << "</VALUE></SETTING>"
402 << endl
403 << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
404 << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume << "</VALUE></SETTING>"
405 << endl;
406 }
407 } else if(variable == "CODEWARRIOR_PACKAGER_PANEL") {
408 if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console")) {
409 QString outdir = "{Project}/", volume;
410 if(!project->isEmpty("DESTDIR"))
411 outdir = project->first("DESTDIR");
412 outdir += var("TARGET") + ".app";
413 if(fixifyToMacPath(outdir, volume, FALSE)) {
414 t << "\t\t<SETTING><NAME>MWMacOSPackager_UsePackager</NAME>"
415 << "<VALUE>1</VALUE></SETTING>" << "\n"
416 << "\t\t<SETTING><NAME>MWMacOSPackager_FolderToPackage</NAME>" << "\n"
417 << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir
418 << "</VALUE></SETTING>" << "\n"
419 << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>"
420 << "\n"
421 << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume
422 << "</VALUE></SETTING>" << "\n"
423 << "\t\t</SETTING>" << "\n"
424 << "\t\t<SETTING><NAME>MWMacOSPackager_CreateClassicAlias</NAME>"
425 << "<VALUE>0</VALUE></SETTING>" << "\n"
426 << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasMethod</NAME>"
427 << "<VALUE>UseTargetOutput</VALUE></SETTING>" << "\n"
428 << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasPath</NAME>"
429 << "<VALUE></VALUE></SETTING>" << "\n"
430 << "\t\t<SETTING><NAME>MWMacOSPackager_CreatePkgInfo</NAME>"
431 << "<VALUE>1</VALUE></SETTING>" << "\n"
432 << "\t\t<SETTING><NAME>MWMacOSPackager_PkgCreatorType</NAME>"
433 << "<VALUE>CUTE</VALUE></SETTING>" << "\n"
434 << "\t\t<SETTING><NAME>MWMacOSPackager_PkgFileType</NAME>"
435 << "<VALUE>APPL</VALUE></SETTING>" << endl;
436 }
437 }
438 } else if(variable == "CODEWARRIOR_FILETYPE") {
439 if(project->first("TEMPLATE") == "lib")
440 t << "MYDL";
441 else
442 t << "MEXE";
443 } else if(variable == "CODEWARRIOR_QTDIR") {
444 t << getenv("QTDIR");
445 } else if(variable == "CODEWARRIOR_CACHEMODDATES") {
446 t << "true";
447 } else {
448 t << var(variable);
449 }
450 }
451 t << line << endl;
452 }
453 t << endl;
454 file.close();
455
456 if(mocAware()) {
457 QString mocs = project->first("MOCS");
458 QFile mocfile(mocs);
459 if(!mocfile.open(IO_WriteOnly)) {
460 fprintf(stderr, "Cannot open MOCS file: %s\n", mocs.latin1());
461 } else {
462 createFork(mocs);
463 QTextStream mocs(&mocfile);
464 QStringList &list = project->variables()["SRCMOC"];
465 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
466 QString src = findMocSource((*it));
467 if(src.findRev('/') != -1)
468 src = src.right(src.length() - src.findRev('/') - 1);
469 mocs << src << endl;
470 }
471 mocfile.close();
472 }
473 }
474
475 if(!project->isEmpty("FORMS")) {
476 QString uics = project->first("UICS");
477 QFile uicfile(uics);
478 if(!uicfile.open(IO_WriteOnly)) {
479 fprintf(stderr, "Cannot open UICS file: %s\n", uics.latin1());
480 } else {
481 createFork(uics);
482 QTextStream uics(&uicfile);
483 QStringList &list = project->variables()["FORMS"];
484 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
485 QString ui = (*it);
486 if(ui.findRev('/') != -1)
487 ui = ui.right(ui.length() - ui.findRev('/') - 1);
488 uics << ui << endl;
489 }
490 uicfile.close();
491 }
492 }
493
494 if(!project->isEmpty("CODEWARRIOR_PREFIX_HEADER")) {
495 QFile prefixfile(project->first("CODEWARRIOR_PREFIX_HEADER"));
496 if(!prefixfile.open(IO_WriteOnly)) {
497 fprintf(stderr, "Cannot open PREFIX file: %s\n", prefixfile.name().latin1());
498 } else {
499 createFork(project->first("CODEWARRIOR_PREFIX_HEADER"));
500 QTextStream prefix(&prefixfile);
501 QStringList &list = project->variables()["DEFINES"];
502 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
503 if((*it).find('=') != -1) {
504 int x = (*it).find('=');
505 prefix << "#define " << (*it).left(x) << " " << (*it).right((*it).length() - x - 1) << endl;
506 } else {
507 prefix << "#define " << (*it) << endl;
508 }
509 }
510 prefixfile.close();
511 }
512 }
513 return TRUE;
514}
515
516
517
518void
519MetrowerksMakefileGenerator::init()
520{
521 if(init_flag)
522 return;
523 init_flag = TRUE;
524
525 if ( project->isEmpty("QMAKE_XML_TEMPLATE") )
526 project->variables()["QMAKE_XML_TEMPLATE"].append("mwerkstmpl.xml");
527
528 QStringList &configs = project->variables()["CONFIG"];
529 if(project->isActiveConfig("qt")) {
530 if(configs.findIndex("moc")) configs.append("moc");
531 if ( !( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") ||
532 (project->first("TARGET") == "qt-mt") ) )
533 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
534 if(configs.findIndex("moc"))
535 configs.append("moc");
536 if ( !project->isActiveConfig("debug") )
537 project->variables()["DEFINES"].append("QT_NO_DEBUG");
538 }
539
540 //version handling
541 if(project->variables()["VERSION"].isEmpty())
542 project->variables()["VERSION"].append("1.0." +
543 (project->isEmpty("VER_PAT") ? QString("0") :
544 project->first("VER_PAT")) );
545 QStringList ver = QStringList::split('.', project->first("VERSION"));
546 ver << "0" << "0"; //make sure there are three
547 project->variables()["VER_MAJ"].append(ver[0]);
548 project->variables()["VER_MIN"].append(ver[1]);
549 project->variables()["VER_PAT"].append(ver[2]);
550
551 if( !project->isEmpty("LIBS") )
552 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
553 if( project->variables()["QMAKE_EXTENSION_SHLIB"].isEmpty() )
554 project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dylib" );
555
556 if ( project->isActiveConfig("moc") ) {
557 QString mocfile = project->first("TARGET");
558 if(project->first("TEMPLATE") == "lib")
559 mocfile += project->isActiveConfig("staticlib") ? "_static" : "_shared";
560 project->variables()["MOCS"].append(mocfile + ".mocs");
561 setMocAware(TRUE);
562 }
563 if(!project->isEmpty("FORMS")) {
564 QString uicfile = project->first("TARGET");
565 if(project->first("TEMPLATE") == "lib")
566 uicfile += project->isActiveConfig("staticlib") ? "_static" : "_shared";
567 project->variables()["UICS"].append(uicfile + ".uics");
568 }
569 if(project->isEmpty("DESTDIR"))
570 project->variables()["DESTDIR"].append(QDir::currentDirPath());
571 MakefileGenerator::init();
572
573 if ( project->isActiveConfig("opengl") ) {
574 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"];
575 if ( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") ||
576 (project->first("TARGET") == "qt-mt") )
577 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"];
578 else
579 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
580 }
581
582 if(project->isActiveConfig("qt"))
583 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
584 if(project->isEmpty("FRAMEWORKPATH"))
585 project->variables()["FRAMEWORKPATH"].append("/System/Library/Frameworks/");
586
587 //set the target up
588 project->variables()["TARGET_STEM"] = project->variables()["TARGET"];
589 if(project->first("TEMPLATE") == "lib") {
590 if(project->isActiveConfig("staticlib"))
591 project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + ".lib";
592 else
593 project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + "." +
594 project->first("QMAKE_EXTENSION_SHLIB");
595
596 project->variables()["CODEWARRIOR_VERSION"].append(project->first("VER_MAJ") +
597 project->first("VER_MIN") +
598 project->first("VER_PAT"));
599 } else {
600 project->variables()["CODEWARRIOR_VERSION"].append("0");
601 if(project->isEmpty("QMAKE_ENTRYPOINT"))
602 project->variables()["QMAKE_ENTRYPOINT"].append("start");
603 project->variables()["CODEWARRIOR_ENTRYPOINT"].append(
604 project->first("QMAKE_ENTRYPOINT"));
605 }
606}
607
608
609QString
610MetrowerksMakefileGenerator::findTemplate(QString file)
611{
612 QString ret;
613 if(!QFile::exists(ret = file) &&
614 !QFile::exists((ret = Option::mkfile::qmakespec + QDir::separator() + file)) &&
615 !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/mac-mwerks/" + file)) &&
616 !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file))))
617 return "";
618 return ret;
619}
620
621bool
622MetrowerksMakefileGenerator::createFork(const QString &f)
623{
624#if defined(Q_OS_MACX)
625 FSRef fref;
626 FSSpec fileSpec;
627 if(QFile::exists(f)) {
628 mode_t perms = 0;
629 {
630 struct stat s;
631 stat(f.latin1(), &s);
632 if(!(s.st_mode & S_IWUSR)) {
633 perms = s.st_mode;
634 chmod(f.latin1(), perms | S_IWUSR);
635 }
636 }
637 FILE *o = fopen(f.latin1(), "a");
638 if(!o)
639 return FALSE;
640 if(FSPathMakeRef((const UInt8 *)f.latin1(), &fref, NULL) == noErr) {
641 if(FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL) == noErr)
642 FSpCreateResFile(&fileSpec, 'CUTE', 'TEXT', smSystemScript);
643 else
644 qDebug("bogus %d", __LINE__);
645 } else
646 qDebug("bogus %d", __LINE__);
647 fclose(o);
648 if(perms)
649 chmod(f.latin1(), perms);
650 }
651#else
652 Q_UNUSED(f)
653#endif
654 return TRUE;
655}
656
657bool
658MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool )
659{
660 v = "Absolute";
661 if(p.find(':') != -1) //guess its macish already
662 return TRUE;
663
664 static QString st_volume;
665 if(st_volume.isEmpty()) {
666 st_volume = var("QMAKE_VOLUMENAME");
667#ifdef Q_OS_MAC
668 if(st_volume.isEmpty()) {
669 uchar foo[512];
670 HVolumeParam pb;
671 memset(&pb, '\0', sizeof(pb));
672 pb.ioVRefNum = 0;
673 pb.ioNamePtr = foo;
674 if(PBHGetVInfoSync((HParmBlkPtr)&pb) == noErr) {
675 int len = foo[0];
676 memcpy(foo,foo+1, len);
677 foo[len] = '\0';
678 st_volume = (char *)foo;
679 }
680 }
681#endif
682 }
683 QString volume = st_volume;
684
685 fixEnvVariables(p);
686 if(p.startsWith("\"") && p.endsWith("\""))
687 p = p.mid(1, p.length() - 2);
688 if(p.isEmpty())
689 return FALSE;
690 if(!p.endsWith("/"))
691 p += "/";
692 if(QDir::isRelativePath(p)) {
693 if(p.startsWith("{")) {
694 int eoc = p.find('}');
695 if(eoc == -1)
696 return FALSE;
697 volume = p.mid(1, eoc - 1);
698 p = p.right(p.length() - eoc - 1);
699 } else {
700 QFileInfo fi(p);
701 if(fi.convertToAbs()) //strange
702 return FALSE;
703 p = fi.filePath();
704 }
705 }
706 p = QDir::cleanDirPath(p);
707 if(!volume.isEmpty())
708 v = volume;
709 p.replace("/", ":");
710 if(p.right(1) != ":")
711 p += ':';
712 return TRUE;
713}
714
715void
716MetrowerksMakefileGenerator::processPrlFiles()
717{
718 QPtrList<MakefileDependDir> libdirs;
719 libdirs.setAutoDelete(TRUE);
720 const QString lflags[] = { "QMAKE_LIBS", QString::null };
721 for(int i = 0; !lflags[i].isNull(); i++) {
722 for(bool ret = FALSE; TRUE; ret = FALSE) {
723 QStringList l_out;
724 QStringList &l = project->variables()[lflags[i]];
725 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
726 QString opt = (*it);
727 if(opt.startsWith("-")) {
728 if(opt.startsWith("-L")) {
729 QString r = opt.right(opt.length() - 2), l = r;
730 fixEnvVariables(l);
731 libdirs.append(new MakefileDependDir(r.replace( "\"", ""),
732 l.replace( "\"", "")));
733 } else if(opt.left(2) == "-l") {
734 QString lib = opt.right(opt.length() - 2), prl;
735 for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
736 prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext;
737 if(processPrlFile(prl)) {
738 if(prl.startsWith(mdd->local_dir))
739 prl.replace(0, mdd->local_dir.length(), mdd->real_dir);
740 QRegExp reg("^.*lib(" + lib + "[^.]*)\\." +
741 project->first("QMAKE_EXTENSION_SHLIB") + "$");
742 if(reg.exactMatch(prl))
743 prl = "-l" + reg.cap(1);
744 opt = prl;
745 ret = TRUE;
746 break;
747 }
748 }
749 } else if(opt == "-framework") {
750 l_out.append(opt);
751 ++it;
752 opt = (*it);
753 QString prl = "/System/Library/Frameworks/" + opt +
754 ".framework/" + opt + Option::prl_ext;
755 if(processPrlFile(prl))
756 ret = TRUE;
757 }
758 if(!opt.isEmpty())
759 l_out.append(opt);
760 } else {
761 if(processPrlFile(opt))
762 ret = TRUE;
763 if(!opt.isEmpty())
764 l_out.append(opt);
765 }
766 }
767 if(ret)
768 l = l_out;
769 else
770 break;
771 }
772 }
773}
774
775void
776MetrowerksMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
777{
778 if(var == "QMAKE_PRL_LIBS") {
779 QStringList &out = project->variables()["QMAKE_LIBS"];
780 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
781 bool append = TRUE;
782 if((*it).startsWith("-")) {
783 if((*it).startsWith("-l") || (*it).startsWith("-L")) {
784 append = out.findIndex((*it)) == -1;
785 } else if((*it).startsWith("-framework")) {
786 ++it;
787 for(QStringList::ConstIterator outit = out.begin();
788 outit != out.end(); ++it) {
789 if((*outit) == "-framework") {
790 ++outit;
791 if((*outit) == (*it)) {
792 append = FALSE;
793 break;
794 }
795 }
796 }
797 }
798 } else if(QFile::exists((*it))) {
799 append = out.findIndex((*it));
800 }
801 if(append)
802 out.append((*it));
803 }
804 } else {
805 MakefileGenerator::processPrlVariable(var, l);
806 }
807}
808
809
810bool
811MetrowerksMakefileGenerator::openOutput(QFile &file) const
812{
813 QString outdir;
814 if(!file.name().isEmpty()) {
815 QFileInfo fi(file);
816 if(fi.isDir())
817 outdir = file.name() + QDir::separator();
818 }
819 if(!outdir.isEmpty() || file.name().isEmpty())
820 file.setName(outdir + project->first("TARGET") + ".xml");
821 return MakefileGenerator::openOutput(file);
822}
diff --git a/qmake/generators/mac/metrowerks_xml.h b/qmake/generators/mac/metrowerks_xml.h
new file mode 100644
index 0000000..ae3cfae
--- a/dev/null
+++ b/qmake/generators/mac/metrowerks_xml.h
@@ -0,0 +1,69 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __METROWERKSMAKE_H__
38#define __METROWERKSMAKE_H__
39
40#include "makefile.h"
41
42class MetrowerksMakefileGenerator : public MakefileGenerator
43{
44 bool createFork(const QString &f);
45 bool fixifyToMacPath(QString &c, QString &v, bool exists=TRUE);
46
47 bool init_flag;
48
49 bool writeMakeParts(QTextStream &);
50 bool writeSubDirs(QTextStream &);
51
52 bool writeMakefile(QTextStream &);
53 QString findTemplate(QString file);
54 void init();
55public:
56 MetrowerksMakefileGenerator(QMakeProject *p);
57 ~MetrowerksMakefileGenerator();
58
59 bool openOutput(QFile &file) const;
60protected:
61 virtual void processPrlFiles();
62 virtual void processPrlVariable(const QString &var, const QStringList &l);
63 virtual bool doDepends() const { return FALSE; } //never necesary
64};
65
66inline MetrowerksMakefileGenerator::~MetrowerksMakefileGenerator()
67{ }
68
69#endif /* __METROWERKSMAKE_H__ */
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
new file mode 100644
index 0000000..8525058
--- a/dev/null
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -0,0 +1,983 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "pbuilder_pbx.h"
39#include "option.h"
40#include <qdir.h>
41#include <qdict.h>
42#include <qregexp.h>
43#include <stdlib.h>
44#include <time.h>
45#ifdef Q_OS_UNIX
46# include <sys/types.h>
47# include <sys/stat.h>
48#endif
49
50// Note: this is fairly hacky, but it does the job...
51
52
53ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p)
54{
55
56}
57
58bool
59ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t)
60{
61 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
62 /* for now just dump, I need to generated an empty xml or something.. */
63 fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
64 var("QMAKE_FAILED_REQUIREMENTS").latin1());
65 return TRUE;
66 }
67
68 project->variables()["MAKEFILE"].clear();
69 project->variables()["MAKEFILE"].append("Makefile");
70 if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") {
71 return writeMakeParts(t);
72 } else if(project->first("TEMPLATE") == "subdirs") {
73 writeSubdirs(t, FALSE);
74 return TRUE;
75 }
76 return FALSE;
77}
78
79bool
80ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
81{
82 int i;
83 QStringList tmp;
84 bool did_preprocess = FALSE;
85
86 //HEADER
87 t << "// !$*UTF8*$!" << "\n"
88 << "{" << "\n"
89 << "\t" << "archiveVersion = 1;" << "\n"
90 << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n"
91 << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n"
92 << "\t" << "objects = {" << endl;
93
94 //MAKE QMAKE equivlant
95 if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") {
96 QString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak";
97 QFile mkf(mkfile);
98 if(mkf.open(IO_WriteOnly | IO_Translate)) {
99 debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
100 QTextStream mkt(&mkf);
101 writeHeader(mkt);
102 mkt << "QMAKE = "<<
103 (project->isEmpty("QMAKE_QMAKE") ? QString("$(QTDIR)/bin/qmake") :
104 var("QMAKE_QMAKE")) << endl;
105 writeMakeQmake(mkt);
106 mkf.close();
107 }
108 QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE");
109 mkfile = fileFixify(mkfile, QDir::currentDirPath());
110 project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
111 t << "\t\t" << phase_key << " = {" << "\n"
112 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
113 << "\t\t\t" << "files = (" << "\n"
114 << "\t\t\t" << ");" << "\n"
115 << "\t\t\t" << "generatedFileNames = (" << "\n"
116 << "\t\t\t" << ");" << "\n"
117 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
118 << "\t\t\t" << "name = \"Qt Qmake\";" << "\n"
119 << "\t\t\t" << "neededFileNames = (" << "\n"
120 << "\t\t\t" << ");" << "\n"
121 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
122 << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
123 " -f " << mkfile << "\";" << "\n"
124 << "\t\t" << "};" << "\n";
125 }
126
127 //DUMP SOURCES
128 QMap<QString, QStringList> groups;
129 QString srcs[] = { "SOURCES", "SRCMOC", "UICIMPLS", QString::null };
130 for(i = 0; !srcs[i].isNull(); i++) {
131 tmp = project->variables()[srcs[i]];
132 QStringList &src_list = project->variables()["QMAKE_PBX_" + srcs[i]];
133 for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) {
134 QString file = fileFixify((*it));
135 if(file.endsWith(Option::moc_ext))
136 continue;
137 bool in_root = TRUE;
138 QString src_key = keyFor(file);
139 if(!project->isActiveConfig("flat")) {
140 QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE);
141 if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) {
142 QString last_grp("QMAKE_PBX_" + srcs[i] + "_HEIR_GROUP");
143 QStringList dirs = QStringList::split(Option::dir_sep, flat_file);
144 dirs.pop_back(); //remove the file portion as it will be added via src_key
145 for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
146 QString new_grp(last_grp + Option::dir_sep + (*dir_it)),
147 new_grp_key(keyFor(new_grp)), last_grp_key(keyFor(last_grp));
148 if(dir_it == dirs.begin()) {
149 if(!groups.contains(new_grp))
150 project->variables()["QMAKE_PBX_" + srcs[i]].append(new_grp_key);
151 } else {
152 groups[last_grp] += new_grp_key;
153 }
154 last_grp = new_grp;
155 }
156 groups[last_grp] += src_key;
157 in_root = FALSE;
158 }
159 }
160 if(in_root)
161 src_list.append(src_key);
162 //source reference
163 t << "\t\t" << src_key << " = {" << "\n"
164 << "\t\t\t" << "isa = PBXFileReference;" << "\n"
165 << "\t\t\t" << "path = \"" << file << "\";" << "\n"
166 << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n"
167 << "\t\t" << "};" << "\n";
168 //build reference
169 QString obj_key = file + ".o";
170 obj_key = keyFor(obj_key);
171 t << "\t\t" << obj_key << " = {" << "\n"
172 << "\t\t\t" << "fileRef = " << src_key << ";" << "\n"
173 << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
174 << "\t\t\t" << "settings = {" << "\n"
175 << "\t\t\t\t" << "ATTRIBUTES = (" << "\n"
176 << "\t\t\t\t" << ");" << "\n"
177 << "\t\t\t" << "};" << "\n"
178 << "\t\t" << "};" << "\n";
179 project->variables()["QMAKE_PBX_OBJ"].append(obj_key);
180 }
181 if(!src_list.isEmpty()) {
182 QString grp;
183 if(srcs[i] == "SOURCES") {
184 if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon
185 QString icns_file = keyFor("ICNS_FILE");
186 src_list.append(icns_file);
187 t << "\t\t" << icns_file << " = {" << "\n"
188 << "\t\t\t" << "isa = PBXFileReference;" << "\n"
189 << "\t\t\t" << "path = \"" << project->first("RC_FILE") << "\";" << "\n"
190 << "\t\t\t" << "refType = " << reftypeForFile(project->first("RC_FILE")) << ";" << "\n"
191 << "\t\t" << "};" << "\n";
192 t << "\t\t" << keyFor("ICNS_FILE_REFERENCE") << " = {" << "\n"
193 << "\t\t\t" << "fileRef = " << icns_file << ";" << "\n"
194 << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
195 << "\t\t\t" << "settings = {" << "\n"
196 << "\t\t\t" << "};" << "\n"
197 << "\t\t" << "};" << "\n";
198 }
199 grp = "Sources";
200 } else if(srcs[i] == "SRCMOC") {
201 grp = "Mocables";
202 } else if(srcs[i] == "UICIMPLS") {
203 grp = "UICables";
204 }
205 QString grp_key = keyFor(grp);
206 project->variables()["QMAKE_PBX_GROUPS"].append(grp_key);
207 t << "\t\t" << grp_key << " = {" << "\n"
208 << "\t\t\t" << "children = (" << "\n"
209 << varGlue("QMAKE_PBX_" + srcs[i], "\t\t\t\t", ",\n\t\t\t\t", "\n")
210 << "\t\t\t" << ");" << "\n"
211 << "\t\t\t" << "isa = PBXGroup;" << "\n"
212 << "\t\t\t" << "name = " << grp << ";" << "\n"
213 << "\t\t\t" << "refType = 4;" << "\n"
214 << "\t\t" << "};" << "\n";
215 }
216 }
217 for(QMap<QString, QStringList>::Iterator grp_it = groups.begin();
218 grp_it != groups.end(); ++grp_it) {
219 t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n"
220 << "\t\t\t" << "isa = PBXGroup;" << "\n"
221 << "\t\t\t" << "children = (" << "\n"
222 << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n")
223 << "\t\t\t" << ");" << "\n"
224 << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n"
225 << "\t\t\t" << "refType = 4;" << "\n"
226 << "\t\t" << "};" << "\n";
227 }
228
229 //PREPROCESS BUILDPHASE (just a makefile)
230 if(!project->isEmpty("UICIMPLS") || !project->isEmpty("SRCMOC") ||
231 !project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) {
232 QString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak";
233 QFile mkf(mkfile);
234 if(mkf.open(IO_WriteOnly | IO_Translate)) {
235 did_preprocess = TRUE;
236 debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
237 QTextStream mkt(&mkf);
238 writeHeader(mkt);
239 mkt << "MOC = " << var("QMAKE_MOC") << endl;
240 mkt << "UIC = " << var("QMAKE_UIC") << endl;
241 mkt << "LEX = " << var("QMAKE_LEX") << endl;
242 mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
243 mkt << "YACC = " << var("QMAKE_YACC") << endl;
244 mkt << "YACCFLAGS = " << var("QMAKE_YACCFLAGS") << endl;
245 mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
246 mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl;
247 mkt << "FORMS = " << varList("UICIMPLS") << endl;
248 mkt << "MOCS = " << varList("SRCMOC") << endl;
249 mkt << "PARSERS =";
250 if(!project->isEmpty("YACCSOURCES")) {
251 QStringList &yaccs = project->variables()["YACCSOURCES"];
252 for(QStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) {
253 QFileInfo fi((*yit));
254 mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE)
255 << Option::yacc_mod << Option::cpp_ext.first();
256 }
257 }
258 if(!project->isEmpty("LEXSOURCES")) {
259 QStringList &lexs = project->variables()["LEXSOURCES"];
260 for(QStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) {
261 QFileInfo fi((*lit));
262 mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE)
263 << Option::lex_mod << Option::cpp_ext.first();
264 }
265 }
266 mkt << "\n";
267 mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS)" << endl;
268 mkt << "preprocess_clean: mocclean uiclean parser_clean" << endl << endl;
269 mkt << "mocclean:" << "\n";
270 if(!project->isEmpty("SRCMOC"))
271 mkt << "\t-rm -f $(MOCS)" << "\n";
272 mkt << "uiclean:" << "\n";
273 if(!project->isEmpty("UICIMPLS"))
274 mkt << "\t-rm -f $(FORMS)" << "\n";
275 mkt << "parser_clean:" << "\n";
276 if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES"))
277 mkt << "\t-rm -f $(PARSERS)" << "\n";
278 writeUicSrc(mkt, "FORMS");
279 writeMocSrc(mkt, "HEADERS");
280 writeMocSrc(mkt, "SOURCES");
281 writeMocSrc(mkt, "UICDECLS");
282 writeYaccSrc(mkt, "YACCSOURCES");
283 writeLexSrc(mkt, "LEXSOURCES");
284 mkf.close();
285 }
286 QString target_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET");
287 mkfile = fileFixify(mkfile, QDir::currentDirPath());
288 t << "\t\t" << target_key << " = {" << "\n"
289 << "\t\t\t" << "buildArgumentsString = \"-f " << mkfile << "\";" << "\n"
290 << "\t\t\t" << "buildPhases = (" << "\n"
291 << "\t\t\t" << ");" << "\n"
292 << "\t\t\t" << "buildSettings = {" << "\n"
293 << "\t\t\t" << "};" << "\n"
294 << "\t\t\t" << "buildToolPath = \"/usr/bin/gnumake\";"<< "\n"
295 << "\t\t\t" << "buildWorkingDirectory = \"" << QDir::currentDirPath() << "\";" << "\n"
296 << "\t\t\t" << "dependencies = (" << "\n"
297 << "\t\t\t" << ");" << "\n"
298 << "\t\t\t" << "isa = PBXLegacyTarget;" << "\n"
299 << "\t\t\t" << "name = QtPreprocessors;" << "\n"
300 << "\t\t\t" << "productName = QtPreprocessors;" << "\n"
301 << "\t\t\t" << "settingsToExpand = 6;" << "\n"
302 << "\t\t\t" << "settingsToPassInEnvironment = 287;" << "\n"
303 << "\t\t\t" << "settingsToPassOnCommandLine = 280;" << "\n"
304 << "\t\t\t" << "shouldsUseHeadermap = 0;" << "\n"
305 << "\t\t" << "};" << "\n";
306
307 QString target_depend_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET_DEPEND");
308 project->variables()["QMAKE_PBX_TARGETDEPENDS"].append(target_depend_key);
309 t << "\t\t" << target_depend_key << " = {" << "\n"
310 << "\t\t\t" << "isa = PBXTargetDependency;" << "\n"
311 << "\t\t\t" << "target = " << target_key << ";" << "\n"
312 << "\t\t" << "};" << "\n";
313 }
314 //SOURCE BUILDPHASE
315 if(!project->isEmpty("QMAKE_PBX_OBJ")) {
316 QString grp = "Build Sources", key = keyFor(grp);
317 project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
318 t << "\t\t" << key << " = {" << "\n"
319 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
320 << "\t\t\t" << "files = (" << "\n"
321 << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n")
322 << "\t\t\t" << ");" << "\n"
323 << "\t\t\t" << "isa = PBXSourcesBuildPhase;" << "\n"
324 << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
325 << "\t\t" << "};" << "\n";
326 }
327
328 if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
329 QStringList &libdirs = project->variables()["QMAKE_PBX_LIBPATHS"];
330 QString libs[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
331 for(i = 0; !libs[i].isNull(); i++) {
332 tmp = project->variables()[libs[i]];
333 for(QStringList::Iterator it = tmp.begin(); it != tmp.end();) {
334 bool remove = FALSE;
335 QString library, name, opt = (*it).stripWhiteSpace();
336 if(opt.startsWith("-L")) {
337 QString r = opt.right(opt.length() - 2);
338 fixEnvVariables(r);
339 libdirs.append(r);
340 } else if(opt.startsWith("-l")) {
341 name = opt.right(opt.length() - 2);
342 QString lib("lib" + name);
343 for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) {
344 if(project->isActiveConfig("link_prl")) {
345 /* This isn't real nice, but it is real usefull. This looks in a prl
346 for what the library will ultimately be called so we can stick it
347 in the ProjectFile. If the prl format ever changes (not likely) then
348 this will not really work. However, more concerning is that it will
349 encode the version number in the Project file which might be a bad
350 things in days to come? --Sam
351 */
352 QString prl_file = (*lit) + Option::dir_sep + lib + Option::prl_ext;
353 if(QFile::exists(prl_file)) {
354 QMakeProject proj;
355 if(proj.read(prl_file, QDir::currentDirPath())) {
356 if(!proj.isEmpty("QMAKE_PRL_TARGET")) {
357 library = (*lit) + Option::dir_sep + proj.first("QMAKE_PRL_TARGET");
358 debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
359 opt.latin1(), prl_file.latin1(), library.latin1());
360 remove = TRUE;
361 }
362 }
363
364 }
365 }
366 if(!remove) {
367 QString extns[] = { ".dylib", ".so", ".a", QString::null };
368 for(int n = 0; !remove && !extns[n].isNull(); n++) {
369 QString tmp = (*lit) + Option::dir_sep + lib + extns[n];
370 if(QFile::exists(tmp)) {
371 library = tmp;
372 debug_msg(1, "pbuilder: Found library (%s) via %s",
373 opt.latin1(), library.latin1());
374 remove = TRUE;
375 }
376 }
377 }
378 }
379 } else if(opt == "-framework") {
380 ++it;
381 if(it == tmp.end())
382 break;
383 QStringList &fdirs = project->variables()["QMAKE_FRAMEWORKDIR"];
384 if(fdirs.isEmpty())
385 fdirs.append("/System/Library/Frameworks/");
386 for(QStringList::Iterator fit = fdirs.begin(); fit != fdirs.end(); ++fit) {
387 if(QFile::exists((*fit) + QDir::separator() + (*it) + ".framework")) {
388 --it;
389 it = tmp.remove(it);
390 remove = TRUE;
391 library = (*fit) + Option::dir_sep + (*it) + ".framework";
392 break;
393 }
394 }
395 } else if(opt.left(1) != "-") {
396 remove = TRUE;
397 library = opt;
398 }
399 if(!library.isEmpty()) {
400 if(name.isEmpty()) {
401 int slsh = library.findRev(Option::dir_sep);
402 if(slsh != -1)
403 name = library.right(library.length() - slsh - 1);
404 }
405 library = fileFixify(library);
406 QString key = keyFor(library);
407 bool is_frmwrk = (library.endsWith(".framework"));
408 t << "\t\t" << key << " = {" << "\n"
409 << "\t\t\t" << "isa = " << (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference") << ";" << "\n"
410 << "\t\t\t" << "name = \"" << name << "\";" << "\n"
411 << "\t\t\t" << "path = \"" << library << "\";" << "\n"
412 << "\t\t\t" << "refType = " << reftypeForFile(library) << ";" << "\n"
413 << "\t\t" << "};" << "\n";
414 project->variables()["QMAKE_PBX_LIBRARIES"].append(key);
415 QString obj_key = library + ".o";
416 obj_key = keyFor(obj_key);
417 t << "\t\t" << obj_key << " = {" << "\n"
418 << "\t\t\t" << "fileRef = " << key << ";" << "\n"
419 << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
420 << "\t\t\t" << "settings = {" << "\n"
421 << "\t\t\t" << "};" << "\n"
422 << "\t\t" << "};" << "\n";
423 project->variables()["QMAKE_PBX_BUILD_LIBRARIES"].append(obj_key);
424 }
425 if(remove)
426 it = tmp.remove(it);
427 else
428 ++it;
429 }
430 project->variables()[libs[i]] = tmp;
431 }
432 }
433 //SUBLIBS BUILDPHASE (just another makefile)
434 if(!project->isEmpty("SUBLIBS")) {
435 QString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak";
436 QFile mkf(mkfile);
437 if(mkf.open(IO_WriteOnly | IO_Translate)) {
438 debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
439 QTextStream mkt(&mkf);
440 writeHeader(mkt);
441 mkt << "SUBLIBS= ";
442 tmp = project->variables()["SUBLIBS"];
443 QStringList::Iterator it;
444 for(it = tmp.begin(); it != tmp.end(); ++it)
445 t << "tmp/lib" << (*it) << ".a ";
446 t << endl << endl;
447 mkt << "sublibs: $(SUBLIBS)" << endl << endl;
448 tmp = project->variables()["SUBLIBS"];
449 for(it = tmp.begin(); it != tmp.end(); ++it)
450 t << "tmp/lib" << (*it) << ".a" << ":\n\t"
451 << var(QString("MAKELIB") + (*it)) << endl << endl;
452 mkf.close();
453 }
454 QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE");
455 mkfile = fileFixify(mkfile, QDir::currentDirPath());
456 project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
457 t << "\t\t" << phase_key << " = {" << "\n"
458 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
459 << "\t\t\t" << "files = (" << "\n"
460 << "\t\t\t" << ");" << "\n"
461 << "\t\t\t" << "generatedFileNames = (" << "\n"
462 << "\t\t\t" << ");" << "\n"
463 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
464 << "\t\t\t" << "name = \"Qt Sublibs\";" << "\n"
465 << "\t\t\t" << "neededFileNames = (" << "\n"
466 << "\t\t\t" << ");" << "\n"
467 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
468 << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
469 " -f " << mkfile << "\";" << "\n"
470 << "\t\t" << "};" << "\n";
471 }
472 //LIBRARY BUILDPHASE
473 if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) {
474 tmp = project->variables()["QMAKE_PBX_LIBRARIES"];
475 if(!tmp.isEmpty()) {
476 QString grp("External Frameworks and Libraries"), key = keyFor(grp);
477 project->variables()["QMAKE_PBX_GROUPS"].append(key);
478 t << "\t\t" << key << " = {" << "\n"
479 << "\t\t\t" << "children = (" << "\n"
480 << varGlue("QMAKE_PBX_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
481 << "\t\t\t" << ");" << "\n"
482 << "\t\t\t" << "isa = PBXGroup;" << "\n"
483 << "\t\t\t" << "name = \"" << grp << "\"" << ";" << "\n"
484 << "\t\t\t" << "path = \"\";" << "\n"
485 << "\t\t\t" << "refType = 4;" << "\n"
486 << "\t\t" << "};" << "\n";
487 }
488 }
489 {
490 QString grp("Frameworks & Libraries"), key = keyFor(grp);
491 project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
492 t << "\t\t" << key << " = {" << "\n"
493 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
494 << "\t\t\t" << "files = (" << "\n"
495 << varGlue("QMAKE_PBX_BUILD_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
496 << "\t\t\t" << ");" << "\n"
497 << "\t\t\t" << "isa = PBXFrameworksBuildPhase;" << "\n"
498 << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
499 << "\t\t" << "};" << "\n";
500 }
501 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console") &&
502 project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES
503 QString grp("Bundle Resources"), key = keyFor(grp);
504 project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
505 t << "\t\t" << key << " = {" << "\n"
506 << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
507 << "\t\t\t" << "files = (" << "\n"
508 << (!project->isEmpty("RC_FILE") ? keyFor("ICNS_FILE_REFERENCE") : QString(""))
509 << "\t\t\t" << ");" << "\n"
510 << "\t\t\t" << "isa = PBXResourcesBuildPhase;" << "\n"
511 << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
512 << "\t\t" << "};" << "\n";
513 }
514
515 //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER
516 //PRODUCTS
517 {
518 QString grp("Products"), key = keyFor(grp);
519 project->variables()["QMAKE_PBX_GROUPS"].append(key);
520 t << "\t\t" << key << " = {" << "\n"
521 << "\t\t\t" << "children = (" << "\n"
522 << "\t\t\t\t" << keyFor("QMAKE_PBX_REFERENCE") << "\n"
523 << "\t\t\t" << ");" << "\n"
524 << "\t\t\t" << "isa = PBXGroup;" << "\n"
525 << "\t\t\t" << "name = Products;" << "\n"
526 << "\t\t\t" << "refType = 4;" << "\n"
527 << "\t\t" << "};" << "\n";
528 }
529 { //INSTALL BUILDPHASE (sh script)
530 QString targ = project->first("TARGET");
531 if(project->first("TEMPLATE") == "app" ||
532 (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") &&
533 project->isActiveConfig("frameworklib")))
534 targ = project->first("QMAKE_ORIG_TARGET");
535 int slsh = targ.findRev(Option::dir_sep);
536 if(slsh != -1)
537 targ = targ.right(targ.length() - slsh - 1);
538 fixEnvVariables(targ);
539 QStringList links;
540 if(project->first("TEMPLATE") == "app") {
541 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
542 targ += ".app";
543 } else if(!project->isActiveConfig("staticlib") &&
544 !project->isActiveConfig("frameworklib")) {
545 QString li[] = { "TARGET_", "TARGET_x", "TARGET_x.y", QString::null };
546 for(int n = 0; !li[n].isNull(); n++) {
547 QString t = project->first(li[n]);
548 slsh = t.findRev(Option::dir_sep);
549 if(slsh != -1)
550 t = t.right(t.length() - slsh);
551 fixEnvVariables(t);
552 links << t;
553 }
554 }
555 QString script = pbx_dir + Option::dir_sep + "qt_install.sh";
556 QFile shf(script);
557 if(shf.open(IO_WriteOnly | IO_Translate)) {
558 debug_msg(1, "pbuilder: Creating file: %s", script.latin1());
559 QString targ = project->first("QMAKE_ORIG_TARGET"), cpflags;
560 if(project->first("TEMPLATE") == "app") {
561 targ = project->first("TARGET");
562 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
563 targ += ".app";
564 cpflags += "-r ";
565 }
566 } else if(!project->isActiveConfig("frameworklib")) {
567 if(project->isActiveConfig("staticlib"))
568 targ = project->first("TARGET");
569 else
570 targ = project->first("TARGET_");
571 int slsh = targ.findRev(Option::dir_sep);
572 if(slsh != -1)
573 targ = targ.right(targ.length() - slsh - 1);
574 }
575 QTextStream sht(&shf);
576 QString dstdir = project->first("DESTDIR");
577 fixEnvVariables(dstdir);
578
579 sht << "#!/bin/sh" << endl;
580 //copy the actual target
581 sht << "OUT_TARG=\"" << targ << "\"\n"
582 << "[ -z \"$BUILD_ROOT\" ] || OUT_TARG=\"${BUILD_ROOT}/${OUT_TARG}\"" << endl;
583 sht << "[ \"$OUT_TARG\" = \""
584 << (dstdir.isEmpty() ? QDir::currentDirPath() + QDir::separator(): dstdir) << targ << "\" ] || "
585 << "[ \"$OUT_TARG\" = \"" << targ << "\" ] || "
586 << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << endl;
587 //rename as a framework
588 if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib"))
589 sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << targ << "\"" << endl;
590 //create all the version symlinks (just to be like unixmake)
591 for(QStringList::Iterator it = links.begin(); it != links.end(); ++it) {
592 if(targ != (*it))
593 sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << (*it) << "\"" << endl;
594 }
595 shf.close();
596#ifdef Q_OS_UNIX
597 chmod(script.latin1(), S_IRWXU | S_IRWXG);
598#endif
599 QString phase_key = keyFor("QMAKE_PBX_INSTALL_BUILDPHASE");
600 script = fileFixify(script, QDir::currentDirPath());
601 project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
602 t << "\t\t" << phase_key << " = {" << "\n"
603 << "\t\t\t" << "buildActionMask = 8;" << "\n" //only on install!
604 << "\t\t\t" << "files = (" << "\n"
605 << "\t\t\t" << ");" << "\n"
606 << "\t\t\t" << "generatedFileNames = (" << "\n"
607 << "\t\t\t" << ");" << "\n"
608 << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
609 << "\t\t\t" << "name = \"Qt Install\";" << "\n"
610 << "\t\t\t" << "neededFileNames = (" << "\n"
611 << "\t\t\t" << ");" << "\n"
612 << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
613 << "\t\t\t" << "shellScript = \"" << script << "\";" << "\n"
614 << "\t\t" << "};" << "\n";
615 }
616 }
617 //ROOT_GROUP
618 t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n"
619 << "\t\t\t" << "children = (" << "\n"
620 << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
621 << "\t\t\t" << ");" << "\n"
622 << "\t\t\t" << "isa = PBXGroup;" << "\n"
623 << "\t\t\t" << "name = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"
624 << "\t\t\t" << "path = \"\";" << "\n"
625 << "\t\t\t" << "refType = 4;" << "\n"
626 << "\t\t" << "};" << "\n";
627 //REFERENCE
628 t << "\t\t" << keyFor("QMAKE_PBX_REFERENCE") << " = {" << "\n";
629 if(project->first("TEMPLATE") == "app") {
630 QString targ = project->first("QMAKE_ORIG_TARGET");
631 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
632 targ += ".app";
633 t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n";
634 } else {
635 t << "\t\t\t" << "isa = PBXExecutableFileReference;" << "\n";
636 }
637 QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") :
638 QDir::currentDirPath()) + Option::dir_sep + targ;
639 t << "\t\t\t" << "name = " << targ << ";" << "\n"
640 << "\t\t\t" << "path = \"" << targ << "\";" << "\n"
641 << "\t\t\t" << "refType = " << reftypeForFile(app) << ";" << "\n";
642 } else {
643 QString lib = project->first("QMAKE_ORIG_TARGET");
644 if(project->isActiveConfig("staticlib")) {
645 lib = project->first("TARGET");
646 } else if(!project->isActiveConfig("frameworklib")) {
647 if(project->isActiveConfig("plugin"))
648 lib = project->first("TARGET");
649 else
650 lib = project->first("TARGET_");
651 }
652 int slsh = lib.findRev(Option::dir_sep);
653 if(slsh != -1)
654 lib = lib.right(lib.length() - slsh - 1);
655 t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n"
656 << "\t\t\t" << "path = " << lib << ";\n"
657 << "\t\t\t" << "refType = " << reftypeForFile(lib) << ";" << "\n";
658 }
659 t << "\t\t" << "};" << "\n";
660 //TARGET
661 t << "\t\t" << keyFor("QMAKE_PBX_TARGET") << " = {" << "\n"
662 << "\t\t\t" << "buildPhases = (" << "\n"
663 << varGlue("QMAKE_PBX_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
664 << "\t\t\t" << ");" << "\n"
665 << "\t\t\t" << "buildSettings = {" << "\n"
666 << "\t\t\t\t" << "FRAMEWORK_SEARCH_PATHS = \"\";" << "\n"
667 << "\t\t\t\t" << "HEADER_SEARCH_PATHS = \"" << fixEnvsList("INCLUDEPATH") << " " << fixEnvs(specdir()) << "\";" << "\n"
668 << "\t\t\t\t" << "LIBRARY_SEARCH_PATHS = \"" << var("QMAKE_PBX_LIBPATHS") << "\";" << "\n"
669 << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n"
670 << "\t\t\t\t" << "OTHER_CFLAGS = \"" <<
671 fixEnvsList("QMAKE_CFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") <<
672 varGlue("DEFINES"," -D"," -D","") << "\";" << "\n"
673 << "\t\t\t\t" << "LEXFLAGS = \"" << var("QMAKE_LEXFLAGS") << "\";" << "\n"
674 << "\t\t\t\t" << "YACCFLAGS = \"" << var("QMAKE_YACCFLAGS") << "\";" << "\n"
675 << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" <<
676 fixEnvsList("QMAKE_CXXFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") <<
677 varGlue("DEFINES"," -D"," -D","") << "\";" << "\n"
678 << "\t\t\t\t" << "OTHER_REZFLAGS = \"\";" << "\n"
679 << "\t\t\t\t" << "SECTORDER_FLAGS = \"\";" << "\n"
680 << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n";
681#if 1
682 t << "\t\t\t\t" << "BUILD_ROOT = \"" << QDir::currentDirPath() << "\";" << "\n";
683#endif
684 if(!project->isActiveConfig("staticlib"))
685 t << "\t\t\t\t" << "OTHER_LDFLAGS = \"" << fixEnvsList("SUBLIBS") << " " <<
686 fixEnvsList("QMAKE_LFLAGS") << " " << fixEnvsList("QMAKE_LIBDIR_FLAGS") <<
687 " " << fixEnvsList("QMAKE_LIBS") << "\";" << "\n";
688 if(!project->isEmpty("DESTDIR"))
689 t << "\t\t\t\t" << "INSTALL_PATH = \"" << project->first("DESTDIR") << "\";" << "\n";
690 if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0")
691 t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VERSION") << "\";" << "\n";
692 if(!project->isEmpty("OBJECTS_DIR"))
693 t << "\t\t\t\t" << "OBJECT_FILE_DIR = \"" << project->first("OBJECTS_DIR") << "\";" << "\n";
694 if(project->first("TEMPLATE") == "app") {
695 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
696 t << "\t\t\t\t" << "WRAPPER_EXTENSION = app;" << "\n";
697 t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n";
698 } else {
699 QString lib = project->first("QMAKE_ORIG_TARGET");
700 if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) {
701 t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n";
702 lib = project->first("TARGET");
703 } else {
704 t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n";
705 if(!project->isActiveConfig("frameworklib")) {
706 if(project->isActiveConfig("plugin"))
707 lib = project->first("TARGET");
708 else
709 lib = project->first("TARGET_");
710 }
711 }
712 int slsh = lib.findRev(Option::dir_sep);
713 if(slsh != -1)
714 lib = lib.right(lib.length() - slsh - 1);
715 t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n";
716 }
717 tmp = project->variables()["QMAKE_PBX_VARS"];
718 for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it)
719 t << "\t\t\t\t" << (*it) << " = \"" << getenv((*it)) << "\";" << "\n";
720 t << "\t\t\t" << "};" << "\n"
721 << "\t\t\t" << "conditionalBuildSettings = {" << "\n"
722 << "\t\t\t" << "};" << "\n"
723 << "\t\t\t" << "dependencies = (" << "\n"
724 << varGlue("QMAKE_PBX_TARGETDEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
725 << "\t\t\t" << ");" << "\n"
726 << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_REFERENCE") << ";" << "\n"
727 << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n";
728 if(project->first("TEMPLATE") == "app") {
729 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
730 t << "\t\t\t" << "isa = PBXApplicationTarget;" << "\n"
731 << "\t\t\t" << "productSettingsXML = " << "\"" << "<?xml version="
732 << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n"
733 << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/"
734 << "Library/DTDs/PropertyList.dtd\\\">" << "\n"
735 << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n"
736 << "\t\t\t\t" << "<dict>" << "\n"
737 << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n"
738 << "\t\t\t\t\t" << "<string>English</string>" << "\n"
739 << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n"
740 << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n"
741 << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n"
742 << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n"
743 << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n"
744 << "\t\t\t\t\t" << "<string>6.0</string>" << "\n"
745 << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n"
746 << "\t\t\t\t\t" << "<string>APPL</string>" << "\n"
747 << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n"
748 << "\t\t\t\t\t" << "<string>????</string>" << "\n"
749 << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n"
750 << "\t\t\t\t\t" << "<string>0.1</string>" << "\n"
751 << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n"
752 << "\t\t\t\t\t" << "<true/>" << "\n"
753 << "\t\t\t\t" << "</dict>" << "\n"
754 << "\t\t\t\t" << "</plist>" << "\";" << "\n";
755 } else {
756 t << "\t\t\t" << "isa = PBXToolTarget;" << "\n";
757 }
758 t << "\t\t\t" << "name = \"" << project->first("QMAKE_ORIG_TARGET") << "\";" << "\n"
759 << "\t\t\t" << "productName = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n";
760 } else {
761 QString lib = project->first("QMAKE_ORIG_TARGET");
762 if(!project->isActiveConfig("frameworklib"))
763 lib.prepend("lib");
764 t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n"
765 << "\t\t\t" << "name = \"" << lib << "\";" << "\n"
766 << "\t\t\t" << "productName = " << lib << ";" << "\n";
767 }
768 if(!project->isEmpty("DESTDIR"))
769 t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n";
770 t << "\t\t" << "};" << "\n";
771 //DEBUG/RELEASE
772 for(i = 0; i < 2; i++) {
773 bool as_release = !i;
774 if(project->isActiveConfig("debug"))
775 as_release = i;
776 QString key = "QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG");
777 key = keyFor(key);
778 project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key);
779 t << "\t\t" << key << " = {" << "\n"
780 << "\t\t\t" << "buildRules = (" << "\n"
781 << "\t\t\t" << ");" << "\n"
782 << "\t\t\t" << "buildSettings = {" << "\n"
783 << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n";
784 if(as_release)
785 t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n";
786 t << "\t\t\t" << "};" << "\n"
787 << "\t\t\t" << "isa = PBXBuildStyle;" << "\n"
788 << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n"
789 << "\t\t" << "};" << "\n";
790 }
791 //ROOT
792 t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n"
793 << "\t\t\t" << "buildStyles = (" << "\n"
794 << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
795 << "\t\t\t" << ");" << "\n"
796 << "\t\t\t" << "isa = PBXProject;" << "\n"
797 << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n"
798 << "\t\t\t" << "targets = (" << "\n"
799 << "\t\t\t\t" << keyFor("QMAKE_PBX_TARGET") << "\n"
800 << "\t\t\t" << ");" << "\n"
801 << "\t\t" << "};" << "\n";
802
803 //FOOTER
804 t << "\t" << "};" << "\n"
805 << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n"
806 << "}" << endl;
807
808 QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
809 QDir::currentDirPath());
810 QFile mkwrapf(mkwrap);
811 if(mkwrapf.open(IO_WriteOnly | IO_Translate)) {
812 debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1());
813 QTextStream mkwrapt(&mkwrapf);
814 writeHeader(mkwrapt);
815 const char *cleans = "uiclean mocclean preprocess_clean ";
816 mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n"
817 << "all:" << "\n\t"
818 << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild") << "\n"
819 << "install: all" << "\n\t"
820 << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild install") << "\n"
821 << "distclean clean: preprocess_clean" << "\n\t"
822 << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild clean") << "\n"
823 << (!did_preprocess ? cleans : "") << ":" << "\n";
824 if(did_preprocess)
825 mkwrapt << cleans << ":" << "\n\t"
826 << "make -f "
827 << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl;
828 }
829 return TRUE;
830}
831
832QString
833ProjectBuilderMakefileGenerator::fixEnvs(QString file)
834{
835 QRegExp reg_var("\\$\\((.*)\\)");
836 for(int rep = 0; (rep = reg_var.search(file, rep)) != -1; ) {
837 if(project->variables()["QMAKE_PBX_VARS"].findIndex(reg_var.cap(1)) == -1)
838 project->variables()["QMAKE_PBX_VARS"].append(reg_var.cap(1));
839 rep += reg_var.matchedLength();
840 }
841 return file;
842}
843
844QString
845ProjectBuilderMakefileGenerator::fixEnvsList(QString where)
846{
847 QString ret;
848 const QStringList &l = project->variables()[where];
849 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
850 fixEnvs((*it));
851 if(!ret.isEmpty())
852 ret += " ";
853 ret += (*it);
854 }
855 return ret;
856}
857
858QString
859ProjectBuilderMakefileGenerator::keyFor(QString block)
860{
861#if 0 //This make this code much easier to debug..
862 return block;
863#endif
864
865 QString ret;
866 if(!keys.contains(block)) {
867#if 0
868 static unsigned int r = 0;
869 ret.sprintf("%024x", ++r);
870#else //not really necesary, but makes it look more interesting..
871 static struct { unsigned int a1, a2, a3; } r = { 0, 0, 0 };
872 if(!r.a1 && !r.a2 && !r.a3) {
873 r.a1 = rand();
874 r.a2 = rand();
875 r.a3 = rand();
876 }
877 switch(rand() % 3) {
878 case 0: ++r.a1; break;
879 case 1: ++r.a2; break;
880 case 2: ++r.a3; break;
881 }
882 ret.sprintf("%08x%08x%08x", r.a1, r.a2, r.a3);
883#endif
884 ret = ret.upper();
885 keys.insert(block, ret);
886 } else {
887 ret = keys[block];
888 }
889 return ret;
890}
891
892bool
893ProjectBuilderMakefileGenerator::openOutput(QFile &file) const
894{
895 if(project->first("TEMPLATE") != "subdirs") {
896 QFileInfo fi(file);
897 if(fi.extension() != "pbxproj" || file.name().isEmpty()) {
898 QString output = file.name();
899 if(fi.isDir())
900 output += QDir::separator();
901 if(fi.extension() != "pbproj") {
902 if(file.name().isEmpty() || fi.isDir())
903 output += project->first("TARGET");
904 output += QString(".pbproj") + QDir::separator();
905 } else if(output[(int)output.length() - 1] != QDir::separator()) {
906 output += QDir::separator();
907 }
908 output += QString("project.pbxproj");
909 file.setName(output);
910 }
911 bool ret = UnixMakefileGenerator::openOutput(file);
912 ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
913 Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
914 return ret;
915 }
916 return UnixMakefileGenerator::openOutput(file);
917}
918
919/* This function is such a hack it is almost pointless, but it
920 eliminates the warning message from ProjectBuilder that the project
921 file is for an older version. I guess this could be used someday if
922 the format of the output is dependant upon the version of
923 ProjectBuilder as well.
924*/
925int
926ProjectBuilderMakefileGenerator::pbuilderVersion() const
927{
928 QString ret;
929 if(project->isEmpty("QMAKE_PBUILDER_VERSION")) {
930 QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST");
931 if(version_plist.isEmpty())
932 version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist";
933 else
934 version_plist = version_plist.replace(QRegExp("\""), "");
935 QFile version_file(version_plist);
936 if(version_file.open(IO_ReadOnly)) {
937 debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.latin1());
938 QTextStream plist(&version_file);
939
940 bool in_dict = FALSE;
941 QString current_key;
942 QRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$");
943 while(!plist.eof()) {
944 QString line = plist.readLine().stripWhiteSpace();
945 if(line == "<dict>")
946 in_dict = TRUE;
947 else if(line == "</dict>")
948 in_dict = FALSE;
949 else if(in_dict) {
950 if(keyreg.exactMatch(line))
951 current_key = keyreg.cap(1);
952 else if(current_key == "CFBundleShortVersionString" && stringreg.exactMatch(line))
953 version = stringreg.cap(1);
954 }
955 }
956 version_file.close();
957 } else debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1());
958 if(version.startsWith("2.0"))
959 ret = "38";
960 else if(version == "1.1")
961 ret = "34";
962 } else {
963 ret = project->first("QMAKE_PBUILDER_VERSION");
964 }
965 if(!ret.isEmpty()) {
966 bool ok;
967 int int_ret = ret.toInt(&ok);
968 if(ok) {
969 debug_msg(1, "pbuilder: version.plist: Got version: %d", int_ret);
970 return int_ret;
971 }
972 }
973 debug_msg(1, "pbuilder: version.plist: Fallback to default version");
974 return 34; //my fallback
975}
976
977QString
978ProjectBuilderMakefileGenerator::reftypeForFile(QString where)
979{
980 if(QDir::isRelativePath(where))
981 return "4"; //relative
982 return "0"; //absolute
983}
diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h
new file mode 100644
index 0000000..ec2e1be
--- a/dev/null
+++ b/qmake/generators/mac/pbuilder_pbx.h
@@ -0,0 +1,68 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __PBUILDERMAKE_H__
38#define __PBUILDERMAKE_H__
39
40#include "unixmake.h"
41
42class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator
43{
44 QString pbx_dir;
45 int pbuilderVersion() const;
46 bool writeMakeParts(QTextStream &);
47 bool writeMakefile(QTextStream &);
48
49 QMap<QString, QString> keys;
50 QString keyFor(QString file);
51 QString fixEnvs(QString file);
52 QString fixEnvsList(QString where);
53 QString reftypeForFile(QString file);
54
55public:
56 ProjectBuilderMakefileGenerator(QMakeProject *p);
57 ~ProjectBuilderMakefileGenerator();
58
59 virtual bool openOutput(QFile &) const;
60protected:
61 virtual bool doDepends() const { return FALSE; } //never necesary
62};
63
64inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator()
65{ }
66
67
68#endif /* __PBUILDERMAKE_H__ */
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
new file mode 100644
index 0000000..7df95b2
--- a/dev/null
+++ b/qmake/generators/unix/unixmake.cpp
@@ -0,0 +1,520 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "unixmake.h"
39#include "option.h"
40#include <qregexp.h>
41#include <qfile.h>
42#include <qdict.h>
43#include <qdir.h>
44#include <time.h>
45
46
47void
48UnixMakefileGenerator::init()
49{
50 if(init_flag)
51 return;
52 init_flag = TRUE;
53
54 if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */
55 return;
56
57 QStringList &configs = project->variables()["CONFIG"];
58 /* this should probably not be here, but I'm using it to wrap the .t files */
59 if(project->first("TEMPLATE") == "app")
60 project->variables()["QMAKE_APP_FLAG"].append("1");
61 else if(project->first("TEMPLATE") == "lib")
62 project->variables()["QMAKE_LIB_FLAG"].append("1");
63 else if(project->first("TEMPLATE") == "subdirs") {
64 MakefileGenerator::init();
65 if(project->isEmpty("MAKEFILE"))
66 project->variables()["MAKEFILE"].append("Makefile");
67 if(project->isEmpty("QMAKE"))
68 project->variables()["QMAKE"].append("qmake");
69 if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1)
70 project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all");
71 return; /* subdirs is done */
72 }
73
74 if( project->isEmpty("QMAKE_EXTENSION_SHLIB") ) {
75 QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 );
76 if ( os == "cygwin" ) {
77 project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" );
78 } else {
79 project->variables()["QMAKE_EXTENSION_SHLIB"].append( "so" );
80 }
81 }
82 if( project->isEmpty("QMAKE_COPY_FILE") )
83 project->variables()["QMAKE_COPY_FILE"].append( "$(COPY) -p" );
84 if( project->isEmpty("QMAKE_COPY_DIR") )
85 project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -pR" );
86 //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
87 if(!project->isEmpty("TARGET")) {
88 QString targ = project->first("TARGET");
89 int slsh = QMAX(targ.findRev('/'), targ.findRev(Option::dir_sep));
90 if(slsh != -1) {
91 if(project->isEmpty("DESTDIR"))
92 project->values("DESTDIR").append("");
93 else if(project->first("DESTDIR").right(1) != Option::dir_sep)
94 project->variables()["DESTDIR"] = project->first("DESTDIR") + Option::dir_sep;
95 project->variables()["DESTDIR"] = project->first("DESTDIR") + targ.left(slsh+1);
96 project->variables()["TARGET"] = targ.mid(slsh+1);
97 }
98 }
99
100 project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
101
102 bool is_qt = (project->first("TARGET") == "qt" || project->first("TARGET") == "qte" ||
103 project->first("TARGET") == "qt-mt" || project->first("TARGET") == "qte-mt");
104 bool extern_libs = !project->isEmpty("QMAKE_APP_FLAG") ||
105 (!project->isEmpty("QMAKE_LIB_FLAG") &&
106 project->isActiveConfig("dll")) || is_qt;
107 if(!project->isActiveConfig("global_init_link_order"))
108 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
109 if ( (!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib") ) ||
110 (project->isActiveConfig("qt") && project->isActiveConfig( "plugin" ) )) {
111 if(configs.findIndex("dll") == -1) configs.append("dll");
112 } else if ( !project->isEmpty("QMAKE_APP_FLAG") || project->isActiveConfig("dll") ) {
113 configs.remove("staticlib");
114 }
115 if ( project->isActiveConfig("warn_off") ) {
116 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
117 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
118 } else if ( project->isActiveConfig("warn_on") ) {
119 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
120 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
121 }
122 if ( project->isActiveConfig("debug") ) {
123 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
124 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
125 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
126 } else {
127 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
128 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
129 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
130 }
131 if(!project->isEmpty("QMAKE_INCREMENTAL"))
132 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_INCREMENTAL"];
133 else if(!project->isEmpty("QMAKE_LFLAGS_PREBIND") &&
134 !project->variables()["QMAKE_LIB_FLAG"].isEmpty() &&
135 project->isActiveConfig("dll"))
136 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"];
137 if(!project->isEmpty("QMAKE_INCDIR"))
138 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
139 if(!project->isEmpty("QMAKE_LIBDIR")) {
140 if ( !project->isEmpty("QMAKE_RPATH") )
141 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"),
142 " " + var("QMAKE_RPATH"), "");
143 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" );
144 }
145 if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) {
146 if(configs.findIndex("x11lib") == -1)
147 configs.append("x11lib");
148 if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 )
149 configs.append("x11inc");
150 }
151 if ( project->isActiveConfig("x11") ) {
152 if(configs.findIndex("x11lib") == -1)
153 configs.append("x11lib");
154 if(configs.findIndex("x11inc") == -1)
155 configs.append("x11inc");
156 }
157 if ( project->isActiveConfig("qt") ) {
158 if ( project->isActiveConfig("accessibility" ) )
159 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
160 if ( project->isActiveConfig("tablet") )
161 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
162 if(configs.findIndex("moc")) configs.append("moc");
163 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
164 if ( !project->isActiveConfig("debug") )
165 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
166 if ( !is_qt ) {
167 if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) {
168 if ( !project->isEmpty("QMAKE_RPATH") )
169 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"),
170 " " + var("QMAKE_RPATH"), "");
171 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", "");
172 }
173 if (project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD"))
174 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
175 else
176 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
177 }
178 }
179 if ( project->isActiveConfig("thread") ) {
180 if(project->isActiveConfig("qt"))
181 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
182 if ( !project->isEmpty("QMAKE_CFLAGS_THREAD"))
183 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"];
184 if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD"))
185 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"];
186 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"];
187 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"];
188 if(!project->isEmpty("QMAKE_LFLAGS_THREAD"))
189 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"];
190 }
191 if ( project->isActiveConfig("opengl") ) {
192 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"];
193 if(!project->isEmpty("QMAKE_LIBDIR_OPENGL"))
194 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_OPENGL", "-L", " -L", "");
195 if ( is_qt )
196 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"];
197 else
198 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
199 }
200 if(project->isActiveConfig("global_init_link_order"))
201 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
202 if ( project->isActiveConfig("x11sm") )
203 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"];
204 if ( project->isActiveConfig("dylib") )
205 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"];
206 if ( project->isActiveConfig("x11inc") )
207 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"];
208 if ( project->isActiveConfig("x11lib") ) {
209 if(!project->isEmpty("QMAKE_LIBDIR_X11"))
210 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_X11", "-L", " -L", "");
211 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11"];
212 }
213 if ( project->isActiveConfig("moc") )
214 setMocAware(TRUE);
215 if ( project->isEmpty("QMAKE_RUN_CC") )
216 project->variables()["QMAKE_RUN_CC"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src");
217 if ( project->isEmpty("QMAKE_RUN_CC_IMP") )
218 project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<");
219 if ( project->isEmpty("QMAKE_RUN_CXX") )
220 project->variables()["QMAKE_RUN_CXX"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src");
221 if ( project->isEmpty("QMAKE_RUN_CXX_IMP") )
222 project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<");
223 project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " ");
224 if ( !project->isEmpty("PRECOMPH") ) {
225 initOutPaths(); // Need to fix MOC_DIR since we do this before init()
226 QString allmoc = fileFixify(project->first("MOC_DIR") + "/allmoc.cpp", QDir::currentDirPath(), Option::output_dir);
227 project->variables()["SOURCES"].prepend(allmoc);
228 project->variables()["HEADERS_ORIG"] = project->variables()["HEADERS"];
229 project->variables()["HEADERS"].clear();
230 }
231 if( project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS"))
232 include_deps = TRUE; //do not generate deps
233
234 MakefileGenerator::init();
235 if ( project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
236 if(!project->isEmpty("QMAKE_APP_FLAG")) {
237 if(project->isEmpty("DESTDIR"))
238 project->values("DESTDIR").append("");
239 project->variables()["DESTDIR"].first() += project->variables()["TARGET"].first() +
240 ".app/Contents/MacOS/";
241 project->variables()["QMAKE_PKGINFO"].append(project->first("DESTDIR") + "../PkgInfo");
242 project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO");
243
244 QString plist = specdir() + QDir::separator() + "Info.plist." +
245 project->first("TEMPLATE");
246 if(QFile::exists(Option::fixPathToLocalOS(plist))) {
247 project->variables()["QMAKE_INFO_PLIST"].append(plist);
248 project->variables()["QMAKE_INFO_PLIST_OUT"].append(project->first("DESTDIR") +
249 "../Info.plist");
250 project->variables()["ALL_DEPS"] += project->first("QMAKE_INFO_PLIST_OUT");
251 if(!project->isEmpty("RC_FILE"))
252 project->variables()["ALL_DEPS"] += project->first("DESTDIR") +
253 "../Resources/application.icns";
254 }
255 }
256 }
257
258 if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES"))
259 project->variables()["DISTFILES"] += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"];
260 project->variables()["DISTFILES"] += Option::mkfile::project_files;
261
262 init2();
263 project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_LIBDIR_FLAGS" << "QMAKE_LIBS";
264 if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) {
265 bool ok;
266 int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok);
267 QStringList ar_sublibs, objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"];
268 if(ok && max_files > 5 && max_files < (int)objs.count()) {
269 int obj_cnt = 0, lib_cnt = 0;
270 QString lib;
271 for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
272 if((++obj_cnt) >= max_files) {
273 if(lib_cnt) {
274 lib.sprintf("lib%s-tmp%d.a", project->first("QMAKE_ORIG_TARGET").latin1(), lib_cnt);
275 ar_sublibs << lib;
276 obj_cnt = 0;
277 }
278 lib_cnt++;
279 }
280 }
281 }
282 if(!ar_sublibs.isEmpty()) {
283 project->variables()["QMAKE_AR_SUBLIBS"] = ar_sublibs;
284 project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_AR_SUBLIBS";
285 }
286 }
287}
288
289QStringList
290UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &list2)
291{
292 QStringList ret;
293 for(QStringList::ConstIterator it = list1.begin(); it != list1.end(); ++it) {
294 bool unique = TRUE;
295 if((*it).startsWith("-")) {
296 if((*it).startsWith("-l") || (*it).startsWith("-L")) {
297 unique = list2.findIndex((*it)) == -1;
298 } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) {
299 int as_one = TRUE;
300 QString framework_in;
301 if((*it).length() > 11) {
302 framework_in = (*it).mid(11);
303 } else {
304 if(it != list1.end()) {
305 ++it;
306 as_one = FALSE;
307 framework_in = (*it);
308 }
309 }
310 if(!framework_in.isEmpty()) {
311 for(QStringList::ConstIterator outit = list2.begin(); outit != list2.end(); ++outit) {
312 if((*outit).startsWith("-framework")) {
313 QString framework_out;
314 if((*outit).length() > 11) {
315 framework_out = (*outit).mid(11);
316 } else {
317 if(it != list2.end()) {
318 ++outit;
319 framework_out = (*outit);
320 }
321 }
322 if(framework_out == framework_in) {
323 unique = FALSE;
324 break;
325 }
326 }
327 }
328 if(unique) {
329 unique = FALSE; //because I'm about to just insert it myself
330 if(as_one) {
331 ret.append("-framework " + framework_in);
332 } else {
333 ret.append("-framework");
334 ret.append(framework_in);
335 }
336 }
337 }
338 } else {
339 unique = (list2.findIndex((*it)) == -1);
340 }
341 } else if(QFile::exists((*it))) {
342 unique = (list2.findIndex((*it)) == -1);
343 }
344 if(unique)
345 ret.append((*it));
346 }
347 return ret;
348}
349
350
351void
352UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
353{
354 if(var == "QMAKE_PRL_LIBS")
355 project->variables()["QMAKE_CURRENT_PRL_LIBS"] += uniqueSetLFlags(l, project->variables()["QMAKE_LIBS"]);
356 else
357 MakefileGenerator::processPrlVariable(var, l);
358}
359
360void
361UnixMakefileGenerator::processPrlFiles()
362{
363 QDict<void> processed;
364 QPtrList<MakefileDependDir> libdirs;
365 libdirs.setAutoDelete(TRUE);
366 const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
367 for(int i = 0; !lflags[i].isNull(); i++) {
368 for(bool ret = FALSE; TRUE; ret = FALSE) {
369 QStringList l_out;
370 QStringList &l = project->variables()[lflags[i]];
371 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
372 project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear();
373 QString opt = (*it).stripWhiteSpace();;
374 if(opt.startsWith("-")) {
375 if(opt.startsWith("-L")) {
376 QString r = opt.right(opt.length() - 2), l = r;
377 fixEnvVariables(l);
378 libdirs.append(new MakefileDependDir(r.replace("\"",""),
379 l.replace("\"","")));
380 } else if(opt.startsWith("-l") && !processed[opt]) {
381 QString lib = opt.right(opt.length() - 2), prl;
382 for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
383 prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext;
384 if(processPrlFile(prl)) {
385 if(prl.startsWith(mdd->local_dir))
386 prl.replace(0, mdd->local_dir.length(), mdd->real_dir);
387 QRegExp reg("^.*lib(" + lib + "[^./=]*)\\..*$");
388 if(reg.exactMatch(prl))
389 prl = "-l" + reg.cap(1);
390 opt = prl;
391 processed.insert(opt, (void*)1);
392 ret = TRUE;
393 break;
394 }
395 }
396 } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) {
397 if(opt.length() > 11) {
398 opt = opt.mid(11);
399 } else {
400 ++it;
401 opt = (*it);
402 }
403 QString prl = "/System/Library/Frameworks/" + opt +
404 ".framework/" + opt + Option::prl_ext;
405 if(processPrlFile(prl))
406 ret = TRUE;
407 l_out.append("-framework");
408 }
409 if(!opt.isEmpty())
410 l_out.append(opt);
411 l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out);
412 } else {
413 if(!processed[opt] && processPrlFile(opt)) {
414 processed.insert(opt, (void*)1);
415 ret = TRUE;
416 }
417 if(!opt.isEmpty())
418 l_out.append(opt);
419 l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out);
420 }
421 }
422 if(ret && l != l_out)
423 l = l_out;
424 else
425 break;
426 }
427 }
428}
429
430QString
431UnixMakefileGenerator::defaultInstall(const QString &t)
432{
433 if(t != "target" || project->first("TEMPLATE") == "subdirs")
434 return QString();
435
436 bool resource = FALSE;
437 QStringList &uninst = project->variables()[t + ".uninstall"];
438 QString ret, destdir=fileFixify(project->first("DESTDIR"));
439 QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), FALSE);
440 if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
441 destdir += Option::dir_sep;
442 targetdir = "$(INSTALL_ROOT)" + Option::fixPathToTargetOS(targetdir, FALSE);
443 if(targetdir.right(1) != Option::dir_sep)
444 targetdir += Option::dir_sep;
445
446 QStringList links;
447 QString target="$(TARGET)";
448 if(project->first("TEMPLATE") == "app") {
449 target = "$(QMAKE_TARGET)";
450 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
451 destdir += "../../../";
452 target += ".app";
453 resource = TRUE;
454 }
455 } else if(project->first("TEMPLATE") == "lib") {
456 if(project->isActiveConfig("create_prl") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
457 QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE");
458 int slsh = dst_prl.findRev('/');
459 if(slsh != -1)
460 dst_prl = dst_prl.right(dst_prl.length() - slsh - 1);
461 dst_prl = targetdir + dst_prl;
462 ret += "-$(COPY) " + project->first("QMAKE_INTERNAL_PRL_FILE") + " " + dst_prl;
463 if(!uninst.isEmpty())
464 uninst.append("\n\t");
465 uninst.append("-$(DEL_FILE) \"" + dst_prl + "\"");
466 }
467 QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 );
468 if ( os != "cygwin" ) {
469 if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) {
470 if ( os == "hpux" ) {
471 links << "$(TARGET0)";
472 } else {
473 links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)";
474 }
475 }
476 }
477 }
478 QString src_targ = target;
479 if(!destdir.isEmpty())
480 src_targ = Option::fixPathToTargetOS(destdir + target, FALSE);
481 QString dst_targ = fileFixify(targetdir + target);
482 if(!ret.isEmpty())
483 ret += "\n\t";
484 ret += QString(resource ? "-$(COPY_DIR)" : "-$(COPY)") + " \"" +
485 src_targ + "\" \"" + dst_targ + "\"";
486 if(!project->isEmpty("QMAKE_STRIP")) {
487 ret += "\n\t-" + var("QMAKE_STRIP");
488 if(resource)
489 ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)";
490 else
491 ret += " \"" + dst_targ + "\"";
492 }
493 if(!uninst.isEmpty())
494 uninst.append("\n\t");
495 if(resource)
496 uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\"");
497 else
498 uninst.append("-$(DEL_FILE) \"" + dst_targ + "\"");
499 if(!links.isEmpty()) {
500 for(QStringList::Iterator it = links.begin(); it != links.end(); it++) {
501 if(Option::target_mode == Option::TARG_WIN_MODE ||
502 Option::target_mode == Option::TARG_MAC9_MODE) {
503 } else if(Option::target_mode == Option::TARG_UNIX_MODE ||
504 Option::target_mode == Option::TARG_MACX_MODE) {
505 QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE);
506 int lslash = link.findRev(Option::dir_sep);
507 if(lslash != -1)
508 link = link.right(link.length() - (lslash + 1));
509 QString dst_link = fileFixify(targetdir + link);
510 ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\"";
511 if(!uninst.isEmpty())
512 uninst.append("\n\t");
513 uninst.append("-$(DEL_FILE) \"" + dst_link + "\"");
514 }
515 }
516 }
517 return ret;
518}
519
520
diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h
new file mode 100644
index 0000000..e889dcc
--- a/dev/null
+++ b/qmake/generators/unix/unixmake.h
@@ -0,0 +1,71 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __UNIXMAKE_H__
38#define __UNIXMAKE_H__
39
40#include "makefile.h"
41
42class UnixMakefileGenerator : public MakefileGenerator
43{
44 bool init_flag, include_deps;
45 bool writeMakefile(QTextStream &);
46 QStringList uniqueSetLFlags(const QStringList &list1, QStringList &list2);
47
48public:
49 UnixMakefileGenerator(QMakeProject *p);
50 ~UnixMakefileGenerator();
51
52protected:
53 virtual bool doDepends() const { return !include_deps && MakefileGenerator::doDepends(); }
54 virtual QString defaultInstall(const QString &);
55 virtual void processPrlVariable(const QString &, const QStringList &);
56 virtual void processPrlFiles();
57
58 virtual void init();
59
60 void writeMakeParts(QTextStream &);
61 void writeSubdirs(QTextStream &, bool=TRUE);
62
63private:
64 void init2();
65};
66
67inline UnixMakefileGenerator::~UnixMakefileGenerator()
68{ }
69
70
71#endif /* __UNIXMAKE_H__ */
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
new file mode 100644
index 0000000..1797b98
--- a/dev/null
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -0,0 +1,1048 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "unixmake.h"
39#include "option.h"
40#include <qregexp.h>
41#include <qfile.h>
42#include <qdir.h>
43#include <time.h>
44
45
46UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE), include_deps(FALSE)
47{
48
49}
50
51bool
52UnixMakefileGenerator::writeMakefile(QTextStream &t)
53{
54 writeHeader(t);
55 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
56 t << "all clean:" << "\n\t"
57 << "@echo \"Some of the required modules ("
58 << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
59 << "@echo \"Skipped.\"" << endl << endl;
60 writeMakeQmake(t);
61 return TRUE;
62 }
63
64 if (project->variables()["TEMPLATE"].first() == "app" ||
65 project->variables()["TEMPLATE"].first() == "lib") {
66 writeMakeParts(t);
67 return MakefileGenerator::writeMakefile(t);
68 } else if(project->variables()["TEMPLATE"].first() == "subdirs") {
69 writeSubdirs(t);
70 return TRUE;
71 }
72 return FALSE;
73}
74
75void
76UnixMakefileGenerator::writeMakeParts(QTextStream &t)
77{
78 QString deps = fileFixify(Option::output.name()), prl;
79 bool do_incremental = (project->isActiveConfig("incremental") &&
80 !project->variables()["QMAKE_INCREMENTAL"].isEmpty() &&
81 (!project->variables()["QMAKE_APP_FLAG"].isEmpty() ||
82 !project->isActiveConfig("staticlib"))),
83 src_incremental=FALSE, moc_incremental=FALSE;
84 QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 );
85
86 t << "####### Compiler, tools and options" << endl << endl;
87 t << "CC = ";
88 if (project->isActiveConfig("thread") &&
89 ! project->variables()["QMAKE_CC_THREAD"].isEmpty())
90 t << var("QMAKE_CC_THREAD") << endl;
91 else
92 t << var("QMAKE_CC") << endl;
93
94 t << "CXX = ";
95 if (project->isActiveConfig("thread") &&
96 ! project->variables()["QMAKE_CXX_THREAD"].isEmpty())
97 t << var("QMAKE_CXX_THREAD") << endl;
98 else
99 t << var("QMAKE_CXX") << endl;
100
101 t << "LEX = " << var("QMAKE_LEX") << endl;
102 t << "YACC = " << var("QMAKE_YACC") << endl;
103 t << "CFLAGS = " << var("QMAKE_CFLAGS") << " "
104 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
105 << varGlue("DEFINES","-D"," -D","") << endl;
106 t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
107 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
108 << varGlue("DEFINES","-D"," -D","") << endl;
109 t << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
110 t << "YACCFLAGS= " << var("QMAKE_YACCFLAGS") << endl;
111 t << "INCPATH = " << varGlue("INCLUDEPATH","-I", " -I", "") << " -I" << specdir() << endl;
112
113 if(!project->isActiveConfig("staticlib")) {
114 t << "LINK = ";
115 if (project->isActiveConfig("thread") &&
116 ! project->variables()["QMAKE_LINK_THREAD"].isEmpty())
117 t << var("QMAKE_LINK_THREAD") << endl;
118 else
119 t << var("QMAKE_LINK") << endl;
120
121 t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl;
122 t << "LIBS = " << "$(SUBLIBS) " << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << endl;
123 }
124
125 t << "AR = " << var("QMAKE_AR") << endl;
126 t << "RANLIB = " << var("QMAKE_RANLIB") << endl;
127 t << "MOC = " << var("QMAKE_MOC") << endl;
128 t << "UIC = "<< var("QMAKE_UIC") << endl;
129 t << "QMAKE = "<< (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
130 t << "TAR = "<< var("QMAKE_TAR") << endl;
131 t << "GZIP = " << var("QMAKE_GZIP") << endl;
132 t << "COPY = " << var("QMAKE_COPY") << endl;
133 t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl;
134 t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl;
135 t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
136 t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl;
137 t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
138 t << "MOVE = " << var("QMAKE_MOVE") << endl;
139 t << endl;
140
141 t << "####### Output directory" << endl << endl;
142 if (! project->variables()["OBJECTS_DIR"].isEmpty())
143 t << "OBJECTS_DIR = " << var("OBJECTS_DIR") << endl;
144 else
145 t << "OBJECTS_DIR = ./" << endl;
146 t << endl;
147
148 /* files */
149 t << "####### Files" << endl << endl;
150 t << "HEADERS = " << varList("HEADERS") << endl;
151 t << "SOURCES = " << varList("SOURCES") << endl;
152 if(do_incremental) {
153 QStringList &objs = project->variables()["OBJECTS"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out;
154 t << "OBJECTS = ";
155 for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
156 bool increment = FALSE;
157 for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
158 if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) {
159 increment = TRUE;
160 incrs_out.append((*objit));
161 break;
162 }
163 }
164 if(!increment)
165 t << "\\\n\t\t" << (*objit);
166 }
167 if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
168 t << incrs_out.join(" \\\n\t\t") << endl;
169 } else if(!incrs_out.count()) {
170 t << endl;
171 } else {
172 src_incremental = TRUE;
173 t << endl;
174 t << "INCREMENTAL_OBJECTS = " << incrs_out.join(" \\\n\t\t") << endl;
175 }
176 } else {
177 t << "OBJECTS = " << varList("OBJECTS") << endl;
178 }
179 t << "FORMS = " << varList("FORMS") << endl;
180 t << "UICDECLS = " << varList("UICDECLS") << endl;
181 t << "UICIMPLS = " << varList("UICIMPLS") << endl;
182 QString srcMoc = varList("SRCMOC"), objMoc = varList("OBJMOC");
183 t << "SRCMOC = " << srcMoc << endl;
184 if(do_incremental) {
185 QStringList &objs = project->variables()["OBJMOC"],
186 &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out;
187 t << "OBJMOC = ";
188 for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
189 bool increment = FALSE;
190 for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
191 if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) {
192 increment = TRUE;
193 incrs_out.append((*objit));
194 break;
195 }
196 }
197 if(!increment)
198 t << "\\\n\t\t" << (*objit);
199 }
200 if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
201 t << incrs_out.join(" \\\n\t\t") << endl;
202 } else if(!incrs_out.count()) {
203 t << endl;
204 } else {
205 moc_incremental = TRUE;
206 t << endl;
207 t << "INCREMENTAL_OBJMOC = " << incrs_out.join(" \\\n\t\t") << endl;
208 }
209 } else {
210 t << "OBJMOC = " << objMoc << endl;
211 }
212 if(do_incremental && !moc_incremental && !src_incremental)
213 do_incremental = FALSE;
214 t << "DIST = " << varList("DISTFILES") << endl;
215 t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl;
216 t << "DESTDIR = " << var("DESTDIR") << endl;
217 t << "TARGET = " << var("TARGET") << endl;
218 if(project->isActiveConfig("plugin") ) {
219 t << "TARGETD = " << var("TARGET") << endl;
220 } else if (!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
221 t << "TARGETA= " << var("TARGETA") << endl;
222 if (os == "hpux") {
223 t << "TARGETD= " << var("TARGET_x") << endl;
224 t << "TARGET0= " << var("TARGET_") << endl;
225 }
226 else {
227 t << "TARGETD= " << var("TARGET_x.y.z") << endl;
228 t << "TARGET0= " << var("TARGET_") << endl;
229 t << "TARGET1= " << var("TARGET_x") << endl;
230 t << "TARGET2= " << var("TARGET_x.y") << endl;
231 }
232 }
233 t << endl;
234
235 // blasted incldues
236 QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"];
237 QStringList::Iterator it;
238 for( it = qeui.begin(); it != qeui.end(); ++it)
239 t << "include " << (*it) << endl;
240
241 /* rules */
242 t << "first: all" << endl;
243 t << "####### Implicit rules" << endl << endl;
244 t << ".SUFFIXES: .c";
245 QStringList::Iterator cppit;
246 for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
247 t << " " << (*cppit);
248 t << endl << endl;
249 for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
250 t << (*cppit) << ".o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
251 t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
252
253 if(include_deps) {
254 QString cmd=var("QMAKE_CFLAGS_DEPS") + " ";
255 cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D","");
256 if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH"))
257 cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " ";
258 cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", "");
259 QString odir;
260 if(!project->variables()["OBJECTS_DIR"].isEmpty())
261 odir = project->first("OBJECTS_DIR");
262 t << "###### Dependancies" << endl << endl;
263 t << odir << ".deps/%.d: %.cpp\n\t"
264 << "@echo Creating depend for $<" << "\n\t"
265 << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t"
266 << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
267
268 t << odir << ".deps/%.d: %.c\n\t"
269 << "@echo Creating depend for $<" << "\n\t"
270 << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t"
271 << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
272
273
274 QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null };
275 for(int x = 0; !src[x].isNull(); x++) {
276 QStringList &l = project->variables()[src[x]];
277 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
278 if(!(*it).isEmpty()) {
279 QString d_file;
280 if((*it).endsWith(".c")) {
281 d_file = (*it).left((*it).length() - 2);
282 } else {
283 for(QStringList::Iterator cppit = Option::cpp_ext.begin();
284 cppit != Option::cpp_ext.end(); ++cppit) {
285 if((*it).endsWith((*cppit))) {
286 d_file = (*it).left((*it).length() - (*cppit).length());
287 break;
288 }
289 }
290 }
291 if(!d_file.isEmpty()) {
292 d_file = odir + ".deps/" + d_file + ".d";
293 QStringList deps = findDependencies((*it)).grep(QRegExp(Option::moc_ext + "$"));
294 if(!deps.isEmpty())
295 t << d_file << ": " << deps.join(" ") << endl;
296 t << "-include " << d_file << endl;
297 }
298 }
299 }
300 }
301 }
302
303 t << "####### Build rules" << endl << endl;
304 if(!project->variables()["SUBLIBS"].isEmpty()) {
305 QString libdir = "tmp/";
306 if(!project->isEmpty("SUBLIBS_DIR"))
307 libdir = project->first("SUBLIBS_DIR");
308 t << "SUBLIBS= ";
309 QStringList &l = project->variables()["SUBLIBS"];
310 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it)
311 t << libdir << "lib" << (*it) << ".a ";
312 t << endl << endl;
313 }
314 if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) {
315 QStringList &l = project->variables()["QMAKE_PRL_INTERNAL_FILES"];
316 QStringList::Iterator it;
317 for(it = l.begin(); it != l.end(); ++it) {
318 QMakeProject proj;
319 if(proj.read((*it), QDir::currentDirPath()) && !proj.isEmpty("QMAKE_PRL_BUILD_DIR")) {
320 QString dir;
321 int slsh = (*it).findRev(Option::dir_sep);
322 if(slsh != -1)
323 dir = (*it).left(slsh + 1);
324 QString targ = dir + proj.first("QMAKE_PRL_TARGET");
325 deps += " " + targ;
326 t << targ << ":" << "\n\t"
327 << "@echo \"Creating '" << targ << "'\"" << "\n\t"
328 << "(cd " << proj.first("QMAKE_PRL_BUILD_DIR") << ";"
329 << "$(MAKE) )" << endl;
330 }
331 }
332 }
333 if(!project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
334 QString destdir = project->first("DESTDIR");
335 if(do_incremental) {
336 //incremental target
337 QString incr_target = var("TARGET") + "_incremental";
338 if(incr_target.find(Option::dir_sep) != -1)
339 incr_target = incr_target.right(incr_target.length() -
340 (incr_target.findRev(Option::dir_sep) + 1));
341 QString incr_deps, incr_objs;
342 if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
343 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
344 //actual target
345 t << incr_target_dir << ": $(OBJECTS)" << "\n\t"
346 << "ld -r -o "<< incr_target_dir << " $(OBJECTS)" << endl;
347 //communicated below
348 deps.prepend(incr_target_dir + " ");
349 incr_deps = "$(UICDECLS) $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC) $(OBJMOC)";
350 if(!incr_objs.isEmpty())
351 incr_objs += " ";
352 incr_objs += incr_target_dir;
353 } else {
354 //actual target
355 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." +
356 project->variables()["QMAKE_EXTENSION_SHLIB"].first();
357 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
358 if(project->isActiveConfig("debug"))
359 incr_lflags += var("QMAKE_LFLAGS_DEBUG");
360 else
361 incr_lflags += var("QMAKE_LFLAGS_RELEASE");
362 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t";
363 if(!destdir.isEmpty())
364 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
365 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
366 " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl;
367 //communicated below
368 if(!destdir.isEmpty()) {
369 if(!incr_objs.isEmpty())
370 incr_objs += " ";
371 incr_objs += "-L" + destdir;
372 } else {
373 if(!incr_objs.isEmpty())
374 incr_objs += " ";
375 incr_objs += "-L" + QDir::currentDirPath();
376 }
377 if(!incr_objs.isEmpty())
378 incr_objs += " ";
379 incr_objs += " -l" + incr_target;
380 deps.prepend(incr_target_dir + " ");
381 incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
382 }
383 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)"
384 << endl << endl;
385
386 //real target
387 t << var("TARGET") << ": " << " " << incr_deps << " " << var("TARGETDEPS") << "\n\t";
388 if(!destdir.isEmpty())
389 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
390 if(!project->isEmpty("QMAKE_PRE_LINK"))
391 t << var("QMAKE_PRE_LINK") << "\n\t";
392 t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(LIBS)";
393 if(!project->isEmpty("QMAKE_POST_LINK"))
394 t << "\n\t" << var("QMAKE_POST_LINK");
395 t << endl << endl;
396 } else {
397 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)"
398 << endl << endl;
399
400 t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS") << "\n\t";
401 if(!destdir.isEmpty())
402 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
403 if(!project->isEmpty("QMAKE_PRE_LINK"))
404 t << var("QMAKE_PRE_LINK") << "\n\t";
405 t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)";
406 if(!project->isEmpty("QMAKE_POST_LINK"))
407 t << "\n\t" << var("QMAKE_POST_LINK");
408 t << endl << endl;
409 }
410 } else if(!project->isActiveConfig("staticlib")) {
411 QString destdir = project->first("DESTDIR"), incr_deps;
412 if(do_incremental) {
413 QString s_ext = project->variables()["QMAKE_EXTENSION_SHLIB"].first();
414 QString incr_target = var("QMAKE_ORIG_TARGET").replace(
415 QRegExp("\\." + s_ext), "").replace(QRegExp("^lib"), "") + "_incremental";
416 if(incr_target.find(Option::dir_sep) != -1)
417 incr_target = incr_target.right(incr_target.length() -
418 (incr_target.findRev(Option::dir_sep) + 1));
419
420 if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
421 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
422 //actual target
423 const QString link_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
424 t << incr_target_dir << ": " << link_deps << "\n\t"
425 << "ld -r -o " << incr_target_dir << " " << link_deps << endl;
426 //communicated below
427 QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"];
428 cmd.first().replace("$(OBJECTS) $(OBJMOC)",
429 "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"); //ick
430 cmd.append(incr_target_dir);
431 deps.prepend(incr_target_dir + " ");
432 incr_deps = "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
433 } else {
434 //actual target
435 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + s_ext;
436 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
437 if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL"))
438 incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " ";
439 if(project->isActiveConfig("debug"))
440 incr_lflags += var("QMAKE_LFLAGS_DEBUG");
441 else
442 incr_lflags += var("QMAKE_LFLAGS_RELEASE");
443 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t";
444 if(!destdir.isEmpty())
445 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
446 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
447 " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl;
448 //communicated below
449 QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"];
450 if(!destdir.isEmpty())
451 cmd.append(" -L" + destdir);
452 cmd.append(" -l" + incr_target);
453 deps.prepend(incr_target_dir + " ");
454 incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
455 }
456
457 t << "all: " << " " << deps << " " << varGlue("ALL_DEPS",""," ","")
458 << " " << var("DESTDIR_TARGET") << endl << endl;
459
460 //real target
461 t << var("DESTDIR_TARGET") << ": " << incr_deps << " $(SUBLIBS) " <<
462 var("TARGETDEPS");
463 } else {
464 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " <<
465 var("DESTDIR_TARGET") << endl << endl;
466 t << var("DESTDIR_TARGET") << ": $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " <<
467 var("TARGETDEPS");
468 }
469 if(!destdir.isEmpty())
470 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir;
471 if(!project->isEmpty("QMAKE_PRE_LINK"))
472 t << "\n\t" << var("QMAKE_PRE_LINK");
473
474 if(project->isActiveConfig("plugin")) {
475 t << "\n\t"
476 << "-$(DEL_FILE) $(TARGET)" << "\n\t"
477 << var("QMAKE_LINK_SHLIB_CMD");
478 if(!destdir.isEmpty())
479 t << "\n\t"
480 << "-$(MOVE) $(TARGET) " << var("DESTDIR");
481 if(!project->isEmpty("QMAKE_POST_LINK"))
482 t << "\n\t" << var("QMAKE_POST_LINK") << "\n\t";
483 t << endl << endl;
484 } else if ( os == "hpux" ) {
485 t << "\n\t"
486 << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t"
487 << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
488 t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)");
489 if(!destdir.isEmpty())
490 t << "\n\t"
491 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t"
492 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t"
493 << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR");
494 if(!project->isEmpty("QMAKE_POST_LINK"))
495 t << "\n\t" << var("QMAKE_POST_LINK");
496 t << endl << endl;
497 } else {
498 t << "\n\t"
499 << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t"
500 << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
501 t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t"
502 << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t"
503 << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)");
504 if(!destdir.isEmpty())
505 t << "\n\t"
506 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t"
507 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t"
508 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t"
509 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t"
510 << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR");
511 if(!project->isEmpty("QMAKE_POST_LINK"))
512 t << "\n\t" << var("QMAKE_POST_LINK");
513 t << endl << endl;
514 }
515 t << endl << endl;
516
517 if (! project->isActiveConfig("plugin")) {
518 t << "staticlib: $(TARGETA)" << endl << endl;
519 t << "$(TARGETA): $(UICDECLS) $(OBJECTS) $(OBJMOC)";
520 if(do_incremental)
521 t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
522 t << var("TARGETDEPS") << "\n\t"
523 << "-$(DEL_FILE) $(TARGETA) " << "\n\t"
524 << var("QMAKE_AR_CMD");
525 if(do_incremental)
526 t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
527 if(!project->isEmpty("QMAKE_RANLIB"))
528 t << "\n\t" << "$(RANLIB) $(TARGETA)";
529 t << endl << endl;
530 }
531 } else {
532 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) "
533 << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n"
534 << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n";
535 if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
536 t << var("DESTDIR") << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(TARGETDEPS) " << "\n\t";
537 if(!project->isEmpty("DESTDIR")) {
538 QString destdir = project->first("DESTDIR");
539 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
540 }
541 t << "-$(DEL_FILE) $(TARGET)" << "\n\t"
542 << var("QMAKE_AR_CMD") << "\n";
543 if(!project->isEmpty("QMAKE_POST_LINK"))
544 t << "\t" << var("QMAKE_POST_LINK") << "\n";
545 if(!project->isEmpty("QMAKE_RANLIB"))
546 t << "\t" << "$(RANLIB) $(TARGET)" << "\n";
547 if(!project->isEmpty("DESTDIR"))
548 t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n"
549 << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n";
550 } else {
551 int cnt = 0, max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt();
552 QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"],
553 libs = project->variables()["QMAKE_AR_SUBLIBS"];
554 libs.prepend("$(TARGET)");
555 for(QStringList::Iterator libit = libs.begin(), objit = objs.begin();
556 libit != libs.end(); ++libit) {
557 QStringList build;
558 for(cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++)
559 build << (*objit);
560 QString ar;
561 if((*libit) == "$(TARGET)") {
562 t << var("DESTDIR") << "$(TARGET): $(UICDECLS) " << " $(TARGETDEPS) "
563 << valList(build) << "\n\t";
564 ar = project->variables()["QMAKE_AR_CMD"].first();
565 ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)",
566 build.join(" "));
567 } else {
568 t << (*libit) << ": " << valList(build) << "\n\t";
569 ar = "$(AR) " + (*libit) + " " + build.join(" ");
570 }
571 if(!project->isEmpty("DESTDIR")) {
572 QString destdir = project->first("DESTDIR");
573 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
574 }
575 t << "-$(DEL_FILE) " << (*libit) << "\n\t"
576 << ar << "\n";
577 if(!project->isEmpty("QMAKE_POST_LINK"))
578 t << "\t" << var("QMAKE_POST_LINK") << "\n";
579 if(!project->isEmpty("QMAKE_RANLIB"))
580 t << "\t" << "$(RANLIB) " << (*libit) << "\n";
581 if(!project->isEmpty("DESTDIR"))
582 t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n"
583 << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n";
584 }
585 }
586 t << endl << endl;
587 }
588
589 t << "mocables: $(SRCMOC)" << endl << endl;
590
591 if(!project->isActiveConfig("no_mocdepend")) {
592 //this is an implicity depend on moc, so it will be built if necesary, however
593 //moc itself shouldn't have this dependancy - this is a little kludgy but it is
594 //better than the alternative for now.
595 QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET");
596 fixEnvVariables(target);
597 fixEnvVariables(moc);
598 if(target != moc)
599 t << "$(MOC): \n\t"
600 << "( cd $(QTDIR)/src/moc ; $(MAKE) )" << endl << endl;
601 }
602
603 writeMakeQmake(t);
604
605 if(!project->first("QMAKE_PKGINFO").isEmpty()) {
606 QString pkginfo = project->first("QMAKE_PKGINFO");
607 QString destdir = project->first("DESTDIR");
608 t << pkginfo << ": " << "\n\t";
609 if(!destdir.isEmpty())
610 t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
611 t << "@$(DEL_FILE) " << pkginfo << "\n\t"
612 << "@echo \"APPL????\" >" << pkginfo << endl;
613 }
614 if(!project->first("QMAKE_INFO_PLIST").isEmpty()) {
615 QString info_plist = project->first("QMAKE_INFO_PLIST"),
616 info_plist_out = project->first("QMAKE_INFO_PLIST_OUT");
617 QString destdir = project->first("DESTDIR");
618 t << info_plist_out << ": " << "\n\t";
619 if(!destdir.isEmpty())
620 t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
621 t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
622 << "@cp \"" << info_plist << "\" \"" << info_plist_out << "\"" << endl;
623 if(!project->first("RC_FILE").isEmpty()) {
624 QString dir = destdir + "../Resources/";
625 t << dir << "application.icns:" << "\n\t"
626 << "@test -d " << dir << " || mkdir -p " << dir << "\n\t"
627 << "@cp " << var("RC_FILE") << " " << dir << "application.icns" << endl;
628 }
629 }
630
631 QString ddir = project->isEmpty("QMAKE_DISTDIR") ? project->first("QMAKE_ORIG_TARGET") :
632 project->first("QMAKE_DISTDIR");
633 QString ddir_c = fileFixify((project->isEmpty("OBJECTS_DIR") ? QString(".tmp/") :
634 project->first("OBJECTS_DIR")) + ddir);
635 t << "dist: " << "\n\t"
636 << "@mkdir -p " << ddir_c << " && "
637 << "$(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) " << ddir_c << Option::dir_sep << " && ";
638 if(!project->isEmpty("TRANSLATIONS"))
639 t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && ";
640 if(!project->isEmpty("FORMS")) {
641 QStringList &forms = project->variables()["FORMS"], ui_headers;
642 for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) {
643 QString ui_h = fileFixify((*formit) + Option::h_ext.first());
644 if(QFile::exists(ui_h) )
645 ui_headers << ui_h;
646 }
647 if(!ui_headers.isEmpty())
648 t << "$(COPY_FILE) --parents " << val(ui_headers) << " " << ddir_c << Option::dir_sep << " && ";
649 }
650 t << "( cd `dirname " << ddir_c << "` && "
651 << "$(TAR) " << var("QMAKE_ORIG_TARGET") << ".tar " << ddir << " && "
652 << "$(GZIP) " << var("QMAKE_ORIG_TARGET") << ".tar ) && "
653 << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << var("QMAKE_ORIG_TARGET") << ".tar.gz . && "
654 << "$(DEL_DIR) " << ddir_c
655 << endl << endl;
656
657 QString clean_targets;
658 if(mocAware()) {
659 t << "mocclean:" << "\n";
660 if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) {
661 if(!objMoc.isEmpty())
662 t << "\t-$(DEL_FILE) $(OBJMOC)" << '\n';
663 if(!srcMoc.isEmpty())
664 t << "\t-$(DEL_FILE) $(SRCMOC)" << '\n';
665 if(moc_incremental)
666 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n';
667 clean_targets += " mocclean";
668 }
669 t << endl;
670 }
671 t << "uiclean:" << "\n";
672 if (!var("UICIMPLS").isEmpty() || !var("UICDECLS").isEmpty()) {
673 t << "\t-$(DEL_FILE) $(UICIMPLS) $(UICDECLS)" << "\n";
674 clean_targets += " uiclean";
675 }
676 t << endl;
677
678 if(do_incremental) {
679 t << "incrclean:" << "\n";
680 if(src_incremental)
681 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n";
682 if(moc_incremental)
683 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n';
684 t << endl;
685 }
686
687 t << "clean:" << clean_targets << "\n\t";
688 if(!project->isEmpty("OBJECTS"))
689 t << "-$(DEL_FILE) $(OBJECTS) " << "\n\t";
690 if(!project->isEmpty("IMAGES"))
691 t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t";
692 if(src_incremental)
693 t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n\t";
694 t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t")
695 << "-$(DEL_FILE) *~ core *.core" << "\n"
696 << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl;
697 t << "####### Sub-libraries" << endl << endl;
698 if ( !project->variables()["SUBLIBS"].isEmpty() ) {
699 QString libdir = "tmp/";
700 if(!project->isEmpty("SUBLIBS_DIR"))
701 libdir = project->first("SUBLIBS_DIR");
702 QStringList &l = project->variables()["SUBLIBS"];
703 for(it = l.begin(); it != l.end(); ++it)
704 t << libdir << "lib" << (*it) << ".a" << ":\n\t"
705 << var(QString("MAKELIB") + (*it)) << endl << endl;
706 }
707
708 QString destdir = project->first("DESTDIR");
709 if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
710 destdir += Option::dir_sep;
711 t << "distclean: " << "clean\n\t"
712 << "-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n";
713 if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() &&
714 !project->isActiveConfig("plugin"))
715 t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
716 << destdir << "$(TARGET2) $(TARGETA)" << "\n";
717 t << endl << endl;
718
719 if ( !project->isEmpty("PRECOMPH") ) {
720 QString outdir = project->first("MOC_DIR");
721 QString qt_dot_h = Option::fixPathToLocalOS(project->first("PRECOMPH"));
722 t << "###### Combined headers" << endl << endl;
723 //XXX
724 t << outdir << "allmoc.cpp: " << qt_dot_h << " "
725 << varList("HEADERS_ORIG") << "\n\t"
726 << "echo '#include \"" << qt_dot_h << "\"' >" << outdir << "allmoc.cpp" << "\n\t"
727 << "$(CXX) -E -DQT_MOC_CPP -DQT_NO_STL $(CXXFLAGS) $(INCPATH) >" << outdir << "allmoc.h "
728 << outdir << "allmoc.cpp" << "\n\t"
729 << "$(MOC) -o " << outdir << "allmoc.cpp " << outdir << "allmoc.h" << "\n\t"
730 << "perl -pi -e 's{#include \"allmoc.h\"}{#define QT_H_CPP\\n#include \""
731 << qt_dot_h << "\"}' " << outdir << "allmoc.cpp" << "\n\t"
732 << "$(DEL_FILE) " << outdir << "allmoc.h" << endl << endl;
733 }
734
735 // blasted user defined targets
736 QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
737 for(it = qut.begin(); it != qut.end(); ++it) {
738 QString targ = var((*it) + ".target"),
739 cmd = var((*it) + ".commands"), deps;
740 if(targ.isEmpty())
741 targ = (*it);
742 QStringList &deplist = project->variables()[(*it) + ".depends"];
743 for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
744 QString dep = var((*dep_it) + ".target");
745 if(dep.isEmpty())
746 dep = (*dep_it);
747 deps += " " + dep;
748 }
749 t << targ << ":" << deps << "\n\t"
750 << cmd << endl << endl;
751 }
752 t <<"FORCE:" << endl << endl;
753}
754
755struct SubDir
756{
757 QString directory, profile, target, makefile;
758};
759
760void
761UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct)
762{
763 QPtrList<SubDir> subdirs;
764 {
765 QStringList subdirs_in = project->variables()["SUBDIRS"];
766 for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) {
767 QString file = (*it);
768 fileFixify(file);
769 SubDir *sd = new SubDir;
770 subdirs.append(sd);
771 sd->makefile = "$(MAKEFILE)";
772 if((*it).right(4) == ".pro") {
773 int slsh = file.findRev(Option::dir_sep);
774 if(slsh != -1) {
775 sd->directory = file.left(slsh+1);
776 sd->profile = file.mid(slsh+1);
777 } else {
778 sd->profile = file;
779 }
780 } else {
781 sd->directory = file;
782 }
783 while(sd->directory.right(1) == Option::dir_sep)
784 sd->directory = sd->directory.left(sd->directory.length() - 1);
785 if(!sd->profile.isEmpty()) {
786 QString basename = sd->directory;
787 int new_slsh = basename.findRev(Option::dir_sep);
788 if(new_slsh != -1)
789 basename = basename.mid(new_slsh+1);
790 if(sd->profile != basename + ".pro")
791 sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro
792 }
793 sd->target = "sub-" + (*it);
794 sd->target.replace('/', '-');
795 sd->target.replace('.', '_');
796 }
797 }
798 QPtrListIterator<SubDir> it(subdirs);
799
800 QString ofile = Option::output.name();
801 if(ofile.findRev(Option::dir_sep) != -1)
802 ofile = ofile.right(ofile.length() - ofile.findRev(Option::dir_sep) -1);
803 t << "MAKEFILE =" << var("MAKEFILE") << endl;
804 t << "QMAKE =" << var("QMAKE") << endl;
805 t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
806 t << "SUBTARGETS ="; // subdirectory targets are sub-directory
807 for( it.toFirst(); it.current(); ++it)
808 t << " \\\n\t\t" << it.current()->target;
809 t << endl << endl;
810 t << "first: all\n\nall: " << ofile << " $(SUBTARGETS)" << endl << endl;
811
812 // generate target rules
813 for( it.toFirst(); it.current(); ++it) {
814 bool have_dir = !(*it)->directory.isEmpty();
815 QString mkfile = (*it)->makefile, out;
816 if(have_dir)
817 mkfile.prepend((*it)->directory + Option::dir_sep);
818 if(direct || (*it)->makefile != "$(MAKEFILE)")
819 out = " -o " + (*it)->makefile;
820 //qmake it
821 t << mkfile << ": " << "\n\t";
822 if(have_dir)
823 t << "cd " << (*it)->directory << " && ";
824 t << "$(QMAKE) " << (*it)->profile << buildArgs() << out << endl;
825 //actually compile
826 t << (*it)->target << ": " << mkfile << " FORCE" << "\n\t";
827 if(have_dir)
828 t << "cd " << (*it)->directory << " && ";
829 t << "$(MAKE) -f " << (*it)->makefile << endl << endl;
830 }
831
832 if (project->isActiveConfig("ordered")) { // generate dependencies
833 for( it.toFirst(); it.current(); ) {
834 QString tar = it.current()->target;
835 ++it;
836 if (it.current())
837 t << it.current()->target << ": " << tar << endl;
838 }
839 t << endl;
840 }
841
842 writeMakeQmake(t);
843
844 if(project->isEmpty("SUBDIRS")) {
845 t << "all qmake_all distclean install uiclean mocclean clean: FORCE" << endl;
846 } else {
847 t << "all: $(SUBTARGETS)" << endl;
848 t << "qmake_all:";
849 for( it.toFirst(); it.current(); ++it) {
850 t << " ";
851 if(!(*it)->directory.isEmpty())
852 t << (*it)->directory << Option::dir_sep;
853 t << (*it)->makefile;
854 }
855 for( it.toFirst(); it.current(); ++it) {
856 t << "\n\t ( ";
857 if(!(*it)->directory.isEmpty())
858 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
859 t << "grep \"^qmake_all:\" " << (*it)->makefile
860 << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true";
861 }
862 t << endl;
863 t << "clean uninstall install uiclean mocclean: qmake_all FORCE";
864 for( it.toFirst(); it.current(); ++it) {
865 t << "\n\t ( ";
866 if(!(*it)->directory.isEmpty())
867 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
868 t << "$(MAKE) -f " << (*it)->makefile << " $@" << "; ) || true";
869 }
870 t << endl;
871 t << "distclean: qmake_all FORCE";
872 for( it.toFirst(); it.current(); ++it) {
873 t << "\n\t ( ";
874 if(!(*it)->directory.isEmpty())
875 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
876 t << "$(MAKE) -f " << (*it)->makefile << " $@; $(DEL_FILE) " << (*it)->makefile << "; ) || true";
877 }
878 t << endl << endl;
879 }
880 t <<"FORCE:" << endl << endl;
881}
882
883void UnixMakefileGenerator::init2()
884{
885 //version handling
886 if(project->variables()["VERSION"].isEmpty())
887 project->variables()["VERSION"].append("1.0." +
888 (project->isEmpty("VER_PAT") ? QString("0") :
889 project->first("VER_PAT")) );
890 QStringList l = QStringList::split('.', project->first("VERSION"));
891 l << "0" << "0"; //make sure there are three
892 project->variables()["VER_MAJ"].append(l[0]);
893 project->variables()["VER_MIN"].append(l[1]);
894 project->variables()["VER_PAT"].append(l[2]);
895
896 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
897#if 0
898 if ( project->isActiveConfig("dll") ) {
899 project->variables()["TARGET"] += project->variables()["TARGET.so"];
900 if(project->variables()["QMAKE_LFLAGS_SHAPP"].isEmpty())
901 project->variables()["QMAKE_LFLAGS_SHAPP"] += project->variables()["QMAKE_LFLAGS_SHLIB"];
902 if(!project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty())
903 project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET");
904 }
905#endif
906 project->variables()["TARGET"].first().prepend(project->first("DESTDIR"));
907 } else if ( project->isActiveConfig("staticlib") ) {
908 project->variables()["TARGET"].first().prepend("lib");
909 project->variables()["TARGET"].first() += ".a";
910 if(project->variables()["QMAKE_AR_CMD"].isEmpty())
911 project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGET) $(OBJECTS) $(OBJMOC)");
912 } else {
913 project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a");
914 if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() )
915 project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)");
916 else
917 project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)");
918 QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 );
919 if( project->isActiveConfig("plugin") ) {
920 project->variables()["TARGET_x.y.z"].append("lib" +
921 project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB"));
922 if(project->isActiveConfig("lib_version_first"))
923 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
924 project->first("VER_MAJ") + "." +
925 project->first("QMAKE_EXTENSION_SHLIB"));
926 else
927 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
928 project->first("QMAKE_EXTENSION_SHLIB") +
929 "." + project->first("VER_MAJ"));
930
931 project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
932 if(project->isActiveConfig("qt"))
933 project->variables()["DEFINES"].append("QT_PLUGIN");
934 } else if ( os == "hpux" ) {
935 project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl");
936 if(project->isActiveConfig("lib_version_first"))
937 project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." +
938 project->first("TARGET"));
939 else
940 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
941 project->first("VER_MAJ"));
942 project->variables()["TARGET"] = project->variables()["TARGET_x"];
943 } else if ( os == "aix" ) {
944 project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".a");
945 if(project->isActiveConfig("lib_version_first")) {
946 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
947 project->first("VER_MAJ") + "." +
948 project->first("QMAKE_EXTENSION_SHLIB"));
949 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
950 project->first("VER_MAJ") +
951 "." + project->first("VER_MIN") + "." +
952 project->first("QMAKE_EXTENSION_SHLIB"));
953 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
954 project->first("VER_MAJ") + "." +
955 project->first("VER_MIN") + "." +
956 project->first("VER_PAT") + "." +
957 project->first("QMAKE_EXTENSION_SHLIB"));
958 } else {
959 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
960 project->first("QMAKE_EXTENSION_SHLIB") +
961 "." + project->first("VER_MAJ"));
962 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
963 project->first("QMAKE_EXTENSION_SHLIB") +
964 "." + project->first("VER_MAJ") +
965 "." + project->first("VER_MIN"));
966 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
967 project->first("QMAKE_EXTENSION_SHLIB") + "." +
968 project->first("VER_MAJ") + "." +
969 project->first("VER_MIN") + "." +
970 project->first("VER_PAT"));
971 }
972 project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
973 } else {
974 project->variables()["TARGET_"].append("lib" + project->first("TARGET") + "." +
975 project->first("QMAKE_EXTENSION_SHLIB"));
976 if(project->isActiveConfig("lib_version_first")) {
977 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
978 project->first("VER_MAJ") + "." +
979 project->first("QMAKE_EXTENSION_SHLIB"));
980 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
981 project->first("VER_MAJ") +
982 "." + project->first("VER_MIN") + "." +
983 project->first("QMAKE_EXTENSION_SHLIB"));
984 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
985 project->first("VER_MAJ") + "." +
986 project->first("VER_MIN") + "." +
987 project->first("VER_PAT") + "." +
988 project->variables()["QMAKE_EXTENSION_SHLIB"].first());
989 } else {
990 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
991 project->first("QMAKE_EXTENSION_SHLIB") +
992 "." + project->first("VER_MAJ"));
993 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
994 project->first("QMAKE_EXTENSION_SHLIB")
995 + "." + project->first("VER_MAJ") +
996 "." + project->first("VER_MIN"));
997 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") +
998 "." +
999 project->variables()[
1000 "QMAKE_EXTENSION_SHLIB"].first() + "." +
1001 project->first("VER_MAJ") + "." +
1002 project->first("VER_MIN") + "." +
1003 project->first("VER_PAT"));
1004 }
1005 project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
1006 }
1007 if(project->isEmpty("QMAKE_LN_SHLIB"))
1008 project->variables()["QMAKE_LN_SHLIB"].append("ln -s");
1009 project->variables()["DESTDIR_TARGET"].append("$(TARGET)");
1010 if ( !project->variables()["DESTDIR"].isEmpty() )
1011 project->variables()["DESTDIR_TARGET"].first().prepend(project->first("DESTDIR"));
1012 if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty() && !project->variables()["TARGET_x"].isEmpty() )
1013 project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x");
1014 if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() )
1015 project->variables()["QMAKE_LINK_SHLIB_CMD"].append(
1016 "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)");
1017 }
1018 if(project->isEmpty("QMAKE_SYMBOLIC_LINK"))
1019 project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf");
1020 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
1021 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHAPP"];
1022 } else if ( project->isActiveConfig("dll") ) {
1023 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"];
1024 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"];
1025 if ( project->isActiveConfig("plugin") ) {
1026 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PLUGIN"];
1027 if( !project->isActiveConfig("plugin_no_soname") )
1028 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"];
1029 } else {
1030 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"];
1031 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"];
1032 }
1033 QString destdir = project->first("DESTDIR");
1034 if ( !destdir.isEmpty() && !project->variables()["QMAKE_RPATH"].isEmpty() ) {
1035 QString rpath_destdir = destdir;
1036 if(QDir::isRelativePath(rpath_destdir)) {
1037 QFileInfo fi(Option::fixPathToLocalOS(rpath_destdir));
1038 if(fi.convertToAbs()) //strange, shouldn't really happen
1039 rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE);
1040 else
1041 rpath_destdir = fi.filePath();
1042 } else {
1043 rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE);
1044 }
1045 project->variables()["QMAKE_LFLAGS"] += project->first("QMAKE_RPATH") + rpath_destdir;
1046 }
1047 }
1048}
diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp
new file mode 100644
index 0000000..ae7b47b
--- a/dev/null
+++ b/qmake/generators/win32/borland_bmake.cpp
@@ -0,0 +1,477 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "borland_bmake.h"
39#include "option.h"
40#include <qdir.h>
41#include <qregexp.h>
42#include <time.h>
43#include <stdlib.h>
44
45
46BorlandMakefileGenerator::BorlandMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
47{
48
49}
50
51bool
52BorlandMakefileGenerator::writeMakefile(QTextStream &t)
53{
54 writeHeader(t);
55 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
56 t << "all clean:" << "\n\t"
57 << "@echo \"Some of the required modules ("
58 << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
59 << "@echo \"Skipped.\"" << endl << endl;
60 return TRUE;
61 }
62
63 if(project->first("TEMPLATE") == "app" ||
64 project->first("TEMPLATE") == "lib") {
65 writeBorlandParts(t);
66 return MakefileGenerator::writeMakefile(t);
67 }
68 else if(project->first("TEMPLATE") == "subdirs") {
69 writeSubDirs(t);
70 return TRUE;
71 }
72 return FALSE;
73}
74
75void
76BorlandMakefileGenerator::writeBorlandParts(QTextStream &t)
77{
78 t << "!if !$d(BCB)" << endl;
79 t << "BCB = $(MAKEDIR)\\.." << endl;
80 t << "!endif" << endl << endl;
81 t << "####### Compiler, tools and options" << endl << endl;
82 t << "CC =" << var("QMAKE_CC") << endl;
83 t << "CXX =" << var("QMAKE_CXX") << endl;
84 t << "LEX = " << var("QMAKE_LEX") << endl;
85 t << "YACC = " << var("QMAKE_YACC") << endl;
86 t << "CFLAGS =" << var("QMAKE_CFLAGS") << " "
87 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
88 << varGlue("DEFINES","-D"," -D","") << endl;
89 t << "CXXFLAGS=" << var("QMAKE_CXXFLAGS") << " "
90 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
91 << varGlue("DEFINES","-D"," -D","") << endl;
92 t << "LEXFLAGS=" << var("QMAKE_LEXFLAGS") << endl;
93 t << "YACCFLAGS=" << var("QMAKE_YACCFLAGS") << endl;
94
95 t << "INCPATH =";
96 QStringList &incs = project->variables()["INCLUDEPATH"];
97 for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
98 QString inc = (*incit);
99 inc.replace(QRegExp("\\\\*$"), "");
100 inc.replace("\"", "");
101 t << " -I\"" << inc << "\"";
102 }
103 t << " -I\"" << specdir() << "\""
104 << endl;
105
106 if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
107 t << "LINK =" << var("QMAKE_LINK") << endl;
108 t << "LFLAGS =";
109 if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
110 t << varGlue("QMAKE_LIBDIR","-L",";","") << " ";
111 t << var("QMAKE_LFLAGS") << endl;
112 t << "LIBS =" << var("QMAKE_LIBS") << endl;
113 }
114 else {
115 t << "LIB =" << var("QMAKE_LIB") << endl;
116 }
117 t << "MOC =" << (project->isEmpty("QMAKE_MOC") ? QString("moc") :
118 Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl;
119 t << "UIC =" << (project->isEmpty("QMAKE_UIC") ? QString("uic") :
120 Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl;
121 t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
122 Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl;
123 t << "IDC =" << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
124 Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl;
125 t << "IDL =" << (project->isEmpty("QMAKE_IDL") ? QString("midl") :
126 Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl;
127 t << "ZIP =" << var("QMAKE_ZIP") << endl;
128 t << "DEF_FILE =" << varList("DEF_FILE") << endl;
129 t << "RES_FILE =" << varList("RES_FILE") << endl;
130 t << "COPY_FILE = " << var("QMAKE_COPY") << endl;
131 t << "COPY_DIR = " << var("QMAKE_COPY") << endl;
132 t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
133 t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
134 t << "MOVE = " << var("QMAKE_MOVE") << endl;
135 t << endl;
136
137 t << "####### Files" << endl << endl;
138 t << "HEADERS =" << varList("HEADERS") << endl;
139 t << "SOURCES =" << varList("SOURCES") << endl;
140 t << "OBJECTS =" << varList("OBJECTS") << endl;
141 t << "FORMS =" << varList("FORMS") << endl;
142 t << "UICDECLS =" << varList("UICDECLS") << endl;
143 t << "UICIMPLS =" << varList("UICIMPLS") << endl;
144 t << "SRCMOC =" << varList("SRCMOC") << endl;
145 t << "OBJMOC =" << varList("OBJMOC") << endl;
146 t << "DIST =" << varList("DISTFILES") << endl;
147 t << "TARGET ="
148 << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT"))
149 << endl;
150 t << endl;
151
152 t << "####### Implicit rules" << endl << endl;
153 t << ".SUFFIXES: .cpp .cxx .cc .c" << endl << endl;
154 t << ".cpp.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
155 t << ".cxx.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
156 t << ".cc.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
157 t << ".c.obj:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
158
159 t << "####### Build rules" << endl << endl;
160 t << "all: " << varGlue("ALL_DEPS",""," "," ") << " $(TARGET)" << endl << endl;
161 t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS");
162 if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
163 t << "\n\t" << "$(LINK) @&&|" << "\n\t"
164 << "$(LFLAGS) $(OBJECTS) $(OBJMOC),$(TARGET),,$(LIBS),$(DEF_FILE),$(RES_FILE)";
165 } else {
166 t << "\n\t-del $(TARGET)"
167 << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+"
168 << project->variables()["OBJECTS"].join(" \\\n+") << " \\\n+"
169 << project->variables()["OBJMOC"].join(" \\\n+");
170 }
171 t << endl << "|" << endl;
172 if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) {
173 QStringList dlldirs = project->variables()["DLLDESTDIR"];
174 for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
175 t << "\n\t" << "-copy $(TARGET) " << *dlldir;
176 }
177 }
178 QString targetfilename = project->variables()["TARGET"].first();
179 if(project->isActiveConfig("activeqt")) {
180 QString version = project->variables()["VERSION"].first();
181 if ( version.isEmpty() )
182 version = "1.0";
183
184 if ( project->isActiveConfig("dll")) {
185 t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version);
186 t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
187 t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
188 t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" );
189 } else {
190 t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version);
191 t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
192 t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
193 t << "\n\t" << ("-$(TARGET) -regserver");
194 }
195 }
196 t << endl << endl;
197
198 if(!project->variables()["RC_FILE"].isEmpty()) {
199 t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t"
200 << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl;
201 }
202 t << "mocables: $(SRCMOC)" << endl << endl;
203
204 writeMakeQmake(t);
205
206 t << "dist:" << "\n\t"
207 << "$(ZIP) " << var("PROJECT") << ".zip " << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)"
208 << endl << endl;
209
210 t << "clean:\n"
211 << varGlue("OBJECTS","\t-del ","\n\t-del ","")
212 << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","")
213 << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","")
214 << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","")
215 << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","")
216 << "\n\t-del $(TARGET)"
217 << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","")
218 << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ","");
219 if ( project->isActiveConfig("activeqt")) {
220 t << ("\n\t-del tmp\\" + targetfilename + ".*");
221 t << "\n\t-del tmp\\dump.*";
222 }
223 if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty())
224 t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
225 if(!project->isEmpty("IMAGES"))
226 t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", "");
227
228 // blasted user defined targets
229 QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
230 for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
231 QString targ = var((*it) + ".target"),
232 cmd = var((*it) + ".commands"), deps;
233 if(targ.isEmpty())
234 targ = (*it);
235 QStringList &deplist = project->variables()[(*it) + ".depends"];
236 for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
237 QString dep = var((*dep_it) + ".target");
238 if(dep.isEmpty())
239 dep = (*dep_it);
240 deps += " " + dep;
241 }
242 t << "\n\n" << targ << ":" << deps << "\n\t"
243 << cmd;
244 }
245
246 t << endl << endl;
247}
248
249void
250BorlandMakefileGenerator::init()
251{
252 if(init_flag)
253 return;
254 init_flag = TRUE;
255
256 project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
257
258 /* this should probably not be here, but I'm using it to wrap the .t files */
259 if(project->first("TEMPLATE") == "app")
260 project->variables()["QMAKE_APP_FLAG"].append("1");
261 else if(project->first("TEMPLATE") == "lib")
262 project->variables()["QMAKE_LIB_FLAG"].append("1");
263 else if(project->first("TEMPLATE") == "subdirs") {
264 MakefileGenerator::init();
265 if(project->variables()["MAKEFILE"].isEmpty())
266 project->variables()["MAKEFILE"].append("Makefile");
267 if(project->variables()["QMAKE"].isEmpty())
268 project->variables()["QMAKE"].append("qmake");
269 return;
270 }
271
272 bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qtmt"QTDLL_POSTFIX);
273 QStringList &configs = project->variables()["CONFIG"];
274 if (project->isActiveConfig("shared"))
275 project->variables()["DEFINES"].append("QT_DLL");
276 if (project->isActiveConfig("qt_dll"))
277 if(configs.findIndex("qt") == -1) configs.append("qt");
278 if ( project->isActiveConfig("qt") ) {
279 if ( project->isActiveConfig("plugin") ) {
280 project->variables()["CONFIG"].append("dll");
281 project->variables()["DEFINES"].append("QT_PLUGIN");
282 }
283 if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
284 ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
285 project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
286 (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
287 project->variables()["QMAKE_QT_DLL"].append("1");
288 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
289 project->variables()["CONFIG"].append("dll");
290 }
291 }
292 if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
293 project->variables()["CONFIG"].remove("staticlib");
294 project->variables()["QMAKE_APP_OR_DLL"].append("1");
295 } else {
296 project->variables()["CONFIG"].append("staticlib");
297 }
298 if ( project->isActiveConfig("warn_off") ) {
299 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
300 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
301 } else if ( project->isActiveConfig("warn_on") ) {
302 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
303 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
304 }
305 if(project->isActiveConfig("qt")) {
306 if ( project->isActiveConfig("thread") )
307 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
308 if ( project->isActiveConfig("accessibility" ) )
309 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
310 if ( project->isActiveConfig("tablet") )
311 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
312 }
313
314 if ( project->isActiveConfig("debug") ) {
315 if ( project->isActiveConfig("thread") ) {
316 if ( project->isActiveConfig("dll") ) {
317 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"];
318 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
319 } else {
320 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"];
321 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
322 }
323 }
324 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
325 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
326 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
327 } else {
328 if ( project->isActiveConfig("thread") ) {
329 if ( project->isActiveConfig("dll") ) {
330 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"];
331 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
332 } else {
333 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"];
334 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"];
335 }
336 }
337 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
338 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
339 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
340 }
341
342 if ( !project->variables()["QMAKE_INCDIR"].isEmpty()) {
343 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
344 }
345 if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) {
346 project->variables()["CONFIG"].append("windows");
347 }
348 if ( project->isActiveConfig("qt") ) {
349 project->variables()["CONFIG"].append("moc");
350 project->variables()["INCLUDEPATH"] +=project->variables()["QMAKE_INCDIR_QT"];
351 project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
352 if ( !project->isActiveConfig("debug") )
353 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
354 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
355 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) {
356 project->variables()["DEFINES"].append("QT_MAKEDLL");
357 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"];
358 }
359 } else {
360 if(project->isActiveConfig("thread"))
361 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
362 else
363 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
364 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
365 int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
366 if ( hver == -1 )
367 hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
368 if(hver != -1) {
369 QString ver;
370 ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "mt" : ""), hver);
371 QStringList &libs = project->variables()["QMAKE_LIBS"];
372 for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
373 (*libit).replace(QRegExp("qt(mt)?\\.lib"), ver);
374 }
375 }
376 if ( project->isActiveConfig( "activeqt" ) ) {
377 project->variables().remove("QMAKE_LIBS_QT_ENTRY");
378 project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
379 if ( project->isActiveConfig( "dll" ) )
380 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
381 }
382 if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
383 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
384 }
385 }
386 }
387 if ( project->isActiveConfig("opengl") ) {
388 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
389 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
390 }
391 if ( project->isActiveConfig("dll") ) {
392 project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"];
393 project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"];
394 project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"];
395 project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"];
396 if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) {
397 project->variables()["TARGET_EXT"].append(
398 QStringList::split('.',project->first("VERSION")).join("") + ".dll");
399 } else {
400 project->variables()["TARGET_EXT"].append(".dll");
401 }
402 } else {
403 project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"];
404 project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"];
405 project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"];
406 project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"];
407 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
408 project->variables()["TARGET_EXT"].append(".exe");
409 } else {
410 project->variables()["TARGET_EXT"].append(".lib");
411 }
412 }
413 if ( project->isActiveConfig("windows") ) {
414 if ( project->isActiveConfig("console") ) {
415 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
416 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
417 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
418 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
419 } else {
420 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"];
421 }
422 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
423 } else {
424 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
425 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
426 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
427 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
428 }
429 if ( project->isActiveConfig("thread") ) {
430 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RTMT"];
431 } else {
432 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RT"];
433 }
434 if ( project->isActiveConfig("moc") ) {
435 setMocAware(TRUE);
436 }
437 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
438 project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
439 "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
440 QStringList &l = project->variables()["QMAKE_FILETAGS"];
441 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
442 QStringList &gdmf = project->variables()[(*it)];
443 for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
444 (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
445 }
446
447 if ( !project->variables()["RC_FILE"].isEmpty()) {
448 if ( !project->variables()["RES_FILE"].isEmpty()) {
449 fprintf(stderr, "Both .rc and .res file specified.\n");
450 fprintf(stderr, "Please specify one of them, not both.");
451 exit(666);
452 }
453 project->variables()["RES_FILE"] = project->variables()["RC_FILE"];
454 project->variables()["RES_FILE"].first().replace(".rc",".res");
455 project->variables()["TARGETDEPS"] += project->variables()["RES_FILE"];
456 }
457 MakefileGenerator::init();
458 if ( !project->variables()["VERSION"].isEmpty()) {
459 QStringList l = QStringList::split('.', project->first("VERSION"));
460 project->variables()["VER_MAJ"].append(l[0]);
461 project->variables()["VER_MIN"].append(l[1]);
462 }
463
464 if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
465 // bcc does not generate a .tds file for static libs
466 QString tdsPostfix;
467 if ( !project->variables()["VERSION"].isEmpty() ) {
468 tdsPostfix = QStringList::split( '.', project->first("VERSION") ).join("")
469 + ".tds";
470 } else {
471 tdsPostfix = ".tds";
472 }
473 project->variables()["QMAKE_CLEAN"].append(
474 project->first("DESTDIR") + project->first("TARGET") + tdsPostfix );
475 }
476}
477
diff --git a/qmake/generators/win32/borland_bmake.h b/qmake/generators/win32/borland_bmake.h
new file mode 100644
index 0000000..90f8229
--- a/dev/null
+++ b/qmake/generators/win32/borland_bmake.h
@@ -0,0 +1,59 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __BORLANDMAKE_H__
38#define __BORLANDMAKE_H__
39
40#include "winmakefile.h"
41
42class BorlandMakefileGenerator : public Win32MakefileGenerator
43{
44 bool init_flag;
45 void writeBorlandParts(QTextStream &);
46
47 bool writeMakefile(QTextStream &);
48 void init();
49
50public:
51 BorlandMakefileGenerator(QMakeProject *p);
52 ~BorlandMakefileGenerator();
53};
54
55inline BorlandMakefileGenerator::~BorlandMakefileGenerator()
56{ }
57
58
59#endif /* __BORLANDMAKE_H__ */
diff --git a/qmake/generators/win32/msvc_dsp.cpp b/qmake/generators/win32/msvc_dsp.cpp
new file mode 100644
index 0000000..8b08c78
--- a/dev/null
+++ b/qmake/generators/win32/msvc_dsp.cpp
@@ -0,0 +1,955 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "msvc_dsp.h"
39#include "option.h"
40#include <qdir.h>
41#include <qregexp.h>
42#include <stdlib.h>
43#include <time.h>
44
45DspMakefileGenerator::DspMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
46{
47
48}
49
50bool
51DspMakefileGenerator::writeMakefile(QTextStream &t)
52{
53 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
54 /* for now just dump, I need to generated an empty dsp or something.. */
55 fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
56 var("QMAKE_FAILED_REQUIREMENTS").latin1());
57 return TRUE;
58 }
59
60 if(project->first("TEMPLATE") == "vcapp" ||
61 project->first("TEMPLATE") == "vclib") {
62 return writeDspParts(t);
63 }
64 else if(project->first("TEMPLATE") == "subdirs") {
65 writeHeader(t);
66 writeSubDirs(t);
67 return TRUE;
68 }
69 return FALSE;
70}
71
72bool
73DspMakefileGenerator::writeDspParts(QTextStream &t)
74{
75 QString dspfile;
76 if ( !project->variables()["DSP_TEMPLATE"].isEmpty() ) {
77 dspfile = project->first("DSP_TEMPLATE");
78 } else {
79 dspfile = project->first("MSVCDSP_TEMPLATE");
80 }
81 QString dspfile_loc = findTemplate(dspfile);
82
83 QFile file(dspfile_loc);
84 if(!file.open(IO_ReadOnly)) {
85 fprintf(stderr, "Cannot open dsp file: %s\n", dspfile.latin1());
86 return FALSE;
87 }
88 QTextStream dsp(&file);
89
90 int rep;
91 QString line;
92 while ( !dsp.eof() ) {
93 line = dsp.readLine();
94 while((rep = line.find(QRegExp("\\$\\$[a-zA-Z0-9_-]*"))) != -1) {
95 QString torep = line.mid(rep, line.find(QRegExp("[^\\$a-zA-Z0-9_-]"), rep) - rep);
96 QString variable = torep.right(torep.length()-2);
97
98 t << line.left(rep); //output the left side
99 line = line.right(line.length() - (rep + torep.length())); //now past the variable
100 if(variable == "MSVCDSP_SOURCES") {
101 if(project->variables()["SOURCES"].isEmpty())
102 continue;
103
104 QString mocpath = var( "QMAKE_MOC" );
105 mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " ";
106
107 QStringList list = project->variables()["SOURCES"] + project->variables()["DEF_FILE"];
108 if(!project->isActiveConfig("flat"))
109 list.sort();
110 QStringList::Iterator it;
111 for( it = list.begin(); it != list.end(); ++it) {
112 beginGroupForFile((*it), t);
113 t << "# Begin Source File\n\nSOURCE=" << (*it) << endl;
114 if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) {
115 QString base = (*it);
116 base.replace(QRegExp("\\..*$"), "").upper();
117 base.replace(QRegExp("[^a-zA-Z]"), "_");
118
119 QString build = "\n\n# Begin Custom Build - Moc'ing " + findMocSource((*it)) +
120 "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + (*it) + "\""
121 " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n"
122 "\t" + mocpath + findMocSource((*it)) + " -o " +
123 (*it) + "\n\n" "# End Custom Build\n\n";
124
125 t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl;
126
127 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
128 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\""
129 << build << "!ENDIF " << endl << endl;
130 }
131 t << "# End Source File" << endl;
132 }
133 endGroups(t);
134 } else if(variable == "MSVCDSP_IMAGES") {
135 if(project->variables()["IMAGES"].isEmpty())
136 continue;
137 t << "# Begin Source File\n\nSOURCE=" << project->first("QMAKE_IMAGE_COLLECTION") << endl;
138 t << "# End Source File" << endl;
139 } else if(variable == "MSVCDSP_HEADERS") {
140 if(project->variables()["HEADERS"].isEmpty())
141 continue;
142
143 QStringList list = project->variables()["HEADERS"];
144 if(!project->isActiveConfig("flat"))
145 list.sort();
146 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
147 // beginGroupForFile((*it), t);
148 t << "# Begin Source File\n\nSOURCE=" << (*it) << endl << endl;
149 if ( project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) {
150 QString base = (*it);
151 base.replace(QRegExp("\\..*$"), "").upper();
152 base.replace(QRegExp("[^a-zA-Z]"), "_");
153
154 QString mocpath = var( "QMAKE_MOC" );
155 mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " ";
156
157 QString build = "\n\n# Begin Custom Build - Moc'ing " + (*it) +
158 "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + findMocDestination((*it)) +
159 "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n"
160 "\t" + mocpath + (*it) + " -o " +
161 findMocDestination((*it)) + "\n\n" "# End Custom Build\n\n";
162
163 t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\"" << endl << endl;
164
165 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
166 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\""
167 << build << "!ENDIF " << endl << endl;
168 }
169 t << "# End Source File" << endl;
170 }
171 // endGroups(t);
172 } else if(variable == "MSVCDSP_FORMSOURCES" || variable == "MSVCDSP_FORMHEADERS") {
173 if(project->variables()["FORMS"].isEmpty())
174 continue;
175
176 QString uiSourcesDir;
177 QString uiHeadersDir;
178 if(!project->variables()["UI_DIR"].isEmpty()) {
179 uiSourcesDir = project->first("UI_DIR");
180 uiHeadersDir = project->first("UI_DIR");
181 } else {
182 if ( !project->variables()["UI_SOURCES_DIR"].isEmpty() )
183 uiSourcesDir = project->first("UI_SOURCES_DIR");
184 else
185 uiSourcesDir = "";
186 if ( !project->variables()["UI_HEADERS_DIR"].isEmpty() )
187 uiHeadersDir = project->first("UI_HEADERS_DIR");
188 else
189 uiHeadersDir = "";
190 }
191
192 QStringList list = project->variables()["FORMS"];
193 if(!project->isActiveConfig("flat"))
194 list.sort();
195 QString ext = variable == "MSVCDSP_FORMSOURCES" ? ".cpp" : ".h";
196 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
197 QString base = (*it);
198 int dot = base.findRev(".");
199 base.replace( dot, base.length() - dot, ext );
200 QString fname = base;
201
202 int lbs = fname.findRev( "\\" );
203 QString fpath;
204 if ( lbs != -1 )
205 fpath = fname.left( lbs + 1 );
206 fname = fname.right( fname.length() - lbs - 1 );
207
208 if ( ext == ".cpp" && !uiSourcesDir.isEmpty() )
209 fname.prepend(uiSourcesDir);
210 else if ( ext == ".h" && !uiHeadersDir.isEmpty() )
211 fname.prepend(uiHeadersDir);
212 else
213 fname = base;
214 // beginGroupForFile(fname, t);
215 t << "# Begin Source File\n\nSOURCE=" << fname
216 << "\n# End Source File" << endl;
217 }
218 // endGroups(t);
219 } else if(variable == "MSVCDSP_TRANSLATIONS" ) {
220 if(project->variables()["TRANSLATIONS"].isEmpty())
221 continue;
222
223 t << "# Begin Group \"Translations\"\n";
224 t << "# Prop Default_Filter \"ts\"\n";
225
226 QStringList list = project->variables()["TRANSLATIONS"];
227 if(!project->isActiveConfig("flat"))
228 list.sort();
229 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
230 QString sify = *it;
231 sify.replace('/', '\\' );
232 QString base = (*it);
233 base.replace(QRegExp("\\..*$"), "").upper();
234 base.replace(QRegExp("[^a-zA-Z]"), "_");
235
236 // beginGroupForFile(sify, t);
237 t << "# Begin Source File\n\nSOURCE=" << sify << endl;
238 t << "\n# End Source File" << endl;
239 }
240 // endGroups(t);
241 t << "\n# End Group\n";
242 } else if (variable == "MSVCDSP_MOCSOURCES" && project->isActiveConfig("moc")) {
243 if ( project->variables()["SRCMOC"].isEmpty())
244 continue;
245
246 QString mocpath = var( "QMAKE_MOC" );
247 mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " ";
248
249 QStringList list = project->variables()["SRCMOC"];
250 if(!project->isActiveConfig("flat"))
251 list.sort();
252 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
253 // beginGroupForFile((*it), t);
254 t << "# Begin Source File\n\nSOURCE=" << (*it) << endl;
255 if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) {
256 QString base = (*it);
257 base.replace(QRegExp("\\..*$"), "").upper();
258 base.replace(QRegExp("[^a-zA-Z]"), "_");
259
260 QString build = "\n\n# Begin Custom Build - Moc'ing " + findMocSource((*it)) +
261 "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + (*it) + "\""
262 " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n"
263 "\t" + mocpath + findMocSource((*it)) + " -o " +
264 (*it) + "\n\n" "# End Custom Build\n\n";
265
266 t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl;
267
268 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
269 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\""
270 << build << "!ENDIF " << endl << endl;
271 }
272 t << "# End Source File" << endl;
273 }
274 // endGroups(t);
275 } else if(variable == "MSVCDSP_PICTURES") {
276 if(project->variables()["IMAGES"].isEmpty())
277 continue;
278
279 t << "# Begin Group \"Images\"\n"
280 << "# Prop Default_Filter \"png jpeg bmp xpm\"\n";
281
282 QStringList list = project->variables()["IMAGES"];
283 if(!project->isActiveConfig("flat"))
284 list.sort();
285 QStringList::Iterator it;
286
287 // dump the image list to a file UIC can read.
288 QFile f( "images.tmp" );
289 f.open( IO_WriteOnly );
290 QTextStream ts( &f );
291 for( it = list.begin(); it != list.end(); ++it )
292 ts << " " << *it;
293 f.close();
294
295 // create an output step for images not more than once
296 bool imagesBuildDone = FALSE;
297 for( it = list.begin(); it != list.end(); ++it ) {
298 // beginGroupForFile((*it), t);
299 t << "# Begin Source File\n\nSOURCE=" << (*it) << endl;
300
301 QString base = (*it);
302 QString uicpath = var("QMAKE_UIC");
303 uicpath = uicpath.replace(QRegExp("\\..*$"), "") + " ";
304
305 if ( !imagesBuildDone ) {
306 imagesBuildDone = TRUE;
307 QString build = "\n\n# Begin Custom Build - Creating image collection...\n"
308 "InputPath=.\\" + base + "\n\n";
309
310 build += "\"" + project->first("QMAKE_IMAGE_COLLECTION") + "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n";
311 build += "\t" + uicpath + "-embed " + project->first("QMAKE_ORIG_TARGET") + " -f images.tmp -o "
312 + project->first("QMAKE_IMAGE_COLLECTION") + "\n\n";
313 build.append("# End Custom Build\n\n");
314
315 t << "USERDEP_" << base << "=";
316 QStringList::Iterator it2 = list.begin();
317 while ( it2 != list.end() ) {
318 t << "\"" << (*it2) << "\"";
319 it2++;
320 if ( it2 != list.end() )
321 t << "\\\n";
322 }
323 t << endl << endl;
324
325 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
326 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build
327 << "!ENDIF \n\n" << endl;
328 }
329
330 t << "# End Source File" << endl;
331 }
332 // endGroups(t);
333 t << "\n# End Group\n";
334 } else if(variable == "MSVCDSP_FORMS") {
335 if(project->variables()["FORMS"].isEmpty())
336 continue;
337
338 t << "# Begin Group \"Forms\"\n"
339 << "# Prop Default_Filter \"ui\"\n";
340
341 QString uicpath = var("QMAKE_UIC");
342 uicpath = uicpath.replace(QRegExp("\\..*$"), "") + " ";
343 QString mocpath = var( "QMAKE_MOC" );
344 mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " ";
345
346 QStringList list = project->variables()["FORMS"];
347 if(!project->isActiveConfig("flat"))
348 list.sort();
349 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
350 QString base = (*it);
351 // beginGroupForFile(base, t);
352 t << "# Begin Source File\n\nSOURCE=" << base << endl;
353
354 QString fname = base;
355 fname.replace(".ui", "");
356 int lbs = fname.findRev( "\\" );
357 QString fpath;
358 if ( lbs != -1 )
359 fpath = fname.left( lbs + 1 );
360 fname = fname.right( fname.length() - lbs - 1 );
361
362 QString mocFile;
363 if(!project->variables()["MOC_DIR"].isEmpty())
364 mocFile = project->first("MOC_DIR");
365 else
366 mocFile = fpath;
367
368 QString uiSourcesDir;
369 QString uiHeadersDir;
370 if(!project->variables()["UI_DIR"].isEmpty()) {
371 uiSourcesDir = project->first("UI_DIR");
372 uiHeadersDir = project->first("UI_DIR");
373 } else {
374 if ( !project->variables()["UI_SOURCES_DIR"].isEmpty() )
375 uiSourcesDir = project->first("UI_SOURCES_DIR");
376 else
377 uiSourcesDir = fpath;
378 if ( !project->variables()["UI_HEADERS_DIR"].isEmpty() )
379 uiHeadersDir = project->first("UI_HEADERS_DIR");
380 else
381 uiHeadersDir = fpath;
382 }
383
384 t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\" \"$(QTDIR)\\bin\\uic.exe\"" << endl << endl;
385
386 QString build = "\n\n# Begin Custom Build - Uic'ing " + base + "...\n"
387 "InputPath=.\\" + base + "\n\n" "BuildCmds= \\\n\t" + uicpath + base +
388 " -o " + uiHeadersDir + fname + ".h \\\n" "\t" + uicpath + base +
389 " -i " + fname + ".h -o " + uiSourcesDir + fname + ".cpp \\\n"
390 "\t" + mocpath + uiHeadersDir + fname + ".h -o " + mocFile + "moc_" + fname + ".cpp \\\n";
391
392 build.append("\n\"" + uiHeadersDir + fname + ".h\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n"
393 "\t$(BuildCmds)\n\n"
394 "\"" + uiSourcesDir + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n"
395 "\t$(BuildCmds)\n\n"
396 "\"" + mocFile + "moc_" + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n"
397 "\t$(BuildCmds)\n\n");
398
399 build.append("# End Custom Build\n\n");
400
401 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
402 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build
403 << "!ENDIF \n\n" << "# End Source File" << endl;
404 }
405 // endGroups(t);
406 t << "\n# End Group\n";
407 } else if(variable == "MSVCDSP_LEXSOURCES") {
408 if(project->variables()["LEXSOURCES"].isEmpty())
409 continue;
410
411 t << "# Begin Group \"Lexables\"\n"
412 << "# Prop Default_Filter \"l\"\n";
413
414 QString lexpath = var("QMAKE_LEX") + varGlue("QMAKE_LEXFLAGS", " ", " ", "") + " ";
415
416 QStringList list = project->variables()["LEXSOURCES"];
417 if(!project->isActiveConfig("flat"))
418 list.sort();
419 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
420 QString fname = (*it);
421 // beginGroupForFile(fname, t);
422 t << "# Begin Source File\n\nSOURCE=" << fname << endl;
423 fname.replace(".l", Option::lex_mod + Option::cpp_ext.first());
424
425 QString build = "\n\n# Begin Custom Build - Lex'ing " + (*it) + "...\n"
426 "InputPath=.\\" + (*it) + "\n\n"
427 "\"" + fname + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n"
428 "\t" + lexpath + (*it) + "\\\n"
429 "\tdel " + fname + "\\\n"
430 "\tcopy lex.yy.c " + fname + "\n\n" +
431 "# End Custom Build\n\n";
432 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
433 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build
434 << "!ENDIF \n\n" << build
435
436 << "# End Source File" << endl;
437 }
438 // endGroups(t);
439 t << "\n# End Group\n";
440 } else if(variable == "MSVCDSP_YACCSOURCES") {
441 if(project->variables()["YACCSOURCES"].isEmpty())
442 continue;
443
444 t << "# Begin Group \"Yaccables\"\n"
445 << "# Prop Default_Filter \"y\"\n";
446
447 QString yaccpath = var("QMAKE_YACC") + varGlue("QMAKE_YACCFLAGS", " ", " ", "") + " ";
448
449 QStringList list = project->variables()["YACCSOURCES"];
450 if(!project->isActiveConfig("flat"))
451 list.sort();
452 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
453 QString fname = (*it);
454 // beginGroupForFile(fname, t);
455 t << "# Begin Source File\n\nSOURCE=" << fname << endl;
456 fname.replace(".y", Option::yacc_mod);
457
458 QString build = "\n\n# Begin Custom Build - Yacc'ing " + (*it) + "...\n"
459 "InputPath=.\\" + (*it) + "\n\n"
460 "\"" + fname + Option::cpp_ext.first() + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n"
461 "\t" + yaccpath + (*it) + "\\\n"
462 "\tdel " + fname + Option::h_ext.first() + "\\\n"
463 "\tmove y.tab.h " + fname + Option::h_ext.first() + "\n\n" +
464 "\tdel " + fname + Option::cpp_ext.first() + "\\\n"
465 "\tmove y.tab.c " + fname + Option::cpp_ext.first() + "\n\n" +
466 "# End Custom Build\n\n";
467
468 t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build
469 << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build
470 << "!ENDIF \n\n"
471 << "# End Source File" << endl;
472 }
473 // endGroups(t);
474 t << "\n# End Group\n";
475 } else if( variable == "MSVCDSP_CONFIGMODE" ) {
476 if( project->isActiveConfig( "debug" ) )
477 t << "Debug";
478 else
479 t << "Release";
480 } else if( variable == "MSVCDSP_IDLSOURCES" ) {
481 QStringList list = project->variables()["MSVCDSP_IDLSOURCES"];
482 if(!project->isActiveConfig("flat"))
483 list.sort();
484 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
485 t << "# Begin Source File" << endl << endl;
486 t << "SOURCE=" << (*it) << endl;
487 t << "# PROP Exclude_From_Build 1" << endl;
488 t << "# End Source File" << endl << endl;
489 }
490 }
491 else
492 t << var(variable);
493 }
494 t << line << endl;
495 }
496 t << endl;
497 file.close();
498 return TRUE;
499}
500
501
502
503void
504DspMakefileGenerator::init()
505{
506 if(init_flag)
507 return;
508 QStringList::Iterator it;
509 init_flag = TRUE;
510
511 /* this should probably not be here, but I'm using it to wrap the .t files */
512 if(project->first("TEMPLATE") == "vcapp" )
513 project->variables()["QMAKE_APP_FLAG"].append("1");
514 else if(project->first("TEMPLATE") == "vclib")
515 project->variables()["QMAKE_LIB_FLAG"].append("1");
516 if ( project->variables()["QMAKESPEC"].isEmpty() )
517 project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") );
518
519 bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX);
520 project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
521
522 QStringList &configs = project->variables()["CONFIG"];
523 if (project->isActiveConfig("shared"))
524 project->variables()["DEFINES"].append("QT_DLL");
525 if (project->isActiveConfig("qt_dll"))
526 if(configs.findIndex("qt") == -1) configs.append("qt");
527 if ( project->isActiveConfig("qt") ) {
528 if ( project->isActiveConfig( "plugin" ) ) {
529 project->variables()["CONFIG"].append("dll");
530 project->variables()["DEFINES"].append("QT_PLUGIN");
531 }
532 if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
533 ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
534 project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
535 (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
536 project->variables()["QMAKE_QT_DLL"].append("1");
537 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
538 project->variables()["CONFIG"].append("dll");
539 }
540 }
541 if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
542 project->variables()["CONFIG"].remove("staticlib");
543 project->variables()["QMAKE_APP_OR_DLL"].append("1");
544 } else {
545 project->variables()["CONFIG"].append("staticlib");
546 }
547
548 if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) {
549 project->variables()["CONFIG"].append("windows");
550 }
551 if ( !project->variables()["VERSION"].isEmpty() ) {
552 QString version = project->variables()["VERSION"][0];
553 int firstDot = version.find( "." );
554 QString major = version.left( firstDot );
555 QString minor = version.right( version.length() - firstDot - 1 );
556 minor.replace( ".", "" );
557 project->variables()["MSVCDSP_VERSION"].append( "/VERSION:" + major + "." + minor );
558 }
559
560 if ( project->isActiveConfig("qt") ) {
561 project->variables()["CONFIG"].append("moc");
562 project->variables()["INCLUDEPATH"] +=project->variables()["QMAKE_INCDIR_QT"];
563 project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
564
565 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
566 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
567 project->variables()["DEFINES"].append("QT_MAKEDLL");
568 project->variables()["QMAKE_LFLAGS"].append("/base:\"0x39D00000\"");
569 }
570 } else {
571 if(project->isActiveConfig("thread"))
572 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
573 else
574 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
575 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
576 int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
577 if ( hver == -1 )
578 hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
579 if(hver != -1) {
580 QString ver;
581 ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
582 QStringList &libs = project->variables()["QMAKE_LIBS"];
583 for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
584 (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
585 }
586 }
587 if ( project->isActiveConfig( "activeqt" ) ) {
588 project->variables().remove("QMAKE_LIBS_QT_ENTRY");
589 project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
590 if ( project->isActiveConfig( "dll" ) )
591 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
592 }
593 if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
594 project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
595 }
596 }
597 }
598
599 if ( project->isActiveConfig("debug") ) {
600 if ( !project->first("OBJECTS_DIR").isEmpty() )
601 project->variables()["MSVCDSP_OBJECTSDIRDEB"] = project->first("OBJECTS_DIR");
602 else
603 project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug";
604 project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release";
605 if ( !project->first("DESTDIR").isEmpty() )
606 project->variables()["MSVCDSP_TARGETDIRDEB"] = project->first("DESTDIR");
607 else
608 project->variables()["MSVCDSP_TARGETDIRDEB"] = "Debug";
609 project->variables()["MSVCDSP_TARGETDIRREL"] = "Release";
610 } else {
611 if ( !project->first("OBJECTS_DIR").isEmpty() )
612 project->variables()["MSVCDSP_OBJECTSDIRREL"] = project->first("OBJECTS_DIR");
613 project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug";
614 if ( !project->first("DESTDIR").isEmpty() )
615 project->variables()["MSVCDSP_TARGETDIRREL"] = project->first("DESTDIR");
616 else
617 project->variables()["MSVCDSP_TARGETDIRREL"] = "Release";
618 project->variables()["MSVCDSP_TARGETDIRDEB"] = "Debug";
619 }
620
621 if ( project->isActiveConfig("opengl") ) {
622 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
623 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
624 }
625 if ( project->isActiveConfig("thread") ) {
626 if(project->isActiveConfig("qt"))
627 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" );
628 if ( project->isActiveConfig("dll") || project->first("TARGET") == "qtmain"
629 || !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
630 project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
631 project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
632 } else {
633 // YES we want to use the DLL even in a static build
634 project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
635 project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT"];
636 }
637 if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt
638 && project->first("TARGET") != "qtmain" )
639 project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:\"libc\"");
640 }
641
642 if(project->isActiveConfig("qt")) {
643 if ( project->isActiveConfig("accessibility" ) )
644 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
645 if ( project->isActiveConfig("tablet") )
646 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
647 }
648 if ( project->isActiveConfig("dll") ) {
649 if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
650 QString ver_xyz(project->first("VERSION"));
651 ver_xyz.replace(".", "");
652 project->variables()["TARGET_EXT"].append(ver_xyz + ".dll");
653 } else {
654 project->variables()["TARGET_EXT"].append(".dll");
655 }
656 } else {
657 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() )
658 project->variables()["TARGET_EXT"].append(".exe");
659 else
660 project->variables()["TARGET_EXT"].append(".lib");
661 }
662
663 project->variables()["MSVCDSP_VER"] = "6.00";
664 project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /ZI";
665
666 if(!project->isActiveConfig("incremental")) {
667 project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
668 if ( is_qt )
669 project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /Zi";
670 }
671
672 QString msvcdsp_project;
673 if ( project->variables()["TARGET"].count() )
674 msvcdsp_project = project->variables()["TARGET"].first();
675
676 QString targetfilename = project->variables()["TARGET"].first();
677 project->variables()["TARGET"].first() += project->first("TARGET_EXT");
678 if ( project->isActiveConfig("moc") )
679 setMocAware(TRUE);
680
681 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
682 project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
683 "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
684 QStringList &l = project->variables()["QMAKE_FILETAGS"];
685 for(it = l.begin(); it != l.end(); ++it) {
686 QStringList &gdmf = project->variables()[(*it)];
687 for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
688 (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
689 }
690
691 MakefileGenerator::init();
692 if ( msvcdsp_project.isEmpty() )
693 msvcdsp_project = Option::output.name();
694
695 msvcdsp_project = msvcdsp_project.right( msvcdsp_project.length() - msvcdsp_project.findRev( "\\" ) - 1 );
696 msvcdsp_project = msvcdsp_project.left( msvcdsp_project.findRev( "." ) );
697 msvcdsp_project.replace("-", "");
698
699 project->variables()["MSVCDSP_PROJECT"].append(msvcdsp_project);
700 QStringList &proj = project->variables()["MSVCDSP_PROJECT"];
701
702 for(it = proj.begin(); it != proj.end(); ++it)
703 (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), "");
704
705 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
706 project->variables()["MSVCDSP_TEMPLATE"].append("win32app" + project->first( "DSP_EXTENSION" ) );
707 if ( project->isActiveConfig("console") ) {
708 project->variables()["MSVCDSP_CONSOLE"].append("Console");
709 project->variables()["MSVCDSP_WINCONDEF"].append("_CONSOLE");
710 project->variables()["MSVCDSP_DSPTYPE"].append("0x0103");
711 project->variables()["MSVCDSP_SUBSYSTEM"].append("console");
712 } else {
713 project->variables()["MSVCDSP_CONSOLE"].clear();
714 project->variables()["MSVCDSP_WINCONDEF"].append("_WINDOWS");
715 project->variables()["MSVCDSP_DSPTYPE"].append("0x0101");
716 project->variables()["MSVCDSP_SUBSYSTEM"].append("windows");
717 }
718 } else {
719 if ( project->isActiveConfig("dll") ) {
720 project->variables()["MSVCDSP_TEMPLATE"].append("win32dll" + project->first( "DSP_EXTENSION" ) );
721 } else {
722 project->variables()["MSVCDSP_TEMPLATE"].append("win32lib" + project->first( "DSP_EXTENSION" ) );
723 }
724 }
725
726 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
727
728 project->variables()["MSVCDSP_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"];
729 if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
730 project->variables()["MSVCDSP_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\""));
731 project->variables()["MSVCDSP_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"];
732 project->variables()["MSVCDSP_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ",""));
733 project->variables()["MSVCDSP_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ",""));
734
735 QStringList &libs = project->variables()["QMAKE_LIBS"];
736 for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) {
737 QString lib = (*libit);
738 lib.replace(QRegExp("\""), "");
739 project->variables()["MSVCDSP_LIBS"].append(" \"" + lib + "\"");
740 }
741
742 QStringList &incs = project->variables()["INCLUDEPATH"];
743 for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
744 QString inc = (*incit);
745 inc.replace("\"", "");
746 project->variables()["MSVCDSP_INCPATH"].append("/I \"" + inc + "\"");
747 }
748
749 project->variables()["MSVCDSP_INCPATH"].append("/I \"" + specdir() + "\"");
750 if ( project->isActiveConfig("qt") ) {
751 project->variables()["MSVCDSP_RELDEFS"].append("/D \"QT_NO_DEBUG\"");
752 } else {
753 project->variables()["MSVCDSP_RELDEFS"].clear();
754 }
755
756 QString dest;
757 if ( !project->variables()["DESTDIR"].isEmpty() ) {
758 project->variables()["TARGET"].first().prepend(project->first("DESTDIR"));
759 Option::fixPathToTargetOS(project->first("TARGET"));
760 dest = project->first("TARGET");
761 if ( project->first("TARGET").startsWith("$(QTDIR)") )
762 dest.replace( "$(QTDIR)", getenv("QTDIR") );
763 project->variables()["MSVCDSP_TARGET"].append(
764 QString("/out:\"") + dest + "\"");
765 if ( project->isActiveConfig("dll") ) {
766 QString imp = dest;
767 imp.replace(".dll", ".lib");
768 project->variables()["MSVCDSP_TARGET"].append(QString(" /implib:\"") + imp + "\"");
769 }
770 }
771 if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) {
772 QStringList dlldirs = project->variables()["DLLDESTDIR"];
773 QString copydll = "# Begin Special Build Tool\n"
774 "TargetPath=" + dest + "\n"
775 "SOURCE=$(InputPath)\n"
776 "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n"
777 "PostBuild_Cmds=";
778
779 for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
780 copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t";
781 }
782
783 copydll += "\n# End Special Build Tool";
784 project->variables()["MSVCDSP_COPY_DLL_REL"].append( copydll );
785 project->variables()["MSVCDSP_COPY_DLL_DBG"].append( copydll );
786 }
787 if ( project->isActiveConfig("activeqt") ) {
788 QString idl = project->variables()["QMAKE_IDL"].first();
789 QString idc = project->variables()["QMAKE_IDC"].first();
790 QString version = project->variables()["VERSION"].first();
791 if ( version.isEmpty() )
792 version = "1.0";
793
794 project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" );
795 project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" );
796 project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" );
797 if ( project->isActiveConfig( "dll" ) ) {
798 QString regcmd = "# Begin Special Build Tool\n"
799 "TargetPath=" + targetfilename + "\n"
800 "SOURCE=$(InputPath)\n"
801 "PostBuild_Desc=Finalizing ActiveQt server...\n"
802 "PostBuild_Cmds=" +
803 idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version +
804 "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"
805 "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"
806 "\t" + idc + " %1 /regserver\n"
807 "# End Special Build Tool";
808
809 QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first();
810 project->variables()["MSVCDSP_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) );
811
812 executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first();
813 project->variables()["MSVCDSP_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) );
814 } else {
815 QString regcmd = "# Begin Special Build Tool\n"
816 "TargetPath=" + targetfilename + "\n"
817 "SOURCE=$(InputPath)\n"
818 "PostBuild_Desc=Finalizing ActiveQt server...\n"
819 "PostBuild_Cmds="
820 "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version +
821 "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"
822 "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"
823 "\t%1 -regserver\n"
824 "# End Special Build Tool";
825
826 QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first();
827 project->variables()["MSVCDSP_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) );
828
829 executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first();
830 project->variables()["MSVCDSP_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) );
831 }
832
833 }
834 if ( !project->variables()["SOURCES"].isEmpty() || !project->variables()["RC_FILE"].isEmpty() ) {
835 project->variables()["SOURCES"] += project->variables()["RC_FILE"];
836 }
837 QStringList &list = project->variables()["FORMS"];
838 for( it = list.begin(); it != list.end(); ++it ) {
839 if ( QFile::exists( *it + ".h" ) )
840 project->variables()["SOURCES"].append( *it + ".h" );
841 }
842 project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS";
843}
844
845
846QString
847DspMakefileGenerator::findTemplate(QString file)
848{
849 QString ret;
850 if(!QFile::exists((ret = file)) &&
851 !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) &&
852 !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc/" + file)) &&
853 !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file))))
854 return "";
855 return ret;
856}
857
858
859void
860DspMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
861{
862 if(var == "QMAKE_PRL_DEFINES") {
863 QStringList &out = project->variables()["MSVCDSP_DEFINES"];
864 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
865 if(out.findIndex((*it)) == -1)
866 out.append((" /D \"" + *it + "\""));
867 }
868 } else {
869 MakefileGenerator::processPrlVariable(var, l);
870 }
871}
872
873
874int
875DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t,
876 QString filter)
877{
878 if(project->isActiveConfig("flat"))
879 return 0;
880
881 fileFixify(file, QDir::currentDirPath(), QDir::currentDirPath(), TRUE);
882 file = file.section(Option::dir_sep, 0, -2);
883 if(file.right(Option::dir_sep.length()) != Option::dir_sep)
884 file += Option::dir_sep;
885 if(file == currentGroup)
886 return 0;
887
888 if(file.isEmpty() || !QDir::isRelativePath(file)) {
889 endGroups(t);
890 return 0;
891 }
892 if(file.startsWith(currentGroup))
893 file = file.mid(currentGroup.length());
894 else
895 endGroups(t);
896 int lvl = file.contains(Option::dir_sep), old_lvl = currentGroup.contains(Option::dir_sep);
897 if(lvl > old_lvl) {
898 QStringList dirs = QStringList::split(Option::dir_sep, file);
899 for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
900 t << "# Begin Group \"" << (*dir_it) << "\"\n"
901 << "# Prop Default_Filter \"" << filter << "\"\n";
902 }
903 } else {
904 for(int x = old_lvl - lvl; x; x--)
905 t << "\n# End Group\n";
906 }
907 currentGroup = file;
908 return lvl - old_lvl;
909}
910
911
912int
913DspMakefileGenerator::endGroups(QTextStream &t)
914{
915 if(project->isActiveConfig("flat"))
916 return 0;
917 else if(currentGroup.isEmpty())
918 return 0;
919
920 QStringList dirs = QStringList::split(Option::dir_sep, currentGroup);
921 for(QStringList::Iterator dir_it = dirs.end(); dir_it != dirs.begin(); --dir_it) {
922 t << "\n# End Group\n";
923 }
924 currentGroup = "";
925 return dirs.count();
926}
927
928bool
929DspMakefileGenerator::openOutput(QFile &file) const
930{
931 QString outdir;
932 if(!file.name().isEmpty()) {
933 QFileInfo fi(file);
934 if(fi.isDir())
935 outdir = file.name() + QDir::separator();
936 }
937 if(!outdir.isEmpty() || file.name().isEmpty())
938 file.setName(outdir + project->first("TARGET") + project->first("DSP_EXTENSION"));
939 if(QDir::isRelativePath(file.name())) {
940 QString ofile;
941 ofile = file.name();
942 int slashfind = ofile.findRev('\\');
943 if (slashfind == -1) {
944 ofile = ofile.replace(QRegExp("-"), "_");
945 } else {
946 int hypenfind = ofile.find('-', slashfind);
947 while (hypenfind != -1 && slashfind < hypenfind) {
948 ofile = ofile.replace(hypenfind, 1, "_");
949 hypenfind = ofile.find('-', hypenfind + 1);
950 }
951 }
952 file.setName(Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + ofile));
953 }
954 return Win32MakefileGenerator::openOutput(file);
955}
diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h
new file mode 100644
index 0000000..a7fc3e7
--- a/dev/null
+++ b/qmake/generators/win32/msvc_dsp.h
@@ -0,0 +1,73 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __DSPMAKE_H__
38#define __DSPMAKE_H__
39
40#include "winmakefile.h"
41#include <qvaluestack.h>
42
43class DspMakefileGenerator : public Win32MakefileGenerator
44{
45 QString currentGroup;
46 int beginGroupForFile(QString file, QTextStream &, const QString filter="");
47 int endGroups(QTextStream &);
48
49 bool init_flag;
50 bool writeDspParts(QTextStream &);
51
52 bool writeMakefile(QTextStream &);
53 QString findTemplate(QString file);
54 void init();
55
56public:
57 DspMakefileGenerator(QMakeProject *p);
58 ~DspMakefileGenerator();
59
60 bool openOutput(QFile &file) const;
61
62protected:
63 virtual void processPrlVariable(const QString &, const QStringList &);
64 virtual bool findLibraries();
65};
66
67inline DspMakefileGenerator::~DspMakefileGenerator()
68{ }
69
70inline bool DspMakefileGenerator::findLibraries()
71{ return Win32MakefileGenerator::findLibraries("MSVCDSP_LIBS"); }
72
73#endif /* __DSPMAKE_H__ */
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
new file mode 100644
index 0000000..9cc9a69
--- a/dev/null
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -0,0 +1,488 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "msvc_nmake.h"
39#include "option.h"
40#include <qregexp.h>
41#include <qdir.h>
42#include <stdlib.h>
43#include <time.h>
44
45
46NmakeMakefileGenerator::NmakeMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
47{
48
49}
50
51bool
52NmakeMakefileGenerator::writeMakefile(QTextStream &t)
53{
54 writeHeader(t);
55 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
56 t << "all clean:" << "\n\t"
57 << "@echo \"Some of the required modules ("
58 << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
59 << "@echo \"Skipped.\"" << endl << endl;
60 writeMakeQmake(t);
61 return TRUE;
62 }
63
64 if(project->first("TEMPLATE") == "app" ||
65 project->first("TEMPLATE") == "lib") {
66 writeNmakeParts(t);
67 return MakefileGenerator::writeMakefile(t);
68 }
69 else if(project->first("TEMPLATE") == "subdirs") {
70 writeSubDirs(t);
71 return TRUE;
72 }
73 return FALSE;
74}
75
76void
77NmakeMakefileGenerator::writeNmakeParts(QTextStream &t)
78{
79 t << "####### Compiler, tools and options" << endl << endl;
80 t << "CC =" << var("QMAKE_CC") << endl;
81 t << "CXX =" << var("QMAKE_CXX") << endl;
82 t << "LEX = " << var("QMAKE_LEX") << endl;
83 t << "YACC = " << var("QMAKE_YACC") << endl;
84 t << "CFLAGS =" << var("QMAKE_CFLAGS") << " "
85 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
86 << varGlue("DEFINES","-D"," -D","") << endl;
87 t << "CXXFLAGS =" << var("QMAKE_CXXFLAGS") << " "
88 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
89 << varGlue("DEFINES","-D"," -D","") << endl;
90 t << "LEXFLAGS=" << var("QMAKE_LEXFLAGS") << endl;
91 t << "YACCFLAGS=" << var("QMAKE_YACCFLAGS") << endl;
92
93 t << "INCPATH =";
94 QStringList &incs = project->variables()["INCLUDEPATH"];
95 for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
96 QString inc = (*incit);
97 inc.replace(QRegExp("\\\\$"), "\\\\");
98 inc.replace("\"", "");
99 t << " -I\"" << inc << "\"";
100 }
101 t << " -I\"" << specdir() << "\""
102 << endl;
103 if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
104 t << "LINK =" << var("QMAKE_LINK") << endl;
105 t << "LFLAGS =" << var("QMAKE_LFLAGS");
106 if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
107 t << " " << varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\"");
108 t << endl;
109 t << "LIBS =";
110 QStringList &libs = project->variables()["QMAKE_LIBS"];
111 for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) {
112 QString lib = (*libit);
113 lib.replace(QRegExp("\\\\$"), "\\\\");
114 lib.replace(QRegExp("\""), "");
115 t << " \"" << lib << "\"";
116 }
117 t << endl;
118 }
119 else {
120 t << "LIB =" << var("QMAKE_LIB") << endl;
121 }
122 t << "MOC =" << (project->isEmpty("QMAKE_MOC") ? QString("moc") :
123 Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl;
124 t << "UIC =" << (project->isEmpty("QMAKE_UIC") ? QString("uic") :
125 Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl;
126 t << "QMAKE =" << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
127 Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl;
128 t << "IDC =" << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
129 Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl;
130 t << "IDL =" << (project->isEmpty("QMAKE_IDL") ? QString("midl") :
131 Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl;
132 t << "ZIP =" << var("QMAKE_ZIP") << endl;
133 t << "COPY_FILE= " << var("QMAKE_COPY") << endl;
134 t << "COPY_DIR= " << var("QMAKE_COPY") << endl;
135 t << "DEL_FILE= " << var("QMAKE_DEL_FILE") << endl;
136 t << "DEL_DIR= " << var("QMAKE_DEL_DIR") << endl;
137 t << "MOVE = " << var("QMAKE_MOVE") << endl;
138 t << endl;
139
140 t << "####### Files" << endl << endl;
141 t << "HEADERS =" << varList("HEADERS") << endl;
142 t << "SOURCES =" << varList("SOURCES") << endl;
143 t << "OBJECTS =" << varList("OBJECTS") << endl;
144 t << "FORMS =" << varList("FORMS") << endl;
145 t << "UICDECLS =" << varList("UICDECLS") << endl;
146 t << "UICIMPLS =" << varList("UICIMPLS") << endl;
147 t << "SRCMOC =" << varList("SRCMOC") << endl;
148 t << "OBJMOC =" << varList("OBJMOC") << endl;
149 t << "DIST =" << varList("DISTFILES") << endl;
150 t << "TARGET =";
151 if( !project->variables()[ "DESTDIR" ].isEmpty() )
152 t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT"));
153 else
154 t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
155 t << endl;
156 t << endl;
157
158 t << "####### Implicit rules" << endl << endl;
159 t << ".SUFFIXES: .cpp .cxx .cc .c" << endl << endl;
160 t << ".cpp.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
161 t << ".cxx.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
162 t << ".cc.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
163 t << ".c.obj:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
164
165 t << "####### Build rules" << endl << endl;
166 t << "all: " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl;
167 t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS");
168 if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
169 t << "\n\t" << "$(LINK) $(LFLAGS) /OUT:$(TARGET) @<< " << "\n\t "
170 << "$(OBJECTS) $(OBJMOC) $(LIBS)";
171 } else {
172 t << "\n\t" << "$(LIB) /OUT:$(TARGET) @<<" << "\n\t "
173 << "$(OBJECTS) $(OBJMOC)";
174 }
175 t << endl << "<<" << endl;
176 if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) {
177 QStringList dlldirs = project->variables()["DLLDESTDIR"];
178 for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
179 t << "\n\t" << "-copy $(TARGET) " << *dlldir;
180 }
181 }
182 QString targetfilename = project->variables()["TARGET"].first();
183 if(project->isActiveConfig("activeqt")) {
184 QString version = project->variables()["VERSION"].first();
185 if ( version.isEmpty() )
186 version = "1.0";
187
188 if ( project->isActiveConfig("dll")) {
189 t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version);
190 t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
191 t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
192 t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" );
193 } else {
194 t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version);
195 t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
196 t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
197 t << "\n\t" << "-$(TARGET) -regserver";
198 }
199 }
200 t << endl << endl;
201
202 if(!project->variables()["RC_FILE"].isEmpty()) {
203 t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t"
204 << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl;
205 }
206
207 t << "mocables: $(SRCMOC)" << endl << endl;
208
209 writeMakeQmake(t);
210
211 t << "dist:" << "\n\t"
212 << "$(ZIP) " << var("PROJECT") << ".zip "
213 << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl;
214
215 t << "clean:"
216 << varGlue("OBJECTS","\n\t-del ","\n\t-del ","")
217 << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","")
218 << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","")
219 << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","")
220 << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","")
221 << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","")
222 << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ","");
223 if ( project->isActiveConfig("activeqt")) {
224 t << ("\n\t-del tmp\\" + targetfilename + ".*");
225 t << "\n\t-del tmp\\dump.*";
226 }
227 if(!project->isEmpty("IMAGES"))
228 t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", "");
229
230 // blasted user defined targets
231 QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
232 for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
233 QString targ = var((*it) + ".target"),
234 cmd = var((*it) + ".commands"), deps;
235 if(targ.isEmpty())
236 targ = (*it);
237 QStringList &deplist = project->variables()[(*it) + ".depends"];
238 for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
239 QString dep = var((*dep_it) + ".target");
240 if(dep.isEmpty())
241 dep = (*dep_it);
242 deps += " " + dep;
243 }
244 t << "\n\n" << targ << ":" << deps << "\n\t"
245 << cmd;
246 }
247
248 t << endl << endl;
249}
250
251
252void
253NmakeMakefileGenerator::init()
254{
255 if(init_flag)
256 return;
257 init_flag = TRUE;
258
259 /* this should probably not be here, but I'm using it to wrap the .t files */
260 if(project->first("TEMPLATE") == "app")
261 project->variables()["QMAKE_APP_FLAG"].append("1");
262 else if(project->first("TEMPLATE") == "lib")
263 project->variables()["QMAKE_LIB_FLAG"].append("1");
264 else if(project->first("TEMPLATE") == "subdirs") {
265 MakefileGenerator::init();
266 if(project->variables()["MAKEFILE"].isEmpty())
267 project->variables()["MAKEFILE"].append("Makefile");
268 if(project->variables()["QMAKE"].isEmpty())
269 project->variables()["QMAKE"].append("qmake");
270 return;
271 }
272
273 bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX);
274 project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
275
276 QString targetfilename = project->variables()["TARGET"].first();
277 QStringList &configs = project->variables()["CONFIG"];
278 if (project->isActiveConfig("qt") && project->isActiveConfig("shared"))
279 project->variables()["DEFINES"].append("QT_DLL");
280 if (project->isActiveConfig("qt_dll"))
281 if(configs.findIndex("qt") == -1) configs.append("qt");
282 if ( project->isActiveConfig("qt") ) {
283 if ( project->isActiveConfig( "plugin" ) ) {
284 project->variables()["CONFIG"].append("dll");
285 if(project->isActiveConfig("qt"))
286 project->variables()["DEFINES"].append("QT_PLUGIN");
287 }
288 if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
289 ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
290 project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
291 (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
292 project->variables()["QMAKE_QT_DLL"].append("1");
293 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
294 project->variables()["CONFIG"].append("dll");
295 }
296 if ( project->isActiveConfig("thread") )
297 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
298 if ( project->isActiveConfig("accessibility" ) )
299 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
300 if ( project->isActiveConfig("tablet") )
301 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
302 }
303 if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
304 project->variables()["CONFIG"].remove("staticlib");
305 project->variables()["QMAKE_APP_OR_DLL"].append("1");
306 } else {
307 project->variables()["CONFIG"].append("staticlib");
308 }
309 if ( project->isActiveConfig("warn_off") ) {
310 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
311 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
312 } else if ( project->isActiveConfig("warn_on") ) {
313 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
314 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
315 }
316 if ( project->isActiveConfig("debug") ) {
317 if ( project->isActiveConfig("thread") ) {
318 // use the DLL RT even here
319 if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
320 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"];
321 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
322 } else {
323 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"];
324 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
325 }
326 }
327 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
328 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
329 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
330 } else {
331 if ( project->isActiveConfig("thread") ) {
332 if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
333 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"];
334 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
335 } else {
336 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"];
337 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"];
338 }
339 }
340 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
341 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
342 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
343 }
344 if ( project->isActiveConfig("thread") && !project->variables()["DEFINES"].contains("QT_DLL")
345 && !is_qt && project->first("TARGET") != "qtmain") {
346 project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:\"libc\"");
347 }
348
349 if ( !project->variables()["QMAKE_INCDIR"].isEmpty())
350 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
351 if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") )
352 project->variables()["CONFIG"].append("windows");
353 if ( project->isActiveConfig("qt") ) {
354 project->variables()["CONFIG"].append("moc");
355 project->variables()["INCLUDEPATH"] +=project->variables()["QMAKE_INCDIR_QT"];
356 project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
357 if ( !project->isActiveConfig("debug") )
358 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
359 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
360 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) {
361 project->variables()["DEFINES"].append("QT_MAKEDLL");
362 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"];
363 }
364 } else {
365 if(project->isActiveConfig("thread"))
366 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
367 else
368 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
369 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
370 int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
371 if ( hver == -1 )
372 hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
373 if(hver != -1) {
374 QString ver;
375 ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
376 QStringList &libs = project->variables()["QMAKE_LIBS"];
377 for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
378 (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
379 }
380 }
381 if ( project->isActiveConfig( "activeqt" ) ) {
382 project->variables().remove("QMAKE_LIBS_QT_ENTRY");
383 project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
384 if ( project->isActiveConfig( "dll" ) )
385 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
386 }
387 if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
388 project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
389 }
390 }
391 }
392 if ( project->isActiveConfig("opengl") ) {
393 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
394 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
395 }
396 if ( project->isActiveConfig("dll") ) {
397 project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"];
398 project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"];
399 project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"];
400 project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"];
401 if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) {
402 project->variables()["TARGET_EXT"].append(
403 QStringList::split('.',project->first("VERSION")).join("") + ".dll");
404 } else {
405 project->variables()["TARGET_EXT"].append(".dll");
406 }
407 } else {
408 project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"];
409 project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"];
410 project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"];
411 project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"];
412 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
413 project->variables()["TARGET_EXT"].append(".exe");
414 } else {
415 project->variables()["TARGET_EXT"].append(".lib");
416 }
417 }
418 if ( project->isActiveConfig("windows") ) {
419 if ( project->isActiveConfig("console") ) {
420 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
421 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
422 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
423 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
424 } else {
425 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"];
426 }
427 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
428 } else {
429 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
430 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
431 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
432 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
433 }
434
435 if ( project->isActiveConfig("moc") )
436 setMocAware(TRUE);
437 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
438 project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
439 "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
440 QStringList &l = project->variables()["QMAKE_FILETAGS"];
441 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
442 QStringList &gdmf = project->variables()[(*it)];
443 for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
444 (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
445 }
446
447 if ( !project->variables()["DEF_FILE"].isEmpty() )
448 project->variables()["QMAKE_LFLAGS"].append(QString("/DEF:") + project->first("DEF_FILE"));
449 if(!project->isActiveConfig("incremental"))
450 project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
451
452 if ( !project->variables()["VERSION"].isEmpty() ) {
453 QString version = project->variables()["VERSION"][0];
454 int firstDot = version.find( "." );
455 QString major = version.left( firstDot );
456 QString minor = version.right( version.length() - firstDot - 1 );
457 minor.replace( ".", "" );
458 project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor );
459 }
460 if ( !project->variables()["RC_FILE"].isEmpty()) {
461 if ( !project->variables()["RES_FILE"].isEmpty()) {
462 fprintf(stderr, "Both .rc and .res file specified.\n");
463 fprintf(stderr, "Please specify one of them, not both.");
464 exit(666);
465 }
466 project->variables()["RES_FILE"] = project->variables()["RC_FILE"];
467 project->variables()["RES_FILE"].first().replace(".rc",".res");
468 project->variables()["TARGETDEPS"] += project->variables()["RES_FILE"];
469 }
470 if ( !project->variables()["RES_FILE"].isEmpty())
471 project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"];
472
473 MakefileGenerator::init();
474 if ( !project->variables()["VERSION"].isEmpty()) {
475 QStringList l = QStringList::split('.', project->first("VERSION"));
476 project->variables()["VER_MAJ"].append(l[0]);
477 project->variables()["VER_MIN"].append(l[1]);
478 }
479 if(project->isActiveConfig("dll")) {
480 project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".lib");
481 project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".exp");
482 }
483 if(project->isActiveConfig("debug")) {
484 project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".pdb");
485 project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".ilk");
486 project->variables()["QMAKE_CLEAN"].append("vc*.pdb");
487 }
488}
diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h
new file mode 100644
index 0000000..d3e170f
--- a/dev/null
+++ b/qmake/generators/win32/msvc_nmake.h
@@ -0,0 +1,59 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __NMAKEMAKE_H__
38#define __NMAKEMAKE_H__
39
40#include "winmakefile.h"
41
42class NmakeMakefileGenerator : public Win32MakefileGenerator
43{
44 bool init_flag;
45 void writeNmakeParts(QTextStream &);
46
47 bool writeMakefile(QTextStream &);
48 void init();
49
50public:
51 NmakeMakefileGenerator(QMakeProject *p);
52 ~NmakeMakefileGenerator();
53
54};
55
56inline NmakeMakefileGenerator::~NmakeMakefileGenerator()
57{ }
58
59#endif /* __NMAKEMAKE_H__ */
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
new file mode 100644
index 0000000..c2b9e30
--- a/dev/null
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -0,0 +1,1955 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Copyright (C) 2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the network 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 licenses may use this
20** file in accordance with the Qt Commercial License Agreement provided
21** 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 "msvc_objectmodel.h"
37#include "msvc_vcproj.h"
38#include <qtextstream.h>
39#include <qstringlist.h>
40#include <quuid.h>
41
42#if defined(Q_OS_WIN32)
43#include <objbase.h>
44#ifndef GUID_DEFINED
45#define GUID_DEFINED
46typedef struct _GUID
47{
48 ulong Data1;
49 ushort Data2;
50 ushort Data3;
51 uchar Data4[8];
52} GUID;
53#endif
54#endif
55
56// XML Tags ---------------------------------------------------------
57 const char* _xmlInit = "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>";
58 const char* _begConfiguration = "\n\t\t<Configuration";
59 const char* _begConfigurations = "\n\t<Configurations>";
60 const char* _begFile = "\n\t\t\t<File";
61 const char* _begFileConfiguration = "\n\t\t\t\t<FileConfiguration";
62 const char* _begFiles = "\n\t<Files>";
63 const char* _begFilter = "\n\t\t<Filter";
64 const char* _begGlobals = "\n\t<Globals>";
65 const char* _begPlatform = "\n\t\t<Platform";
66 const char* _begPlatforms = "\n\t<Platforms>";
67 const char* _begTool3 = "\n\t\t\t<Tool";
68 const char* _begTool5 = "\n\t\t\t\t\t<Tool";
69 const char* _begVisualStudioProject = "\n<VisualStudioProject";
70 const char* _endConfiguration = "\n\t\t</Configuration>";
71 const char* _endConfigurations = "\n\t</Configurations>";
72 const char* _endFile = "\n\t\t\t</File>";
73 const char* _endFileConfiguration = "\n\t\t\t\t</FileConfiguration>";
74 const char* _endFiles = "\n\t</Files>";
75 const char* _endFilter = "\n\t\t</Filter>";
76 const char* _endGlobals = "\n\t</Globals>";
77 const char* _endPlatforms = "\n\t</Platforms>";
78 const char* _endVisualStudioProject = "\n</VisualStudioProject>";
79
80// XML Properties ---------------------------------------------------
81 const char* _AddModuleNamesToAssembly = "\n\t\t\t\tAddModuleNamesToAssembly=\"";
82 const char* _AdditionalDependencies4 = "\n\t\t\t\tAdditionalDependencies=\"";
83 const char* _AdditionalDependencies6 = "\n\t\t\t\t\t\tAdditionalDependencies=\"";
84 const char* _AdditionalIncludeDirectories = "\n\t\t\t\tAdditionalIncludeDirectories=\"";
85 const char* _AdditionalLibraryDirectories = "\n\t\t\t\tAdditionalLibraryDirectories=\"";
86 const char* _AdditionalOptions = "\n\t\t\t\tAdditionalOptions=\"";
87 const char* _AdditionalUsingDirectories = "\n\t\t\t\tAdditionalUsingDirectories=\"";
88 const char* _AssemblerListingLocation = "\n\t\t\t\tAssemblerListingLocation=\"";
89 const char* _AssemblerOutput = "\n\t\t\t\tAssemblerOutput=\"";
90 const char* _ATLMinimizesCRunTimeLibraryUsage= "\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\"";
91 const char* _BaseAddress = "\n\t\t\t\tBaseAddress=\"";
92 const char* _BasicRuntimeChecks = "\n\t\t\t\tBasicRuntimeChecks=\"";
93 const char* _BrowseInformation = "\n\t\t\t\tBrowseInformation=\"";
94 const char* _BrowseInformationFile = "\n\t\t\t\tBrowseInformationFile=\"";
95 const char* _BufferSecurityCheck = "\n\t\t\t\tBufferSecurityCheck=\"";
96 const char* _BuildBrowserInformation = "\n\t\t\tBuildBrowserInformation=\"";
97 const char* _CPreprocessOptions = "\n\t\t\t\tCPreprocessOptions=\"";
98 const char* _CallingConvention = "\n\t\t\t\tCallingConvention=\"";
99 const char* _CharacterSet = "\n\t\t\tCharacterSet=\"";
100 const char* _CommandLine4 = "\n\t\t\t\tCommandLine=\"";
101 const char* _CommandLine6 = "\n\t\t\t\t\t\tCommandLine=\"";
102 const char* _CompileAs = "\n\t\t\t\tCompileAs=\"";
103 const char* _CompileAsManaged = "\n\t\t\t\tCompileAsManaged=\"";
104 const char* _CompileOnly = "\n\t\t\t\tCompileOnly=\"";
105 const char* _ConfigurationType = "\n\t\t\tConfigurationType=\"";
106 const char* _Culture = "\n\t\t\t\tCulture=\"";
107 const char* _DLLDataFileName = "\n\t\t\t\tDLLDataFileName=\"";
108 const char* _DebugInformationFormat = "\n\t\t\t\tDebugInformationFormat=\"";
109 const char* _DefaultCharIsUnsigned = "\n\t\t\t\tDefaultCharIsUnsigned=\"";
110 const char* _DefaultCharType = "\n\t\t\t\tDefaultCharType=\"";
111 const char* _DelayLoadDLLs = "\n\t\t\t\tDelayLoadDLLs=\"";
112 const char* _DeleteExtensionsOnClean = "\n\t\t\tDeleteExtensionsOnClean=\"";
113 const char* _Description4 = "\n\t\t\t\tDescription=\"";
114 const char* _Description6 = "\n\t\t\t\t\t\tDescription=\"";
115 const char* _Detect64BitPortabilityProblems = "\n\t\t\t\tDetect64BitPortabilityProblems=\"";
116 const char* _DisableLanguageExtensions = "\n\t\t\t\tDisableLanguageExtensions=\"";
117 const char* _DisableSpecificWarnings = "\n\t\t\t\tDisableSpecificWarnings=\"";
118 const char* _EnableCOMDATFolding = "\n\t\t\t\tEnableCOMDATFolding=\"";
119 const char* _EnableErrorChecks = "\n\t\t\t\tEnableErrorChecks=\"";
120 const char* _EnableFiberSafeOptimizations = "\n\t\t\t\tEnableFiberSafeOptimizations=\"";
121 const char* _EnableFunctionLevelLinking = "\n\t\t\t\tEnableFunctionLevelLinking=\"";
122 const char* _EnableIntrinsicFunctions = "\n\t\t\t\tEnableIntrinsicFunctions=\"";
123 const char* _EntryPointSymbol = "\n\t\t\t\tEntryPointSymbol=\"";
124 const char* _ErrorCheckAllocations = "\n\t\t\t\tErrorCheckAllocations=\"";
125 const char* _ErrorCheckBounds = "\n\t\t\t\tErrorCheckBounds=\"";
126 const char* _ErrorCheckEnumRange = "\n\t\t\t\tErrorCheckEnumRange=\"";
127 const char* _ErrorCheckRefPointers = "\n\t\t\t\tErrorCheckRefPointers=\"";
128 const char* _ErrorCheckStubData = "\n\t\t\t\tErrorCheckStubData=\"";
129 const char* _ExceptionHandling = "\n\t\t\t\tExceptionHandling=\"";
130 const char* _ExcludedFromBuild = "\n\t\t\t\tExcludedFromBuild=\"";
131 const char* _ExpandAttributedSource = "\n\t\t\t\tExpandAttributedSource=\"";
132 const char* _ExportNamedFunctions = "\n\t\t\t\tExportNamedFunctions=\"";
133 const char* _FavorSizeOrSpeed = "\n\t\t\t\tFavorSizeOrSpeed=\"";
134 const char* _Filter = "\n\t\t\tFilter=\"";
135 const char* _ForceConformanceInForLoopScope = "\n\t\t\t\tForceConformanceInForLoopScope=\"";
136 const char* _ForceSymbolReferences = "\n\t\t\t\tForceSymbolReferences=\"";
137 const char* _ForcedIncludeFiles = "\n\t\t\t\tForcedIncludeFiles=\"";
138 const char* _ForcedUsingFiles = "\n\t\t\t\tForcedUsingFiles=\"";
139 const char* _FullIncludePath = "\n\t\t\t\tFullIncludePath=\"";
140 const char* _FunctionOrder = "\n\t\t\t\tFunctionOrder=\"";
141 const char* _GenerateDebugInformation = "\n\t\t\t\tGenerateDebugInformation=\"";
142 const char* _GenerateMapFile = "\n\t\t\t\tGenerateMapFile=\"";
143 const char* _GeneratePreprocessedFile = "\n\t\t\t\tGeneratePreprocessedFile=\"";
144 const char* _GenerateStublessProxies = "\n\t\t\t\tGenerateStublessProxies=\"";
145 const char* _GenerateTypeLibrary = "\n\t\t\t\tGenerateTypeLibrary=\"";
146 const char* _GlobalOptimizations = "\n\t\t\t\tGlobalOptimizations=\"";
147 const char* _HeaderFileName = "\n\t\t\t\tHeaderFileName=\"";
148 const char* _HeapCommitSize = "\n\t\t\t\tHeapCommitSize=\"";
149 const char* _HeapReserveSize = "\n\t\t\t\tHeapReserveSize=\"";
150 const char* _IgnoreAllDefaultLibraries = "\n\t\t\t\tIgnoreAllDefaultLibraries=\"";
151 const char* _IgnoreDefaultLibraryNames = "\n\t\t\t\tIgnoreDefaultLibraryNames=\"";
152 const char* _IgnoreEmbeddedIDL = "\n\t\t\t\tIgnoreEmbeddedIDL=\"";
153 const char* _IgnoreImportLibrary = "\n\t\t\t\tIgnoreImportLibrary=\"";
154 const char* _IgnoreStandardIncludePath = "\n\t\t\t\tIgnoreStandardIncludePath=\"";
155 const char* _ImportLibrary = "\n\t\t\t\tImportLibrary=\"";
156 const char* _ImproveFloatingPointConsistency = "\n\t\t\t\tImproveFloatingPointConsistency=\"";
157 const char* _InlineFunctionExpansion = "\n\t\t\t\tInlineFunctionExpansion=\"";
158 const char* _InterfaceIdentifierFileName = "\n\t\t\t\tInterfaceIdentifierFileName=\"";
159 const char* _IntermediateDirectory = "\n\t\t\tIntermediateDirectory=\"";
160 const char* _KeepComments = "\n\t\t\t\tKeepComments=\"";
161 const char* _LargeAddressAware = "\n\t\t\t\tLargeAddressAware=\"";
162 const char* _LinkDLL = "\n\t\t\t\tLinkDLL=\"";
163 const char* _LinkIncremental = "\n\t\t\t\tLinkIncremental=\"";
164 const char* _LinkTimeCodeGeneration = "\n\t\t\t\tLinkTimeCodeGeneration=\"";
165 const char* _LinkToManagedResourceFile = "\n\t\t\t\tLinkToManagedResourceFile=\"";
166 const char* _MapExports = "\n\t\t\t\tMapExports=\"";
167 const char* _MapFileName = "\n\t\t\t\tMapFileName=\"";
168 const char* _MapLines = "\n\t\t\t\tMapLines =\"";
169 const char* _MergeSections = "\n\t\t\t\tMergeSections=\"";
170 const char* _MergedIDLBaseFileName = "\n\t\t\t\tMergedIDLBaseFileName=\"";
171 const char* _MidlCommandFile = "\n\t\t\t\tMidlCommandFile=\"";
172 const char* _MinimalRebuild = "\n\t\t\t\tMinimalRebuild=\"";
173 const char* _MkTypLibCompatible = "\n\t\t\t\tMkTypLibCompatible=\"";
174 const char* _ModuleDefinitionFile = "\n\t\t\t\tModuleDefinitionFile=\"";
175 const char* _Name1 = "\n\tName=\"";
176 const char* _Name2 = "\n\t\tName=\"";
177 const char* _Name3 = "\n\t\t\tName=\"";
178 const char* _Name4 = "\n\t\t\t\tName=\"";
179 const char* _Name5 = "\n\t\t\t\t\tName=\"";
180 const char* _ObjectFile = "\n\t\t\t\tObjectFile=\"";
181 const char* _OmitFramePointers = "\n\t\t\t\tOmitFramePointers=\"";
182 const char* _Optimization = "\n\t\t\t\tOptimization =\"";
183 const char* _OptimizeForProcessor = "\n\t\t\t\tOptimizeForProcessor=\"";
184 const char* _OptimizeForWindows98 = "\n\t\t\t\tOptimizeForWindows98=\"";
185 const char* _OptimizeForWindowsApplication = "\n\t\t\t\tOptimizeForWindowsApplication=\"";
186 const char* _OptimizeReferences = "\n\t\t\t\tOptimizeReferences=\"";
187 const char* _OutputDirectory3 = "\n\t\t\tOutputDirectory=\"";
188 const char* _OutputDirectory4 = "\n\t\t\t\tOutputDirectory=\"";
189 const char* _OutputFile = "\n\t\t\t\tOutputFile=\"";
190 const char* _Outputs4 = "\n\t\t\t\tOutputs=\"";
191 const char* _Outputs6 = "\n\t\t\t\t\t\tOutputs=\"";
192 const char* _ParseFiles = "\n\t\t\tParseFiles=\"";
193 const char* _PrecompiledHeaderFile = "\n\t\t\t\tPrecompiledHeaderFile=\"";
194 const char* _PrecompiledHeaderThrough = "\n\t\t\t\tPrecompiledHeaderThrough=\"";
195 const char* _PreprocessorDefinitions = "\n\t\t\t\tPreprocessorDefinitions=\"";
196 const char* _PrimaryOutput = "\n\t\t\tPrimaryOutput=\"";
197 const char* _ProjectGUID = "\n\tProjectGUID=\"";
198 const char* _ProjectType = "\n\tProjectType=\"Visual C++\"";
199 const char* _ProgramDatabase = "\n\t\t\tProgramDatabase=\"";
200 const char* _ProgramDataBaseFileName = "\n\t\t\t\tProgramDataBaseFileName=\"";
201 const char* _ProgramDatabaseFile = "\n\t\t\t\tProgramDatabaseFile=\"";
202 const char* _ProxyFileName = "\n\t\t\t\tProxyFileName=\"";
203 const char* _RedirectOutputAndErrors = "\n\t\t\t\tRedirectOutputAndErrors=\"";
204 const char* _RegisterOutput = "\n\t\t\t\tRegisterOutput=\"";
205 const char* _RelativePath = "\n\t\t\t\tRelativePath=\"";
206 const char* _ResourceOnlyDLL = "\n\t\t\t\tResourceOnlyDLL=\"";
207 const char* _ResourceOutputFileName = "\n\t\t\t\tResourceOutputFileName=\"";
208 const char* _RuntimeLibrary = "\n\t\t\t\tRuntimeLibrary=\"";
209 const char* _RuntimeTypeInfo = "\n\t\t\t\tRuntimeTypeInfo=\"";
210 const char* _SccProjectName = "\n\tSccProjectName=\"";
211 const char* _SccLocalPath = "\n\tSccLocalPath=\"";
212 const char* _SetChecksum = "\n\t\t\t\tSetChecksum=\"";
213 const char* _ShowIncludes = "\n\t\t\t\tShowIncludes=\"";
214 const char* _ShowProgress = "\n\t\t\t\tShowProgress=\"";
215 const char* _SmallerTypeCheck = "\n\t\t\t\tSmallerTypeCheck=\"";
216 const char* _StackCommitSize = "\n\t\t\t\tStackCommitSize=\"";
217 const char* _StackReserveSize = "\n\t\t\t\tStackReserveSize=\"";
218 const char* _StringPooling = "\n\t\t\t\tStringPooling=\"";
219 const char* _StripPrivateSymbols = "\n\t\t\t\tStripPrivateSymbols=\"";
220 const char* _StructMemberAlignment = "\n\t\t\t\tStructMemberAlignment=\"";
221 const char* _SubSystem = "\n\t\t\t\tSubSystem=\"";
222 const char* _SupportUnloadOfDelayLoadedDLL = "\n\t\t\t\tSupportUnloadOfDelayLoadedDLL=\"";
223 const char* _SuppressStartupBanner = "\n\t\t\t\tSuppressStartupBanner=\"";
224 const char* _SwapRunFromCD = "\n\t\t\t\tSwapRunFromCD=\"";
225 const char* _SwapRunFromNet = "\n\t\t\t\tSwapRunFromNet=\"";
226 const char* _TargetEnvironment = "\n\t\t\t\tTargetEnvironment=\"";
227 const char* _TargetMachine = "\n\t\t\t\tTargetMachine=\"";
228 const char* _TerminalServerAware = "\n\t\t\t\tTerminalServerAware=\"";
229 const char* _ToolName = "\n\t\t\t\tName=\"";
230 const char* _ToolPath = "\n\t\t\t\tPath=\"";
231 const char* _TreatWChar_tAsBuiltInType = "\n\t\t\t\tTreatWChar_tAsBuiltInType=\"";
232 const char* _TurnOffAssemblyGeneration = "\n\t\t\t\tTurnOffAssemblyGeneration=\"";
233 const char* _TypeLibraryFile = "\n\t\t\t\tTypeLibraryFile=\"";
234 const char* _TypeLibraryName = "\n\t\t\t\tTypeLibraryName=\"";
235 const char* _TypeLibraryResourceID = "\n\t\t\t\tTypeLibraryResourceID=\"";
236const char* _UndefineAllPreprocessorDefinitions = "\n\t\t\t\tUndefineAllPreprocessorDefinitions=\"";
237 const char* _UndefinePreprocessorDefinitions = "\n\t\t\t\tUndefinePreprocessorDefinitions=\"";
238 const char* _UseOfATL = "\n\t\t\tUseOfATL=\"";
239 const char* _UseOfMfc = "\n\t\t\tUseOfMfc=\"";
240 const char* _UsePrecompiledHeader = "\n\t\t\t\tUsePrecompiledHeader=\"";
241 const char* _ValidateParameters = "\n\t\t\t\tValidateParameters=\"";
242 const char* _VCCLCompilerToolName = "\n\t\t\t\tName=\"VCCLCompilerTool\"";
243 const char* _VCCustomBuildTool = "\n\t\t\t\t\t\tName=\"VCCustomBuildTool\"";
244 const char* _VCLinkerToolName = "\n\t\t\t\tName=\"VCLinkerTool\"";
245 const char* _VCResourceCompilerToolName = "\n\t\t\t\tName=\"VCResourceCompilerTool\"";
246 const char* _VCMIDLToolName = "\n\t\t\t\tName=\"VCMIDLTool\"";
247 const char* _Version1 = "\n\tVersion=\"";
248 const char* _Version4 = "\n\t\t\t\tVersion=\"";
249 const char* _WarnAsError = "\n\t\t\t\tWarnAsError=\"";
250 const char* _WarnLevel = "\n\t\t\t\tWarnLevel=\"";
251 const char* _WarningLevel = "\n\t\t\t\tWarningLevel=\"";
252 const char* _WholeProgramOptimization = "\n\t\t\t\tWholeProgramOptimization=\"";
253
254// Property name and value as Pairs ---------------------------------
255struct TPair {
256 TPair( const char* n, const triState v ) : name(n), value(v) {};
257 const char* name;
258 const triState value;
259};
260struct EPair {
261 EPair( const char* n, const int v ) : name(n), value(v) {};
262 const char* name;
263 const int value;
264};
265struct LPair {
266 LPair( const char* n, const long v ) : name(n), value(v) {};
267 const char* name;
268 const long value;
269};
270struct SPair {
271 SPair( const char* n, const QString& v ) : name(n), value(v) {};
272 const char* name;
273 const QString& value;
274};
275struct XPair {
276 XPair( const char* n, const QStringList& v, const char* s = "," ) : name(n), value(v), sep(s) {};
277 const char* name;
278 const QStringList& value;
279 const char* sep;
280};
281
282// void streamSPair( QTextStream &strm, const char *n, const QString &s )
283
284
285// Streaming operators for property Pairs ---------------------------
286QTextStream &operator<<( QTextStream &strm, const TPair &prop )
287{
288 switch( prop.value ) {
289 case _False:
290 strm << prop.name << "FALSE\"";
291 break;
292 case _True:
293 strm << prop.name << "TRUE\"";
294 break;
295 case unset:
296 default:
297 break;
298 }
299 return strm;
300}
301
302/* Be sure to check that each enum is not set to
303 default before streaming it out. Defaults seem
304 to not be in the XML file.
305*/
306QTextStream &operator<<( QTextStream &strm, const EPair &prop )
307{
308 strm << prop.name << prop.value << "\"";
309 return strm;
310}
311
312QTextStream &operator<<( QTextStream &strm, const LPair &prop )
313{
314 strm << prop.name << prop.value << "\"";
315 return strm;
316}
317
318QTextStream &operator<<( QTextStream &strm, const SPair &prop )
319{
320 if ( !prop.value.isEmpty() )
321 strm << prop.name << prop.value.latin1() << "\"";
322 return strm;
323}
324
325QTextStream &operator<<( QTextStream &strm, const XPair &prop )
326{
327 if ( !prop.value.isEmpty() )
328 strm << prop.name << prop.value.join(prop.sep).latin1() << "\"";
329 return strm;
330}
331
332// VCCLCompilerTool -------------------------------------------------
333VCCLCompilerTool::VCCLCompilerTool()
334 :AssemblerOutput( asmListingNone ),
335 BasicRuntimeChecks( runtimeBasicCheckNone ),
336 BrowseInformation( brInfoNone ),
337 BufferSecurityCheck( unset ),
338 CallingConvention( callConventionDefault ),
339 CompileAs( compileAsDefault ),
340 CompileAsManaged( managedDefault ),
341 CompileOnly( unset ),
342 DebugInformationFormat( debugDisabled ),
343 DefaultCharIsUnsigned( unset ),
344 Detect64BitPortabilityProblems( unset ),
345 DisableLanguageExtensions( unset ),
346 EnableFiberSafeOptimizations( unset ),
347 EnableFunctionLevelLinking( unset ),
348 EnableIntrinsicFunctions( unset ),
349 ExceptionHandling( unset ),
350 ExpandAttributedSource( unset ),
351 FavorSizeOrSpeed( favorNone ),
352 ForceConformanceInForLoopScope( unset ),
353 GeneratePreprocessedFile( preprocessNo ),
354 GlobalOptimizations( unset ),
355 IgnoreStandardIncludePath( unset ),
356 ImproveFloatingPointConsistency( unset ),
357 InlineFunctionExpansion( expandOnlyInline ),
358 KeepComments( unset ),
359 MinimalRebuild( unset ),
360 OmitFramePointers( unset ),
361 Optimization( optimizeDisabled ),
362 OptimizeForProcessor( procOptimizeBlended ),
363 OptimizeForWindowsApplication( unset ),
364 RuntimeLibrary( rtMultiThreaded ),
365 RuntimeTypeInfo( unset ),
366 ShowIncludes( unset ),
367 SmallerTypeCheck( unset ),
368 StringPooling( unset ),
369 StructMemberAlignment( alignNotSet ),
370 SuppressStartupBanner( unset ),
371 TreatWChar_tAsBuiltInType( unset ),
372 TurnOffAssemblyGeneration( unset ),
373 UndefineAllPreprocessorDefinitions( unset ),
374 UsePrecompiledHeader( pchGenerateAuto ),
375 WarnAsError( unset ),
376 WarningLevel( warningLevel_0 ),
377 WholeProgramOptimization( unset )
378{
379}
380
381QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool )
382{
383 strm << _begTool3;
384 strm << _VCCLCompilerToolName;
385 strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories );
386 strm << XPair( _AdditionalOptions, tool.AdditionalOptions );
387 strm << XPair( _AdditionalUsingDirectories, tool.AdditionalUsingDirectories );
388 strm << SPair( _AssemblerListingLocation, tool.AssemblerListingLocation );
389 if ( tool.AssemblerOutput != asmListingNone ) strm << EPair( _AssemblerOutput, tool.AssemblerOutput );
390 if ( tool.BasicRuntimeChecks != runtimeBasicCheckNone ) strm << EPair( _BasicRuntimeChecks, tool.BasicRuntimeChecks );
391 if ( tool.BrowseInformation != brInfoNone ) strm << EPair( _BrowseInformation, tool.BrowseInformation );
392 strm << SPair( _BrowseInformationFile, tool.BrowseInformationFile );
393 strm << TPair( _BufferSecurityCheck, tool.BufferSecurityCheck );
394 if ( tool.CallingConvention != callConventionDefault ) strm << EPair( _CallingConvention, tool.CallingConvention );
395 if ( tool.CompileAs != compileAsDefault ) strm << EPair( _CompileAs, tool.CompileAs );
396 if ( tool.CompileAsManaged != managedDefault ) strm << EPair( _CompileAsManaged, tool.CompileAsManaged );
397 strm << TPair( _CompileOnly, tool.CompileOnly );
398 strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat );
399 strm << TPair( _DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned );
400 strm << TPair( _Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems );
401 strm << TPair( _DisableLanguageExtensions, tool.DisableLanguageExtensions );
402 strm << XPair( _DisableSpecificWarnings, tool.DisableSpecificWarnings );
403 strm << TPair( _EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations );
404 strm << TPair( _EnableFunctionLevelLinking, tool.EnableFunctionLevelLinking );
405 strm << TPair( _EnableIntrinsicFunctions, tool.EnableIntrinsicFunctions );
406 strm << TPair( _ExceptionHandling, tool.ExceptionHandling );
407 strm << TPair( _ExpandAttributedSource, tool.ExpandAttributedSource );
408 if ( tool.FavorSizeOrSpeed != favorNone ) strm << EPair( _FavorSizeOrSpeed, tool.FavorSizeOrSpeed );
409 strm << TPair( _ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope );
410 strm << XPair( _ForcedIncludeFiles, tool.ForcedIncludeFiles );
411 strm << XPair( _ForcedUsingFiles, tool.ForcedUsingFiles );
412 strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile );
413 strm << TPair( _GlobalOptimizations, tool.GlobalOptimizations );
414 strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath );
415 strm << TPair( _ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency );
416 strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion );
417 strm << TPair( _KeepComments, tool.KeepComments );
418 strm << TPair( _MinimalRebuild, tool.MinimalRebuild );
419 strm << SPair( _ObjectFile, tool.ObjectFile );
420 strm << TPair( _OmitFramePointers, tool.OmitFramePointers );
421 strm << EPair( _Optimization, tool.Optimization );
422 if ( tool.OptimizeForProcessor != procOptimizeBlended ) strm << EPair( _OptimizeForProcessor, tool.OptimizeForProcessor );
423 strm << TPair( _OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication );
424 strm << SPair( _OutputFile, tool.OutputFile );
425 strm << SPair( _PrecompiledHeaderFile, tool.PrecompiledHeaderFile );
426 strm << SPair( _PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough );
427 strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions );
428 strm << SPair( _ProgramDataBaseFileName, tool.ProgramDataBaseFileName );
429 strm << EPair( _RuntimeLibrary, tool.RuntimeLibrary );
430 strm << TPair( _RuntimeTypeInfo, tool.RuntimeTypeInfo );
431 strm << TPair( _ShowIncludes, tool.ShowIncludes );
432 strm << TPair( _SmallerTypeCheck, tool.SmallerTypeCheck );
433 strm << TPair( _StringPooling, tool.StringPooling );
434 if ( tool.StructMemberAlignment != alignNotSet ) strm << EPair( _StructMemberAlignment, tool.StructMemberAlignment );
435 strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner );
436 strm << TPair( _TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType );
437 strm << TPair( _TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration );
438 strm << TPair( _UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions );
439 strm << XPair( _UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions );
440 if ( !tool.PrecompiledHeaderFile.isEmpty() ||
441 !tool.PrecompiledHeaderThrough.isEmpty() )
442 strm << EPair( _UsePrecompiledHeader, tool.UsePrecompiledHeader );
443 strm << TPair( _WarnAsError, tool.WarnAsError );
444 strm << EPair( _WarningLevel, tool.WarningLevel );
445 strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization );
446 strm << "/>";
447return strm;
448}
449
450bool VCCLCompilerTool::parseOption( const char* option )
451{
452 // skip index 0 ('/' or '-')
453 char first = option[1];
454 char second = option[2];
455 char third = option[3];
456 char fourth = option[4];
457
458 switch ( first ) {
459 case '?':
460 case 'h':
461 qWarning( "Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info" );
462 return FALSE;
463 case '@':
464 qWarning( "Generator: Option '/@': MSVC.NET projects do not support the use of a response file" );
465 return FALSE;
466 case 'l':
467 qWarning( "Generator: Option '/link': qmake generator does not support passing link options through the compiler tool" );
468 return FALSE;
469
470 case 'A':
471 if ( second != 'I' )
472 return FALSE;
473 AdditionalUsingDirectories += option+2;
474 break;
475 case 'C':
476 KeepComments = _True;
477 break;
478 case 'D':
479 PreprocessorDefinitions += option+1;
480 break;
481 case 'E':
482 if ( second == 'H' ) {
483 if ( third == 'a' || third == 'c' || third == 's' ) {
484 // ExceptionHandling must be false, or it will override
485 // with an /EHsc option
486 ExceptionHandling = _False;
487 AdditionalOptions += option;
488 break;
489 }
490 return FALSE;
491 }
492 GeneratePreprocessedFile = preprocessYes;
493 break;
494 case 'F':
495 if ( second <= '9' && second >= '0' ) {
496 AdditionalOptions += option;
497 break;
498 } else {
499 switch ( second ) {
500 case 'A':
501 if ( third == 'c' ) {
502 AssemblerOutput = asmListingAsmMachine;
503 if ( fourth == 's' )
504 AssemblerOutput = asmListingAsmMachineSrc;
505 } else if ( third == 's' ) {
506 AssemblerOutput = asmListingAsmSrc;
507 } else {
508 AssemblerOutput = asmListingAssemblyOnly;
509 }
510 break;
511 case 'a':
512 AssemblerListingLocation = option+3;
513 break;
514 case 'I':
515 ForcedIncludeFiles += option+3;
516 break;
517 case 'R':
518 BrowseInformation = brAllInfo;
519 BrowseInformationFile = option+3;
520 break;
521 case 'r':
522 BrowseInformation = brNoLocalSymbols;
523 BrowseInformationFile = option+3;
524 break;
525 case 'U':
526 ForcedUsingFiles += option+3;
527 break;
528 case 'd':
529 ProgramDataBaseFileName = option+3;
530 break;
531 case 'e':
532 OutputFile = option+3;
533 break;
534 case 'm':
535 AdditionalOptions += option;
536 break;
537 case 'o':
538 ObjectFile = option+3;
539 break;
540 case 'p':
541 PrecompiledHeaderFile = option+3;
542 break;
543 case 'x':
544 ExpandAttributedSource = _True;
545 break;
546 default:
547 return FALSE;
548 }
549 }
550 break;
551 case 'G':
552 switch ( second ) {
553 case '3':
554 case '4':
555 qWarning( "Option '/G3' and '/G4' were phased out in Visual C++ 5.0" );
556 return FALSE;
557 case '5':
558 OptimizeForProcessor = procOptimizePentium;
559 break;
560 case '6':
561 case 'B':
562 OptimizeForProcessor = procOptimizePentiumProAndAbove;
563 break;
564 case 'A':
565 OptimizeForWindowsApplication = _True;
566 break;
567 case 'F':
568 StringPooling = _True;
569 break;
570 case 'H':
571 AdditionalOptions += option;
572 break;
573 case 'L':
574 WholeProgramOptimization = _True;
575 if ( third == '-' )
576 WholeProgramOptimization = _False;
577 break;
578 case 'R':
579 RuntimeTypeInfo = _True;
580 if ( third == '-' )
581 RuntimeTypeInfo = _False;
582 break;
583 case 'S':
584 BufferSecurityCheck = _True;
585 break;
586 case 'T':
587 EnableFiberSafeOptimizations = _True;
588 break;
589 case 'X':
590 case 'Z':
591 case 'e':
592 case 'h':
593 AdditionalOptions += option;
594 break;
595 case 'd':
596 CallingConvention = callConventionCDecl;
597 break;
598 case 'f':
599 StringPooling = _True;
600 AdditionalOptions += option;
601 break;
602 case 'm':
603 MinimalRebuild = _True;
604 if ( third == '-' )
605 MinimalRebuild = _False;
606 break;
607 case 'r':
608 CallingConvention = callConventionFastCall;
609 break;
610 case 's':
611 // Warning: following [num] is not used,
612 // were should we put it?
613 BufferSecurityCheck = _True;
614 break;
615 case 'y':
616 EnableFunctionLevelLinking = _True;
617 break;
618 case 'z':
619 CallingConvention = callConventionStdCall;
620 break;
621 default:
622 return FALSE;
623 }
624 break;
625 case 'H':
626 AdditionalOptions += option;
627 break;
628 case 'I':
629 AdditionalIncludeDirectories += option+2;
630 break;
631 case 'L':
632 if ( second == 'D' ) {
633 AdditionalOptions += option;
634 break;
635 }
636 return FALSE;
637 case 'M':
638 if ( second == 'D' ) {
639 RuntimeLibrary = rtMultiThreadedDLL;
640 if ( third == 'd' )
641 RuntimeLibrary = rtMultiThreadedDebugDLL;
642 break;
643 } else if ( second == 'L' ) {
644 RuntimeLibrary = rtSingleThreaded;
645 if ( third == 'd' )
646 RuntimeLibrary = rtSingleThreadedDebug;
647 break;
648 } else if ( second == 'T' ) {
649 RuntimeLibrary = rtMultiThreaded;
650 if ( third == 'd' )
651 RuntimeLibrary = rtMultiThreadedDebug;
652 break;
653 }
654 return FALSE;
655 case 'O':
656 switch ( second ) {
657 case '1':
658 Optimization = optimizeMinSpace;
659 break;
660 case '2':
661 Optimization = optimizeMaxSpeed;
662 break;
663 case 'a':
664 AdditionalOptions += option;
665 break;
666 case 'b':
667 if ( third == '0' )
668 InlineFunctionExpansion = expandDisable;
669 else if ( third == '1' )
670 InlineFunctionExpansion = expandOnlyInline;
671 else if ( third == '2' )
672 InlineFunctionExpansion = expandAnySuitable;
673 else
674 return FALSE;
675 break;
676 case 'd':
677 Optimization = optimizeDisabled;
678 break;
679 case 'g':
680 GlobalOptimizations = _True;
681 break;
682 case 'i':
683 EnableIntrinsicFunctions = _True;
684 break;
685 case 'p':
686 ImproveFloatingPointConsistency = _True;
687 if ( third == '-' )
688 ImproveFloatingPointConsistency = _False;
689 break;
690 case 's':
691 FavorSizeOrSpeed = favorSize;
692 break;
693 case 't':
694 FavorSizeOrSpeed = favorSpeed;
695 break;
696 case 'w':
697 AdditionalOptions += option;
698 break;
699 case 'x':
700 Optimization = optimizeFull;
701 break;
702 case 'y':
703 OmitFramePointers = _True;
704 if ( third == '-' )
705 OmitFramePointers = _False;
706 break;
707 default:
708 return FALSE;
709 }
710 break;
711 case 'P':
712 GeneratePreprocessedFile = preprocessYes;
713 break;
714 case 'Q':
715 if ( second == 'I' ) {
716 AdditionalOptions += option;
717 break;
718 }
719 return FALSE;
720 case 'R':
721 if ( second == 'T' && third == 'C' ) {
722 if ( fourth == '1' )
723 BasicRuntimeChecks = runtimeBasicCheckAll;
724 else if ( fourth == 'c' )
725 SmallerTypeCheck = _True;
726 else if ( fourth == 's' )
727 BasicRuntimeChecks = runtimeCheckStackFrame;
728 else if ( fourth == 'u' )
729 BasicRuntimeChecks = runtimeCheckUninitVariables;
730 else
731 return FALSE;
732 }
733 break;
734 case 'T':
735 if ( second == 'C' ) {
736 CompileAs = compileAsC;
737 } else if ( second == 'P' ) {
738 CompileAs = compileAsCPlusPlus;
739 } else {
740 qWarning( "Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake" );
741 return FALSE;
742 }
743 break;
744 case 'U':
745 UndefinePreprocessorDefinitions += option+2;
746 break;
747 case 'V':
748 AdditionalOptions += option;
749 break;
750 case 'W':
751 switch ( second ) {
752 case 'a':
753 case '4':
754 WarningLevel = warningLevel_4;
755 break;
756 case '3':
757 WarningLevel = warningLevel_3;
758 break;
759 case '2':
760 WarningLevel = warningLevel_2;
761 break;
762 case '1':
763 WarningLevel = warningLevel_1;
764 break;
765 case '0':
766 WarningLevel = warningLevel_0;
767 break;
768 case 'L':
769 AdditionalOptions += option;
770 break;
771 case 'X':
772 WarnAsError = _True;
773 break;
774 case 'p':
775 if ( third == '6' && fourth == '4' ) {
776 Detect64BitPortabilityProblems = _True;
777 break;
778 }
779 // Fallthrough
780 default:
781 return FALSE;
782 }
783 break;
784 case 'X':
785 IgnoreStandardIncludePath = _True;
786 break;
787 case 'Y':
788 switch ( second ) {
789 case '\0':
790 case '-':
791 AdditionalOptions += option;
792 break;
793 case 'X':
794 UsePrecompiledHeader = pchGenerateAuto;
795 PrecompiledHeaderFile = option+3;
796 break;
797 case 'c':
798 UsePrecompiledHeader = pchCreateUsingSpecific;
799 PrecompiledHeaderFile = option+3;
800 break;
801 case 'd':
802 case 'l':
803 AdditionalOptions =+ option;
804 break;
805 case 'u':
806 UsePrecompiledHeader = pchUseUsingSpecific;
807 PrecompiledHeaderFile = option+3;
808 break;
809 default:
810 return FALSE;
811 }
812 break;
813 case 'Z':
814 switch ( second ) {
815 case '7':
816 DebugInformationFormat = debugOldStyleInfo;
817 break;
818 case 'I':
819 DebugInformationFormat = debugEditAndContinue;
820 break;
821 case 'd':
822 DebugInformationFormat = debugLineInfoOnly;
823 break;
824 case 'i':
825 DebugInformationFormat = debugEnabled;
826 break;
827 case 'l':
828 DebugInformationFormat = debugEditAndContinue;
829 break;
830 case 'a':
831 DisableLanguageExtensions = _True;
832 break;
833 case 'e':
834 DisableLanguageExtensions = _False;
835 break;
836 case 'c':
837 if ( third == ':' ) {
838 if ( fourth == 'f' )
839 ForceConformanceInForLoopScope = _True;
840 else if ( fourth == 'w' )
841 TreatWChar_tAsBuiltInType = _True;
842 else
843 return FALSE;
844 } else {
845 return FALSE;
846 }
847 break;
848 case 'g':
849 case 'm':
850 case 's':
851 AdditionalOptions += option;
852 break;
853 case 'p':
854 switch ( third )
855 {
856 case '\0':
857 case '1':
858 StructMemberAlignment = alignSingleByte;
859 if ( fourth == '6' )
860 StructMemberAlignment = alignSixteenBytes;
861 break;
862 case '2':
863 StructMemberAlignment = alignTwoBytes;
864 break;
865 case '4':
866 StructMemberAlignment = alignFourBytes;
867 break;
868 case '8':
869 StructMemberAlignment = alignEightBytes;
870 break;
871 default:
872 return FALSE;
873 }
874 break;
875 default:
876 return FALSE;
877 }
878 break;
879 case 'c':
880 if ( second == '\0' ) {
881 CompileOnly = _True;
882 } else if ( second == 'l' ) {
883 if ( *(option+5) == 'n' ) {
884 CompileAsManaged = managedAssembly;
885 TurnOffAssemblyGeneration = _True;
886 } else {
887 CompileAsManaged = managedAssembly;
888 }
889 } else {
890 return FALSE;
891 }
892 break;
893 case 'd':
894 if ( second != 'r' )
895 return FALSE;
896 CompileAsManaged = managedAssembly;
897 break;
898 case 'n':
899 if ( second == 'o' && third == 'B' && fourth == 'o' ) {
900 AdditionalOptions += "/noBool";
901 break;
902 }
903 if ( second == 'o' && third == 'l' && fourth == 'o' ) {
904 SuppressStartupBanner = _True;
905 break;
906 }
907 return FALSE;
908 case 's':
909 if ( second == 'h' && third == 'o' && fourth == 'w' ) {
910 ShowIncludes = _True;
911 break;
912 }
913 return FALSE;
914 case 'u':
915 UndefineAllPreprocessorDefinitions = _True;
916 break;
917 case 'v':
918 if ( second == 'd' || second == 'm' ) {
919 AdditionalOptions += option;
920 break;
921 }
922 return FALSE;
923 case 'w':
924 switch ( second ) {
925 case '\0':
926 WarningLevel = warningLevel_0;
927 break;
928 case 'd':
929 DisableSpecificWarnings += option+3;
930 break;
931 default:
932 AdditionalOptions += option;
933 }
934 break;
935 default:
936 return FALSE;
937 }
938 return TRUE;
939}
940
941// VCLinkerTool -----------------------------------------------------
942VCLinkerTool::VCLinkerTool()
943 :EnableCOMDATFolding( optFoldingDefault ),
944 GenerateDebugInformation( unset ),
945 GenerateMapFile( unset ),
946 HeapCommitSize( -1 ),
947 HeapReserveSize( -1 ),
948 IgnoreAllDefaultLibraries( unset ),
949 IgnoreEmbeddedIDL( unset ),
950 IgnoreImportLibrary( unset ),
951 LargeAddressAware( addrAwareDefault ),
952 LinkDLL( unset ),
953 LinkIncremental( linkIncrementalYes ),
954 LinkTimeCodeGeneration( unset ),
955 MapExports( unset ),
956 MapLines( unset ),
957 OptimizeForWindows98( optWin98Default ),
958 OptimizeReferences( optReferencesDefault ),
959 RegisterOutput( unset ),
960 ResourceOnlyDLL( unset ),
961 SetChecksum( unset ),
962 ShowProgress( linkProgressNotSet ),
963 StackCommitSize( -1 ),
964 StackReserveSize( -1 ),
965 SubSystem( subSystemNotSet ),
966 SupportUnloadOfDelayLoadedDLL( unset ),
967 SuppressStartupBanner( unset ),
968 SwapRunFromCD( unset ),
969 SwapRunFromNet( unset ),
970 TargetMachine( machineNotSet ),
971 TerminalServerAware( termSvrAwareDefault ),
972 TurnOffAssemblyGeneration( unset ),
973 TypeLibraryResourceID( 0 )
974{
975}
976
977QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool )
978{
979 strm << _begTool3;
980 strm << _VCLinkerToolName;
981 strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, " " );
982 strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories );
983 strm << XPair( _AdditionalOptions, tool.AdditionalOptions );
984 strm << XPair( _AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly );
985 strm << SPair( _BaseAddress, tool.BaseAddress );
986 strm << XPair( _DelayLoadDLLs, tool.DelayLoadDLLs );
987 if ( tool.EnableCOMDATFolding != optFoldingDefault ) strm << EPair( _EnableCOMDATFolding, tool.EnableCOMDATFolding );
988 strm << SPair( _EntryPointSymbol, tool.EntryPointSymbol );
989 strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences );
990 strm << SPair( _FunctionOrder, tool.FunctionOrder );
991 strm << TPair( _GenerateDebugInformation, tool.GenerateDebugInformation );
992 strm << TPair( _GenerateMapFile, tool.GenerateMapFile );
993 if ( tool.HeapCommitSize != -1 ) strm << LPair( _HeapCommitSize, tool.HeapCommitSize );
994 if ( tool.HeapReserveSize != -1 ) strm << LPair( _HeapReserveSize, tool.HeapReserveSize );
995 strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries );
996 strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames );
997 strm << TPair( _IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL );
998 strm << TPair( _IgnoreImportLibrary, tool.IgnoreImportLibrary );
999 strm << SPair( _ImportLibrary, tool.ImportLibrary );
1000 if ( tool.LargeAddressAware != addrAwareDefault ) strm << EPair( _LargeAddressAware, tool.LargeAddressAware );
1001 strm << TPair( _LinkDLL, tool.LinkDLL );
1002 if ( tool.LinkIncremental != linkIncrementalDefault ) strm << EPair( _LinkIncremental, tool.LinkIncremental );
1003 strm << TPair( _LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration );
1004 strm << SPair( _LinkToManagedResourceFile, tool.LinkToManagedResourceFile );
1005 strm << TPair( _MapExports, tool.MapExports );
1006 strm << SPair( _MapFileName, tool.MapFileName );
1007 strm << TPair( _MapLines, tool.MapLines );
1008 strm << SPair( _MergedIDLBaseFileName, tool.MergedIDLBaseFileName );
1009 strm << SPair( _MergeSections, tool.MergeSections );
1010 strm << SPair( _MidlCommandFile, tool.MidlCommandFile );
1011 strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile );
1012 if ( tool.OptimizeForWindows98 != optWin98Default ) strm << EPair( _OptimizeForWindows98, tool.OptimizeForWindows98 );
1013 if ( tool.OptimizeReferences != optReferencesDefault ) strm << EPair( _OptimizeReferences, tool.OptimizeReferences );
1014 strm << SPair( _OutputFile, tool.OutputFile );
1015 strm << SPair( _ProgramDatabaseFile, tool.ProgramDatabaseFile );
1016 strm << TPair( _RegisterOutput, tool.RegisterOutput );
1017 strm << TPair( _ResourceOnlyDLL, tool.ResourceOnlyDLL );
1018 strm << TPair( _SetChecksum, tool.SetChecksum );
1019 if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress );
1020 if ( tool.StackCommitSize != -1 ) strm << LPair( _StackCommitSize, tool.StackCommitSize );
1021 if ( tool.StackReserveSize != -1 ) strm << LPair( _StackReserveSize, tool.StackReserveSize );
1022 strm << SPair( _StripPrivateSymbols, tool.StripPrivateSymbols );
1023 strm << EPair( _SubSystem, tool.SubSystem );
1024 strm << TPair( _SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL );
1025 strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner );
1026 strm << TPair( _SwapRunFromCD, tool.SwapRunFromCD );
1027 strm << TPair( _SwapRunFromNet, tool.SwapRunFromNet );
1028 if ( tool.TargetMachine != machineNotSet ) strm << EPair( _TargetMachine, tool.TargetMachine );
1029 if ( tool.TerminalServerAware != termSvrAwareDefault ) strm << EPair( _TerminalServerAware, tool.TerminalServerAware );
1030 strm << TPair( _TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration );
1031 strm << SPair( _TypeLibraryFile, tool.TypeLibraryFile );
1032 if ( tool.TypeLibraryResourceID != rcUseDefault ) strm << LPair( _TypeLibraryResourceID, tool.TypeLibraryResourceID );
1033 strm << SPair( _Version4, tool.Version );
1034 strm << "/>";
1035 return strm;
1036}
1037
1038// Hashing routine to do fast option lookups ----
1039// Slightly rewritten to stop on ':' ',' and '\0'
1040// Original routine in qtranslator.cpp ----------
1041static uint elfHash( const char* name )
1042{
1043 const uchar *k;
1044 uint h = 0;
1045 uint g;
1046
1047 if ( name ) {
1048 k = (const uchar *) name;
1049 while ( (*k) &&
1050 (*k)!= ':' &&
1051 (*k)!=',' &&
1052 (*k)!=' ' ) {
1053 h = ( h << 4 ) + *k++;
1054 if ( (g = (h & 0xf0000000)) != 0 )
1055 h ^= g >> 24;
1056 h &= ~g;
1057 }
1058 }
1059 if ( !h )
1060 h = 1;
1061 return h;
1062}
1063static void displayHash( const char* str )
1064{
1065 printf( "case 0x%07x: // %s\n break;\n", elfHash(str), str );
1066}
1067
1068bool VCLinkerTool::parseOption( const char* option )
1069{
1070#if 0
1071 // Main options
1072 displayHash( "/ALIGN" ); displayHash( "/ALLOWBIND" ); displayHash( "/ASSEMBLYMODULE" );
1073 displayHash( "/ASSEMBLYRESOURCE" ); displayHash( "/BASE" ); displayHash( "/DEBUG" );
1074 displayHash( "/DEF" ); displayHash( "/DEFAULTLIB" ); displayHash( "/DELAY" );
1075 displayHash( "/DELAYLOAD" ); displayHash( "/DLL" ); displayHash( "/DRIVER" );
1076 displayHash( "/ENTRY" ); displayHash( "/EXETYPE" ); displayHash( "/EXPORT" );
1077 displayHash( "/FIXED" ); displayHash( "/FORCE" ); displayHash( "/HEAP" );
1078 displayHash( "/IDLOUT" ); displayHash( "/IGNOREIDL" ); displayHash( "/IMPLIB" );
1079 displayHash( "/INCLUDE" ); displayHash( "/INCREMENTAL" ); displayHash( "/LARGEADDRESSAWARE" );
1080 displayHash( "/LIBPATH" ); displayHash( "/LTCG" ); displayHash( "/MACHINE" );
1081 displayHash( "/MAP" ); displayHash( "/MAPINFO" ); displayHash( "/MERGE" );
1082 displayHash( "/MIDL" ); displayHash( "/NOASSEMBLY" ); displayHash( "/NODEFAULTLIB" );
1083 displayHash( "/NOENTRY" ); displayHash( "/NOLOGO" ); displayHash( "/OPT" );
1084 displayHash( "/ORDER" ); displayHash( "/OUT" ); displayHash( "/PDB" );
1085 displayHash( "/PDBSTRIPPED" ); displayHash( "/RELEASE" ); displayHash( "/SECTION" );
1086 displayHash( "/STACK" ); displayHash( "/STUB" ); displayHash( "/SUBSYSTEM" );
1087 displayHash( "/SWAPRUN" ); displayHash( "/TLBID" ); displayHash( "/TLBOUT" );
1088 displayHash( "/TSAWARE" ); displayHash( "/VERBOSE" ); displayHash( "/VERSION" );
1089 displayHash( "/VXD" ); displayHash( "/WS " );
1090#endif
1091#if 0
1092 // Sub options
1093 displayHash( "UNLOAD" ); displayHash( "NOBIND" ); displayHash( "no" ); displayHash( "NOSTATUS" ); displayHash( "STATUS" );
1094 displayHash( "AM33" ); displayHash( "ARM" ); displayHash( "CEE" ); displayHash( "IA64" ); displayHash( "X86" ); displayHash( "M32R" );
1095 displayHash( "MIPS" ); displayHash( "MIPS16" ); displayHash( "MIPSFPU" ); displayHash( "MIPSFPU16" ); displayHash( "MIPSR41XX" ); displayHash( "PPC" );
1096 displayHash( "SH3" ); displayHash( "SH4" ); displayHash( "SH5" ); displayHash( "THUMB" ); displayHash( "TRICORE" ); displayHash( "EXPORTS" );
1097 displayHash( "LINES" ); displayHash( "REF" ); displayHash( "NOREF" ); displayHash( "ICF" ); displayHash( "WIN98" ); displayHash( "NOWIN98" );
1098 displayHash( "CONSOLE" ); displayHash( "EFI_APPLICATION" ); displayHash( "EFI_BOOT_SERVICE_DRIVER" ); displayHash( "EFI_ROM" ); displayHash( "EFI_RUNTIME_DRIVER" ); displayHash( "NATIVE" );
1099 displayHash( "POSIX" ); displayHash( "WINDOWS" ); displayHash( "WINDOWSCE" ); displayHash( "NET" ); displayHash( "CD" ); displayHash( "NO" );
1100#endif
1101
1102 switch ( elfHash(option) ) {
1103 case 0x3360dbe: // /ALIGN[:number]
1104 case 0x1485c34: // /ALLOWBIND[:NO]
1105 case 0x6b21972: // /DEFAULTLIB:library
1106 case 0x396ea92: // /DRIVER[:UPONLY | :WDM]
1107 case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386]
1108 case 0x3ad5444: // /EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
1109 case 0x33aec94: // /FIXED[:NO]
1110 case 0x33b4675: // /FORCE:[MULTIPLE|UNRESOLVED]
1111 case 0x7988f7e: // /SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#]
1112 case 0x0348992: // /STUB:filename
1113 case 0x0034bc4: // /VXD
1114 case 0x0034c50: // /WS
1115 AdditionalOptions += option;
1116 break;
1117 case 0x679c075: // /ASSEMBLYMODULE:filename
1118 AddModuleNamesToAssembly += option+15;
1119 break;
1120 case 0x062d065: // /ASSEMBLYRESOURCE:filename
1121 LinkToManagedResourceFile = option+18;
1122 break;
1123 case 0x0336675: // /BASE:{address | @filename,key}
1124 // Do we need to do a manual lookup when '@filename,key'?
1125 // Seems BaseAddress only can contain the location...
1126 // We don't use it in Qt, so keep it simple for now
1127 BaseAddress = option+6;
1128 break;
1129 case 0x3389797: // /DEBUG
1130 GenerateDebugInformation = _True;
1131 break;
1132 case 0x0033896: // /DEF:filename
1133 ModuleDefinitionFile = option+5;
1134 break;
1135 case 0x338a069: // /DELAY:{UNLOAD | NOBIND}
1136 // MS documentation does not specify what to do with
1137 // this option, so we'll put it in AdditionalOptions
1138 AdditionalOptions += option;
1139 break;
1140 case 0x06f4bf4: // /DELAYLOAD:dllname
1141 DelayLoadDLLs += option+11;
1142 break;
1143 // case 0x003390c: // /DLL
1144 // This option is not used for vcproj files
1145 //break;
1146 case 0x33a3979: // /ENTRY:function
1147 EntryPointSymbol = option+7;
1148 break;
1149 case 0x033c960: // /HEAP:reserve[,commit]
1150 {
1151 QStringList both = QStringList::split( ",", option+6 );
1152 HeapReserveSize = both[0].toLong();
1153 if ( both.count() == 2 )
1154 HeapCommitSize = both[1].toLong();
1155 }
1156 break;
1157 case 0x3d91494: // /IDLOUT:[path\]filename
1158 MergedIDLBaseFileName = option+8;
1159 break;
1160 case 0x345a04c: // /IGNOREIDL
1161 IgnoreEmbeddedIDL = _True;
1162 break;
1163 case 0x3e250e2: // /IMPLIB:filename
1164 ImportLibrary = option+8;
1165 break;
1166 case 0xe281ab5: // /INCLUDE:symbol
1167 ForceSymbolReferences += option+9;
1168 break;
1169 case 0xb28103c: // /INCREMENTAL[:no]
1170 if ( *(option+12) == ':' &&
1171 *(option+13) == 'n' )
1172 LinkIncremental = linkIncrementalNo;
1173 else
1174 LinkIncremental = linkIncrementalYes;
1175 break;
1176 case 0x26e4675: // /LARGEADDRESSAWARE[:no]
1177 if ( *(option+18) == ':' &&
1178 *(option+19) == 'n' )
1179 LargeAddressAware = addrAwareNoLarge;
1180 else
1181 LargeAddressAware = addrAwareLarge;
1182 break;
1183 case 0x0d745c8: // /LIBPATH:dir
1184 AdditionalLibraryDirectories += option+9;
1185 break;
1186 case 0x0341877: // /LTCG[:NOSTATUS|:STATUS]
1187 config->WholeProgramOptimization = _True;
1188 LinkTimeCodeGeneration = _True;
1189 if ( *(option+5) == ':' &&
1190 *(option+6) == 'S' )
1191 ShowProgress = linkProgressAll;
1192 break;
1193 case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE}
1194 switch ( elfHash(option+9) ) {
1195 // Very limited documentation on all options but X86,
1196 // so we put the others in AdditionalOptions...
1197 case 0x0046063: // AM33
1198 case 0x000466d: // ARM
1199 case 0x0004795: // CEE
1200 case 0x004d494: // IA64
1201 case 0x0050672: // M32R
1202 case 0x0051e53: // MIPS
1203 case 0x51e5646: // MIPS16
1204 case 0x1e57b05: // MIPSFPU
1205 case 0x57b09a6: // MIPSFPU16
1206 case 0x5852738: // MIPSR41XX
1207 case 0x0005543: // PPC
1208 case 0x00057b3: // SH3
1209 case 0x00057b4: // SH4
1210 case 0x00057b5: // SH5
1211 case 0x058da12: // THUMB
1212 case 0x96d8435: // TRICORE
1213 AdditionalOptions += option;
1214 break;
1215 case 0x0005bb6: // X86
1216 TargetMachine = machineX86;
1217 break;
1218 default:
1219 return FALSE;
1220 }
1221 break;
1222 case 0x0034160: // /MAP[:filename]
1223 GenerateMapFile = _True;
1224 MapFileName = option+5;
1225 break;
1226 case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES}
1227 if ( *(option+9) == 'E' )
1228 MapExports = _True;
1229 else if ( *(option+9) == 'L' )
1230 MapLines = _True;
1231 break;
1232 case 0x341a6b5: // /MERGE:from=to
1233 MergeSections = option+7;
1234 break;
1235 case 0x0341d8c: // /MIDL:@file
1236 MidlCommandFile = option+7;
1237 break;
1238 case 0x84e2679: // /NOASSEMBLY
1239 TurnOffAssemblyGeneration = _True;
1240 break;
1241 case 0x2b21942: // /NODEFAULTLIB[:library]
1242 if ( *(option+13) == '\0' )
1243 IgnoreAllDefaultLibraries = _True;
1244 else
1245 IgnoreDefaultLibraryNames += option+14;
1246 break;
1247 case 0x33a3a39: // /NOENTRY
1248 ResourceOnlyDLL = _True;
1249 break;
1250 case 0x434138f: // /NOLOGO
1251 SuppressStartupBanner = _True;
1252 break;
1253 case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98}
1254 {
1255 char third = *(option+7);
1256 switch ( third ) {
1257 case 'F': // REF
1258 if ( *(option+5) == 'R' ) {
1259 OptimizeReferences = optReferences;
1260 } else { // ICF[=iterations]
1261 EnableCOMDATFolding = optFolding;
1262 // [=iterations] case is not documented
1263 }
1264 break;
1265 case 'R': // NOREF
1266 OptimizeReferences = optNoReferences;
1267 break;
1268 case 'I': // NOICF
1269 EnableCOMDATFolding = optNoFolding;
1270 break;
1271 case 'N': // WIN98
1272 OptimizeForWindows98 = optWin98Yes;
1273 break;
1274 case 'W': // NOWIN98
1275 OptimizeForWindows98 = optWin98No;
1276 break;
1277 default:
1278 return FALSE;
1279 }
1280 }
1281 break;
1282 case 0x34468a2: // /ORDER:@filename
1283 FunctionOrder = option+8;
1284 break;
1285 case 0x00344a4: // /OUT:filename
1286 OutputFile = option+5;
1287 break;
1288 case 0x0034482: // /PDB:filename
1289 ProgramDatabaseFile = option+5;
1290 break;
1291 case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name
1292 StripPrivateSymbols = option+13;
1293 break;
1294 case 0x6a09535: // /RELEASE
1295 SetChecksum = _True;
1296 break;
1297 case 0x348857b: // /STACK:reserve[,commit]
1298 {
1299 QStringList both = QStringList::split( ",", option+7 );
1300 StackReserveSize = both[0].toLong();
1301 if ( both.count() == 2 )
1302 StackCommitSize = both[1].toLong();
1303 }
1304 break;
1305 case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
1306 {
1307 // Split up in subsystem, and version number
1308 QStringList both = QStringList::split( ",", option+11 );
1309 switch ( elfHash(both[0].latin1()) ) {
1310 case 0x8438445: // CONSOLE
1311 SubSystem = subSystemConsole;
1312 break;
1313 case 0xbe29493: // WINDOWS
1314 SubSystem = subSystemWindows;
1315 break;
1316 // The following are undocumented, so add them to AdditionalOptions
1317 case 0x240949e: // EFI_APPLICATION
1318 case 0xe617652: // EFI_BOOT_SERVICE_DRIVER
1319 case 0x9af477d: // EFI_ROM
1320 case 0xd34df42: // EFI_RUNTIME_DRIVER
1321 case 0x5268ea5: // NATIVE
1322 case 0x05547e8: // POSIX
1323 case 0x2949c95: // WINDOWSCE
1324 AdditionalOptions += option;
1325 break;
1326 default:
1327 return FALSE;
1328 }
1329 }
1330 break;
1331 case 0x8b654de: // /SWAPRUN:{NET | CD}
1332 if ( *(option+9) == 'N' )
1333 SwapRunFromNet = _True;
1334 else if ( *(option+9) == 'C' )
1335 SwapRunFromCD = _True;
1336 else
1337 return FALSE;
1338 break;
1339 case 0x34906d4: // /TLBID:id
1340 TypeLibraryResourceID = QString( option+7 ).toLong();
1341 break;
1342 case 0x4907494: // /TLBOUT:[path\]filename
1343 TypeLibraryFile = option+8;
1344 break;
1345 case 0x976b525: // /TSAWARE[:NO]
1346 if ( *(option+8) == ':' )
1347 TerminalServerAware = termSvrAwareNo;
1348 else
1349 TerminalServerAware = termSvrAwareYes;
1350 break;
1351 case 0xaa67735: // /VERBOSE[:lib]
1352 if ( *(option+9) == ':' ) {
1353 ShowProgress = linkProgressLibs;
1354 AdditionalOptions += option;
1355 } else {
1356 ShowProgress = linkProgressAll;
1357 }
1358 break;
1359 case 0xaa77f7e: // /VERSION:major[.minor]
1360 Version = option+9;
1361 break;
1362 default:
1363 return FALSE;
1364 }
1365 return TRUE;
1366}
1367
1368// VCMIDLTool -------------------------------------------------------
1369VCMIDLTool::VCMIDLTool()
1370 :DefaultCharType( midlCharUnsigned ),
1371 EnableErrorChecks( midlDisableAll ),
1372 ErrorCheckAllocations( unset ),
1373 ErrorCheckBounds( unset ),
1374 ErrorCheckEnumRange( unset ),
1375 ErrorCheckRefPointers( unset ),
1376 ErrorCheckStubData( unset ),
1377 GenerateStublessProxies( unset ),
1378 GenerateTypeLibrary( unset ),
1379 IgnoreStandardIncludePath( unset ),
1380 MkTypLibCompatible( unset ),
1381 StructMemberAlignment( midlAlignNotSet ),
1382 SuppressStartupBanner( unset ),
1383 TargetEnvironment( midlTargetNotSet ),
1384 ValidateParameters( unset ),
1385 WarnAsError( unset ),
1386 WarningLevel( midlWarningLevel_0 )
1387{
1388}
1389
1390QTextStream &operator<<( QTextStream &strm, const VCMIDLTool &tool )
1391{
1392 strm << _begTool3;
1393 strm << _VCMIDLToolName;
1394 strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories );
1395 strm << XPair( _AdditionalOptions, tool.AdditionalOptions );
1396 strm << XPair( _CPreprocessOptions, tool.CPreprocessOptions );
1397 strm << EPair( _DefaultCharType, tool.DefaultCharType );
1398 strm << SPair( _DLLDataFileName, tool.DLLDataFileName );
1399 strm << EPair( _EnableErrorChecks, tool.EnableErrorChecks );
1400 strm << TPair( _ErrorCheckAllocations, tool.ErrorCheckAllocations );
1401 strm << TPair( _ErrorCheckBounds, tool.ErrorCheckBounds );
1402 strm << TPair( _ErrorCheckEnumRange, tool.ErrorCheckEnumRange );
1403 strm << TPair( _ErrorCheckRefPointers, tool.ErrorCheckRefPointers );
1404 strm << TPair( _ErrorCheckStubData, tool.ErrorCheckStubData );
1405 strm << XPair( _FullIncludePath, tool.FullIncludePath );
1406 strm << TPair( _GenerateStublessProxies, tool.GenerateStublessProxies );
1407 strm << TPair( _GenerateTypeLibrary, tool.GenerateTypeLibrary );
1408 strm << SPair( _HeaderFileName, tool.HeaderFileName );
1409 strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath );
1410 strm << SPair( _InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName );
1411 strm << TPair( _MkTypLibCompatible, tool.MkTypLibCompatible );
1412 strm << SPair( _OutputDirectory4, tool.OutputDirectory );
1413 strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions );
1414 strm << SPair( _ProxyFileName, tool.ProxyFileName );
1415 strm << SPair( _RedirectOutputAndErrors, tool.RedirectOutputAndErrors );
1416 if ( tool.StructMemberAlignment != midlAlignNotSet) strm << EPair( _StructMemberAlignment, tool.StructMemberAlignment );
1417 strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner );
1418 if ( tool.TargetEnvironment != midlTargetNotSet ) strm << EPair( _TargetEnvironment, tool.TargetEnvironment );
1419 strm << SPair( _TypeLibraryName, tool.TypeLibraryName );
1420 strm << XPair( _UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions );
1421 strm << TPair( _ValidateParameters, tool.ValidateParameters );
1422 strm << TPair( _WarnAsError, tool.WarnAsError );
1423 strm << EPair( _WarningLevel, tool.WarningLevel );
1424 strm << "/>";
1425 return strm;
1426}
1427
1428bool VCMIDLTool::parseOption( const char* option )
1429{
1430#if 0
1431 displayHash( "/D name[=def]" ); displayHash( "/I directory-list" ); displayHash( "/Oi" );
1432 displayHash( "/Oic" ); displayHash( "/Oicf" ); displayHash( "/Oif" ); displayHash( "/Os" );
1433 displayHash( "/U name" ); displayHash( "/WX" ); displayHash( "/W{0|1|2|3|4}" );
1434 displayHash( "/Zp {N}" ); displayHash( "/Zs" ); displayHash( "/acf filename" );
1435 displayHash( "/align {N}" ); displayHash( "/app_config" ); displayHash( "/c_ext" );
1436 displayHash( "/char ascii7" ); displayHash( "/char signed" ); displayHash( "/char unsigned" );
1437 displayHash( "/client none" ); displayHash( "/client stub" ); displayHash( "/confirm" );
1438 displayHash( "/cpp_cmd cmd_line" ); displayHash( "/cpp_opt options" );
1439 displayHash( "/cstub filename" ); displayHash( "/dlldata filename" ); displayHash( "/env win32" );
1440 displayHash( "/env win64" ); displayHash( "/error all" ); displayHash( "/error allocation" );
1441 displayHash( "/error bounds_check" ); displayHash( "/error enum" ); displayHash( "/error none" );
1442 displayHash( "/error ref" ); displayHash( "/error stub_data" ); displayHash( "/h filename" );
1443 displayHash( "/header filename" ); displayHash( "/iid filename" ); displayHash( "/lcid" );
1444 displayHash( "/mktyplib203" ); displayHash( "/ms_ext" ); displayHash( "/ms_union" );
1445 displayHash( "/msc_ver <nnnn>" ); displayHash( "/newtlb" ); displayHash( "/no_cpp" );
1446 displayHash( "/no_def_idir" ); displayHash( "/no_default_epv" ); displayHash( "/no_format_opt" );
1447 displayHash( "/no_warn" ); displayHash( "/nocpp" ); displayHash( "/nologo" ); displayHash( "/notlb" );
1448 displayHash( "/o filename" ); displayHash( "/oldnames" ); displayHash( "/oldtlb" );
1449 displayHash( "/osf" ); displayHash( "/out directory" ); displayHash( "/pack {N}" );
1450 displayHash( "/prefix all" ); displayHash( "/prefix client" ); displayHash( "/prefix server" );
1451 displayHash( "/prefix switch" ); displayHash( "/protocol all" ); displayHash( "/protocol dce" );
1452 displayHash( "/protocol ndr64" ); displayHash( "/proxy filename" ); displayHash( "/robust" );
1453 displayHash( "/rpcss" ); displayHash( "/savePP" ); displayHash( "/server none" );
1454 displayHash( "/server stub" ); displayHash( "/sstub filename" ); displayHash( "/syntax_check" );
1455 displayHash( "/target {system}" ); displayHash( "/tlb filename" ); displayHash( "/use_epv" );
1456 displayHash( "/win32" ); displayHash( "/win64" );
1457#endif
1458 int offset = 0;
1459 switch( elfHash(option) ) {
1460 case 0x0000334: // /D name[=def]
1461 PreprocessorDefinitions += option+3;
1462 break;
1463 case 0x0000339: // /I directory-list
1464 AdditionalIncludeDirectories += option+3;
1465 break;
1466 case 0x0345f96: // /Oicf
1467 case 0x00345f6: // /Oif
1468 GenerateStublessProxies = _True;
1469 break;
1470 case 0x0000345: // /U name
1471 UndefinePreprocessorDefinitions += option+3;
1472 break;
1473 case 0x00034c8: // /WX
1474 WarnAsError = _True;
1475 break;
1476 case 0x3582fde: // /align {N}
1477 offset = 3; // Fallthrough
1478 case 0x0003510: // /Zp {N}
1479 switch ( *(option+offset+4) ) {
1480 case '1':
1481 StructMemberAlignment = ( *(option+offset+5) == '\0' ) ? midlAlignSingleByte : midlAlignSixteenBytes;
1482 break;
1483 case '2':
1484 StructMemberAlignment = midlAlignTwoBytes;
1485 break;
1486 case '4':
1487 StructMemberAlignment = midlAlignFourBytes;
1488 break;
1489 case '8':
1490 StructMemberAlignment = midlAlignEightBytes;
1491 break;
1492 default:
1493 return FALSE;
1494 }
1495 break;
1496 case 0x0359e82: // /char {ascii7|signed|unsigned}
1497 switch( *(option+6) ) {
1498 case 'a':
1499 DefaultCharType = midlCharAscii7;
1500 break;
1501 case 's':
1502 DefaultCharType = midlCharSigned;
1503 break;
1504 case 'u':
1505 DefaultCharType = midlCharUnsigned;
1506 break;
1507 default:
1508 return FALSE;
1509 }
1510 break;
1511 case 0xa766524: // /cpp_opt options
1512 CPreprocessOptions += option+9;
1513 break;
1514 case 0xb32abf1: // /dlldata filename
1515 DLLDataFileName = option + 9;
1516 break;
1517 case 0x0035c56: // /env {win32|win64}
1518 TargetEnvironment = ( *(option+8) == '6' ) ? midlTargetWin64 : midlTargetWin32;
1519 break;
1520 case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data}
1521 EnableErrorChecks = midlEnableCustom;
1522 switch ( *(option+7) ) {
1523 case 'a':
1524 if ( *(option+10) == '\0' )
1525 EnableErrorChecks = midlEnableAll;
1526 else
1527 ErrorCheckAllocations = _True;
1528 break;
1529 case 'b':
1530 ErrorCheckBounds = _True;
1531 break;
1532 case 'e':
1533 ErrorCheckEnumRange = _True;
1534 break;
1535 case 'n':
1536 EnableErrorChecks = midlDisableAll;
1537 break;
1538 case 'r':
1539 break;
1540 ErrorCheckRefPointers = _True;
1541 case 's':
1542 break;
1543 ErrorCheckStubData = _True;
1544 default:
1545 return FALSE;
1546 }
1547 break;
1548 case 0x5eb7af2: // /header filename
1549 offset = 5;
1550 case 0x0000358: // /h filename
1551 HeaderFileName = option + offset + 3;
1552 break;
1553 case 0x0035ff4: // /iid filename
1554 InterfaceIdentifierFileName = option+5;
1555 break;
1556 case 0x64b7933: // /mktyplib203
1557 MkTypLibCompatible = _True;
1558 break;
1559 case 0x8e0b0a2: // /no_def_idir
1560 IgnoreStandardIncludePath = _True;
1561 break;
1562 case 0x65635ef: // /nologo
1563 SuppressStartupBanner = _True;
1564 break;
1565 case 0x3656b22: // /notlb
1566 GenerateTypeLibrary = _True;
1567 break;
1568 case 0x000035f: // /o filename
1569 RedirectOutputAndErrors = option+3;
1570 break;
1571 case 0x00366c4: // /out directory
1572 OutputDirectory = option+5;
1573 break;
1574 case 0x36796f9: // /proxy filename
1575 ProxyFileName = option+7;
1576 break;
1577 case 0x6959c94: // /robust
1578 ValidateParameters = _True;
1579 break;
1580 case 0x6a88df4: // /target {system}
1581 if ( *(option+11) == '6' )
1582 TargetEnvironment = midlTargetWin64;
1583 else
1584 TargetEnvironment = midlTargetWin32;
1585 break;
1586 case 0x0036b22: // /tlb filename
1587 TypeLibraryName = option+5;
1588 break;
1589 case 0x36e0162: // /win32
1590 TargetEnvironment = midlTargetWin32;
1591 break;
1592 case 0x36e0194: // /win64
1593 TargetEnvironment = midlTargetWin64;
1594 break;
1595 case 0x0003459: // /Oi
1596 case 0x00345f3: // /Oic
1597 case 0x0003463: // /Os
1598 case 0x0003513: // /Zs
1599 case 0x0035796: // /acf filename
1600 case 0x5b1cb97: // /app_config
1601 case 0x3595cf4: // /c_ext
1602 case 0x5a2fc64: // /client {none|stub}
1603 case 0xa64d3dd: // /confirm
1604 case 0xa765b64: // /cpp_cmd cmd_line
1605 case 0x35aabb2: // /cstub filename
1606 case 0x03629f4: // /lcid
1607 case 0x6495cc4: // /ms_ext
1608 case 0x96c7a1e: // /ms_union
1609 case 0x4996fa2: // /msc_ver <nnnn>
1610 case 0x64ceb12: // /newtlb
1611 case 0x6555a40: // /no_cpp
1612 case 0xf64d6a6: // /no_default_epv
1613 case 0x6dd9384: // /no_format_opt
1614 case 0x556dbee: // /no_warn
1615 case 0x3655a70: // /nocpp
1616 case 0x2b455a3: // /oldnames
1617 case 0x662bb12: // /oldtlb
1618 case 0x0036696: // /osf
1619 case 0x036679b: // /pack {N}
1620 case 0x678bd38: // /prefix {all|client|server|switch}
1621 case 0x96b702c: // /protocol {all|dce|ndr64}
1622 case 0x3696aa3: // /rpcss
1623 case 0x698ca60: // /savePP
1624 case 0x69c9cf2: // /server {none|stub}
1625 case 0x36aabb2: // /sstub filename
1626 case 0xce9b12b: // /syntax_check
1627 case 0xc9b5f16: // /use_epv
1628 AdditionalOptions += option;
1629 break;
1630 default:
1631 // /W{0|1|2|3|4} case
1632 if ( *(option+1) == 'W' ) {
1633 switch ( *(option+2) ) {
1634 case '0':
1635 WarningLevel = midlWarningLevel_0;
1636 break;
1637 case '1':
1638 WarningLevel = midlWarningLevel_1;
1639 break;
1640 case '2':
1641 WarningLevel = midlWarningLevel_2;
1642 break;
1643 case '3':
1644 WarningLevel = midlWarningLevel_3;
1645 break;
1646 case '4':
1647 WarningLevel = midlWarningLevel_4;
1648 break;
1649 default:
1650 return FALSE;
1651 }
1652 }
1653 break;
1654 }
1655 return TRUE;
1656}
1657
1658// VCLibrarianTool --------------------------------------------------
1659VCLibrarianTool::VCLibrarianTool()
1660 :IgnoreAllDefaultLibraries( unset ),
1661 SuppressStartupBanner( _True )
1662{
1663}
1664
1665QTextStream &operator<<( QTextStream &strm, const VCLibrarianTool &tool )
1666{
1667 strm << _begTool3;
1668 strm << SPair( _ToolName, QString( "VCLibrarianTool" ) );
1669 strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies );
1670 strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories );
1671 strm << XPair( _AdditionalOptions, tool.AdditionalOptions );
1672 strm << XPair( _ExportNamedFunctions, tool.ExportNamedFunctions );
1673 strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences );
1674 strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries );
1675 strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames );
1676 strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile );
1677 strm << SPair( _OutputFile, tool.OutputFile );
1678 strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner );
1679 strm << "/>";
1680 return strm;
1681}
1682
1683// VCCustomBuildTool ------------------------------------------------
1684VCCustomBuildTool::VCCustomBuildTool()
1685{
1686 ToolName = "VCCustomBuildTool";
1687}
1688
1689QTextStream &operator<<( QTextStream &strm, const VCCustomBuildTool &tool )
1690{
1691 strm << _begTool3;
1692 strm << SPair( _ToolName, tool.ToolName );
1693 strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, ";" );
1694 strm << SPair( _CommandLine4, tool.CommandLine );
1695 strm << SPair( _Description4, tool.Description );
1696 strm << SPair( _Outputs4, tool.Outputs );
1697 strm << SPair( _ToolPath, tool.ToolPath );
1698 strm << "/>";
1699 return strm;
1700}
1701
1702// VCResourceCompilerTool -------------------------------------------
1703VCResourceCompilerTool::VCResourceCompilerTool()
1704 : Culture( rcUseDefault ),
1705 IgnoreStandardIncludePath( unset ),
1706 ShowProgress( linkProgressNotSet )
1707{
1708 PreprocessorDefinitions = "NDEBUG";
1709}
1710
1711QTextStream &operator<<( QTextStream &strm, const VCResourceCompilerTool &tool )
1712{
1713 strm << _begTool3;
1714 strm << _VCResourceCompilerToolName;
1715 strm << SPair( _ToolPath, tool.ToolPath );
1716 strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories );
1717 strm << XPair( _AdditionalOptions, tool.AdditionalOptions );
1718 if ( tool.Culture != rcUseDefault ) strm << EPair( _Culture, tool.Culture );
1719 strm << XPair( _FullIncludePath, tool.FullIncludePath );
1720 strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath );
1721 strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions );
1722 strm << SPair( _ResourceOutputFileName, tool.ResourceOutputFileName );
1723 if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress );
1724 strm << "/>";
1725 return strm;
1726}
1727
1728// VCEventTool -------------------------------------------------
1729QTextStream &operator<<( QTextStream &strm, const VCEventTool &tool )
1730{
1731 strm << _begTool3;
1732 strm << SPair( _ToolName, tool.ToolName );
1733 strm << SPair( _ToolPath, tool.ToolPath );
1734 strm << SPair( _CommandLine4, tool.CommandLine );
1735 strm << SPair( _Description4, tool.Description );
1736 strm << TPair( _ExcludedFromBuild, tool.ExcludedFromBuild );
1737 strm << "/>";
1738 return strm;
1739}
1740
1741// VCPostBuildEventTool ---------------------------------------------
1742VCPostBuildEventTool::VCPostBuildEventTool()
1743{
1744 ToolName = "VCPostBuildEventTool";
1745}
1746
1747// VCPreBuildEventTool ----------------------------------------------
1748VCPreBuildEventTool::VCPreBuildEventTool()
1749{
1750 ToolName = "VCPreBuildEventTool";
1751}
1752
1753// VCPreLinkEventTool -----------------------------------------------
1754VCPreLinkEventTool::VCPreLinkEventTool()
1755{
1756 ToolName = "VCPreLinkEventTool";
1757}
1758
1759// VCConfiguration --------------------------------------------------
1760
1761VCConfiguration::VCConfiguration()
1762 :ATLMinimizesCRunTimeLibraryUsage( unset ),
1763 BuildBrowserInformation( unset ),
1764 CharacterSet( charSetNotSet ),
1765 ConfigurationType( typeApplication ),
1766 RegisterOutput( unset ),
1767 UseOfATL( useATLNotSet ),
1768 UseOfMfc( useMfcStdWin ),
1769 WholeProgramOptimization( unset )
1770{
1771 compiler.config = this;
1772 linker.config = this;
1773 idl.config = this;
1774}
1775
1776QTextStream &operator<<( QTextStream &strm, const VCConfiguration &tool )
1777{
1778 strm << _begConfiguration;
1779 strm << SPair( _Name3, tool.Name );
1780 strm << SPair( _OutputDirectory3, tool.OutputDirectory );
1781 strm << TPair( _ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage );
1782 strm << TPair( _BuildBrowserInformation, tool.BuildBrowserInformation );
1783 if ( tool.CharacterSet != charSetNotSet)strm << EPair( _CharacterSet, tool.CharacterSet );
1784 strm << EPair( _ConfigurationType, tool.ConfigurationType );
1785 strm << SPair( _DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean );
1786 strm << SPair( _ImportLibrary, tool.ImportLibrary );
1787 strm << SPair( _IntermediateDirectory, tool.IntermediateDirectory );
1788 strm << SPair( _PrimaryOutput, tool.PrimaryOutput );
1789 strm << SPair( _ProgramDatabase, tool.ProgramDatabase );
1790 strm << TPair( _RegisterOutput, tool.RegisterOutput );
1791 if ( tool.UseOfATL != useATLNotSet) strm << EPair( _UseOfATL, tool.UseOfATL );
1792 strm << EPair( _UseOfMfc, tool.UseOfMfc );
1793 strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization );
1794 strm << ">";
1795 strm << tool.compiler;
1796 strm << tool.custom;
1797 if ( tool.ConfigurationType == typeStaticLibrary )
1798 strm << tool.librarian;
1799 else
1800 strm << tool.linker;
1801 strm << tool.idl;
1802 strm << tool.postBuild;
1803 strm << tool.preBuild;
1804 strm << tool.preLink;
1805 strm << tool.resource;
1806 strm << _endConfiguration;
1807 return strm;
1808}
1809// VCFilter ---------------------------------------------------------
1810VCFilter::VCFilter()
1811 : ParseFiles( unset )
1812{
1813}
1814
1815void VCFilter::generateMOC( QTextStream &strm, QString str ) const
1816{
1817 QString mocOutput = Project->findMocDestination( str );
1818 QString mocApp = Project->var( "QMAKE_MOC" );
1819
1820 if( mocOutput.isEmpty() ) {
1821 // In specialcases we DO moc .cpp files
1822 // when the result is an .moc file
1823 if ( !str.endsWith(".moc") )
1824 return;
1825 mocOutput = str;
1826 str = Project->findMocSource( mocOutput );
1827 }
1828
1829 strm << _begFileConfiguration;
1830 strm << _Name5;
1831 strm << Config->Name;
1832 strm << "\">";
1833 strm << _begTool5;
1834 strm << _VCCustomBuildTool;
1835 strm << _Description6;
1836 strm << "Moc'ing " << str << "...\"";
1837 strm << _CommandLine6;
1838 strm << mocApp;
1839 strm << " " << str << " -o " << mocOutput << "\"";
1840 strm << _AdditionalDependencies6;
1841 strm << mocApp << "\"";
1842 strm << _Outputs6;
1843 strm << mocOutput << "\"";
1844 strm << "/>";
1845 strm << _endFileConfiguration;
1846}
1847
1848void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const
1849{
1850 QString uicApp = Project->var("QMAKE_UIC");
1851 QString mocApp = Project->var( "QMAKE_MOC" );
1852 QString fname = str.section( '\\', -1 );
1853 QString mocDir = Project->var( "MOC_DIR" );
1854 int dot = fname.findRev( '.' );
1855 if( dot != -1 )
1856 fname.truncate( dot );
1857
1858 int slash = str.findRev( '\\' );
1859 QString pname = ( slash != -1 ) ? str.left( slash+1 ) : QString(".\\");
1860
1861 strm << _begFileConfiguration;
1862 strm << _Name5;
1863 strm << Config->Name;
1864 strm << "\">";
1865 strm << _begTool5;
1866 strm << _VCCustomBuildTool;
1867 strm << _Description6;
1868 strm << "Uic'ing " << str << "...\"";
1869 strm << _CommandLine6;
1870 strm << uicApp << " " << str << " -o " << pname << fname << ".h &amp;&amp; "; // Create .h from .ui file
1871 strm << uicApp << " " << str << " -i " << fname << ".h -o " << pname << fname << ".cpp &amp;&amp; ";// Create .cpp from .ui file
1872 strm << mocApp << " " << pname << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\"";
1873 strm << _AdditionalDependencies6;
1874 strm << mocApp << ";" << uicApp << "\"";
1875 strm << _Outputs6;
1876 strm << pname << fname << ".h;" << pname << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\"";
1877 strm << "/>";
1878 strm << _endFileConfiguration;
1879}
1880
1881QTextStream &operator<<( QTextStream &strm, const VCFilter &tool )
1882{
1883 if ( tool.Files.count() == 0 )
1884 return strm;
1885
1886 strm << _begFilter;
1887 strm << SPair( _Name3, tool.Name );
1888 strm << TPair( _ParseFiles, tool.ParseFiles );
1889 strm << SPair( _Filter, tool.Filter );
1890 strm << ">";
1891 for ( QStringList::ConstIterator it = tool.Files.begin(); it != tool.Files.end(); ++it ) {
1892 strm << _begFile;
1893 strm << SPair( _RelativePath, *it );
1894 strm << ">";
1895 if ( tool.CustomBuild == moc )
1896 tool.generateMOC( strm, *it );
1897 else if ( tool.CustomBuild == uic )
1898 tool.generateUIC( strm, *it );
1899 strm << _endFile;
1900 }
1901
1902 strm << _endFilter;
1903 return strm;
1904}
1905
1906// VCProject --------------------------------------------------------
1907VCProject::VCProject()
1908{
1909 QUuid uniqueId;
1910#if defined(Q_WS_WIN32)
1911 GUID guid;
1912 HRESULT h = CoCreateGuid( &guid );
1913 if ( h == S_OK )
1914 uniqueId = QUuid( guid );
1915 ProjectGUID = uniqueId.toString();
1916#else
1917 // Qt doesn't support GUID on other platforms yet
1918 ProjectGUID = "";
1919#endif
1920}
1921
1922QTextStream &operator<<( QTextStream &strm, const VCProject &tool )
1923{
1924 strm << _xmlInit;
1925 strm << _begVisualStudioProject;
1926 strm << _ProjectType;
1927 strm << SPair( _Version1, tool.Version );
1928 strm << SPair( _Name1, tool.Name );
1929 strm << SPair( _ProjectGUID, tool.ProjectGUID );
1930 strm << SPair( _SccProjectName, tool.SccProjectName );
1931 strm << SPair( _SccLocalPath, tool.SccLocalPath );
1932 strm << ">";
1933 strm << _begPlatforms;
1934 strm << _begPlatform;
1935 strm << SPair( _Name3, tool.PlatformName );
1936 strm << "/>";
1937 strm << _endPlatforms;
1938 strm << _begConfigurations;
1939 strm << tool.Configuration;
1940 strm << _endConfigurations;
1941 strm << _begFiles;
1942 strm << tool.SourceFiles;
1943 strm << tool.HeaderFiles;
1944 strm << tool.MOCFiles;
1945 strm << tool.UICFiles;
1946 strm << tool.FormFiles;
1947 strm << tool.TranslationFiles;
1948 strm << tool.LexYaccFiles;
1949 strm << tool.ResourceFiles;
1950 strm << _endFiles;
1951 strm << _begGlobals;
1952 strm << _endGlobals;
1953 strm << _endVisualStudioProject;
1954 return strm;
1955}
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
new file mode 100644
index 0000000..2d09280
--- a/dev/null
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -0,0 +1,775 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Copyright (C) 2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the network 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 licenses may use this
20** file in accordance with the Qt Commercial License Agreement provided
21** 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#ifndef __MSVC_OBJECTMODEL_H__
36#define __MSVC_OBJECTMODEL_H__
37
38#include "project.h"
39#include <qstring.h>
40#include <qstringlist.h>
41
42/*
43 This Object model is of course VERY simplyfied,
44 and does not actually follow the original MSVC
45 object model. However, it fulfilles the basic
46 needs for qmake
47*/
48
49/*
50 If a triState value is 'unset' then the
51 corresponding property is not in the output,
52 forcing the tool to utilize default values.
53 False/True values will be in the output...
54*/
55enum customBuildCheck {
56 none,
57 moc,
58 uic,
59 lexyacc
60};
61enum triState {
62 unset = -1,
63 _False = 0,
64 _True = 1
65};
66enum addressAwarenessType {
67 addrAwareDefault,
68 addrAwareNoLarge,
69 addrAwareLarge
70};
71enum asmListingOption {
72 asmListingNone,
73 asmListingAssemblyOnly,
74 asmListingAsmMachineSrc,
75 asmListingAsmMachine,
76 asmListingAsmSrc
77};
78enum basicRuntimeCheckOption {
79 runtimeBasicCheckNone,
80 runtimeCheckStackFrame,
81 runtimeCheckUninitVariables,
82 runtimeBasicCheckAll
83};
84enum browseInfoOption {
85 brInfoNone,
86 brAllInfo,
87 brNoLocalSymbols
88};
89enum callingConventionOption {
90 callConventionDefault = -1,
91 callConventionCDecl,
92 callConventionFastCall,
93 callConventionStdCall
94};
95enum charSet {
96 charSetNotSet,
97 charSetUnicode,
98 charSetMBCS
99};
100enum compileAsManagedOptions {
101 managedDefault = -1,
102 managedAssembly = 2
103};
104enum CompileAsOptions{
105 compileAsDefault,
106 compileAsC,
107 compileAsCPlusPlus
108};
109enum ConfigurationTypes {
110 typeUnknown = 0,
111 typeApplication = 1,
112 typeDynamicLibrary = 2,
113 typeStaticLibrary = 4,
114 typeGeneric = 10
115};
116enum debugOption {
117 debugDisabled,
118 debugOldStyleInfo,
119 debugLineInfoOnly,
120 debugEnabled,
121 debugEditAndContinue
122};
123enum eAppProtectionOption {
124 eAppProtectUnchanged,
125 eAppProtectLow,
126 eAppProtectMedium,
127 eAppProtectHigh
128};
129enum enumResourceLangID {
130 rcUseDefault = 0,
131 rcAfrikaans = 1078,
132 rcAlbanian = 1052,
133 rcArabicAlgeria = 5121,
134 rcArabicBahrain = 15361,
135 rcArabicEgypt = 3073,
136 rcArabicIraq = 2049,
137 rcArabicJordan = 11265,
138 rcArabicKuwait = 13313,
139 rcArabicLebanon = 12289,
140 rcArabicLibya = 4097,
141 rcArabicMorocco = 6145,
142 rcArabicOman = 8193,
143 rcArabicQatar = 16385,
144 rcArabicSaudi = 1025,
145 rcArabicSyria = 10241,
146 rcArabicTunisia = 7169,
147 rcArabicUnitedArabEmirates= 14337,
148 rcArabicYemen = 9217,
149 rcBasque = 1069,
150 rcBulgarian = 1026,
151 rcByelorussian = 1059,
152 rcCatalan = 1027,
153 rcChineseHongKong = 3076,
154 rcChinesePRC = 2052,
155 rcChineseSingapore = 4100,
156 rcChineseTaiwan = 1028,
157 rcCroatian = 1050,
158 rcCzech = 1029,
159 rcDanish = 1030,
160 rcDutchBelgium = 2067,
161 rcDutchStandard = 1043,
162 rcEnglishAustralia = 3081,
163 rcEnglishBritain = 2057,
164 rcEnglishCanada = 4105,
165 RcEnglishCaribbean = 9225,
166 rcEnglishIreland = 6153,
167 rcEnglishJamaica = 8201,
168 rcEnglishNewZealand = 5129,
169 rcEnglishSouthAfrica= 7177,
170 rcEnglishUS = 1033,
171 rcEstonian = 1061,
172 rcFarsi = 1065,
173 rcFinnish = 1035,
174 rcFrenchBelgium = 2060,
175 rcFrenchCanada = 3084,
176 rcFrenchLuxembourg = 5132,
177 rcFrenchStandard = 1036,
178 rcFrenchSwitzerland = 4108,
179 rcGermanAustria = 3079,
180 rcGermanLichtenstein= 5127,
181 rcGermanLuxembourg = 4103,
182 rcGermanStandard = 1031,
183 rcGermanSwitzerland = 2055,
184 rcGreek = 1032,
185 rcHebrew = 1037,
186 rcHungarian = 1038,
187 rcIcelandic = 1039,
188 rcIndonesian = 1057,
189 rcItalianStandard = 1040,
190 rcItalianSwitzerland= 2064,
191 rcJapanese = 1041,
192 rcKorean = 1042,
193 rcKoreanJohab = 2066,
194 rcLatvian = 1062,
195 rcLithuanian = 1063,
196 rcNorwegianBokmal = 1044,
197 rcNorwegianNynorsk = 2068,
198 rcPolish = 1045,
199 rcPortugueseBrazilian= 1046,
200 rcPortugueseStandard= 2070,
201 rcRomanian = 1048,
202 rcRussian = 1049,
203 rcSerbian = 2074,
204 rcSlovak = 1051,
205 rcSpanishArgentina = 11274,
206 rcSpanishBolivia = 16394,
207 rcSpanishChile = 13322,
208 rcSpanishColombia = 9226,
209 rcSpanishCostaRica = 5130,
210 rcSpanishDominicanRepublic= 7178,
211 rcSpanishEcuador = 12298,
212 rcSpanishGuatemala = 4106,
213 rcSpanishMexico = 2058,
214 rcSpanishModern = 3082,
215 rcSpanishPanama = 6154,
216 rcSpanishParaguay = 15370,
217 rcSpanishPeru = 10250,
218 rcSpanishTraditional= 1034,
219 rcSpanishUruguay = 14346,
220 rcSpanishVenezuela = 8202,
221 rcSwedish = 1053,
222 rcThai = 1054,
223 rcTurkish = 1055,
224 rcUkrainian = 1058,
225 rcUrdu = 1056
226};
227enum enumSccEvent {
228 eProjectInScc,
229 ePreDirtyNotification
230};
231enum favorSizeOrSpeedOption {
232 favorNone,
233 favorSpeed,
234 favorSize
235};
236enum genProxyLanguage {
237 genProxyNative,
238 genProxyManaged
239};
240enum inlineExpansionOption {
241 expandDisable,
242 expandOnlyInline,
243 expandAnySuitable
244};
245enum linkIncrementalType {
246 linkIncrementalDefault,
247 linkIncrementalNo,
248 linkIncrementalYes
249};
250enum linkProgressOption {
251 linkProgressNotSet,
252 linkProgressAll,
253 linkProgressLibs
254};
255enum machineTypeOption {
256 machineNotSet,
257 machineX86
258};
259enum midlCharOption {
260 midlCharUnsigned,
261 midlCharSigned,
262 midlCharAscii7
263};
264enum midlErrorCheckOption {
265 midlEnableCustom,
266 midlDisableAll,
267 midlEnableAll
268};
269enum midlStructMemberAlignOption {
270 midlAlignNotSet,
271 midlAlignSingleByte,
272 midlAlignTwoBytes,
273 midlAlignFourBytes,
274 midlAlignEightBytes,
275 midlAlignSixteenBytes
276};
277enum midlTargetEnvironment {
278 midlTargetNotSet,
279 midlTargetWin32,
280 midlTargetWin64
281};
282enum midlWarningLevelOption {
283 midlWarningLevel_0,
284 midlWarningLevel_1,
285 midlWarningLevel_2,
286 midlWarningLevel_3,
287 midlWarningLevel_4
288};
289enum optFoldingType {
290 optFoldingDefault,
291 optNoFolding,
292 optFolding
293};
294enum optimizeOption {
295 optimizeDisabled,
296 optimizeMinSpace,
297 optimizeMaxSpeed,
298 optimizeFull,
299 optimizeCustom
300};
301enum optRefType {
302 optReferencesDefault,
303 optNoReferences,
304 optReferences
305};
306enum optWin98Type {
307 optWin98Default,
308 optWin98No,
309 optWin98Yes
310};
311enum pchOption {
312 pchNone,
313 pchCreateUsingSpecific,
314 pchGenerateAuto,
315 pchUseUsingSpecific
316};
317enum preprocessOption {
318 preprocessNo,
319 preprocessYes,
320 preprocessNoLineNumbers
321};
322enum ProcessorOptimizeOption {
323 procOptimizeBlended,
324 procOptimizePentium,
325 procOptimizePentiumProAndAbove
326};
327enum RemoteDebuggerType {
328 DbgLocal,
329 DbgRemote,
330 DbgRemoteTCPIP
331};
332enum runtimeLibraryOption {
333 rtMultiThreaded,
334 rtMultiThreadedDebug,
335 rtMultiThreadedDLL,
336 rtMultiThreadedDebugDLL,
337 rtSingleThreaded,
338 rtSingleThreadedDebug
339};
340enum structMemberAlignOption {
341 alignNotSet,
342 alignSingleByte,
343 alignTwoBytes,
344 alignFourBytes,
345 alignEightBytes,
346 alignSixteenBytes
347};
348enum subSystemOption {
349 subSystemNotSet,
350 subSystemConsole,
351 subSystemWindows
352};
353enum termSvrAwarenessType {
354 termSvrAwareDefault,
355 termSvrAwareNo,
356 termSvrAwareYes
357};
358enum toolSetType {
359 toolSetUtility,
360 toolSetMakefile,
361 toolSetLinker,
362 toolSetLibrarian,
363 toolSetAll
364};
365enum TypeOfDebugger {
366 DbgNativeOnly,
367 DbgManagedOnly,
368 DbgMixed,
369 DbgAuto
370};
371enum useOfATL {
372 useATLNotSet,
373 useATLStatic,
374 useATLDynamic
375};
376enum useOfMfc {
377 useMfcStdWin,
378 useMfcStatic,
379 useMfcDynamic
380};
381enum warningLevelOption {
382 warningLevel_0,
383 warningLevel_1,
384 warningLevel_2,
385 warningLevel_3,
386 warningLevel_4
387};
388
389class VCToolBase {
390protected:
391 // Functions
392 VCToolBase(){};
393 ~VCToolBase(){};
394 virtual bool parseOption( const char* option ) = 0;
395public:
396 bool parseOptions( QStringList& options ) {
397 bool result = TRUE;
398 for ( QStringList::ConstIterator it=options.begin(); (it!=options.end()) && result; it++ )
399 result = parseOption( (*it).latin1() );
400 return result;
401 }
402};
403
404class VCConfiguration;
405class VCProject;
406
407class VCCLCompilerTool : public VCToolBase
408{
409public:
410 // Functions
411 VCCLCompilerTool();
412 ~VCCLCompilerTool(){};
413 virtual bool parseOption( const char* option );
414
415 // Variables
416 QStringList AdditionalIncludeDirectories;
417 QStringList AdditionalOptions;
418 QStringList AdditionalUsingDirectories;
419 QString AssemblerListingLocation;
420 asmListingOption AssemblerOutput;
421 basicRuntimeCheckOption BasicRuntimeChecks;
422 browseInfoOption BrowseInformation;
423 QString BrowseInformationFile;
424 triState BufferSecurityCheck;
425 callingConventionOption CallingConvention;
426 CompileAsOptions CompileAs;
427 compileAsManagedOptions CompileAsManaged;
428 triState CompileOnly;
429 debugOption DebugInformationFormat;
430 triState DefaultCharIsUnsigned;
431 triState Detect64BitPortabilityProblems;
432 triState DisableLanguageExtensions;
433 QStringList DisableSpecificWarnings;
434 triState EnableFiberSafeOptimizations;
435 triState EnableFunctionLevelLinking;
436 triState EnableIntrinsicFunctions;
437 triState ExceptionHandling;
438 triState ExpandAttributedSource;
439 favorSizeOrSpeedOption FavorSizeOrSpeed;
440 triState ForceConformanceInForLoopScope;
441 QStringList ForcedIncludeFiles;
442 QStringList ForcedUsingFiles;
443 preprocessOption GeneratePreprocessedFile;
444 triState GlobalOptimizations;
445 triState IgnoreStandardIncludePath;
446 triState ImproveFloatingPointConsistency;
447 inlineExpansionOption InlineFunctionExpansion;
448 triState KeepComments;
449 triState MinimalRebuild;
450 QString ObjectFile;
451 triState OmitFramePointers;
452 optimizeOption Optimization;
453 ProcessorOptimizeOption OptimizeForProcessor;
454 triState OptimizeForWindowsApplication;
455 QString OutputFile;
456 QString PrecompiledHeaderFile;
457 QString PrecompiledHeaderThrough;
458 QStringList PreprocessorDefinitions;
459 QString ProgramDataBaseFileName;
460 runtimeLibraryOption RuntimeLibrary;
461 triState RuntimeTypeInfo;
462 triState ShowIncludes;
463 triState SmallerTypeCheck;
464 triState StringPooling;
465 structMemberAlignOption StructMemberAlignment;
466 triState SuppressStartupBanner;
467 triState TreatWChar_tAsBuiltInType;
468 triState TurnOffAssemblyGeneration;
469 triState UndefineAllPreprocessorDefinitions;
470 QStringList UndefinePreprocessorDefinitions;
471 pchOption UsePrecompiledHeader;
472 triState WarnAsError;
473 warningLevelOption WarningLevel;
474 triState WholeProgramOptimization;
475 VCConfiguration* config;
476};
477
478class VCLinkerTool : public VCToolBase
479{
480public:
481 // Functions
482 VCLinkerTool();
483 ~VCLinkerTool(){};
484 virtual bool parseOption( const char* option );
485
486 // Variables
487 QStringList AdditionalDependencies;
488 QStringList AdditionalLibraryDirectories;
489 QStringList AdditionalOptions;
490 QStringList AddModuleNamesToAssembly;
491 QString BaseAddress;
492 QStringList DelayLoadDLLs;
493 optFoldingType EnableCOMDATFolding;
494 QString EntryPointSymbol;
495 QStringList ForceSymbolReferences;
496 QString FunctionOrder;
497 triState GenerateDebugInformation;
498 triState GenerateMapFile;
499 long HeapCommitSize;
500 long HeapReserveSize;
501 triState IgnoreAllDefaultLibraries;
502 QStringList IgnoreDefaultLibraryNames;
503 triState IgnoreEmbeddedIDL;
504 triState IgnoreImportLibrary;
505 QString ImportLibrary;
506 addressAwarenessType LargeAddressAware;
507 triState LinkDLL;
508 linkIncrementalType LinkIncremental;
509 triState LinkTimeCodeGeneration;
510 QString LinkToManagedResourceFile;
511 triState MapExports;
512 QString MapFileName;
513 triState MapLines;
514 QString MergedIDLBaseFileName;
515 QString MergeSections; // Should be list?
516 QString MidlCommandFile;
517 QString ModuleDefinitionFile; // Should be list?
518 optWin98Type OptimizeForWindows98;
519 optRefType OptimizeReferences;
520 QString OutputFile;
521 QString ProgramDatabaseFile;
522 triState RegisterOutput;
523 triState ResourceOnlyDLL;
524 triState SetChecksum;
525 linkProgressOption ShowProgress;
526 long StackCommitSize;
527 long StackReserveSize;
528 QString StripPrivateSymbols; // Should be list?
529 subSystemOption SubSystem;
530 triState SupportUnloadOfDelayLoadedDLL;
531 triState SuppressStartupBanner;
532 triState SwapRunFromCD;
533 triState SwapRunFromNet;
534 machineTypeOption TargetMachine;
535 termSvrAwarenessType TerminalServerAware;
536 triState TurnOffAssemblyGeneration;
537 QString TypeLibraryFile;
538 long TypeLibraryResourceID;
539 QString Version;
540 VCConfiguration* config;
541};
542
543class VCMIDLTool : public VCToolBase
544{
545public:
546 // Functions
547 VCMIDLTool();
548 ~VCMIDLTool(){};
549 virtual bool parseOption( const char* option );
550
551 // Variables
552 QStringList AdditionalIncludeDirectories;
553 QStringList AdditionalOptions;
554 QStringList CPreprocessOptions;
555 midlCharOption DefaultCharType;
556 QString DLLDataFileName; // Should be list?
557 midlErrorCheckOption EnableErrorChecks;
558 triState ErrorCheckAllocations;
559 triState ErrorCheckBounds;
560 triState ErrorCheckEnumRange;
561 triState ErrorCheckRefPointers;
562 triState ErrorCheckStubData;
563 QStringList FullIncludePath;
564 triState GenerateStublessProxies;
565 triState GenerateTypeLibrary;
566 QString HeaderFileName;
567 triState IgnoreStandardIncludePath;
568 QString InterfaceIdentifierFileName;
569 triState MkTypLibCompatible;
570 QString OutputDirectory;
571 QStringList PreprocessorDefinitions;
572 QString ProxyFileName;
573 QString RedirectOutputAndErrors;
574 midlStructMemberAlignOption StructMemberAlignment;
575 triState SuppressStartupBanner;
576 midlTargetEnvironment TargetEnvironment;
577 QString TypeLibraryName;
578 QStringList UndefinePreprocessorDefinitions;
579 triState ValidateParameters;
580 triState WarnAsError;
581 midlWarningLevelOption WarningLevel;
582 VCConfiguration* config;
583};
584
585class VCLibrarianTool : public VCToolBase
586{
587public:
588 // Functions
589 VCLibrarianTool();
590 ~VCLibrarianTool(){};
591 virtual bool parseOption( const char* option ){ return FALSE; };
592
593 // Variables
594 QStringList AdditionalDependencies;
595 QStringList AdditionalLibraryDirectories;
596 QStringList AdditionalOptions;
597 QStringList ExportNamedFunctions;
598 QStringList ForceSymbolReferences;
599 triState IgnoreAllDefaultLibraries;
600 QStringList IgnoreDefaultLibraryNames;
601 QString ModuleDefinitionFile;
602 QString OutputFile;
603 triState SuppressStartupBanner;
604};
605
606class VCCustomBuildTool : public VCToolBase
607{
608public:
609 // Functions
610 VCCustomBuildTool();
611 ~VCCustomBuildTool(){};
612 virtual bool parseOption( const char* option ){ return FALSE; };
613
614 // Variables
615 QStringList AdditionalDependencies;
616 QString CommandLine;
617 QString Description;
618 QString Outputs;
619 QString ToolName;
620 QString ToolPath;
621};
622
623class VCResourceCompilerTool : public VCToolBase
624{
625public:
626 // Functions
627 VCResourceCompilerTool();
628 ~VCResourceCompilerTool(){};
629 virtual bool parseOption( const char* option ){ return FALSE; };
630
631 // Variables
632 QStringList AdditionalIncludeDirectories;
633 QStringList AdditionalOptions;
634 enumResourceLangID Culture;
635 QStringList FullIncludePath;
636 triState IgnoreStandardIncludePath;
637 QStringList PreprocessorDefinitions;
638 QString ResourceOutputFileName;
639 linkProgressOption ShowProgress;
640 QString ToolPath;
641};
642
643class VCEventTool : public VCToolBase
644{
645protected:
646 // Functions
647 VCEventTool() : ExcludedFromBuild( unset ){};
648 ~VCEventTool(){};
649 virtual bool parseOption( const char* option ){ return FALSE; };
650
651public:
652 // Variables
653 QString CommandLine;
654 QString Description;
655 triState ExcludedFromBuild;
656 QString ToolName;
657 QString ToolPath;
658};
659
660class VCPostBuildEventTool : public VCEventTool
661{
662public:
663 VCPostBuildEventTool();
664 ~VCPostBuildEventTool(){};
665};
666
667class VCPreBuildEventTool : public VCEventTool
668{
669public:
670 VCPreBuildEventTool();
671 ~VCPreBuildEventTool(){};
672};
673
674class VCPreLinkEventTool : public VCEventTool
675{
676public:
677 VCPreLinkEventTool();
678 ~VCPreLinkEventTool(){};
679};
680
681class VCConfiguration
682{
683public:
684 // Functions
685 VCConfiguration();
686 ~VCConfiguration(){};
687
688 // Variables
689 triState ATLMinimizesCRunTimeLibraryUsage;
690 triState BuildBrowserInformation;
691 charSet CharacterSet;
692 ConfigurationTypesConfigurationType;
693 QString DeleteExtensionsOnClean;
694 QString ImportLibrary;
695 QString IntermediateDirectory;
696 QString Name;
697 QString OutputDirectory;
698 QString PrimaryOutput;
699 QString ProgramDatabase;
700 triState RegisterOutput;
701 useOfATL UseOfATL;
702 useOfMfc UseOfMfc;
703 triState WholeProgramOptimization;
704
705 // XML sub-parts
706 VCCLCompilerTool compiler;
707 VCLinkerTool linker;
708 VCLibrarianTool librarian;
709 VCCustomBuildTool custom;
710 VCMIDLTool idl;
711 VCPostBuildEventTool postBuild;
712 VCPreBuildEventTool preBuild;
713 VCPreLinkEventTool preLink;
714 VCResourceCompilerTool resource;
715};
716
717class VcprojGenerator;
718class VCFilter
719{
720public:
721 // Functions
722 VCFilter();
723 ~VCFilter(){};
724 void generateMOC( QTextStream &strm, QString str ) const;
725 void generateUIC( QTextStream &strm, const QString& str ) const;
726
727 // Variables
728 QString Name;
729 QString Filter;
730 triState ParseFiles;
731 QStringList Files;
732 VcprojGenerator*Project;
733 VCConfiguration*Config;
734 customBuildCheckCustomBuild;
735};
736
737class VCProject
738{
739public:
740 // Functions
741 VCProject();
742 ~VCProject(){};
743
744 // Variables
745 QString Name;
746 QString Version;
747 QString ProjectGUID;
748 QString SccProjectName;
749 QString SccLocalPath;
750 QString PlatformName;
751
752 // XML sub-parts
753 VCConfigurationConfiguration;
754 VCFilter SourceFiles;
755 VCFilter HeaderFiles;
756 VCFilter MOCFiles;
757 VCFilter UICFiles;
758 VCFilter FormFiles;
759 VCFilter TranslationFiles;
760 VCFilter LexYaccFiles;
761 VCFilter ResourceFiles;
762};
763
764QTextStream &operator<<( QTextStream &, const VCCLCompilerTool & );
765QTextStream &operator<<( QTextStream &, const VCLinkerTool & );
766QTextStream &operator<<( QTextStream &, const VCMIDLTool & );
767QTextStream &operator<<( QTextStream &, const VCCustomBuildTool & );
768QTextStream &operator<<( QTextStream &, const VCLibrarianTool & );
769QTextStream &operator<<( QTextStream &, const VCResourceCompilerTool & );
770QTextStream &operator<<( QTextStream &, const VCEventTool & );
771QTextStream &operator<<( QTextStream &, const VCConfiguration & );
772QTextStream &operator<<( QTextStream &, const VCFilter & );
773QTextStream &operator<<( QTextStream &, const VCProject & );
774
775#endif //__MSVC_OBJECTMODEL_H__
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
new file mode 100644
index 0000000..a2bb6e9
--- a/dev/null
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -0,0 +1,1050 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of VcprojGenerator class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "msvc_vcproj.h"
39#include "option.h"
40#include <qdir.h>
41#include <stdlib.h>
42#include <qregexp.h>
43
44#if defined(Q_OS_WIN32)
45#include <objbase.h>
46#endif
47
48VcprojGenerator::VcprojGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
49{
50}
51
52/* \internal
53 Generates a project file for the given profile.
54 Options are either a Visual Studio projectfiles, or
55 recursive projectfiles.. Maybe we can make .sln files
56 someday?
57*/
58bool VcprojGenerator::writeMakefile(QTextStream &t)
59{
60 // Check if all requirements are fullfilled
61 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
62 fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
63 var("QMAKE_FAILED_REQUIREMENTS").latin1());
64 return TRUE;
65 }
66
67 // Generate full project file
68 if(project->first("TEMPLATE") == "vcapp" ||
69 project->first("TEMPLATE") == "vclib") {
70 debug_msg(1, "Generator: MSVC.NET: Writing project file" );
71 t << vcProject;
72 return TRUE;
73 } else if(project->first("TEMPLATE") == "vcsubdirs") { // Generate recursive project
74 debug_msg(1, "Generator: MSVC.NET: Writing solution file" );
75 writeSubDirs(t);
76 return TRUE;
77 }
78 return FALSE;
79
80}
81
82struct VcsolutionDepend {
83 QString vcprojFile, orig_target, target;
84 QStringList dependencies;
85};
86
87void VcprojGenerator::writeSubDirs(QTextStream &t)
88{
89 if(project->first("TEMPLATE") == "subdirs") {
90 writeHeader(t);
91 Win32MakefileGenerator::writeSubDirs(t);
92 return;
93 }
94
95 QPtrList<VcsolutionDepend> solution_depends;
96 solution_depends.setAutoDelete(TRUE);
97 QStringList subdirs = project->variables()["SUBDIRS"];
98 QString oldpwd = QDir::currentDirPath();
99 for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) {
100 QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE));
101 if(fi.exists()) {
102 if(fi.isDir()) {
103 QString profile = (*it);
104 if(!profile.endsWith(Option::dir_sep))
105 profile += Option::dir_sep;
106 profile += fi.baseName() + ".pro";
107 subdirs.append(profile);
108 } else {
109 QMakeProject tmp_proj;
110 QString dir = fi.dirPath(), fn = fi.fileName();
111 if(!dir.isEmpty()) {
112 if(!QDir::setCurrent(dir))
113 fprintf(stderr, "Cannot find directory: %s\n", dir.latin1());
114 }
115 if(tmp_proj.read(fn, oldpwd)) {
116 if(tmp_proj.first("TEMPLATE") == "vcsubdirs") {
117 QStringList tmp_subdirs = fileFixify(tmp_proj.variables()["SUBDIRS"]);
118 subdirs += tmp_subdirs;
119 } else if(tmp_proj.first("TEMPLATE") == "vcapp" ||
120 tmp_proj.first("TEMPLATE") == "vclib") {
121 QString vcproj = fi.baseName() + project->first("VCPROJ_EXTENSION");
122 if(QFile::exists(vcproj) || 1) {
123 VcprojGenerator tmp_dsp(&tmp_proj);
124 tmp_dsp.setNoIO(TRUE);
125 tmp_dsp.init();
126 if(Option::debug_level) {
127 QMap<QString, QStringList> &vars = tmp_proj.variables();
128 for(QMap<QString, QStringList>::Iterator it = vars.begin();
129 it != vars.end(); ++it) {
130 if(it.key().left(1) != "." && !it.data().isEmpty())
131 debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(),
132 it.data().join(" :: ").latin1());
133 }
134 }
135 VcsolutionDepend *newDep = new VcsolutionDepend;
136 newDep->vcprojFile = fileFixify(vcproj);
137 newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET");
138 newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1);
139 if(newDep->target.endsWith(".dll"))
140 newDep->target = newDep->target.left(newDep->target.length()-3) + "lib";
141 if(!tmp_proj.isEmpty("FORMS"))
142 newDep->dependencies << "uic.exe";
143 {
144 QStringList where("QMAKE_LIBS");
145 if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
146 where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"];
147 for(QStringList::iterator wit = where.begin();
148 wit != where.end(); ++wit) {
149 QStringList &l = tmp_proj.variables()[(*wit)];
150 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
151 QString opt = (*it);
152 if(!opt.startsWith("/")) //Not a switch
153 newDep->dependencies << opt.section(Option::dir_sep, -1);
154 }
155 }
156 }
157 solution_depends.append(newDep);
158 }
159 }
160 }
161 QDir::setCurrent(oldpwd);
162 }
163 }
164 }
165
166 VcsolutionDepend *vc;
167 QMap<QString, int> uuids;
168 QRegExp libVersion("[0-9]{3,3}\\.lib$");
169 for(vc = solution_depends.first(); vc; vc = solution_depends.next()) {
170 static int uuid = 666;
171 uuids.insert(vc->target, uuid);
172 if(libVersion.match(vc->target) != -1)
173 uuids.insert(vc->target.left(vc->target.length() - libVersion.matchedLength()) + ".lib",
174 uuid);
175 t << "\"" << vc->orig_target << "\" \"" << vc->vcprojFile << "\" { " << uuid << " }" << endl;
176 uuid++;
177 }
178 for(vc = solution_depends.first(); vc; vc = solution_depends.next()) {
179 int uuid = uuids[vc->target], cnt = 0;
180 for(QStringList::iterator dit = vc->dependencies.begin(); dit != vc->dependencies.end(); ++dit) {
181 if(uuids.contains((*dit)))
182 t << uuid << "." << cnt++ << " = " << uuids[(*dit)] << endl;
183 }
184 }
185}
186
187// ------------------------------------------------------------------------------------------------
188// ------------------------------------------------------------------------------------------------
189
190void VcprojGenerator::init()
191{
192 if( init_flag )
193 return;
194 if(project->first("TEMPLATE") == "vcsubdirs") { //too much work for subdirs
195 init_flag = TRUE;
196 return;
197 }
198
199 debug_msg(1, "Generator: MSVC.NET: Initializing variables" );
200
201/*
202 // Once to be nice and clean code...
203 // Wouldn't life be great?
204
205 // Are we building Qt?
206 bool is_qt =
207 ( project->first("TARGET") == "qt"QTDLL_POSTFIX ||
208 project->first("TARGET") == "qt-mt"QTDLL_POSTFIX );
209
210 // Are we using Qt?
211 bool isQtActive = project->isActiveConfig("qt");
212
213 if ( isQtActive ) {
214 project->variables()["CONFIG"] += "moc";
215 project->variables()["CONFIG"] += "windows";
216 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
217 project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
218
219 if( projectTarget == SharedLib )
220 project->variables()["DEFINES"] += "QT_DLL";
221
222 if( project->isActiveConfig("accessibility" ) )
223 project->variables()["DEFINES"] += "QT_ACCESSIBILITY_SUPPORT";
224
225 if ( project->isActiveConfig("plugin")) {
226 project->variables()["DEFINES"] += "QT_PLUGIN";
227 project->variables()["CONFIG"] += "dll";
228 }
229
230 if( project->isActiveConfig("thread") ) {
231 project->variables()["DEFINES"] += "QT_THREAD_SUPPORT";
232 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
233 } else {
234 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
235 }
236 }
237
238 if ( project->isActiveConfig("opengl") ) {
239 project->variables()["CONFIG"] += "windows"; // <-- Also in 'qt' above
240 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
241 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
242
243 }
244*/
245 initOld(); // Currently calling old DSP code to set variables. CLEAN UP!
246
247 // Figure out what we're trying to build
248 if ( project->first("TEMPLATE") == "vcapp" ) {
249 projectTarget = Application;
250 } else if ( project->first("TEMPLATE") == "vclib") {
251 if ( project->isActiveConfig( "staticlib" ) )
252 projectTarget = StaticLib;
253 else
254 projectTarget = SharedLib;
255 }
256 initProject(); // Fills the whole project with proper data
257}
258
259void VcprojGenerator::initProject()
260{
261 // Initialize XML sub elements
262 // - Do this first since project elements may need
263 // - to know of certain configuration options
264 initConfiguration();
265 initSourceFiles();
266 initHeaderFiles();
267 initMOCFiles();
268 initUICFiles();
269 initFormsFiles();
270 initTranslationFiles();
271 initLexYaccFiles();
272 initResourceFiles();
273
274 // Own elements -----------------------------
275 vcProject.Name = project->first("QMAKE_ORIG_TARGET");
276 vcProject.Version = "7.00";
277 vcProject.PlatformName = ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" );
278 // These are not used by Qt, but may be used by customers
279 vcProject.SccProjectName = project->first("SCCPROJECTNAME");
280 vcProject.SccLocalPath = project->first("SCCLOCALPATH");
281}
282
283void VcprojGenerator::initConfiguration()
284{
285 // Initialize XML sub elements
286 // - Do this first since main configuration elements may need
287 // - to know of certain compiler/linker options
288 initCompilerTool();
289 if ( projectTarget == StaticLib )
290 initLibrarianTool();
291 else
292 initLinkerTool();
293 initIDLTool();
294
295 // Own elements -----------------------------
296 QString temp = project->first("BuildBrowserInformation");
297 switch ( projectTarget ) {
298 case SharedLib:
299 vcProject.Configuration.ConfigurationType = typeDynamicLibrary;
300 break;
301 case StaticLib:
302 vcProject.Configuration.ConfigurationType = typeStaticLibrary;
303 break;
304 case Application:
305 default:
306 vcProject.Configuration.ConfigurationType = typeApplication;
307 break;
308 }
309 vcProject.Configuration.Name = ( project->isActiveConfig( "release" ) ? "Release|" : "Debug|" );
310 vcProject.Configuration.Name += ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" );
311 vcProject.Configuration.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True );
312 vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? unset : temp.toShort() );
313 temp = project->first("CharacterSet");
314 vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? charSetNotSet : temp.toShort() );
315 vcProject.Configuration.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean");
316 vcProject.Configuration.ImportLibrary = vcProject.Configuration.linker.ImportLibrary;
317 vcProject.Configuration.IntermediateDirectory = project->first("OBJECTS_DIR");
318// temp = (projectTarget == StaticLib) ? project->first("DESTDIR"):project->first("DLLDESTDIR");
319 vcProject.Configuration.OutputDirectory = "."; //( temp.isEmpty() ? QString(".") : temp );
320 vcProject.Configuration.PrimaryOutput = project->first("PrimaryOutput");
321 vcProject.Configuration.WholeProgramOptimization = vcProject.Configuration.compiler.WholeProgramOptimization;
322 temp = project->first("UseOfATL");
323 if ( !temp.isEmpty() )
324 vcProject.Configuration.UseOfATL = useOfATL( temp.toShort() );
325 temp = project->first("UseOfMfc");
326 if ( !temp.isEmpty() )
327 vcProject.Configuration.UseOfMfc = useOfMfc( temp.toShort() );
328
329 // Configuration does not need parameters from
330 // these sub XML items;
331 initCustomBuildTool();
332 initPreBuildEventTools();
333 initPostBuildEventTools();
334 initPreLinkEventTools();
335}
336
337void VcprojGenerator::initCompilerTool()
338{
339 QString placement = project->first("OBJECTS_DIR");
340 if ( placement.isEmpty() )
341 placement = project->isActiveConfig( "release" )? ".\\Release\\":".\\Debug\\";
342
343 vcProject.Configuration.compiler.AssemblerListingLocation = placement ;
344 vcProject.Configuration.compiler.ProgramDataBaseFileName = placement ;
345 vcProject.Configuration.compiler.ObjectFile = placement ;
346 vcProject.Configuration.compiler.PrecompiledHeaderFile = placement + project->first("QMAKE_ORIG_TARGET") + ".pch";
347
348 if ( project->isActiveConfig("debug") ){
349 // Debug version
350 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] );
351 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] );
352 if ( project->isActiveConfig("thread") ) {
353 if ( (projectTarget == Application) || (projectTarget == StaticLib) )
354 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] );
355 else
356 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] );
357 } else {
358 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST_DBG"] );
359 }
360 } else {
361 // Release version
362 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] );
363 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] );
364 vcProject.Configuration.compiler.PreprocessorDefinitions += "QT_NO_DEBUG";
365 if ( project->isActiveConfig("thread") ) {
366 if ( (projectTarget == Application) || (projectTarget == StaticLib) )
367 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] );
368 else
369 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] );
370 } else {
371 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST"] );
372 }
373 }
374
375 // Common for both release and debug
376 if ( project->isActiveConfig("warn_off") )
377 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] );
378 else
379 vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] );
380 if ( project->isActiveConfig("windows") )
381 vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"];
382
383 // Can this be set for ALL configs?
384 // If so, use qmake.conf!
385 if ( projectTarget == SharedLib )
386 vcProject.Configuration.compiler.PreprocessorDefinitions += "_WINDOWS";
387
388 vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["DEFINES"];
389 vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"];
390 vcProject.Configuration.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] );
391}
392
393void VcprojGenerator::initLibrarianTool()
394{
395 vcProject.Configuration.librarian.OutputFile = project->first( "DESTDIR" );
396 if( vcProject.Configuration.librarian.OutputFile.isEmpty() )
397 vcProject.Configuration.librarian.OutputFile = ".\\";
398
399 if( !vcProject.Configuration.librarian.OutputFile.endsWith("\\") )
400 vcProject.Configuration.librarian.OutputFile += '\\';
401
402 vcProject.Configuration.librarian.OutputFile += project->first("MSVCPROJ_TARGET");
403}
404
405void VcprojGenerator::initLinkerTool()
406{
407 vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] );
408 vcProject.Configuration.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"];
409
410 switch ( projectTarget ) {
411 case Application:
412 vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" );
413 break;
414 case SharedLib:
415 vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] );
416 vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" );
417 break;
418 }
419
420 if( vcProject.Configuration.linker.OutputFile.isEmpty() )
421 vcProject.Configuration.linker.OutputFile = ".\\";
422
423 if( !vcProject.Configuration.linker.OutputFile.endsWith("\\") )
424 vcProject.Configuration.linker.OutputFile += '\\';
425
426 vcProject.Configuration.linker.OutputFile += project->first("MSVCPROJ_TARGET");
427 vcProject.Configuration.linker.ProgramDatabaseFile = project->first("OBJECTS_DIR") + project->first("QMAKE_ORIG_TARGET") + ".pdb";
428
429 if ( project->isActiveConfig("debug") ){
430 vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] );
431 } else {
432 vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] );
433 }
434
435 if ( project->isActiveConfig("dll") ){
436 vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] );
437 }
438
439 if ( project->isActiveConfig("console") ){
440 vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] );
441 } else {
442 vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] );
443 }
444
445}
446
447void VcprojGenerator::initIDLTool()
448{
449}
450
451void VcprojGenerator::initCustomBuildTool()
452{
453}
454
455void VcprojGenerator::initPreBuildEventTools()
456{
457 QString collectionName = project->first("QMAKE_IMAGE_COLLECTION");
458 if( !collectionName.isEmpty() ) {
459 QStringList& list = project->variables()["IMAGES"];
460 vcProject.Configuration.preBuild.Description = "Generate imagecollection";
461 //vcProject.Configuration.preBuild.AdditionalDependencies += list;
462 vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " " + list.join(" ") + " -o " + collectionName;
463 //vcProject.Configuration.preBuild.Outputs = collectionName;
464
465 }
466}
467
468void VcprojGenerator::initPostBuildEventTools()
469{
470 if( project->isActiveConfig( "activeqt" ) ) {
471 QString name = project->first( "QMAKE_ORIG_TARGET" );
472 QString nameext = project->first( "TARGET" );
473 QString objdir = project->first( "OBJECTS_DIR" );
474 QString idc = project->first( "QMAKE_IDC" );
475
476 vcProject.Configuration.postBuild.Description = "Finalizing ActiveQt server...";
477
478 if( project->isActiveConfig( "dll" ) ) { // In process
479 vcProject.Configuration.postBuild.CommandLine =
480 // call idc to generate .idl file from .dll
481 idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " -idl " + objdir + name + ".idl -version 1.0 &amp;&amp; " +
482 // call midl to create implementations of the .idl file
483 project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir +
484 "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " +
485 objdir + "dump.midl &amp;&amp; " +
486 // call idc to replace tlb...
487 idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb &amp;&amp; " +
488 // register server
489 idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /regserver";
490 } else { // out of process
491 vcProject.Configuration.postBuild.CommandLine =
492 // call application to dump idl
493 vcProject.Configuration.OutputDirectory + "\\" + nameext + " -dumpidl " + objdir + name + ".idl -version 1.0 &amp;&amp; " +
494 // call midl to create implementations of the .idl file
495 project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir +
496 "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " +
497 objdir + "dump.midl &amp;&amp; " +
498 // call idc to replace tlb...
499 idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb &amp;&amp; " +
500 // call app to register
501 vcProject.Configuration.OutputDirectory + "\\" + nameext + " -regserver";
502 }
503 }
504}
505
506void VcprojGenerator::initPreLinkEventTools()
507{
508}
509
510void VcprojGenerator::initSourceFiles()
511{
512 vcProject.SourceFiles.Name = "Source Files";
513 vcProject.SourceFiles.Filter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat";
514 vcProject.SourceFiles.Files += project->variables()["SOURCES"];
515 vcProject.SourceFiles.Files.sort();
516 vcProject.SourceFiles.Project = this;
517 vcProject.SourceFiles.Config = &(vcProject.Configuration);
518 vcProject.SourceFiles.CustomBuild = none;
519}
520
521void VcprojGenerator::initHeaderFiles()
522{
523 vcProject.HeaderFiles.Name = "Header Files";
524 vcProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl";
525 vcProject.HeaderFiles.Files += project->variables()["HEADERS"];
526 vcProject.HeaderFiles.Files.sort();
527 vcProject.HeaderFiles.Project = this;
528 vcProject.HeaderFiles.Config = &(vcProject.Configuration);
529 vcProject.HeaderFiles.CustomBuild = moc;
530}
531
532void VcprojGenerator::initMOCFiles()
533{
534 vcProject.MOCFiles.Name = "Generated MOC Files";
535 vcProject.MOCFiles.Filter = "cpp;c;cxx;moc";
536 vcProject.MOCFiles.Files += project->variables()["SRCMOC"];
537 vcProject.MOCFiles.Files.sort();
538 vcProject.MOCFiles.Project = this;
539 vcProject.MOCFiles.Config = &(vcProject.Configuration);
540 vcProject.MOCFiles.CustomBuild = moc;
541}
542
543void VcprojGenerator::initUICFiles()
544{
545 vcProject.UICFiles.Name = "Generated UI Files";
546 vcProject.UICFiles.Filter = "cpp;c;cxx;h;hpp;hxx;";
547 vcProject.UICFiles.Project = this;
548 vcProject.UICFiles.Files += project->variables()["UICDECLS"];
549 vcProject.UICFiles.Files += project->variables()["UICIMPLS"];
550 vcProject.UICFiles.Files.sort();
551 vcProject.UICFiles.Config = &(vcProject.Configuration);
552 vcProject.UICFiles.CustomBuild = none;
553}
554
555void VcprojGenerator::initFormsFiles()
556{
557 vcProject.FormFiles.Name = "Forms";
558 vcProject.FormFiles.ParseFiles = _False;
559 vcProject.FormFiles.Filter = "ui";
560 vcProject.FormFiles.Files += project->variables()["FORMS"];
561 vcProject.FormFiles.Files.sort();
562 vcProject.FormFiles.Project = this;
563 vcProject.FormFiles.Config = &(vcProject.Configuration);
564 vcProject.FormFiles.CustomBuild = uic;
565}
566
567void VcprojGenerator::initTranslationFiles()
568{
569 vcProject.TranslationFiles.Name = "Translations Files";
570 vcProject.TranslationFiles.ParseFiles = _False;
571 vcProject.TranslationFiles.Filter = "ts";
572 vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"];
573 vcProject.TranslationFiles.Files.sort();
574 vcProject.TranslationFiles.Project = this;
575 vcProject.TranslationFiles.Config = &(vcProject.Configuration);
576 vcProject.TranslationFiles.CustomBuild = none;
577}
578
579void VcprojGenerator::initLexYaccFiles()
580{
581 vcProject.LexYaccFiles.Name = "Lex / Yacc Files";
582 vcProject.LexYaccFiles.ParseFiles = _False;
583 vcProject.LexYaccFiles.Filter = "l;y";
584 vcProject.LexYaccFiles.Files += project->variables()["LEXSOURCES"];
585 vcProject.LexYaccFiles.Files += project->variables()["YACCSOURCES"];
586 vcProject.LexYaccFiles.Files.sort();
587 vcProject.LexYaccFiles.Project = this;
588 vcProject.LexYaccFiles.CustomBuild = lexyacc;
589}
590
591void VcprojGenerator::initResourceFiles()
592{
593 vcProject.ResourceFiles.Name = "Resources";
594 vcProject.ResourceFiles.ParseFiles = _False;
595 vcProject.ResourceFiles.Filter = "cpp;ico;png;jpg;jpeg;gif;xpm;bmp;rc;ts";
596 vcProject.ResourceFiles.Files += project->variables()["RC_FILE"];
597 vcProject.ResourceFiles.Files += project->variables()["QMAKE_IMAGE_COLLECTION"];
598 vcProject.ResourceFiles.Files += project->variables()["IMAGES"];
599 vcProject.ResourceFiles.Files += project->variables()["IDLSOURCES"];
600 vcProject.ResourceFiles.Files.sort();
601 vcProject.ResourceFiles.Project = this;
602 vcProject.ResourceFiles.CustomBuild = none;
603}
604
605/*
606// $$MSVCPROJ_IDLSOURCES ---------------------------------------------
607void VcprojGenerator::writeIDLs( QTextStream &t )
608{
609 QStringList &l = project->variables()["MSVCPROJ_IDLSOURCES"];
610 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
611 t << "# Begin Source File" << endl << endl;
612 t << "SOURCE=" << (*it) << endl;
613 t << "# PROP Exclude_From_Build 1" << endl;
614 t << "# End Source File" << endl << endl;
615 }
616 debug_msg(3, "Generator: MSVC.NET: Added IDLs" );
617}
618*/
619
620/* \internal
621 Sets up all needed variables from the environment and all the different caches and .conf files
622*/
623
624void VcprojGenerator::initOld()
625{
626 if( init_flag )
627 return;
628
629 init_flag = TRUE;
630 QStringList::Iterator it;
631
632 // this should probably not be here, but I'm using it to wrap the .t files
633 if(project->first("TEMPLATE") == "vcapp" )
634 project->variables()["QMAKE_APP_FLAG"].append("1");
635 else if(project->first("TEMPLATE") == "vclib")
636 project->variables()["QMAKE_LIB_FLAG"].append("1");
637 if ( project->variables()["QMAKESPEC"].isEmpty() )
638 project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") );
639
640 bool is_qt =
641 ( project->first("TARGET") == "qt"QTDLL_POSTFIX ||
642 project->first("TARGET") == "qt-mt"QTDLL_POSTFIX );
643
644 QStringList &configs = project->variables()["CONFIG"];
645
646 if ( project->isActiveConfig( "shared" ) )
647 project->variables()["DEFINES"].append( "QT_DLL" );
648
649 if ( project->isActiveConfig( "qt_dll" ) &&
650 configs.findIndex("qt") == -1 )
651 configs.append("qt");
652
653 if ( project->isActiveConfig( "qt" ) ) {
654 if ( project->isActiveConfig( "plugin" ) ) {
655 project->variables()["CONFIG"].append( "dll" );
656 project->variables()["DEFINES"].append( "QT_PLUGIN" );
657 }
658 if ( ( project->variables()["DEFINES"].findIndex( "QT_NODLL" ) == -1 ) &&
659 (( project->variables()["DEFINES"].findIndex( "QT_MAKEDLL" ) != -1 ||
660 project->variables()["DEFINES"].findIndex( "QT_DLL" ) != -1 ) ||
661 ( getenv( "QT_DLL" ) && !getenv( "QT_NODLL" ))) ) {
662 project->variables()["QMAKE_QT_DLL"].append( "1" );
663 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
664 project->variables()["CONFIG"].append( "dll" );
665 }
666 }
667
668 // If we are a dll, then we cannot be a staticlib at the same time...
669 if ( project->isActiveConfig( "dll" ) || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
670 project->variables()["CONFIG"].remove( "staticlib" );
671 project->variables()["QMAKE_APP_OR_DLL"].append( "1" );
672 } else {
673 project->variables()["CONFIG"].append( "staticlib" );
674 }
675
676 // If we need 'qt' and/or 'opengl', then we need windows and not console
677 if ( project->isActiveConfig( "qt" ) || project->isActiveConfig( "opengl" ) ) {
678 project->variables()["CONFIG"].append( "windows" );
679 }
680
681 // Decode version, and add it to $$MSVCPROJ_VERSION --------------
682 if ( !project->variables()["VERSION"].isEmpty() ) {
683 QString version = project->variables()["VERSION"][0];
684 int firstDot = version.find( "." );
685 QString major = version.left( firstDot );
686 QString minor = version.right( version.length() - firstDot - 1 );
687 minor.replace( QRegExp( "\\." ), "" );
688 project->variables()["MSVCPROJ_VERSION"].append( "/VERSION:" + major + "." + minor );
689 }
690
691 // QT ------------------------------------------------------------
692 if ( project->isActiveConfig("qt") ) {
693 project->variables()["CONFIG"].append("moc");
694 project->variables()["INCLUDEPATH"] +=project->variables()["QMAKE_INCDIR_QT"];
695 project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
696
697 if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
698 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
699 project->variables()["DEFINES"].append("QT_MAKEDLL");
700 project->variables()["QMAKE_LFLAGS"].append("/BASE:0x39D00000");
701 }
702 } else {
703 if(project->isActiveConfig("thread"))
704 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
705 else
706 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
707 if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
708 int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
709 if( hver==-1 ) {
710 hver = findHighestVersion( project->first("QMAKE_LIBDIR_QT"), "qt-mt" );
711 }
712
713 if(hver != -1) {
714 QString ver;
715 ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
716 QStringList &libs = project->variables()["QMAKE_LIBS"];
717 for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
718 (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
719 }
720 }
721 if ( project->isActiveConfig( "activeqt" ) ) {
722 project->variables().remove("QMAKE_LIBS_QT_ENTRY");
723 project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
724 if ( project->isActiveConfig( "dll" ) ) {
725 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
726 project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE"));
727 }
728 }
729 if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
730 project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
731 }
732 }
733 }
734
735 // Set target directories ----------------------------------------
736 // if ( !project->first("OBJECTS_DIR").isEmpty() )
737 //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->first("OBJECTS_DIR");
738 // else
739 //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->isActiveConfig( "release" )?"Release":"Debug";
740 // if ( !project->first("DESTDIR").isEmpty() )
741 //project->variables()["MSVCPROJ_TARGETDIR"] = project->first("DESTDIR");
742 // else
743 //project->variables()["MSVCPROJ_TARGETDIR"] = project->isActiveConfig( "release" )?"Release":"Debug";
744
745 // OPENGL --------------------------------------------------------
746 if ( project->isActiveConfig("opengl") ) {
747 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
748 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
749 }
750
751 // THREAD --------------------------------------------------------
752 if ( project->isActiveConfig("thread") ) {
753 if(project->isActiveConfig("qt"))
754 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" );
755 if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt
756 && project->first("TARGET") != "qtmain" )
757 project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:libc");
758 }
759
760 // ACCESSIBILITY -------------------------------------------------
761 if(project->isActiveConfig("qt")) {
762 if ( project->isActiveConfig("accessibility" ) )
763 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
764 if ( project->isActiveConfig("tablet") )
765 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
766 }
767
768 // DLL -----------------------------------------------------------
769 if ( project->isActiveConfig("dll") ) {
770 if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
771 QString ver_xyz(project->first("VERSION"));
772 ver_xyz.replace(QRegExp("\\."), "");
773 project->variables()["TARGET_EXT"].append(ver_xyz + ".dll");
774 } else {
775 project->variables()["TARGET_EXT"].append(".dll");
776 }
777 }
778 // EXE / LIB -----------------------------------------------------
779 else {
780 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() )
781 project->variables()["TARGET_EXT"].append(".exe");
782 else
783 project->variables()["TARGET_EXT"].append(".lib");
784 }
785
786 project->variables()["MSVCPROJ_VER"] = "7.00";
787 project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /ZI";
788
789 // INCREMENTAL:NO ------------------------------------------------
790 if(!project->isActiveConfig("incremental")) {
791 project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
792 if ( is_qt )
793 project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /Zi";
794 }
795
796 // MOC -----------------------------------------------------------
797 if ( project->isActiveConfig("moc") )
798 setMocAware(TRUE);
799
800
801 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
802
803 // Run through all variables containing filepaths, and -----------
804 // slash-slosh them correctly depending on current OS -----------
805 project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
806 QStringList &l = project->variables()["QMAKE_FILETAGS"];
807 for(it = l.begin(); it != l.end(); ++it) {
808 QStringList &gdmf = project->variables()[(*it)];
809 for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
810 (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
811 }
812
813 // Get filename w/o extention -----------------------------------
814 QString msvcproj_project = "";
815 QString targetfilename = "";
816 if ( project->variables()["TARGET"].count() ) {
817 msvcproj_project = project->variables()["TARGET"].first();
818 targetfilename = msvcproj_project;
819 }
820
821 // Save filename w/o extention in $$QMAKE_ORIG_TARGET ------------
822 project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
823
824 // TARGET (add extention to $$TARGET) ----------------------------
825 project->variables()["TARGET"].first() += project->first("TARGET_EXT");
826
827 // Init base class too -------------------------------------------
828 MakefileGenerator::init();
829
830
831 if ( msvcproj_project.isEmpty() )
832 msvcproj_project = Option::output.name();
833
834 msvcproj_project = msvcproj_project.right( msvcproj_project.length() - msvcproj_project.findRev( "\\" ) - 1 );
835 msvcproj_project = msvcproj_project.left( msvcproj_project.findRev( "." ) );
836 msvcproj_project.replace(QRegExp("-"), "");
837
838 project->variables()["MSVCPROJ_PROJECT"].append(msvcproj_project);
839 QStringList &proj = project->variables()["MSVCPROJ_PROJECT"];
840
841 for(it = proj.begin(); it != proj.end(); ++it)
842 (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), "");
843
844 // SUBSYSTEM -----------------------------------------------------
845 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
846 project->variables()["MSVCPROJ_TEMPLATE"].append("win32app" + project->first( "VCPROJ_EXTENSION" ) );
847 if ( project->isActiveConfig("console") ) {
848 project->variables()["MSVCPROJ_CONSOLE"].append("CONSOLE");
849 project->variables()["MSVCPROJ_WINCONDEF"].append("_CONSOLE");
850 project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0103");
851 project->variables()["MSVCPROJ_SUBSYSTEM"].append("CONSOLE");
852 } else {
853 project->variables()["MSVCPROJ_CONSOLE"].clear();
854 project->variables()["MSVCPROJ_WINCONDEF"].append("_WINDOWS");
855 project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0101");
856 project->variables()["MSVCPROJ_SUBSYSTEM"].append("WINDOWS");
857 }
858 } else {
859 if ( project->isActiveConfig("dll") ) {
860 project->variables()["MSVCPROJ_TEMPLATE"].append("win32dll" + project->first( "VCPROJ_EXTENSION" ) );
861 } else {
862 project->variables()["MSVCPROJ_TEMPLATE"].append("win32lib" + project->first( "VCPROJ_EXTENSION" ) );
863 }
864 }
865
866 // $$QMAKE.. -> $$MSVCPROJ.. -------------------------------------
867 project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS"];
868 project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
869 project->variables()["MSVCPROJ_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"];
870 if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
871 project->variables()["MSVCPROJ_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:"," /LIBPATH:",""));
872 project->variables()["MSVCPROJ_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"];
873 // We don't use this... Direct manipulation of compiler object
874 //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ",""));
875 //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ",""));
876 QStringList &incs = project->variables()["INCLUDEPATH"];
877 for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
878 QString inc = (*incit);
879 inc.replace(QRegExp("\""), "");
880 project->variables()["MSVCPROJ_INCPATH"].append("/I" + inc );
881 }
882 project->variables()["MSVCPROJ_INCPATH"].append("/I" + specdir());
883
884 QString dest;
885 project->variables()["MSVCPROJ_TARGET"] = project->first("TARGET");
886 if ( !project->variables()["DESTDIR"].isEmpty() ) {
887 project->variables()["TARGET"].first().prepend(project->first("DESTDIR"));
888 Option::fixPathToTargetOS(project->first("TARGET"));
889 dest = project->first("TARGET");
890 if ( project->first("TARGET").startsWith("$(QTDIR)") )
891 dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") );
892 project->variables()["MSVCPROJ_TARGET"].append(
893 QString("/OUT:") + dest );
894 if ( project->isActiveConfig("dll") ) {
895 QString imp = dest;
896 imp.replace(QRegExp("\\.dll"), ".lib");
897 project->variables()["MSVCPROJ_LIBOPTIONS"] += (QString("/IMPLIB:") + imp );
898 }
899 }
900
901 // DLL COPY ------------------------------------------------------
902 if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) {
903 QStringList dlldirs = project->variables()["DLLDESTDIR"];
904 QString copydll = "# Begin Special Build Tool\n"
905 "TargetPath=" + dest + "\n"
906 "SOURCE=$(InputPath)\n"
907 "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n"
908 "PostBuild_Cmds=";
909
910 for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
911 copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t";
912 }
913
914 copydll += "\n# End Special Build Tool";
915 project->variables()["MSVCPROJ_COPY_DLL_REL"].append( copydll );
916 project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( copydll );
917 }
918
919 // ACTIVEQT ------------------------------------------------------
920 if ( project->isActiveConfig("activeqt") ) {
921 QString idl = project->variables()["QMAKE_IDL"].first();
922 QString idc = project->variables()["QMAKE_IDC"].first();
923 QString version = project->variables()["VERSION"].first();
924 if ( version.isEmpty() )
925 version = "1.0";
926
927 project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" );
928 project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" );
929 project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" );
930 if ( project->isActiveConfig( "dll" ) ) {
931 QString regcmd = "# Begin Special Build Tool\n"
932 "TargetPath=" + targetfilename + "\n"
933 "SOURCE=$(InputPath)\n"
934 "PostBuild_Desc=Finalizing ActiveQt server...\n"
935 "PostBuild_Cmds=" +
936 idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version +
937 "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"
938 "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"
939 "\tregsvr32 /s %1\n"
940 "# End Special Build Tool";
941
942 QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first();
943 project->variables()["MSVCPROJ_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) );
944
945 executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first();
946 project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) );
947 } else {
948 QString regcmd = "# Begin Special Build Tool\n"
949 "TargetPath=" + targetfilename + "\n"
950 "SOURCE=$(InputPath)\n"
951 "PostBuild_Desc=Finalizing ActiveQt server...\n"
952 "PostBuild_Cmds="
953 "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version +
954 "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"
955 "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"
956 "\t%1 -regserver\n"
957 "# End Special Build Tool";
958
959 QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first();
960 project->variables()["MSVCPROJ_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) );
961
962 executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first();
963 project->variables()["MSVCPROJ_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) );
964 }
965
966 }
967
968 // FORMS ---------------------------------------------------------
969 QStringList &list = project->variables()["FORMS"];
970 for( it = list.begin(); it != list.end(); ++it ) {
971 if ( QFile::exists( *it + ".h" ) )
972 project->variables()["SOURCES"].append( *it + ".h" );
973 }
974
975 project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCPROJ_LFLAGS" << "MSVCPROJ_LIBS";
976
977 // Verbose output if "-d -d"...
978 outputVariables();
979}
980
981// ------------------------------------------------------------------------------------------------
982// ------------------------------------------------------------------------------------------------
983
984bool VcprojGenerator::openOutput(QFile &file) const
985{
986 QString outdir;
987 if(!file.name().isEmpty()) {
988 QFileInfo fi(file);
989 if(fi.isDir())
990 outdir = file.name() + QDir::separator();
991 }
992 if(!outdir.isEmpty() || file.name().isEmpty()) {
993 QString ext = project->first("VCPROJ_EXTENSION");
994 if(project->first("TEMPLATE") == "vcsubdirs")
995 ext = project->first("VCSOLUTION_EXTENSION");
996 file.setName(outdir + project->first("TARGET") + ext);
997 }
998 if(QDir::isRelativePath(file.name())) {
999 QString ofile;
1000 ofile = file.name();
1001 int slashfind = ofile.findRev('\\');
1002 if (slashfind == -1) {
1003 ofile = ofile.replace("-", "_");
1004 } else {
1005 int hypenfind = ofile.find('-', slashfind);
1006 while (hypenfind != -1 && slashfind < hypenfind) {
1007 ofile = ofile.replace(hypenfind, 1, "_");
1008 hypenfind = ofile.find('-', hypenfind + 1);
1009 }
1010 }
1011 file.setName(Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + ofile));
1012 }
1013 return Win32MakefileGenerator::openOutput(file);
1014}
1015
1016QString VcprojGenerator::findTemplate(QString file)
1017{
1018 QString ret;
1019 if(!QFile::exists((ret = file)) &&
1020 !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) &&
1021 !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc.net/" + file)) &&
1022 !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file))))
1023 return "";
1024 debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.latin1() );
1025 return ret;
1026}
1027
1028
1029void VcprojGenerator::processPrlVariable(const QString &var, const QStringList &l)
1030{
1031 if(var == "QMAKE_PRL_DEFINES") {
1032 QStringList &out = project->variables()["MSVCPROJ_DEFINES"];
1033 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
1034 if(out.findIndex((*it)) == -1)
1035 out.append((" /D " + *it ));
1036 }
1037 } else {
1038 MakefileGenerator::processPrlVariable(var, l);
1039 }
1040}
1041
1042void VcprojGenerator::outputVariables()
1043{
1044#if 0
1045 debug_msg(3, "Generator: MSVC.NET: List of current variables:" );
1046 for ( QMap<QString, QStringList>::ConstIterator it = project->variables().begin(); it != project->variables().end(); ++it) {
1047 debug_msg(3, "Generator: MSVC.NET: %s => %s", it.key().latin1(), it.data().join(" | ").latin1() );
1048 }
1049#endif
1050}
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
new file mode 100644
index 0000000..583b164
--- a/dev/null
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -0,0 +1,129 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of VcprojGenerator class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __VCPROJMAKE_H__
38#define __VCPROJMAKE_H__
39
40#include "winmakefile.h"
41#include "msvc_objectmodel.h"
42
43enum target {
44 Application,
45 SharedLib,
46 StaticLib
47};
48
49class VcprojGenerator : public Win32MakefileGenerator
50{
51 bool init_flag;
52 bool writeVcprojParts(QTextStream &);
53
54 bool writeMakefile(QTextStream &);
55 virtual void writeSubDirs(QTextStream &t);
56 QString findTemplate(QString file);
57 void init();
58
59public:
60 VcprojGenerator(QMakeProject *p);
61 ~VcprojGenerator();
62
63 QString defaultMakefile() const;
64 virtual bool doDepends() const { return FALSE; } //never necesary
65
66protected:
67 virtual bool openOutput(QFile &file) const;
68 virtual void processPrlVariable(const QString &, const QStringList &);
69 virtual bool findLibraries();
70 virtual void outputVariables();
71
72 void initOld();
73 void initProject();
74 void initConfiguration();
75 void initCompilerTool();
76 void initLinkerTool();
77 void initLibrarianTool();
78 void initIDLTool();
79 void initCustomBuildTool();
80 void initPreBuildEventTools();
81 void initPostBuildEventTools();
82 void initPreLinkEventTools();
83 void initSourceFiles();
84 void initHeaderFiles();
85 void initMOCFiles();
86 void initUICFiles();
87 void initFormsFiles();
88 void initTranslationFiles();
89 void initLexYaccFiles();
90 void initResourceFiles();
91
92 /*
93 void writeGuid( QTextStream &t );
94 void writeAdditionalOptions( QTextStream &t );
95 void writeHeaders( QTextStream &t );
96 void writeSources( QTextStream &t );
97 void writeMocs( QTextStream &t );
98 void writeLexs( QTextStream &t );
99 void writeYaccs( QTextStream &t );
100 void writePictures( QTextStream &t );
101 void writeImages( QTextStream &t );
102 void writeIDLs( QTextStream &t );
103
104 void writeForms( QTextStream &t );
105 void writeFormsSourceHeaders( QString &variable, QTextStream &t );
106 void writeTranslations( QTextStream &t );
107 void writeStrippedTranslations( QTextStream &t );
108 */
109
110 VCProject vcProject;
111 target projectTarget;
112
113 friend class VCFilter;
114};
115
116inline VcprojGenerator::~VcprojGenerator()
117{ }
118
119inline QString VcprojGenerator::defaultMakefile() const
120{
121 return project->first("TARGET") + project->first("VCPROJ_EXTENSION");
122}
123
124inline bool VcprojGenerator::findLibraries()
125{
126 return Win32MakefileGenerator::findLibraries("MSVCVCPROJ_LIBS");
127}
128
129#endif /* __VCPROJMAKE_H__ */
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
new file mode 100644
index 0000000..a07c921
--- a/dev/null
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -0,0 +1,360 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "winmakefile.h"
39#include "option.h"
40#include "project.h"
41#include <qtextstream.h>
42#include <qstring.h>
43#include <qdict.h>
44#include <qregexp.h>
45#include <qstringlist.h>
46#include <qdir.h>
47
48
49Win32MakefileGenerator::Win32MakefileGenerator(QMakeProject *p) : MakefileGenerator(p)
50{
51
52}
53
54
55struct SubDir
56{
57 QString directory, profile, target, makefile;
58};
59
60void
61Win32MakefileGenerator::writeSubDirs(QTextStream &t)
62{
63 QPtrList<SubDir> subdirs;
64 {
65 QStringList subdirs_in = project->variables()["SUBDIRS"];
66 for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) {
67 QString file = (*it);
68 file = fileFixify(file);
69 SubDir *sd = new SubDir;
70 subdirs.append(sd);
71 sd->makefile = "$(MAKEFILE)";
72 if((*it).right(4) == ".pro") {
73 int slsh = file.findRev(Option::dir_sep);
74 if(slsh != -1) {
75 sd->directory = file.left(slsh+1);
76 sd->profile = file.mid(slsh+1);
77 } else {
78 sd->profile = file;
79 }
80 } else {
81 sd->directory = file;
82 }
83 while(sd->directory.right(1) == Option::dir_sep)
84 sd->directory = sd->directory.left(sd->directory.length() - 1);
85 if(!sd->profile.isEmpty()) {
86 QString basename = sd->directory;
87 int new_slsh = basename.findRev(Option::dir_sep);
88 if(new_slsh != -1)
89 basename = basename.mid(new_slsh+1);
90 if(sd->profile != basename + ".pro")
91 sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro
92 }
93 sd->target = "sub-" + (*it);
94 sd->target.replace('/', '-');
95 sd->target.replace('.', '_');
96 }
97 }
98 QPtrListIterator<SubDir> it(subdirs);
99
100 if(!project->isEmpty("MAKEFILE"))
101 t << "MAKEFILE=" << var("MAKEFILE") << endl;
102 t << "QMAKE =" << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
103 t << "SUBTARGETS= ";
104 for( it.toFirst(); it.current(); ++it)
105 t << " \\\n\t\t" << it.current()->target;
106 t << endl << endl;
107 t << "all: qmake_all $(SUBTARGETS)" << endl << endl;
108
109 for( it.toFirst(); it.current(); ++it) {
110 bool have_dir = !(*it)->directory.isEmpty();
111
112 //make the makefile
113 QString mkfile = (*it)->makefile;
114 if(have_dir)
115 mkfile.prepend((*it)->directory + Option::dir_sep);
116 t << mkfile << ":";
117 if(project->variables()["QMAKE_NOFORCE"].isEmpty())
118 t << " FORCE";
119 if(have_dir)
120 t << "\n\t" << "cd " << (*it)->directory;
121 t << "\n\t" << "$(QMAKE) " << (*it)->profile << " " << buildArgs();
122 if((*it)->makefile != "$(MAKEFILE)")
123 t << " -o " << (*it)->makefile;
124 if(have_dir) {
125 int subLevels = it.current()->directory.contains(Option::dir_sep) + 1;
126 t << "\n\t" << "@cd ..";
127 for(int i = 1; i < subLevels; i++ )
128 t << Option::dir_sep << "..";
129 }
130 t << endl;
131
132 //now actually build
133 t << (*it)->target << ": " << mkfile;
134 if(project->variables()["QMAKE_NOFORCE"].isEmpty())
135 t << " FORCE";
136 if(have_dir)
137 t << "\n\t" << "cd " << (*it)->directory;
138 t << "\n\t" << "$(MAKE)";
139 if((*it)->makefile != "$(MAKEFILE)")
140 t << " -f " << (*it)->makefile;
141 if(have_dir) {
142 int subLevels = it.current()->directory.contains(Option::dir_sep) + 1;
143 t << "\n\t" << "@cd ..";
144 for(int i = 1; i < subLevels; i++ )
145 t << Option::dir_sep << "..";
146 }
147 t << endl << endl;
148 }
149
150 if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1)
151 project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all");
152 writeMakeQmake(t);
153
154 t << "qmake_all:";
155 if ( !subdirs.isEmpty() ) {
156 for( it.toFirst(); it.current(); ++it) {
157 QString subdir = (*it)->directory;
158 int subLevels = subdir.contains(Option::dir_sep) + 1;
159 t << "\n\t"
160 << "cd " << subdir << "\n\t";
161 int lastSlash = subdir.findRev(Option::dir_sep);
162 if(lastSlash != -1)
163 subdir = subdir.mid( lastSlash + 1 );
164 t << "$(QMAKE) " << subdir << ".pro"
165 << (!project->isEmpty("MAKEFILE") ? QString(" -o ") + var("MAKEFILE") : QString(""))
166 << " " << buildArgs() << "\n\t"
167 << "@cd ..";
168 for(int i = 1; i < subLevels; i++ )
169 t << Option::dir_sep << "..";
170 }
171 } else {
172 // Borland make does not like empty an empty command section, so insert
173 // a dummy command.
174 t << "\n\t" << "@cd .";
175 }
176 t << endl << endl;
177
178 QString targs[] = { QString("clean"), QString("install"), QString("mocclean"), QString::null };
179 for(int x = 0; targs[x] != QString::null; x++) {
180 t << targs[x] << ": qmake_all";
181 if(targs[x] == "clean")
182 t << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ", "");
183 if (!subdirs.isEmpty()) {
184 for( it.toFirst(); it.current(); ++it) {
185 int subLevels = (*it)->directory.contains(Option::dir_sep) + 1;
186 bool have_dir = !(*it)->directory.isEmpty();
187 if(have_dir)
188 t << "\n\t" << "cd " << (*it)->directory;
189 QString in_file;
190 if((*it)->makefile != "$(MAKEFILE)")
191 in_file = " -f " + (*it)->makefile;
192 t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x];
193 if(have_dir) {
194 t << "\n\t" << "@cd ..";
195 for(int i = 1; i < subLevels; i++ )
196 t << Option::dir_sep << "..";
197 }
198 }
199 } else {
200 // Borland make does not like empty an empty command section, so
201 // insert a dummy command.
202 t << "\n\t" << "@cd .";
203 }
204 t << endl << endl;
205 }
206
207 if(project->variables()["QMAKE_NOFORCE"].isEmpty())
208 t << "FORCE:" << endl << endl;
209}
210
211
212int
213Win32MakefileGenerator::findHighestVersion(const QString &d, const
214 QString &stem)
215{
216 if(!QFile::exists(Option::fixPathToLocalOS(d)))
217 return -1;
218 if(!project->variables()["QMAKE_" + stem.upper() +
219 "_VERSION_OVERRIDE"].isEmpty())
220 return project->variables()["QMAKE_" + stem.upper() +
221 "_VERSION_OVERRIDE"].first().toInt();
222 QString bd = d;
223 fixEnvVariables(bd);
224 QDir dir(bd);
225 int biggest=-1;
226 QStringList entries = dir.entryList();
227 QRegExp regx( "(" + stem + "([0-9]*)).lib", FALSE );
228 for(QStringList::Iterator it = entries.begin(); it != entries.end();
229 ++it) {
230 if(regx.exactMatch((*it)))
231 biggest = QMAX(biggest, (regx.cap(1) == stem ||
232 regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt());
233 }
234 return biggest;
235}
236
237
238bool
239Win32MakefileGenerator::findLibraries(const QString &where)
240{
241
242 QStringList &l = project->variables()[where];
243 QPtrList<MakefileDependDir> dirs;
244 dirs.setAutoDelete(TRUE);
245 for(QStringList::Iterator it = l.begin(); it != l.end(); ) {
246 QString opt = (*it);
247 bool remove = FALSE;
248 if(opt.startsWith("-L") || opt.startsWith("/L")) {
249 QString r = opt.right(opt.length() - 2), l = Option::fixPathToLocalOS(r);
250 dirs.append(new MakefileDependDir(r.replace("\"",""),
251 l.replace("\"","")));
252 remove = TRUE;
253 } else if(opt.startsWith("-l") || opt.startsWith("/l")) {
254 QString lib = opt.right(opt.length() - 2), out;
255 if(!lib.isEmpty()) {
256 for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) {
257 int ver = findHighestVersion(mdd->local_dir, lib);
258 if(ver > 0)
259 lib += QString::number(ver);
260 lib += ".lib";
261 if(QFile::exists(mdd->local_dir + Option::dir_sep + lib)) {
262 out = mdd->real_dir + Option::dir_sep + lib;
263 break;
264 }
265 }
266 }
267 if(out.isEmpty())
268 remove = TRUE;
269 else
270 (*it) = out;
271 } else if(!QFile::exists(Option::fixPathToLocalOS(opt))) {
272 QString dir, file = opt;
273 int slsh = file.findRev(Option::dir_sep);
274 if(slsh != -1) {
275 dir = file.left(slsh+1);
276 file = file.right(file.length() - slsh - 1);
277 }
278 if ( !(project->variables()["QMAKE_QT_DLL"].isEmpty() && (file == "qt.lib" || file == "qt-mt.lib")) ) {
279 if(file.endsWith(".lib")) {
280 file = file.left(file.length() - 4);
281 if(!file.at(file.length()-1).isNumber()) {
282 int ver = findHighestVersion(dir, file);
283 if(ver != -1) {
284 file = QString(dir + file + "%1" + ".lib");
285 if(ver)
286 (*it) = file.arg(ver);
287 else
288 (*it) = file.arg("");
289 }
290 }
291 }
292 }
293 }
294 if(remove)
295 it = l.remove(it);
296 else
297 ++it;
298 }
299 return TRUE;
300}
301
302void
303Win32MakefileGenerator::processPrlFiles()
304{
305 QDict<void> processed;
306 QPtrList<MakefileDependDir> libdirs;
307 libdirs.setAutoDelete(TRUE);
308 {
309 QStringList &libpaths = project->variables()["QMAKE_LIBDIR"];
310 for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) {
311 QString r = (*libpathit), l = r;
312 fixEnvVariables(l);
313 libdirs.append(new MakefileDependDir(r.replace("\"",""),
314 l.replace("\"","")));
315 }
316 }
317 for(bool ret = FALSE; TRUE; ret = FALSE) {
318 //read in any prl files included..
319 QStringList l_out;
320 QString where = "QMAKE_LIBS";
321 if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
322 where = project->first("QMAKE_INTERNAL_PRL_LIBS");
323 QStringList &l = project->variables()[where];
324 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
325 QString opt = (*it);
326 if(opt.left(1) == "/") {
327 if(opt.left(9) == "/LIBPATH:") {
328 QString r = opt.mid(9), l = r;
329 fixEnvVariables(l);
330 libdirs.append(new MakefileDependDir(r.replace("\"",""),
331 l.replace("\"","")));
332 }
333 } else {
334 if(!processed[opt]) {
335 if(processPrlFile(opt)) {
336 processed.insert(opt, (void*)1);
337 ret = TRUE;
338 } else {
339 for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
340 QString prl = mdd->local_dir + Option::dir_sep + opt;
341 if(processed[prl]) {
342 break;
343 } else if(processPrlFile(prl)) {
344 processed.insert(prl, (void*)1);
345 ret = TRUE;
346 break;
347 }
348 }
349 }
350 }
351 }
352 if(!opt.isEmpty())
353 l_out.append(opt);
354 }
355 if(ret)
356 l = l_out;
357 else
358 break;
359 }
360}
diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h
new file mode 100644
index 0000000..75ba0e0
--- a/dev/null
+++ b/qmake/generators/win32/winmakefile.h
@@ -0,0 +1,72 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __WINMAKEFILE_H__
38#define __WINMAKEFILE_H__
39
40#include "makefile.h"
41
42// In the Qt evaluation and educational version, we have a postfix in the
43// library name (e.g. qtmteval301.dll). QTDLL_POSTFIX is used for this.
44// A script modifies these lines when building eval/edu version, so be careful
45// when changing them.
46#ifndef QTDLL_POSTFIX
47#define QTDLL_POSTFIX ""
48#endif
49
50class Win32MakefileGenerator : public MakefileGenerator
51{
52protected:
53 virtual void writeSubDirs(QTextStream &t);
54 int findHighestVersion(const QString &dir, const QString &stem);
55 bool findLibraries(const QString &);
56 virtual bool findLibraries();
57 virtual void processPrlFiles();
58
59public:
60 Win32MakefileGenerator(QMakeProject *p);
61 ~Win32MakefileGenerator();
62};
63
64inline Win32MakefileGenerator::~Win32MakefileGenerator()
65{ }
66
67inline bool Win32MakefileGenerator::findLibraries()
68{ return findLibraries("QMAKE_LIBS"); }
69
70
71
72#endif /* __WINMAKEFILE_H__ */
diff --git a/qmake/include/private/qapplication_p.h b/qmake/include/private/qapplication_p.h
new file mode 100644
index 0000000..6fab6b3
--- a/dev/null
+++ b/qmake/include/private/qapplication_p.h
@@ -0,0 +1,87 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of some Qt private functions.
5**
6** Created : 000228
7**
8** Copyright (C) 2000-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#ifndef QAPPLICATION_P_H
39#define QAPPLICATION_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
48// and many other. This header file may change from version to version
49// without notice, or even be removed.
50//
51// We mean it.
52//
53//
54
55#ifndef QT_H
56#endif // QT_H
57
58class QWidget;
59class QObject;
60class QClipboard;
61class QKeyEvent;
62class QMouseEvent;
63class QWheelEvent;
64
65extern Q_EXPORT bool qt_modal_state();
66extern Q_EXPORT void qt_enter_modal( QWidget* );
67extern Q_EXPORT void qt_leave_modal( QWidget* );
68
69extern bool qt_is_gui_used;
70#ifndef QT_NO_CLIPBOARD
71extern QClipboard *qt_clipboard;
72#endif
73
74#if defined (Q_OS_WIN32) || defined (Q_OS_CYGWIN)
75extern Qt::WindowsVersion qt_winver;
76#endif
77
78#if defined (Q_WS_X11)
79extern int qt_ncols_option;
80#endif
81
82
83extern void qt_dispatchEnterLeave( QWidget*, QWidget* );
84
85
86
87#endif
diff --git a/qmake/include/private/qcolor_p.h b/qmake/include/private/qcolor_p.h
new file mode 100644
index 0000000..942a803
--- a/dev/null
+++ b/qmake/include/private/qcolor_p.h
@@ -0,0 +1,63 @@
1/****************************************************************************
2** $Id$
3**
4** Named color support for non-X platforms.
5** The color names have been borrowed from X.
6**
7** Created : 000228
8**
9** Copyright (C) 2000 Trolltech AS. All rights reserved.
10**
11** This file is part of the kernel 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#ifndef QCOLOR_P_H
40#define QCOLOR_P_H
41
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of qmenudata.cpp, qmenubar.cpp, qmenubar.cpp, qpopupmenu.cpp,
49// qmotifstyle.cpp and qwindowssstyle.cpp. This header file may change
50// from version to version without notice, or even be removed.
51//
52// We mean it.
53//
54//
55
56#ifndef QT_H
57#endif // QT_H
58
59extern uint qt_get_rgb_val( const char *name );
60extern bool qt_get_named_rgb( const char *, QRgb* );
61extern void qt_reset_color_avail();
62
63#endif
diff --git a/qmake/include/private/qcom_p.h b/qmake/include/private/qcom_p.h
new file mode 100644
index 0000000..6e7e1c8
--- a/dev/null
+++ b/qmake/include/private/qcom_p.h
@@ -0,0 +1,337 @@
1/****************************************************************************
2** $Id$
3**
4** ...
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#ifndef QCOM_H
37#define QCOM_H
38
39//
40// W A R N I N G
41// -------------
42//
43// This file is not part of the Qt API. It exists for the convenience
44// of a number of Qt sources files. This header file may change from
45// version to version without notice, or even be removed.
46//
47// We mean it.
48//
49//
50
51#ifndef QT_H
52#include "qstringlist.h"
53#include "quuid.h"
54#endif // QT_H
55
56#ifndef QT_NO_COMPONENT
57
58class QObject;
59struct QUInterfaceDescription;
60struct QUObject;
61
62 #define QRESULT unsigned long
63 #define QS_OK (QRESULT)0x00000000
64 #define QS_FALSE(QRESULT)0x00000001
65
66#define QE_NOTIMPL (QRESULT)0x80000001
67#define QE_OUTOFMEMORY (QRESULT)0x80000002
68 #define QE_INVALIDARG(QRESULT)0x80000003
69 #define QE_NOINTERFACE(QRESULT)0x80000004
70 #define QE_NOCOMPONENT(QRESULT)0x80000005
71
72
73// {1D8518CD-E8F5-4366-99E8-879FD7E482DE}
74#ifndef IID_QUnknown
75#define IID_QUnknown QUuid(0x1d8518cd, 0xe8f5, 0x4366, 0x99, 0xe8, 0x87, 0x9f, 0xd7, 0xe4, 0x82, 0xde)
76#endif
77
78struct Q_EXPORT QUnknownInterface
79{
80 virtual QRESULT queryInterface( const QUuid&, QUnknownInterface** ) = 0;
81 virtual ulong addRef() = 0;
82 virtual ulong release() = 0;
83};
84
85// {FBAC965E-A441-413F-935E-CDF582573FAB}
86#ifndef IID_QDispatch
87#define IID_QDispatch QUuid( 0xfbac965e, 0xa441, 0x413f, 0x93, 0x5e, 0xcd, 0xf5, 0x82, 0x57, 0x3f, 0xab)
88#endif
89
90// the dispatch interface that inherits the unknown interface.. It is
91// used to explore interfaces during runtime and to do dynamic calls.
92struct Q_EXPORT QDispatchInterface : public QUnknownInterface
93{
94 // returns the interface description of this dispatch interface.
95 virtual const QUInterfaceDescription* interfaceDescription() const = 0;
96
97 // returns the event description of this dispatch interface.
98 virtual const QUInterfaceDescription* eventsDescription() const = 0;
99
100 // invokes method id with parameters V*. Returns some sort of
101 // exception code.
102 virtual QRESULT invoke( int id, QUObject* o ) = 0;
103
104 // installs listener as event listener
105 virtual void installListener( QDispatchInterface* listener ) = 0;
106
107 // remove listener as event listener
108 virtual void removeListener( QDispatchInterface* listener ) = 0;
109};
110
111template <class T>
112class QInterfacePtr
113{
114public:
115 QInterfacePtr():iface(0){}
116
117 QInterfacePtr( T* i) {
118 if ( (iface = i) )
119 iface->addRef();
120 }
121
122 QInterfacePtr(const QInterfacePtr<T> &p) {
123 if ( (iface = p.iface) )
124 iface->addRef();
125 }
126
127 ~QInterfacePtr() {
128 if ( iface )
129 iface->release();
130 }
131
132 QInterfacePtr<T> &operator=(const QInterfacePtr<T> &p) {
133 if ( iface != p.iface ) {
134 if ( iface )
135 iface->release();
136 if ( (iface = p.iface) )
137 iface->addRef();
138 }
139 return *this;
140 }
141
142 QInterfacePtr<T> &operator=(T* i) {
143 if (iface != i ) {
144 if ( iface )
145 iface->release();
146 if ( (iface = i) )
147 iface->addRef();
148 }
149 return *this;
150 }
151
152 bool operator==( const QInterfacePtr<T> &p ) const { return iface == p.iface; }
153
154 bool operator!= ( const QInterfacePtr<T>& p ) const { return !( *this == p ); }
155
156 bool isNull() const { return !iface; }
157
158 T* operator->() const { return iface; }
159
160 T& operator*() const { return *iface; }
161
162 operator T*() const { return iface; }
163
164 QUnknownInterface** operator &() const {
165 if( iface )
166 iface->release();
167 return (QUnknownInterface**)&iface;
168 }
169
170 T** operator &() {
171 if ( iface )
172 iface->release();
173 return &iface;
174 }
175
176private:
177 T* iface;
178};
179
180// {10A1501B-4C5F-4914-95DD-C400486CF900}
181#ifndef IID_QObject
182#define IID_QObject QUuid( 0x10a1501b, 0x4c5f, 0x4914, 0x95, 0xdd, 0xc4, 0x00, 0x48, 0x6c, 0xf9, 0x00)
183#endif
184
185struct Q_EXPORT QObjectInterface
186{
187 virtual QObject* qObject() = 0;
188};
189
190// {5F3968A5-F451-45b1-96FB-061AD98F926E}
191#ifndef IID_QComponentInformation
192#define IID_QComponentInformation QUuid(0x5f3968a5, 0xf451, 0x45b1, 0x96, 0xfb, 0x6, 0x1a, 0xd9, 0x8f, 0x92, 0x6e)
193#endif
194
195struct Q_EXPORT QComponentInformationInterface : public QUnknownInterface
196{
197 virtual QString name() const = 0;
198 virtual QString description() const = 0;
199 virtual QString author() const = 0;
200 virtual QString version() const = 0;
201};
202
203// {6CAA771B-17BB-4988-9E78-BA5CDDAAC31E}
204#ifndef IID_QComponentFactory
205#define IID_QComponentFactory QUuid( 0x6caa771b, 0x17bb, 0x4988, 0x9e, 0x78, 0xba, 0x5c, 0xdd, 0xaa, 0xc3, 0x1e)
206#endif
207
208struct Q_EXPORT QComponentFactoryInterface : public QUnknownInterface
209{
210 virtual QRESULT createInstance( const QUuid &cid, const QUuid &iid, QUnknownInterface** instance, QUnknownInterface *outer ) = 0;
211};
212
213// {D16111D4-E1E7-4C47-8599-24483DAE2E07}
214#ifndef IID_QLibrary
215#define IID_QLibrary QUuid( 0xd16111d4, 0xe1e7, 0x4c47, 0x85, 0x99, 0x24, 0x48, 0x3d, 0xae, 0x2e, 0x07)
216#endif
217
218struct Q_EXPORT QLibraryInterface : public QUnknownInterface
219{
220 virtual bool init() = 0;
221 virtual void cleanup() = 0;
222 virtual bool canUnload() const = 0;
223};
224
225// {3F8FDC44-3015-4f3e-B6D6-E4AAAABDEAAD}
226#ifndef IID_QFeatureList
227#define IID_QFeatureList QUuid(0x3f8fdc44, 0x3015, 0x4f3e, 0xb6, 0xd6, 0xe4, 0xaa, 0xaa, 0xbd, 0xea, 0xad)
228#endif
229
230struct Q_EXPORT QFeatureListInterface : public QUnknownInterface
231{
232 virtual QStringListfeatureList() const = 0;
233};
234
235// {B5FEB5DE-E0CD-4E37-B0EB-8A812499A0C1}
236#ifndef IID_QComponentRegistration
237#define IID_QComponentRegistration QUuid( 0xb5feb5de, 0xe0cd, 0x4e37, 0xb0, 0xeb, 0x8a, 0x81, 0x24, 0x99, 0xa0, 0xc1)
238#endif
239
240struct Q_EXPORT QComponentRegistrationInterface : public QUnknownInterface
241{
242 virtual bool registerComponents( const QString &filepath ) const = 0;
243 virtual bool unregisterComponents() const = 0;
244};
245
246// internal class that wraps an initialized ulong
247struct Q_EXPORT QtULong
248{
249 QtULong() : ref( 0 ) { }
250 operator unsigned long () const { return ref; }
251 unsigned long& operator++() { return ++ref; }
252 unsigned long operator++( int ) { return ref++; }
253 unsigned long& operator--() { return --ref; }
254 unsigned long operator--( int ) { return ref--; }
255
256 unsigned long ref;
257};
258// default implementation of ref counting. A variable "ulong ref" has to be a member
259
260
261#define Q_REFCOUNT \
262 private: \
263 QtULong qtrefcount; \
264 public: \
265 ulong addRef() {return qtrefcount++;} \
266 ulong release() {if(!--qtrefcount){delete this;return 0;}return qtrefcount;}
267
268#ifndef Q_EXPORT_COMPONENT
269#if defined(QT_THREAD_SUPPORT)
270#define QT_THREADED_BUILD 1
271#define Q_UCM_FLAGS_STRING "11"
272#else
273#define QT_THREADED_BUILD 0
274#define Q_UCM_FLAGS_STRING "01"
275#endif
276
277#ifndef Q_EXTERN_C
278#ifdef __cplusplus
279#define Q_EXTERN_C extern "C"
280#else
281#define Q_EXTERN_C extern
282#endif
283#endif
284
285// this is duplicated at Q_PLUGIN_VERIFICATION_DATA in qgplugin.h
286// NOTE: if you change pattern, you MUST change the pattern in
287// qcomlibrary.cpp as well. changing the pattern will break all
288// backwards compatibility as well (no old plugins will be loaded).
289#ifndef Q_UCM_VERIFICATION_DATA
290# define Q_UCM_VERIFICATION_DATA \
291 static const char *qt_ucm_verification_data = \
292 "pattern=""QT_UCM_VERIFICATION_DATA""\n" \
293 "version="QT_VERSION_STR"\n" \
294 "flags="Q_UCM_FLAGS_STRING"\n" \
295 "buildkey="QT_BUILD_KEY"\0";
296#endif // Q_UCM_VERIFICATION_DATA
297
298// This macro expands to the default implementation of ucm_instantiate.
299#ifndef Q_CREATE_INSTANCE
300 # define Q_CREATE_INSTANCE( IMPLEMENTATION ) \
301 IMPLEMENTATION *i = new IMPLEMENTATION; \
302 QUnknownInterface* iface = 0; \
303 i->queryInterface( IID_QUnknown, &iface );\
304 return iface;
305#endif // Q_CREATE_INSTANCE
306
307# ifdef Q_WS_WIN
308 #ifdef Q_CC_BOR
309 # define Q_EXPORT_COMPONENT() \
310 Q_UCM_VERIFICATION_DATA \
311 Q_EXTERN_C __declspec(dllexport) \
312 const char * __stdcall qt_ucm_query_verification_data() \
313 { return qt_ucm_verification_data; } \
314 Q_EXTERN_C __declspec(dllexport) QUnknownInterface* \
315 __stdcall ucm_instantiate()
316 #else
317 # define Q_EXPORT_COMPONENT() \
318 Q_UCM_VERIFICATION_DATA \
319 Q_EXTERN_C __declspec(dllexport) \
320 const char *qt_ucm_query_verification_data() \
321 { return qt_ucm_verification_data; } \
322 Q_EXTERN_C __declspec(dllexport) QUnknownInterface* ucm_instantiate()
323 #endif
324# else
325 #define Q_EXPORT_COMPONENT() \
326 Q_UCM_VERIFICATION_DATA \
327 Q_EXTERN_C \
328 const char *qt_ucm_query_verification_data() \
329 { return qt_ucm_verification_data; } \
330 Q_EXTERN_C QUnknownInterface* ucm_instantiate()
331# endif
332# define Q_EXPORT_INTERFACE() Q_EXPORT_COMPONENT()
333#endif
334
335#endif //QT_NO_COMPONENT
336
337#endif //QCOM_H
diff --git a/qmake/include/private/qcomlibrary_p.h b/qmake/include/private/qcomlibrary_p.h
new file mode 100644
index 0000000..f52f679
--- a/dev/null
+++ b/qmake/include/private/qcomlibrary_p.h
@@ -0,0 +1,79 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QUCOMLIBRARY_H
37#define QUCOMLIBRARY_H
38
39//
40// W A R N I N G
41// -------------
42//
43// This file is not part of the Qt API. It exists for the convenience
44// of a number of Qt sources files. This header file may change from
45// version to version without notice, or even be removed.
46//
47// We mean it.
48//
49//
50
51#ifndef QT_H
52#include "qcom_p.h"
53#include "qlibrary.h"
54#endif // QT_H
55
56#ifndef QT_NO_COMPONENT
57
58class Q_EXPORT QComLibrary : public QLibrary
59{
60public:
61 QComLibrary( const QString &filename );
62 ~QComLibrary();
63
64 bool unload();
65 QRESULT queryInterface( const QUuid &iid, QUnknownInterface **iface );
66 uint qtVersion();
67
68private:
69 void createInstanceInternal();
70
71 QUnknownInterface *entry;
72 QLibraryInterface *libiface;
73 uint qt_version;
74
75};
76
77#endif //QT_NO_COMPONENT
78
79#endif // QUCOMLIBRARY_H
diff --git a/qmake/include/private/qcomplextext_p.h b/qmake/include/private/qcomplextext_p.h
new file mode 100644
index 0000000..2132522
--- a/dev/null
+++ b/qmake/include/private/qcomplextext_p.h
@@ -0,0 +1,123 @@
1/****************************************************************************
2** $Id$
3**
4** Internal header file.
5**
6** Created :
7**
8** Copyright (C) 2001 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#ifndef QCOMPLEXTEXT_H
39#define QCOMPLEXTEXT_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of Qt Remote Control. This header file may change from version to
47// version without notice, or even be removed.
48//
49// We mean it.
50//
51//
52
53#ifndef QT_H
54#include <qstring.h>
55#include <qpointarray.h>
56#include <qfont.h>
57#include <qpainter.h>
58#include <qptrlist.h>
59#include <qshared.h>
60#endif // QT_H
61
62#ifndef QT_NO_COMPLEXTEXT
63
64// bidi helper classes. Internal to Qt
65struct Q_EXPORT QBidiStatus {
66 QBidiStatus() {
67 eor = QChar::DirON;
68 lastStrong = QChar::DirON;
69 last = QChar:: DirON;
70 }
71 QChar::Direction eor;
72 QChar::Direction lastStrong;
73 QChar::Direction last;
74};
75
76struct Q_EXPORT QBidiContext : public QShared {
77 // ### ref and deref parent?
78 QBidiContext( uchar level, QChar::Direction embedding, QBidiContext *parent = 0, bool override = FALSE );
79 ~QBidiContext();
80
81 unsigned char level;
82 bool override : 1;
83 QChar::Direction dir : 5;
84
85 QBidiContext *parent;
86};
87
88struct Q_EXPORT QBidiControl {
89 QBidiControl() { context = 0; }
90 QBidiControl( QBidiContext *c, QBidiStatus s)
91 { context = c; if( context ) context->ref(); status = s; }
92 ~QBidiControl() { if ( context && context->deref() ) delete context; }
93 void setContext( QBidiContext *c ) { if ( context == c ) return; if ( context && context->deref() ) delete context; context = c; context->ref(); }
94 QBidiContext *context;
95 QBidiStatus status;
96};
97
98struct Q_EXPORT QTextRun {
99 QTextRun(int _start, int _stop, QBidiContext *context, QChar::Direction dir);
100
101 int start;
102 int stop;
103 // explicit + implicit levels here
104 uchar level;
105};
106
107class Q_EXPORT QComplexText {
108public:
109 static QString shapedString( const QString &str, int from = 0, int len = -1, QPainter::TextDirection dir = QPainter::Auto, const QFontMetrics *fm = 0);
110 static QChar shapedCharacter(const QString &str, int pos, const QFontMetrics *fm = 0);
111
112 // positions non spacing marks relative to the base character at position pos.
113 static QPointArray positionMarks( QFontPrivate *f, const QString &str, int pos, QRect *boundingRect = 0 );
114
115 static QPtrList<QTextRun> *bidiReorderLine( QBidiControl *control, const QString &str, int start, int len,
116 QChar::Direction basicDir = QChar::DirON );
117 static QString bidiReorderString( const QString &str, QChar::Direction basicDir = QChar::DirON );
118};
119
120
121#endif //QT_NO_COMPLEXTEXT
122
123#endif
diff --git a/qmake/include/private/qcomponentfactory_p.h b/qmake/include/private/qcomponentfactory_p.h
new file mode 100644
index 0000000..1ac973f
--- a/dev/null
+++ b/qmake/include/private/qcomponentfactory_p.h
@@ -0,0 +1,73 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QCOMPONENTFACTORY_H
39#define QCOMPONENTFACTORY_H
40
41#ifndef QT_H
42#include "qcom_p.h"
43#endif // QT_H
44
45//
46// W A R N I N G
47// -------------
48//
49// This file is not part of the Qt API. It exists for the convenience
50// of a number of Qt sources files. This header file may change from
51// version to version without notice, or even be removed.
52//
53// We mean it.
54//
55//
56
57#ifndef QT_NO_COMPONENT
58
59class Q_EXPORT QComponentFactory
60{
61public:
62 static QRESULT createInstance( const QString &cid, const QUuid &iid, QUnknownInterface** instance, QUnknownInterface *outer = 0 );
63 static QRESULT registerServer( const QString &filename );
64 static QRESULT unregisterServer( const QString &filename );
65
66 static bool registerComponent( const QUuid &cid, const QString &filename, const QString &name = QString::null,
67 int version = 0, const QString &description = QString::null );
68 static bool unregisterComponent( const QUuid &cid );
69};
70
71#endif // QT_NO_COMPONENT
72
73#endif // QCOMPONENTFACTORY_H
diff --git a/qmake/include/private/qcriticalsection_p.h b/qmake/include/private/qcriticalsection_p.h
new file mode 100644
index 0000000..7d9feca
--- a/dev/null
+++ b/qmake/include/private/qcriticalsection_p.h
@@ -0,0 +1,80 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QCriticalSection class
5**
6** Copyright (C) 2001-2002 Trolltech AS. All rights reserved.
7**
8** This file is part 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#ifndef QCRITICALSECTION_H
37#define QCRITICALSECTION_H
38
39#ifndef QT_H
40#endif // QT_H
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of Qt Remote Control. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52//
53
54#if defined(QT_THREAD_SUPPORT)
55
56#if defined(Q_WS_WIN)
57
58/*
59 QCriticalSection
60*/
61
62class QCriticalSectionPrivate;
63
64class QCriticalSection
65{
66public:
67 QCriticalSection();
68 ~QCriticalSection();
69 void enter();
70 void leave();
71
72private:
73 QCriticalSectionPrivate *d;
74};
75
76#endif
77
78#endif
79
80#endif
diff --git a/qmake/include/private/qdir_p.h b/qmake/include/private/qdir_p.h
new file mode 100644
index 0000000..35dba28
--- a/dev/null
+++ b/qmake/include/private/qdir_p.h
@@ -0,0 +1,78 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of some private QDir functions.
5**
6** Created : 2000.11.06
7**
8** Copyright (C) 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#ifndef QDIR_P_H
39#define QDIR_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qdir.cpp and qdir_*.cpp.
48// This header file may change from version to version without notice,
49// or even be removed.
50//
51// We mean it.
52//
53//
54
55#ifndef QT_H
56#endif // QT_H
57
58extern QStringList qt_makeFilterList( const QString & );
59
60
61extern int qt_cmp_si_sortSpec;
62
63#if defined(Q_C_CALLBACKS)
64extern "C" {
65#endif
66
67#ifdef Q_OS_TEMP
68extern int __cdecl qt_cmp_si( const void *, const void * );
69#else
70extern int qt_cmp_si( const void *, const void * );
71#endif
72
73#if defined(Q_C_CALLBACKS)
74}
75#endif
76
77
78#endif // QDIR_P_H
diff --git a/qmake/include/private/qeffects_p.h b/qmake/include/private/qeffects_p.h
new file mode 100644
index 0000000..4178b6f
--- a/dev/null
+++ b/qmake/include/private/qeffects_p.h
@@ -0,0 +1,78 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QEffects functions
5**
6** Created : 2000.06.21
7**
8** Copyright (C) 2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the widgets 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#ifndef QEFFECTS_P_H
39#define QEFFECTS_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qeffects.cpp, qcombobox.cpp, qpopupmenu.cpp and qtooltip.cpp.
48// This header file may change from version to version without notice,
49// or even be removed.
50//
51// We mean it.
52//
53//
54
55#ifndef QT_H
56#include "qnamespace.h"
57#endif // QT_H
58
59#ifndef QT_NO_EFFECTS
60class QWidget;
61
62struct QEffects
63{
64 enum Direction {
65 LeftScroll= 0x0001,
66 RightScroll= 0x0002,
67 UpScroll= 0x0004,
68 DownScroll= 0x0008
69 };
70
71 typedef uint DirFlags;
72};
73
74extern void Q_EXPORT qScrollEffect( QWidget*, QEffects::DirFlags dir = QEffects::DownScroll, int time = -1 );
75extern void Q_EXPORT qFadeEffect( QWidget*, int time = -1 );
76#endif // QT_NO_EFFECTS
77
78#endif // QEFFECTS_P_H
diff --git a/qmake/include/private/qeventloop_p.h b/qmake/include/private/qeventloop_p.h
new file mode 100644
index 0000000..b64d0df
--- a/dev/null
+++ b/qmake/include/private/qeventloop_p.h
@@ -0,0 +1,74 @@
1#ifndef QEVENTLOOP_P_H
2#define QEVENTLOOP_P_H
3
4#include "qplatformdefs.h"
5#include "qwindowdefs.h"
6
7class QSocketNotifier;
8
9#if defined(Q_OS_UNIX)
10#include <qptrlist.h>
11
12struct QSockNot
13{
14 QSocketNotifier *obj;
15 int fd;
16 fd_set *queue;
17};
18
19class QSockNotType
20{
21public:
22 QSockNotType();
23 ~QSockNotType();
24
25 QPtrList<QSockNot> *list;
26 fd_set select_fds;
27 fd_set enabled_fds;
28 fd_set pending_fds;
29
30};
31#endif // Q_OS_UNIX
32
33
34class QEventLoopPrivate
35{
36public:
37 QEventLoopPrivate()
38 {
39 reset();
40 }
41
42 void reset() {
43 looplevel = 0;
44 quitcode = 0;
45 quitnow = FALSE;
46 exitloop = FALSE;
47 }
48
49 int looplevel;
50 int quitcode;
51 bool quitnow;
52 bool exitloop;
53
54#if defined(Q_WS_MAC)
55 EventLoopTimerRef select_timer;
56#endif
57
58#if defined(Q_WS_X11)
59 int xfd;
60#endif // Q_WS_X11
61
62#if defined(Q_OS_UNIX)
63 int thread_pipe[2];
64
65 // pending socket notifiers list
66 QPtrList<QSockNot> sn_pending_list;
67 // highest fd for all socket notifiers
68 int sn_highest;
69 // 3 socket notifier types - read, write and exception
70 QSockNotType sn_vec[3];
71#endif
72};
73
74#endif // QEVENTLOOP_P_H
diff --git a/qmake/include/private/qfiledefs_p.h b/qmake/include/private/qfiledefs_p.h
new file mode 100644
index 0000000..627717f
--- a/dev/null
+++ b/qmake/include/private/qfiledefs_p.h
@@ -0,0 +1,64 @@
1/****************************************************************************
2** $Id$
3**
4** Common macros and system include files for QFile, QFileInfo and QDir.
5**
6** Created : 930812
7**
8** Copyright (C) 1992-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#ifndef QFILEDEFS_P_H
39#define QFILEDEFS_P_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of qfileinfo*.cpp. This header file may change from version to version
47// without notice, or even be removed.
48//
49// We mean it.
50//
51//
52
53// Be sure to include qplatformdefs.h first!
54struct QFileInfoCache
55{
56#if defined(Q_WS_WIN)
57 QT_STATBUF st;
58#else
59 struct stat st;
60#endif
61};
62
63
64#endif
diff --git a/qmake/include/private/qfontcodecs_p.h b/qmake/include/private/qfontcodecs_p.h
new file mode 100644
index 0000000..8222f98
--- a/dev/null
+++ b/qmake/include/private/qfontcodecs_p.h
@@ -0,0 +1,368 @@
1/****************************************************************************
2** $Id$
3**
4** Font utilities for X11
5**
6** Created : 20001101
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#ifndef QFONTCODECS_P_H
39#define QFONTCODECS_P_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of qfontencodings_x11.cpp and qfont_x11.cpp. This header file may
47// change from version to version without notice, or even be removed.
48//
49// We mean it.
50//
51//
52
53#ifndef QT_H
54#include <qglobal.h>
55#include <qtextcodec.h>
56#endif // QT_H
57
58
59#ifndef QT_NO_CODECS
60#ifndef QT_NO_BIG_CODECS
61
62
63class QJpUnicodeConv;
64
65
66class QFontJis0201Codec : public QTextCodec
67{
68public:
69 QFontJis0201Codec();
70
71 const char *name() const;
72
73 int mibEnum() const;
74
75#if !defined(Q_NO_USING_KEYWORD)
76 using QTextCodec::fromUnicode;
77#endif
78 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
79
80 int heuristicContentMatch(const char *, int) const;
81 int heuristicNameMatch(const char* hint) const;
82
83#if !defined(Q_NO_USING_KEYWORD)
84 using QTextCodec::canEncode;
85#endif
86 bool canEncode( QChar ) const;
87};
88
89
90class QFontJis0208Codec : public QTextCodec
91{
92public:
93 QFontJis0208Codec();
94 ~QFontJis0208Codec();
95
96 // Return the official name for the encoding.
97 const char* name() const ;
98
99 // Return the MIB enum for the encoding if it is listed in the
100 // IANA character-sets encoding file.
101 int mibEnum() const ;
102
103 // Converts len characters from chars to Unicode.
104 QString toUnicode(const char* chars, int len) const ;
105
106 // Converts lenInOut characters (of type QChar) from the start of
107 // the string uc, returning a QCString result, and also returning
108 // the length of the result in lenInOut.
109#if !defined(Q_NO_USING_KEYWORD)
110 using QTextCodec::fromUnicode;
111#endif
112 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
113
114 int heuristicContentMatch(const char *, int) const;
115 int heuristicNameMatch(const char* hint) const;
116
117#if !defined(Q_NO_USING_KEYWORD)
118 using QTextCodec::canEncode;
119#endif
120 bool canEncode( QChar ) const;
121
122private:
123 QJpUnicodeConv *convJP;
124};
125
126
127
128
129class QFontKsc5601Codec : public QTextCodec
130{
131public:
132 QFontKsc5601Codec();
133
134 // Return the official name for the encoding.
135 const char* name() const ;
136
137 // Return the MIB enum for the encoding if it is listed in the
138 // IANA character-sets encoding file.
139 int mibEnum() const ;
140
141 // Converts len characters from chars to Unicode.
142 QString toUnicode(const char* chars, int len) const ;
143
144 // Converts lenInOut characters (of type QChar) from the start of
145 // the string uc, returning a QCString result, and also returning
146 // the length of the result in lenInOut.
147#if !defined(Q_NO_USING_KEYWORD)
148 using QTextCodec::fromUnicode;
149#endif
150 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
151
152 int heuristicContentMatch(const char *, int) const;
153#if !defined(Q_NO_USING_KEYWORD)
154 using QTextCodec::canEncode;
155#endif
156 bool canEncode( QChar ) const;
157};
158
159
160
161
162class QFontGb2312Codec : public QTextCodec
163{
164public:
165 QFontGb2312Codec();
166
167 // Return the official name for the encoding.
168 const char* name() const ;
169
170 // Return the MIB enum for the encoding if it is listed in the
171 // IANA character-sets encoding file.
172 int mibEnum() const ;
173
174 // Converts len characters from chars to Unicode.
175 QString toUnicode(const char* chars, int len) const ;
176
177 // Converts lenInOut characters (of type QChar) from the start of
178 // the string uc, returning a QCString result, and also returning
179 // the length of the result in lenInOut.
180 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
181
182 int heuristicContentMatch(const char *, int) const;
183 bool canEncode( QChar ) const;
184};
185
186
187
188
189class QFontGbkCodec : public QTextCodec
190{
191public:
192 QFontGbkCodec();
193
194 // Return the official name for the encoding.
195 const char* name() const ;
196
197 // Return the MIB enum for the encoding if it is listed in the
198 // IANA character-sets encoding file.
199 int mibEnum() const ;
200
201 // Converts len characters from chars to Unicode.
202 QString toUnicode(const char* chars, int len) const ;
203
204 // Converts lenInOut characters (of type QChar) from the start of
205 // the string uc, returning a QCString result, and also returning
206 // the length of the result in lenInOut.
207 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
208
209 int heuristicContentMatch(const char *, int) const;
210 int heuristicNameMatch(const char* hint) const;
211 bool canEncode( QChar ) const;
212};
213
214
215
216
217class QFontGb18030_0Codec : public QTextCodec
218{
219public:
220 QFontGb18030_0Codec();
221
222 // Return the official name for the encoding.
223 const char* name() const ;
224
225 // Return the MIB enum for the encoding if it is listed in the
226 // IANA character-sets encoding file.
227 int mibEnum() const ;
228
229 // Converts len characters from chars to Unicode.
230 QString toUnicode(const char* chars, int len) const ;
231
232 // Converts lenInOut characters (of type QChar) from the start of
233 // the string uc, returning a QCString result, and also returning
234 // the length of the result in lenInOut.
235#if !defined(Q_NO_USING_KEYWORD)
236 using QTextCodec::fromUnicode;
237#endif
238 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
239
240 int heuristicContentMatch(const char *, int) const;
241#if !defined(Q_NO_USING_KEYWORD)
242 using QTextCodec::canEncode;
243#endif
244 bool canEncode( QChar ) const;
245};
246
247
248
249
250class QFontBig5Codec : public QTextCodec
251{
252public:
253 QFontBig5Codec();
254
255 // Return the official name for the encoding.
256 const char* name() const ;
257
258 // Return the MIB enum for the encoding if it is listed in the
259 // IANA character-sets encoding file.
260 int mibEnum() const ;
261
262 // Converts len characters from chars to Unicode.
263 QString toUnicode(const char* chars, int len) const ;
264
265 // Converts lenInOut characters (of type QChar) from the start of
266 // the string uc, returning a QCString result, and also returning
267 // the length of the result in lenInOut.
268#if !defined(Q_NO_USING_KEYWORD)
269 using QTextCodec::fromUnicode;
270#endif
271 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
272
273 int heuristicContentMatch(const char *, int) const;
274#if !defined(Q_NO_USING_KEYWORD)
275 using QTextCodec::canEncode;
276#endif
277 int heuristicNameMatch(const char* hint) const;
278 bool canEncode( QChar ) const;
279};
280
281
282
283class QFontBig5hkscsCodec : public QTextCodec
284{
285public:
286 QFontBig5hkscsCodec();
287
288 // Return the official name for the encoding.
289 const char* name() const ;
290
291 // Return the MIB enum for the encoding if it is listed in the
292 // IANA character-sets encoding file.
293 int mibEnum() const ;
294
295 // Converts len characters from chars to Unicode.
296 QString toUnicode(const char* chars, int len) const ;
297
298 // Converts lenInOut characters (of type QChar) from the start of
299 // the string uc, returning a QCString result, and also returning
300 // the length of the result in lenInOut.
301 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
302
303 int heuristicContentMatch(const char *, int) const;
304 int heuristicNameMatch(const char* hint) const;
305#if !defined(Q_NO_USING_KEYWORD)
306 using QTextCodec::canEncode;
307#endif
308 bool canEncode( QChar ) const;
309};
310
311
312
313
314// ------------------------------------------------------------------
315// the shaping codec for iso8859-6.8x fonts (see www.langbox.com)
316
317class QFontArabic68Codec : public QTextCodec
318{
319public:
320 QFontArabic68Codec();
321
322 // Return the official name for the encoding.
323 const char* name() const ;
324
325 // Return the MIB enum for the encoding if it is listed in the
326 // IANA character-sets encoding file.
327 int mibEnum() const ;
328
329 // Converts len characters from chars to Unicode.
330 QString toUnicode(const char* chars, int len) const ;
331
332 // Converts lenInOut characters (of type QChar) from the start of
333 // the string uc, returning a QCString result, and also returning
334 // the length of the result in lenInOut.
335 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
336
337 int heuristicContentMatch(const char *, int) const;
338 QByteArray fromUnicode( const QString &str, int from, int len ) const;
339 unsigned short characterFromUnicode(const QString &str, int pos) const;
340};
341
342
343class QFontLaoCodec : public QTextCodec
344{
345public:
346 QFontLaoCodec();
347
348 const char *name() const;
349
350 int mibEnum() const;
351
352#if !defined(Q_NO_USING_KEYWORD)
353 using QTextCodec::fromUnicode;
354#endif
355 QCString fromUnicode(const QString& uc, int& lenInOut ) const;
356
357 int heuristicContentMatch(const char *, int) const;
358
359#if !defined(Q_NO_USING_KEYWORD)
360 using QTextCodec::canEncode;
361#endif
362 bool canEncode( QChar ) const;
363};
364
365#endif // QT_NO_BIG_CODECS
366#endif // QT_NO_CODECS
367
368#endif // QFONTCODECS_P_H
diff --git a/qmake/include/private/qfontdata_p.h b/qmake/include/private/qfontdata_p.h
new file mode 100644
index 0000000..917d14f
--- a/dev/null
+++ b/qmake/include/private/qfontdata_p.h
@@ -0,0 +1,479 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of internal QFontData struct
5**
6** Created : 941229
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#ifndef QFONTDATA_P_H
39#define QFONTDATA_P_H
40
41#ifndef QT_H
42#include <qcache.h>
43#include <qobject.h>
44#include <qpaintdevice.h>
45#endif // QT_H
46#include <limits.h>
47
48//
49// W A R N I N G
50// -------------
51//
52// This file is not part of the Qt API. It exists for the convenience
53// of internal files. This header file may change from version to version
54// without notice, or even be removed.
55//
56// We mean it.
57//
58//
59
60class QPaintDevice;
61
62#ifdef Q_WS_WIN
63#include <qt_windows.h>
64#endif
65
66#ifdef Q_WS_X11
67#include <qt_x11.h>
68
69class QCharStruct;
70#endif
71
72// font description
73struct QFontDef {
74 QFontDef()
75 : pixelSize(0), pointSize(0), lbearing(SHRT_MIN), rbearing(SHRT_MIN),
76 styleStrategy(QFont::PreferDefault), styleHint(QFont::AnyStyle),
77 weight(0), italic(FALSE), underline(FALSE), strikeOut(FALSE),
78 fixedPitch(FALSE), hintSetByUser(FALSE), rawMode(FALSE), dirty(TRUE)
79 { ; }
80
81 QString family;
82 QString addStyle;
83
84 int pixelSize;
85 int pointSize;
86 short lbearing;
87 short rbearing;
88
89 ushort styleStrategy;
90 uchar styleHint;
91 uchar weight;
92
93 bool italic;
94 bool underline;
95 bool strikeOut;
96 bool fixedPitch;
97 bool hintSetByUser;
98 bool rawMode;
99
100 bool dirty;
101};
102
103
104class QTextCodec;
105
106#ifdef Q_WS_X11
107
108// this is a shared wrapper for XFontStruct (to prevent a font being freed by
109// the cache while it's being used)
110class QFontStruct : public QShared
111{
112public:
113 QFontStruct(Qt::HANDLE h, Qt::HANDLE xfth, Qt::HANDLE xftp,
114 QCString n, QTextCodec *c, int a) :
115 QShared(), handle(h), xfthandle(xfth), xftpattern(xftp),
116 name(n), codec(c), cache_cost(a), scale( 1. )
117 { ; }
118
119 ~QFontStruct();
120
121 Qt::HANDLE handle, xfthandle, xftpattern;
122 QCString name;
123 QTextCodec *codec;
124 int cache_cost;
125 float scale; // needed for printing, to correctly scale font metrics for bitmap fonts
126};
127
128enum { widthCacheSize = 0x500 };
129
130class QFontX11Data // used as a QFontPrivate member
131{
132public:
133 // X fontstruct handles for each character set
134 QFontStruct *fontstruct[QFont::LastPrivateScript];
135
136 uchar widthCache[widthCacheSize];
137
138 QFontX11Data();
139 ~QFontX11Data();
140};
141
142#endif // Q_WS_X11
143
144
145#ifdef Q_WS_WIN
146
147class QFontStruct : public QShared
148{
149public:
150 QFontStruct( const QString &key );
151 ~QFontStruct() { reset(); }
152 bool dirty() const { return hfont == 0; }
153 HDC dc() const;
154 HFONT font() const { return hfont; }
155 const TEXTMETRICA *textMetricA() const { return &tm.a; }
156 const TEXTMETRICW *textMetricW() const { return &tm.w; }
157 QString key() const { return k; }
158 void reset();
159
160 QStringk;
161 HDC hdc;
162 HFONThfont;
163 uintstockFont:1;
164 uintpaintDevice:1;
165 union {
166 TEXTMETRICWw;
167 TEXTMETRICAa;
168 } tm;
169 int lw;
170 int cache_cost;
171// friend void QFont::initFontInfo() const;
172};
173
174#endif // Q_WS_WIN
175
176#if defined( Q_WS_MAC )
177
178#if defined( Q_WS_MACX )
179# define QMAC_FONT_ATSUI
180#endif
181#include "qt_mac.h"
182class QMacFontInfo;
183
184class QFontStruct : public QShared
185{
186public:
187 inline QFontStruct() : QShared(), info(NULL), fnum(-1), cache_cost(0), internal_fi(NULL) { }
188#if defined( QMAC_FONT_ATSUI ) && 0
189 ATSFontMetrics *info;
190 int maxWidth() const { return (int)info->maxAdvanceWidth; }
191#else
192 FontInfo *info;
193 int maxWidth() const { return info->widMax; }
194#endif
195 int ascent() const { return (int)info->ascent; }
196 int descent() const { return (int)info->descent; }
197 int leading() const { return (int)info->leading; }
198 int minLeftBearing() const { return 0; }
199 int minRightBearing() const { return 0; }
200
201 short fnum;
202 int psize, cache_cost;
203 QMacFontInfo *internal_fi;
204};
205
206#endif
207
208#ifdef Q_WS_QWS
209class QFontStruct;
210class QGfx;
211#endif
212
213typedef QCacheIterator<QFontStruct> QFontCacheIterator;
214class QFontCache : public QObject, public QCache<QFontStruct>
215{
216public:
217 QFontCache();
218 ~QFontCache();
219
220 bool insert(const QString &, const QFontStruct *, int c);
221#ifndef Q_WS_MAC
222 void deleteItem(Item d);
223#endif
224 void timerEvent(QTimerEvent *);
225
226
227protected:
228
229
230private:
231 int timer_id;
232 bool fast;
233};
234
235
236// QFontPrivate - holds all data on which a font operates
237class QFontPrivate : public QShared
238{
239public:
240 static QFontCache *fontCache;
241
242
243public:
244
245 QFontPrivate();
246 QFontPrivate(const QFontPrivate &fp);
247 QFontPrivate( const QFontPrivate &fp, QPaintDevice *pd );
248 ~QFontPrivate();
249
250 // requested font
251 QFontDef request;
252 // actual font
253 QFontDef actual;
254
255 bool exactMatch;
256 int lineWidth;
257
258 // common functions
259 QString defaultFamily() const;
260 QString lastResortFamily() const;
261 QString lastResortFont() const;
262 QString key() const;
263
264 static int getFontWeight(const QCString &, bool = FALSE);
265 QRect boundingRect( const QChar &ch );
266
267 struct TextRun {
268 TextRun()
269 {
270 xoff = 0;
271 yoff = 0;
272 x2off = 0;
273 script = QFont::NoScript;
274 string = 0;
275 length = 0;
276 next = 0;
277 }
278
279 ~TextRun()
280 {
281 if ( next )
282 delete next;
283 }
284
285 void setParams( int x, int y, int x2, const QChar *s, int len,
286 QFont::Script sc = QFont::NoScript ) {
287 xoff = x;
288 yoff = y;
289 x2off = x2;
290 string = s;
291 length = len;
292 script = sc;
293 }
294 int xoff;
295 int yoff;
296 int x2off;
297 QFont::Script script;
298 const QChar *string;
299 int length;
300 TextRun *next;
301#ifdef Q_WS_X11
302 QByteArray mapped;
303#endif
304 };
305
306 // some replacement functions for native calls. This is needed, because shaping and
307 // non spacing marks can change the extents of a string to draw. At the same time
308 // drawing needs to take care to correctly position non spacing marks.
309 int textWidth( const QString &str, int pos, int len );
310
311 // returns the script a certain character is in. Needed to separate the string
312 // into runs of different scripts as required for X11 and opentype.
313 QFont::Script scriptForChar(const QChar &c);
314
315#ifdef Q_WS_X11
316 QFont::Script hanHack( const QChar & c );
317 static char **getXFontNames(const char *, int *);
318 static bool fontExists(const QString &);
319 static bool parseXFontName(char *, char **);
320 static QCString fixXLFD( const QCString & );
321 static bool fillFontDef(XFontStruct *, QFontDef *, int);
322 static bool fillFontDef(const QCString &, QFontDef *, int);
323
324 static inline bool isZero(char *x)
325 {
326 return (x[0] == '0' && x[1] == 0);
327 }
328
329 static inline bool isScalable( char **tokens )
330 {
331 return (isZero(tokens[PixelSize]) &&
332 isZero(tokens[PointSize]) &&
333 isZero(tokens[AverageWidth]));
334 }
335
336 static inline bool isSmoothlyScalable( char **tokens )
337 {
338 return (isZero(tokens[ResolutionX]) && isZero(tokens[ResolutionY]));
339 }
340
341 static inline bool isFixedPitch( char **tokens )
342 {
343 return (tokens[Spacing][0] == 'm' ||
344 tokens[Spacing][0] == 'c' ||
345 tokens[Spacing][0] == 'M' ||
346 tokens[Spacing][0] == 'C');
347 }
348
349 // XLFD fields
350 enum FontFieldNames {
351 Foundry,
352 Family,
353 Weight,
354 Slant,
355 Width,
356 AddStyle,
357 PixelSize,
358 PointSize,
359 ResolutionX,
360 ResolutionY,
361 Spacing,
362 AverageWidth,
363 CharsetRegistry,
364 CharsetEncoding,
365 NFontFields
366 };
367
368#ifndef QT_NO_XFTFREETYPE
369 XftPattern *findXftFont(const QChar &, bool *, double *scale) const;
370 XftPattern *bestXftPattern(const QString &, const QString &, const QChar &, double *scale) const;
371#endif // QT_NO_XFTFREETYPE
372 QCString findFont(QFont::Script, bool *, double *) const;
373 QCString bestFamilyMember(QFont::Script, const QString &, const QString &,
374 const QString &, int *, double *) const;
375 QCString bestMatch(const char *, int *, QFont::Script, double *) const;
376 int fontMatchScore(const char *, QCString &, float *, int *, bool *,
377 bool *, QFont::Script, double *) const;
378 void initFontInfo(QFont::Script, double scale);
379 void load(QFont::Script = QFont::NoScript, bool = TRUE);
380 bool loadUnicode(QFont::Script, const QChar &);
381 void computeLineWidth();
382
383 int textWidth( const QString &str, int pos, int len, TextRun *cache );
384 void textExtents( const QString &str, int pos, int len, QCharStruct *overall );
385 void drawText( Display *dpy, int screen, Qt::HANDLE hd, Qt::HANDLE rendhd,
386 GC gc, const QColor &pen, Qt::BGMode, const QColor &bgcolor,
387 int x, int y, const TextRun *cache, int pdWidth );
388 bool inFont( const QChar &ch );
389
390 QFontX11Data x11data;
391 static QFont::Script defaultScript;
392 int x11Screen;
393#endif // Q_WS_X11
394
395 QPaintDevice *paintdevice;
396
397#ifdef Q_WS_WIN
398 void load();
399 void initFontInfo();
400 HFONT create( bool *stockFont, HDC hdc = 0, bool compatMode = FALSE );
401 QFontStruct *fin;
402
403 void buildCache( HDC hdc, const QString &str, int pos, int len, TextRun *cache );
404 void drawText( HDC hdc, int x, int y, TextRun *cache );
405#endif // Q_WS_WIN
406
407#ifdef Q_WS_QWS
408 void load();
409 QFontStruct *fin;
410 int textWidth( const QString &str, int pos, int len, TextRun *cache );
411 void drawText( QGfx *gfx, int x, int y, const TextRun *cache );
412#endif
413
414#if defined( Q_WS_MAC )
415 void macSetFont(QPaintDevice *);
416 void drawText(int x, int y, QString s, int len, QPaintDevice *dev, const QRegion *rgn);
417 void computeLineWidth();
418 void load();
419 QFontStruct *fin;
420#endif
421
422};
423
424inline QFontPrivate::QFontPrivate()
425 : QShared(), exactMatch(FALSE), lineWidth(1)
426{
427
428#if defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
429 fin = 0;
430#endif // Q_WS_WIN || Q_WS_QWS
431#if defined(Q_WS_X11)
432 x11Screen = QPaintDevice::x11AppScreen();
433#endif // Q_WS_X11
434 paintdevice = 0;
435}
436
437inline QFontPrivate::QFontPrivate(const QFontPrivate &fp)
438 : QShared(), request(fp.request), actual(fp.actual),
439exactMatch(fp.exactMatch), lineWidth(1)
440{
441 Q_ASSERT(!fp.paintdevice);
442#if defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
443 fin = 0;
444#endif // Q_WS_WIN || Q_WS_QWS
445#if defined(Q_WS_X11)
446 x11Screen = fp.x11Screen;
447#endif // Q_WS_X11
448 paintdevice = 0;
449}
450
451inline QFontPrivate::QFontPrivate( const QFontPrivate &fp, QPaintDevice *pd )
452 : QShared(), request(fp.request), actual(fp.actual),
453exactMatch(fp.exactMatch), lineWidth(1)
454{
455
456#if defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
457 fin = 0;
458#endif // Q_WS_WIN || Q_WS_QWS
459#if defined(Q_WS_X11)
460 x11Screen = pd->x11Screen();
461#endif // Q_WS_X11
462 paintdevice = pd;
463}
464
465#ifndef Q_WS_QWS
466inline QFontPrivate::~QFontPrivate()
467{
468#if defined(Q_WS_WIN)
469 if( fin )
470 fin->deref();
471#endif
472#if defined(Q_WS_MAC)
473 if( fin && fin->deref() )
474 delete fin;
475#endif
476}
477#endif
478
479#endif // QFONTDATA_P_H
diff --git a/qmake/include/private/qgfxdriverinterface_p.h b/qmake/include/private/qgfxdriverinterface_p.h
new file mode 100644
index 0000000..1782ed4
--- a/dev/null
+++ b/qmake/include/private/qgfxdriverinterface_p.h
@@ -0,0 +1,56 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of Qt/Embedded Graphics Driver Interface
5**
6** Created : 20020211
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 and/or modified under the terms of the
13** GNU General Public License version 2 as published by the Free Software
14** Foundation and appearing in the file LICENSE.GPL included in the
15** packaging of this file.
16**
17** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
18** licenses for Qt/Embedded may use this file in accordance with the
19** Qt Embedded Commercial License Agreement provided with the Software.
20**
21** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
22** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23**
24** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
25** information about Qt Commercial License Agreements.
26** See http://www.trolltech.com/gpl/ for GPL licensing information.
27**
28** Contact info@trolltech.com if any conditions of this licensing are
29** not clear to you.
30**
31**********************************************************************/
32
33#ifndef QGFXDRIVERINTERFACE_H
34#define QGFXDRIVERINTERFACE_H
35
36#ifndef QT_H
37#include <private/qcom_p.h>
38#endif // QT_H
39
40#ifndef QT_NO_COMPONENT
41
42// {449EC6C6-DF3E-43E3-9E57-354A3D05AB34}
43#ifndef IID_QGfxDriver
44#define IID_QGfxDriver QUuid( 0x449ec6c6, 0xdf3e, 0x43e3, 0x9e, 0x57, 0x35, 0x4a, 0x3d, 0x05, 0xab, 0x34)
45#endif
46
47class QScreen;
48
49struct Q_EXPORT QGfxDriverInterface : public QFeatureListInterface
50{
51 virtual QScreen* create( const QString& driver, int displayId ) = 0;
52};
53
54#endif // QT_NO_COMPONENT
55
56#endif // QGFXDRIVERINTERFACE_H
diff --git a/qmake/include/private/qgpluginmanager_p.h b/qmake/include/private/qgpluginmanager_p.h
new file mode 100644
index 0000000..e0c0e78
--- a/dev/null
+++ b/qmake/include/private/qgpluginmanager_p.h
@@ -0,0 +1,107 @@
1/**********************************************************************
2** $Id$
3**
4** Definition 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#ifndef QGPLUGINMANAGER_H
37#define QGPLUGINMANAGER_H
38
39#ifndef QT_H
40#include "qdict.h"
41#include "qlibrary.h"
42#include "quuid.h"
43#include "qstringlist.h"
44#include "qcom_p.h"
45#endif // QT_H
46
47//
48// W A R N I N G
49// -------------
50//
51// This file is not part of the Qt API. It exists for the convenience
52// of a number of Qt sources files. This header file may change from
53// version to version without notice, or even be removed.
54//
55// We mean it.
56//
57//
58
59#ifndef QT_NO_COMPONENT
60
61#if defined(Q_TEMPLATEDLL)
62// MOC_SKIP_BEGIN
63Q_TEMPLATE_EXTERN template class Q_EXPORT QDict<QLibrary>;
64// MOC_SKIP_END
65#endif
66
67class Q_EXPORT QGPluginManager
68{
69public:
70 QGPluginManager( const QUuid& id, const QStringList& paths = QString::null, const QString &suffix = QString::null, bool cs = TRUE );
71 ~QGPluginManager();
72
73 void addLibraryPath( const QString& path );
74 const QLibrary* library( const QString& feature ) const;
75 QStringList featureList() const;
76
77 bool autoUnload() const;
78 void setAutoUnload( bool );
79
80protected:
81 bool enabled() const;
82 bool addLibrary( QLibrary* plugin );
83
84 QRESULT queryUnknownInterface(const QString& feature, QUnknownInterface** iface) const;
85
86 QUuid interfaceId;
87 QDict<QLibrary> plugDict; // Dict to match feature with library
88 QDict<QLibrary> libDict; // Dict to match library file with library
89 QStringList libList;
90
91 uint casesens : 1;
92 uint autounload : 1;
93};
94
95inline void QGPluginManager::setAutoUnload( bool unload )
96{
97 autounload = unload;
98}
99
100inline bool QGPluginManager::autoUnload() const
101{
102 return autounload;
103}
104
105#endif
106
107#endif //QGPLUGINMANAGER_H
diff --git a/qmake/include/private/qimageformatinterface_p.h b/qmake/include/private/qimageformatinterface_p.h
new file mode 100644
index 0000000..5f7601c
--- a/dev/null
+++ b/qmake/include/private/qimageformatinterface_p.h
@@ -0,0 +1,75 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ???
5**
6** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the kernel 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#ifndef QIMAGEFORMATINTERFACE_H
37#define QIMAGEFORMATINTERFACE_H
38
39#ifndef QT_H
40#include <private/qcom_p.h>
41#endif // QT_H
42
43
44//
45// W A R N I N G
46// -------------
47//
48// This file is not part of the Qt API. It exists for the convenience
49// of internal files. This header file may change from version to version
50// without notice, or even be removed.
51//
52// We mean it.
53//
54//
55
56#ifndef QT_NO_COMPONENT
57
58// {04903F05-54B1-4726-A849-FB5CB097CA87}
59#ifndef IID_QImageFormat
60#define IID_QImageFormat QUuid( 0x04903f05, 0x54b1, 0x4726, 0xa8, 0x49, 0xfb, 0x5c, 0xb0, 0x97, 0xca, 0x87 )
61#endif
62
63class QImage;
64
65struct Q_EXPORT QImageFormatInterface : public QFeatureListInterface
66{
67 virtual QRESULT loadImage( const QString &format, const QString &filename, QImage * ) = 0;
68 virtual QRESULT saveImage( const QString &format, const QString &filename, const QImage & ) = 0;
69
70 virtual QRESULT installIOHandler( const QString & ) = 0;
71};
72
73#endif // QT_NO_COMPONENT
74
75#endif // QIMAGEFORMATINTERFACE_H
diff --git a/qmake/include/private/qinputcontext_p.h b/qmake/include/private/qinputcontext_p.h
new file mode 100644
index 0000000..9ac0d2b
--- a/dev/null
+++ b/qmake/include/private/qinputcontext_p.h
@@ -0,0 +1,121 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ???
5**
6** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the kernel 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#ifndef QINPUTCONTEXT_P_H
37#define QINPUTCONTEXT_P_H
38
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists for the convenience
45// of internal files. This header file may change from version to version
46// without notice, or even be removed.
47//
48// We mean it.
49//
50//
51
52#include <qglobal.h>
53
54class QKeyEvent;
55class QWidget;
56class QFont;
57class QString;
58
59
60#ifdef Q_WS_X11
61#include "qarray.h"
62#include "qwindowdefs.h"
63#include "qt_x11.h"
64#endif
65
66#ifdef Q_WS_WIN
67#include <qt_windows.h>
68#endif
69
70#ifdef Q_WS_QWS
71class QWSIMEvent;
72#endif
73
74class QInputContext
75{
76public:
77#ifdef Q_WS_X11
78 QInputContext(QWidget *); // should be a toplevel widget
79 ~QInputContext();
80
81 void setFocus();
82 void setComposePosition(int, int);
83 void setComposeArea(int, int, int, int);
84 void reset();
85
86 int lookupString(XKeyEvent *, QCString &, KeySym *, Status *) const;
87 void setXFontSet(const QFont &);
88
89 void *ic;
90 QString text, lastcompose;
91 QWidget *focusWidget;
92 bool composing;
93 QFont font;
94 XFontSet fontset;
95 QMemArray<bool> selectedChars;
96#endif // Q_WS_X11
97
98#ifdef Q_WS_QWS
99 static void translateIMEvent( QWSIMEvent *, QWidget * );
100 static void reset();
101private:
102 static QWidget* focusWidget;
103 static QString* composition;
104#endif //Q_WS_QWS
105
106#ifdef Q_WS_WIN
107 static void init();
108 static void shutdown();
109
110 static void TranslateMessage( const MSG *msg);
111 static LRESULT DefWindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
112
113 static void setFont( const QWidget *w, const QFont & );
114 static void setFocusHint( int x, int y, int w, int h, const QWidget *widget );
115 static bool startComposition();
116 static bool endComposition( QWidget *fw = 0 );
117 static bool composition( LPARAM lparam );
118#endif
119};
120
121#endif // QINPUTCONTEXT_P_H
diff --git a/qmake/include/private/qinternal_p.h b/qmake/include/private/qinternal_p.h
new file mode 100644
index 0000000..ae38695
--- a/dev/null
+++ b/qmake/include/private/qinternal_p.h
@@ -0,0 +1,157 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of some shared interal classes
5**
6** Created : 010427
7**
8** Copyright (C) 1992-2000 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#ifndef QINTERNAL_P_H
39#define QINTERNAL_P_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of a number of Qt sources files. This header file may change from
47// version to version without notice, or even be removed.
48//
49// We mean it.
50//
51//
52#ifndef QT_H
53#include <qnamespace.h>
54#include <qrect.h>
55#endif // QT_H
56
57class QWidget;
58class QPainter;
59class QPixmap;
60
61class Q_EXPORT QSharedDoubleBuffer
62{
63public:
64 enum DoubleBufferFlags {
65 NoFlags = 0x00,
66 InitBG = 0x01,
67 Force = 0x02,
68 Default = InitBG | Force
69 };
70 typedef uint DBFlags;
71
72 QSharedDoubleBuffer( DBFlags f = Default );
73 QSharedDoubleBuffer( QWidget* widget,
74 int x = 0, int y = 0, int w = -1, int h = -1,
75 DBFlags f = Default );
76 QSharedDoubleBuffer( QPainter* painter,
77 int x = 0, int y = 0, int w = -1, int h = -1,
78 DBFlags f = Default );
79 QSharedDoubleBuffer( QWidget *widget, const QRect &r, DBFlags f = Default );
80 QSharedDoubleBuffer( QPainter *painter, const QRect &r, DBFlags f = Default );
81 ~QSharedDoubleBuffer();
82
83 bool begin( QWidget* widget, int x = 0, int y = 0, int w = -1, int h = -1 );
84 bool begin( QPainter* painter, int x = 0, int y = 0, int w = -1, int h = -1);
85 bool begin( QWidget* widget, const QRect &r );
86 bool begin( QPainter* painter, const QRect &r );
87 bool end();
88
89 QPainter* painter() const;
90
91 bool isActive() const;
92 bool isBuffered() const;
93 void flush();
94
95 static bool isDisabled() { return !dblbufr; }
96 static void setDisabled( bool off ) { dblbufr = !off; }
97
98 static void cleanup();
99
100private:
101 enum DoubleBufferState {
102 Active = 0x0100,
103 BufferActive= 0x0200,
104 ExternalPainter= 0x0400
105 };
106 typedef uint DBState;
107
108 QPixmap *getPixmap();
109 void releasePixmap();
110
111 QWidget *wid;
112 int rx, ry, rw, rh;
113 DBFlags flags;
114 DBState state;
115
116 QPainter *p, *external_p;
117 QPixmap *pix;
118
119 static bool dblbufr;
120};
121
122inline bool QSharedDoubleBuffer::begin( QWidget* widget, const QRect &r )
123{ return begin( widget, r.x(), r.y(), r.width(), r.height() ); }
124
125inline bool QSharedDoubleBuffer::begin( QPainter *painter, const QRect &r )
126{ return begin( painter, r.x(), r.y(), r.width(), r.height() ); }
127
128inline QPainter* QSharedDoubleBuffer::painter() const
129{ return p; }
130
131inline bool QSharedDoubleBuffer::isActive() const
132{ return ( state & Active ); }
133
134inline bool QSharedDoubleBuffer::isBuffered() const
135{ return ( state & BufferActive ); }
136
137
138class QVirtualDestructor {
139public:
140 virtual ~QVirtualDestructor() {}
141};
142
143template <class T>
144class QAutoDeleter : public QVirtualDestructor {
145public:
146 QAutoDeleter( T* p ) : ptr( p ) {}
147 ~QAutoDeleter() { delete ptr; }
148private:
149 T* ptr;
150};
151
152template <class T>
153QAutoDeleter<T>* qAutoDeleter( T* p )
154{
155 return new QAutoDeleter<T>( p );
156}
157#endif // QINTERNAL_P_H
diff --git a/qmake/include/private/qkbddriverinterface_p.h b/qmake/include/private/qkbddriverinterface_p.h
new file mode 100644
index 0000000..efc7ded
--- a/dev/null
+++ b/qmake/include/private/qkbddriverinterface_p.h
@@ -0,0 +1,56 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of Qt/Embedded Keyboard Driver Interface
5**
6** Created : 20020218
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 and/or modified under the terms of the
13** GNU General Public License version 2 as published by the Free Software
14** Foundation and appearing in the file LICENSE.GPL included in the
15** packaging of this file.
16**
17** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
18** licenses for Qt/Embedded may use this file in accordance with the
19** Qt Embedded Commercial License Agreement provided with the Software.
20**
21** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
22** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23**
24** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
25** information about Qt Commercial License Agreements.
26** See http://www.trolltech.com/gpl/ for GPL licensing information.
27**
28** Contact info@trolltech.com if any conditions of this licensing are
29** not clear to you.
30**
31**********************************************************************/
32
33#ifndef QKBDDRIVERINTERFACE_H
34#define QKBDDRIVERINTERFACE_H
35
36#ifndef QT_H
37#include <private/qcom_p.h>
38#endif // QT_H
39
40#ifndef QT_NO_COMPONENT
41
42// {C7C838EA-FC3E-4905-92AD-F479E81F1D02}
43#ifndef IID_QKbdDriver
44#define IID_QKbdDriver QUuid( 0xc7c838ea, 0xfc3e, 0x4905, 0x92, 0xad, 0xf4, 0x79, 0xe8, 0x1f, 0x1d, 0x02)
45#endif
46
47class QWSKeyboardHandler;
48
49struct Q_EXPORT QKbdDriverInterface : public QFeatureListInterface
50{
51 virtual QWSKeyboardHandler* create( const QString& driver, const QString& device ) = 0;
52};
53
54#endif // QT_NO_COMPONENT
55
56#endif // QKBDDRIVERINTERFACE_H
diff --git a/qmake/include/private/qlayoutengine_p.h b/qmake/include/private/qlayoutengine_p.h
new file mode 100644
index 0000000..4d88afe
--- a/dev/null
+++ b/qmake/include/private/qlayoutengine_p.h
@@ -0,0 +1,128 @@
1/****************************************************************************
2** $Id$
3**
4** Internal header file.
5**
6** Created : 981027
7**
8** Copyright (C) 1998-99 by 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#ifndef QLAYOUTENGINE_P_H
39#define QLAYOUTENGINE_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qlayout.cpp, qlayoutengine.cpp, qmainwindow.cpp and qsplitter.cpp.
48// This header file may change from version to version without notice,
49// or even be removed.
50//
51// We mean it.
52//
53//
54
55
56#ifndef QT_H
57#include "qabstractlayout.h"
58#endif // QT_H
59
60#ifndef QT_NO_LAYOUT
61
62struct QLayoutStruct
63{
64 void initParameters() {
65 minimumSize = sizeHint = 0;
66 maximumSize = QLAYOUTSIZE_MAX;
67 expansive = FALSE;
68 empty = TRUE;
69 }
70 void init() {
71 stretch = 0;
72 initParameters();
73 }
74
75 QCOORD smartSizeHint() {
76 return ( stretch > 0 ) ? minimumSize : sizeHint;
77 }
78
79 // permanent storage
80 int stretch;
81
82 // parameters
83 QCOORD sizeHint;
84 QCOORD maximumSize;
85 QCOORD minimumSize;
86 bool expansive;
87 bool empty;
88
89 // temporary storage
90 bool done;
91
92 // result
93 int pos;
94 int size;
95};
96
97
98Q_EXPORT void qGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count,
99 int pos, int space, int spacer );
100Q_EXPORT QSize qSmartMinSize( const QWidgetItem *i );
101Q_EXPORT QSize qSmartMinSize( QWidget *w );
102Q_EXPORT QSize qSmartMaxSize( const QWidgetItem *i, int align = 0 );
103Q_EXPORT QSize qSmartMaxSize( QWidget *w, int align = 0 );
104
105
106/*
107 Modify total maximum (max) and total expansion (exp)
108 when adding boxmax/boxexp.
109
110 Expansive boxes win over non-expansive boxes.
111*/
112static inline void qMaxExpCalc( QCOORD & max, bool &exp,
113 QCOORD boxmax, bool boxexp )
114{
115 if ( exp ) {
116 if ( boxexp )
117 max = QMAX( max, boxmax );
118 } else {
119 if ( boxexp )
120 max = boxmax;
121 else
122 max = QMIN( max, boxmax );
123 }
124 exp = exp || boxexp;
125}
126
127#endif //QT_NO_LAYOUT
128#endif
diff --git a/qmake/include/private/qlibrary_p.h b/qmake/include/private/qlibrary_p.h
new file mode 100644
index 0000000..c4dd565
--- a/dev/null
+++ b/qmake/include/private/qlibrary_p.h
@@ -0,0 +1,84 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of an internal 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#ifndef QLIBRARY_P_H
39#define QLIBRARY_P_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of the QLibrary class. This header file may change from
47// version to version without notice, or even be removed.
48//
49// We mean it.
50//
51//
52
53#include "qlibrary.h"
54
55#ifndef QT_NO_LIBRARY
56
57#ifndef QT_H
58#if defined(Q_CC_GNU)
59#warning "avoid including header file \"qwindowdefs.h\" in directory 'tools'"
60#endif
61#include "qwindowdefs.h"
62#endif // QT_H
63
64class QLibraryPrivate
65{
66public:
67 QLibraryPrivate( QLibrary *lib );
68
69#ifdef Q_WS_WIN
70 HINSTANCE pHnd;
71#else
72 void *pHnd;
73#endif
74
75 bool loadLibrary();
76 bool freeLibrary();
77 void *resolveSymbol( const char * );
78
79private:
80 QLibrary *library;
81};
82
83#endif // QT_NO_LIBRARY
84#endif // QLIBRARY_P_H
diff --git a/qmake/include/private/qmousedriverinterface_p.h b/qmake/include/private/qmousedriverinterface_p.h
new file mode 100644
index 0000000..fd76308
--- a/dev/null
+++ b/qmake/include/private/qmousedriverinterface_p.h
@@ -0,0 +1,56 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of Qt/Embedded Mouse Driver Interface
5**
6** Created : 20020220
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 and/or modified under the terms of the
13** GNU General Public License version 2 as published by the Free Software
14** Foundation and appearing in the file LICENSE.GPL included in the
15** packaging of this file.
16**
17** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
18** licenses for Qt/Embedded may use this file in accordance with the
19** Qt Embedded Commercial License Agreement provided with the Software.
20**
21** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
22** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23**
24** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
25** information about Qt Commercial License Agreements.
26** See http://www.trolltech.com/gpl/ for GPL licensing information.
27**
28** Contact info@trolltech.com if any conditions of this licensing are
29** not clear to you.
30**
31**********************************************************************/
32
33#ifndef QMOUSEDRIVERINTERFACE_H
34#define QMOUSEDRIVERINTERFACE_H
35
36#ifndef QT_H
37#include <private/qcom_p.h>
38#endif // QT_H
39
40#ifndef QT_NO_COMPONENT
41
42// {4367CF5A-F7CE-407B-8BB6-DF19AEDA2EBB}
43#ifndef IID_QMouseDriver
44#define IID_QMouseDriver QUuid( 0x4367cf5a, 0xf7ce, 0x407b, 0x8b, 0xb6, 0xdf, 0x19, 0xae, 0xda, 0x2e, 0xbb)
45#endif
46
47class QWSMouseHandler;
48
49struct Q_EXPORT QMouseDriverInterface : public QFeatureListInterface
50{
51 virtual QWSMouseHandler* create( const QString& driver, const QString &device ) = 0;
52};
53
54#endif // QT_NO_COMPONENT
55
56#endif // QMOUSEDRIVERINTERFACE_H
diff --git a/qmake/include/private/qmutex_p.h b/qmake/include/private/qmutex_p.h
new file mode 100644
index 0000000..d4ce97a
--- a/dev/null
+++ b/qmake/include/private/qmutex_p.h
@@ -0,0 +1,70 @@
1/****************************************************************************
2** $Id$
3**
4** QMutex private class declarations
5**
6** Created : 20012507
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#ifndef QMUTEX_P_H
39#define QMUTEX_P_H
40
41#ifndef QT_H
42#endif // QT_H
43
44//
45// W A R N I N G
46// -------------
47//
48// This file is not part of the Qt API. It exists for the convenience
49// of qmutex_unix.cpp and qmutex_win.cpp. This header file may change
50// from version to version without notice, or even be removed.
51//
52// We mean it.
53//
54
55class QMutexPrivate {
56public:
57 // Q_MUTEX_T is defined in the various *.cpp files
58 Q_MUTEX_T handle;
59
60 virtual ~QMutexPrivate();
61
62 virtual void lock() = 0;
63 virtual void unlock() = 0;
64 virtual bool locked() = 0;
65 virtual bool trylock() = 0;
66 virtual int type() const = 0;
67};
68
69
70#endif // QMUTEX_P_H
diff --git a/qmake/include/private/qmutexpool_p.h b/qmake/include/private/qmutexpool_p.h
new file mode 100644
index 0000000..3d9fef7
--- a/dev/null
+++ b/qmake/include/private/qmutexpool_p.h
@@ -0,0 +1,39 @@
1#ifndef QMUTEXPOOL_H
2#define QMUTEXPOOL_H
3
4//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists for the convenience
9// of QSettings. This header file may change from version to
10// version without notice, or even be removed.
11//
12// We mean it.
13//
14//
15
16#ifdef QT_THREAD_SUPPORT
17
18#include "qmutex.h"
19#include "qmemarray.h"
20
21class QMutexPool
22{
23public:
24 QMutexPool( bool recursive = FALSE, int size = 17 );
25 ~QMutexPool();
26
27 QMutex *get( void *address );
28
29private:
30 QMutex mutex;
31 QMemArray<QMutex*> mutexes;
32 bool recurs;
33};
34
35extern QMutexPool *qt_global_mutexpool;
36
37#endif // QT_THREAD_SUPPORT
38
39#endif // QMUTEXPOOL_H
diff --git a/qmake/include/private/qpainter_p.h b/qmake/include/private/qpainter_p.h
new file mode 100644
index 0000000..43f454e
--- a/dev/null
+++ b/qmake/include/private/qpainter_p.h
@@ -0,0 +1,63 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of some Qt private functions.
5**
6** Created : 000909
7**
8** Copyright (C) 2000 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#ifndef QPAINTER_P_H
39#define QPAINTER_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qpainter.cpp and qfont.cpp. This header file may change
48// from version to version without notice, or even be removed.
49//
50// We mean it.
51//
52//
53
54#ifndef QT_H
55#endif // QT_H
56
57extern void qt_format_text( const QFont& f, const QRect &r,
58 int tf, const QString& str, int len, QRect *brect,
59 int tabstops, int* tabarray, int tabarraylen,
60 QTextParag **internal, QPainter* painter );
61
62
63#endif
diff --git a/qmake/include/private/qpluginmanager_p.h b/qmake/include/private/qpluginmanager_p.h
new file mode 100644
index 0000000..4b64ba0
--- a/dev/null
+++ b/qmake/include/private/qpluginmanager_p.h
@@ -0,0 +1,73 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QPluginManager 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#ifndef QPLUGINMANAGER_H
39#define QPLUGINMANAGER_H
40
41#ifndef QT_H
42#include "qgpluginmanager_p.h"
43#endif // QT_H
44
45//
46// W A R N I N G
47// -------------
48//
49// This file is not part of the Qt API. It exists for the convenience
50// of a number of Qt sources files. This header file may change from
51// version to version without notice, or even be removed.
52//
53// We mean it.
54//
55//
56
57#ifndef QT_NO_COMPONENT
58
59template<class Type>
60class QPluginManager : public QGPluginManager
61{
62public:
63 QPluginManager( const QUuid& id, const QStringList& paths = QString::null, const QString &suffix = QString::null, bool cs = TRUE )
64 : QGPluginManager( id, paths, suffix, cs ) {}
65 QRESULT queryInterface(const QString& feature, Type** iface) const
66 {
67 return queryUnknownInterface( feature, (QUnknownInterface**)iface );
68 }
69};
70
71#endif //QT_NO_COMPONENT
72
73#endif //QPLUGINMANAGER_H
diff --git a/qmake/include/private/qpsprinter_p.h b/qmake/include/private/qpsprinter_p.h
new file mode 100644
index 0000000..27a4968
--- a/dev/null
+++ b/qmake/include/private/qpsprinter_p.h
@@ -0,0 +1,89 @@
1/**********************************************************************
2** $Id$
3**
4** Definition of internal QPSPrinter class.
5** QPSPrinter implements PostScript (tm) output via QPrinter.
6**
7** Created : 940927
8**
9** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
10**
11** This file is part of the kernel 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#ifndef QPSPRINTER_P_H
40#define QPSPRINTER_P_H
41
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of qpsprinter.cpp and qprinter_x11.cpp.
49// This header file may change from version to version without notice,
50// or even be removed.
51//
52// We mean it.
53//
54//
55
56
57#ifndef QT_H
58#include "qprinter.h"
59#include "qtextstream.h"
60#endif // QT_H
61
62#ifndef QT_NO_PRINTER
63
64struct QPSPrinterPrivate;
65
66class Q_EXPORT QPSPrinter : public QPaintDevice
67{
68private:
69 // QPrinter uses these
70 QPSPrinter( QPrinter *, int );
71 ~QPSPrinter();
72
73 bool cmd ( int, QPainter *, QPDevCmdParam * );
74
75 enum { NewPage = 100, AbortPrinting };
76
77 friend class QPrinter;
78private:
79 // not used by QPrinter
80 QPSPrinterPrivate *d;
81
82 // Disabled copy constructor and operator=
83 QPSPrinter( const QPSPrinter & );
84 QPSPrinter &operator=( const QPSPrinter & );
85};
86
87#endif // QT_NO_PRINTER
88
89#endif // QPSPRINTER_P_H
diff --git a/qmake/include/private/qrichtext_p.h b/qmake/include/private/qrichtext_p.h
new file mode 100644
index 0000000..8e29804
--- a/dev/null
+++ b/qmake/include/private/qrichtext_p.h
@@ -0,0 +1,2133 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of internal rich text classes
5**
6** Created : 990124
7**
8** Copyright (C) 1999-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#ifndef QRICHTEXT_P_H
39#define QRICHTEXT_P_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of a number of Qt sources files. This header file may change from
47// version to version without notice, or even be removed.
48//
49// We mean it.
50//
51//
52
53#ifndef QT_H
54#include "qstring.h"
55#include "qptrlist.h"
56#include "qrect.h"
57#include "qfontmetrics.h"
58#include "qintdict.h"
59#include "qmap.h"
60#include "qstringlist.h"
61#include "qfont.h"
62#include "qcolor.h"
63#include "qsize.h"
64#include "qvaluelist.h"
65#include "qvaluestack.h"
66#include "qobject.h"
67#include "qdict.h"
68#include "qpixmap.h"
69#include "qstylesheet.h"
70#include "qptrvector.h"
71#include "qpainter.h"
72#include "qlayout.h"
73#include "qobject.h"
74#include "private/qcomplextext_p.h"
75#include "qapplication.h"
76#endif // QT_H
77
78#ifndef QT_NO_RICHTEXT
79
80class QTextDocument;
81class QTextString;
82class QTextPreProcessor;
83class QTextFormat;
84class QTextCursor;
85class QTextParagraph;
86class QTextFormatter;
87class QTextIndent;
88class QTextFormatCollection;
89class QStyleSheetItem;
90#ifndef QT_NO_TEXTCUSTOMITEM
91class QTextCustomItem;
92#endif
93class QTextFlow;
94struct QBidiContext;
95
96// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
97
98class Q_EXPORT QTextStringChar
99{
100 friend class QTextString;
101
102public:
103 // this is never called, initialize variables in QTextString::insert()!!!
104 QTextStringChar() : lineStart( 0 ), type( Regular ), startOfRun( 0 ) {d.format=0;}
105 ~QTextStringChar();
106
107 QChar c;
108 enum Type { Regular=0, Custom=1, Anchor=2, CustomAnchor=3 };
109 uint lineStart : 1;
110 uint rightToLeft : 1;
111 uint hasCursor : 1;
112 uint canBreak : 1;
113 Type type : 2;
114 uint startOfRun : 1;
115
116 int x;
117 int height() const;
118 int ascent() const;
119 int descent() const;
120 bool isCustom() const { return (type & Custom) != 0; }
121 QTextFormat *format() const;
122#ifndef QT_NO_TEXTCUSTOMITEM
123 QTextCustomItem *customItem() const;
124#endif
125 void setFormat( QTextFormat *f );
126#ifndef QT_NO_TEXTCUSTOMITEM
127 void setCustomItem( QTextCustomItem *i );
128#endif
129 struct CustomData
130 {
131 QTextFormat *format;
132#ifndef QT_NO_TEXTCUSTOMITEM
133 QTextCustomItem *custom;
134#endif
135 QString anchorName;
136 QString anchorHref;
137 };
138
139#ifndef QT_NO_TEXTCUSTOMITEM
140 void loseCustomItem();
141#endif
142
143 union {
144 QTextFormat* format;
145 CustomData* custom;
146 } d;
147
148 bool isAnchor() const { return ( type & Anchor) != 0; }
149 bool isLink() const { return isAnchor() && !!d.custom->anchorHref; }
150 QString anchorName() const;
151 QString anchorHref() const;
152 void setAnchor( const QString& name, const QString& href );
153
154private:
155 QTextStringChar &operator=( const QTextStringChar & ) {
156 //abort();
157 return *this;
158 }
159 friend class QComplexText;
160 friend class QTextParagraph;
161};
162
163#if defined(Q_TEMPLATEDLL)
164// MOC_SKIP_BEGIN
165Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<QTextStringChar>;
166// MOC_SKIP_END
167#endif
168
169class Q_EXPORT QTextString
170{
171public:
172
173 QTextString();
174 QTextString( const QTextString &s );
175 virtual ~QTextString();
176
177 static QString toString( const QMemArray<QTextStringChar> &data );
178 QString toString() const;
179
180 QTextStringChar &at( int i ) const;
181#if defined(Q_STRICT_INLINING_RULES)
182 // This is for the IRIX MIPSpro o32 ABI - it fails, claiming the
183 // implementation to be a redefinition.
184 inline int length() const;
185#else
186 int length() const;
187#endif
188
189 int width( int idx ) const;
190
191 void insert( int index, const QString &s, QTextFormat *f );
192 void insert( int index, const QChar *unicode, int len, QTextFormat *f );
193 void insert( int index, QTextStringChar *c, bool doAddRefFormat = FALSE );
194 void truncate( int index );
195 void remove( int index, int len );
196 void clear();
197
198 void setFormat( int index, QTextFormat *f, bool useCollection );
199
200 void setBidi( bool b ) { bidi = b; }
201 bool isBidi() const;
202 bool isRightToLeft() const;
203 QChar::Direction direction() const;
204 void setDirection( QChar::Direction d ) { dir = d; bidiDirty = TRUE; }
205
206 QMemArray<QTextStringChar> subString( int start = 0, int len = 0xFFFFFF ) const;
207 QMemArray<QTextStringChar> rawData() const { return data.copy(); }
208
209 void operator=( const QString &s ) { clear(); insert( 0, s, 0 ); }
210 void operator+=( const QString &s ) { insert( length(), s, 0 ); }
211 void prepend( const QString &s ) { insert( 0, s, 0 ); }
212
213private:
214 void checkBidi() const;
215
216 QMemArray<QTextStringChar> data;
217 uint bidiDirty : 1;
218 uint bidi : 1; // true when the paragraph has right to left characters
219 uint rightToLeft : 1;
220 uint dir : 5;
221};
222
223inline bool QTextString::isBidi() const
224{
225 if ( bidiDirty )
226 checkBidi();
227 return bidi;
228}
229
230inline bool QTextString::isRightToLeft() const
231{
232 if ( bidiDirty )
233 checkBidi();
234 return rightToLeft;
235}
236
237inline QChar::Direction QTextString::direction() const
238{
239 return (QChar::Direction) dir;
240}
241
242// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
243
244#if defined(Q_TEMPLATEDLL)
245// MOC_SKIP_BEGIN
246Q_TEMPLATE_EXTERN template class Q_EXPORT QValueStack<int>;
247Q_TEMPLATE_EXTERN template class Q_EXPORT QValueStack<QTextParagraph*>;
248Q_TEMPLATE_EXTERN template class Q_EXPORT QValueStack<bool>;
249// MOC_SKIP_END
250#endif
251
252class Q_EXPORT QTextCursor
253{
254public:
255 QTextCursor( QTextDocument *d = 0 );
256 QTextCursor( const QTextCursor &c );
257 QTextCursor &operator=( const QTextCursor &c );
258 virtual ~QTextCursor() {}
259
260 bool operator==( const QTextCursor &c ) const;
261 bool operator!=( const QTextCursor &c ) const { return !(*this == c); }
262
263#if defined(Q_STRICT_INLINING_RULES)
264 // This is for the IRIX MIPSpro o32 ABI - it fails, claiming the
265 // implementation to be a redefinition.
266 inline QTextParagraph *paragraph() const;
267#else
268 QTextParagraph *paragraph() const;
269#endif
270
271 void setParagraph( QTextParagraph*p ) { gotoPosition(p, 0 ); }
272 QTextDocument *document() const;
273 int index() const;
274 void setIndex( int index ) { gotoPosition(paragraph(), index ); }
275
276 void gotoPosition( QTextParagraph* p, int index = 0);
277 void gotoLeft();
278 void gotoRight();
279 void gotoNextLetter();
280 void gotoPreviousLetter();
281 void gotoUp();
282 void gotoDown();
283 void gotoLineEnd();
284 void gotoLineStart();
285 void gotoHome();
286 void gotoEnd();
287 void gotoPageUp( int visibleHeight );
288 void gotoPageDown( int visibleHeight );
289 void gotoNextWord();
290 void gotoPreviousWord();
291 void gotoWordLeft();
292 void gotoWordRight();
293
294 void insert( const QString &s, bool checkNewLine, QMemArray<QTextStringChar> *formatting = 0 );
295 void splitAndInsertEmptyParagraph( bool ind = TRUE, bool updateIds = TRUE );
296 bool remove();
297 void indent();
298
299 bool atParagStart();
300 bool atParagEnd();
301
302 int x() const; // x in current paragraph
303 int y() const; // y in current paragraph
304
305 int globalX() const;
306 int globalY() const;
307
308 QTextParagraph *topParagraph() const { return paras.isEmpty() ? para : paras.first(); }
309 int offsetX() const { return ox; } // inner document offset
310 int offsetY() const { return oy; } // inner document offset
311 int totalOffsetX() const; // total document offset
312 int totalOffsetY() const; // total document offset
313
314 bool place( const QPoint &pos, QTextParagraph *s ) { return place( pos, s, FALSE ); }
315 bool place( const QPoint &pos, QTextParagraph *s, bool link );
316 void restoreState();
317
318
319 int nestedDepth() const { return (int)indices.count(); } //### size_t/int cast
320 void oneUp() { if ( !indices.isEmpty() ) pop(); }
321 void setValid( bool b ) { valid = b; }
322 bool isValid() const { return valid; }
323
324private:
325 enum Operation { EnterBegin, EnterEnd, Next, Prev, Up, Down };
326
327 void push();
328 void pop();
329 void processNesting( Operation op );
330 void invalidateNested();
331 void gotoIntoNested( const QPoint &globalPos );
332
333 QTextParagraph *para;
334 int idx, tmpIndex;
335 int ox, oy;
336 QValueStack<int> indices;
337 QValueStack<QTextParagraph*> paras;
338 QValueStack<int> xOffsets;
339 QValueStack<int> yOffsets;
340 uint valid : 1;
341
342};
343
344// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
345
346class Q_EXPORT QTextCommand
347{
348public:
349 enum Commands { Invalid, Insert, Delete, Format, Style };
350
351 QTextCommand( QTextDocument *d ) : doc( d ), cursor( d ) {}
352 virtual ~QTextCommand();
353
354 virtual Commands type() const;
355
356 virtual QTextCursor *execute( QTextCursor *c ) = 0;
357 virtual QTextCursor *unexecute( QTextCursor *c ) = 0;
358
359protected:
360 QTextDocument *doc;
361 QTextCursor cursor;
362
363};
364
365#if defined(Q_TEMPLATEDLL)
366// MOC_SKIP_BEGIN
367Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextCommand>;
368// MOC_SKIP_END
369#endif
370
371class Q_EXPORT QTextCommandHistory
372{
373public:
374 QTextCommandHistory( int s ) : current( -1 ), steps( s ) { history.setAutoDelete( TRUE ); }
375 virtual ~QTextCommandHistory();
376
377 void clear() { history.clear(); current = -1; }
378
379 void addCommand( QTextCommand *cmd );
380 QTextCursor *undo( QTextCursor *c );
381 QTextCursor *redo( QTextCursor *c );
382
383 bool isUndoAvailable();
384 bool isRedoAvailable();
385
386 void setUndoDepth( int d ) { steps = d; }
387 int undoDepth() const { return steps; }
388
389 int historySize() const { return history.count(); }
390 int currentPosition() const { return current; }
391
392private:
393 QPtrList<QTextCommand> history;
394 int current, steps;
395
396};
397
398inline QTextCommandHistory::~QTextCommandHistory()
399{
400 clear();
401}
402
403// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
404
405#ifndef QT_NO_TEXTCUSTOMITEM
406class Q_EXPORT QTextCustomItem
407{
408public:
409 QTextCustomItem( QTextDocument *p )
410 : xpos(0), ypos(-1), width(-1), height(0), parent( p )
411 {}
412 virtual ~QTextCustomItem();
413 virtual void draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) = 0;
414
415 virtual void adjustToPainter( QPainter* );
416
417 enum Placement { PlaceInline = 0, PlaceLeft, PlaceRight };
418 virtual Placement placement() const;
419 bool placeInline() { return placement() == PlaceInline; }
420
421 virtual bool ownLine() const;
422 virtual void resize( int nwidth );
423 virtual void invalidate();
424 virtual int ascent() const { return height; }
425
426 virtual bool isNested() const;
427 virtual int minimumWidth() const;
428
429 virtual QString richText() const;
430
431 int xpos; // used for floating items
432 int ypos; // used for floating items
433 int width;
434 int height;
435
436 QRect geometry() const { return QRect( xpos, ypos, width, height ); }
437
438 virtual bool enter( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE );
439 virtual bool enterAt( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint & );
440 virtual bool next( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
441 virtual bool prev( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
442 virtual bool down( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
443 virtual bool up( QTextCursor *, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
444
445 void setParagraph( QTextParagraph *p ) { parag = p; }
446 QTextParagraph *paragraph() const { return parag; }
447
448 QTextDocument *parent;
449 QTextParagraph *parag;
450
451 virtual void pageBreak( int y, QTextFlow* flow );
452};
453#endif
454
455#if defined(Q_TEMPLATEDLL)
456// MOC_SKIP_BEGIN
457Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<QString, QString>;
458// MOC_SKIP_END
459#endif
460
461#ifndef QT_NO_TEXTCUSTOMITEM
462class Q_EXPORT QTextImage : public QTextCustomItem
463{
464public:
465 QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context,
466 QMimeSourceFactory &factory );
467 virtual ~QTextImage();
468
469 Placement placement() const { return place; }
470 void adjustToPainter( QPainter* );
471 int minimumWidth() const { return width; }
472
473 QString richText() const;
474
475 void draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected );
476
477private:
478 QRegion* reg;
479 QPixmap pm;
480 Placement place;
481 int tmpwidth, tmpheight;
482 QMap<QString, QString> attributes;
483 QString imgId;
484
485};
486#endif
487
488#ifndef QT_NO_TEXTCUSTOMITEM
489class Q_EXPORT QTextHorizontalLine : public QTextCustomItem
490{
491public:
492 QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context,
493 QMimeSourceFactory &factory );
494 virtual ~QTextHorizontalLine();
495
496 void adjustToPainter( QPainter* );
497 void draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected );
498 QString richText() const;
499
500 bool ownLine() const { return TRUE; }
501
502private:
503 int tmpheight;
504 QColor color;
505 bool shade;
506
507};
508#endif
509
510#ifndef QT_NO_TEXTCUSTOMITEM
511#if defined(Q_TEMPLATEDLL)
512// MOC_SKIP_BEGIN
513Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextCustomItem>;
514// MOC_SKIP_END
515#endif
516#endif
517
518class Q_EXPORT QTextFlow
519{
520 friend class QTextDocument;
521#ifndef QT_NO_TEXTCUSTOMITEM
522 friend class QTextTableCell;
523#endif
524
525public:
526 QTextFlow();
527 virtual ~QTextFlow();
528
529 virtual void setWidth( int width );
530 int width() const;
531
532 virtual void setPageSize( int ps );
533 int pageSize() const { return pagesize; }
534
535 virtual int adjustLMargin( int yp, int h, int margin, int space );
536 virtual int adjustRMargin( int yp, int h, int margin, int space );
537
538#ifndef QT_NO_TEXTCUSTOMITEM
539 virtual void registerFloatingItem( QTextCustomItem* item );
540 virtual void unregisterFloatingItem( QTextCustomItem* item );
541#endif
542 virtual QRect boundingRect() const;
543 virtual void drawFloatingItems(QPainter* p, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected );
544
545 virtual int adjustFlow( int y, int w, int h ); // adjusts y according to the defined pagesize. Returns the shift.
546
547 virtual bool isEmpty();
548
549 void clear();
550
551private:
552 int w;
553 int pagesize;
554
555#ifndef QT_NO_TEXTCUSTOMITEM
556 QPtrList<QTextCustomItem> leftItems;
557 QPtrList<QTextCustomItem> rightItems;
558#endif
559};
560
561inline int QTextFlow::width() const { return w; }
562
563#ifndef QT_NO_TEXTCUSTOMITEM
564class QTextTable;
565
566class Q_EXPORT QTextTableCell : public QLayoutItem
567{
568 friend class QTextTable;
569
570public:
571 QTextTableCell( QTextTable* table,
572 int row, int column,
573 const QMap<QString, QString> &attr,
574 const QStyleSheetItem* style,
575 const QTextFormat& fmt, const QString& context,
576 QMimeSourceFactory &factory, QStyleSheet *sheet, const QString& doc );
577 virtual ~QTextTableCell();
578
579 QSize sizeHint() const ;
580 QSize minimumSize() const ;
581 QSize maximumSize() const ;
582 QSizePolicy::ExpandData expanding() const;
583 bool isEmpty() const;
584 void setGeometry( const QRect& ) ;
585 QRect geometry() const;
586
587 bool hasHeightForWidth() const;
588 int heightForWidth( int ) const;
589
590 void adjustToPainter( QPainter* );
591
592 int row() const { return row_; }
593 int column() const { return col_; }
594 int rowspan() const { return rowspan_; }
595 int colspan() const { return colspan_; }
596 int stretch() const { return stretch_; }
597
598 QTextDocument* richText() const { return richtext; }
599 QTextTable* table() const { return parent; }
600
601 void draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected );
602
603 QBrush *backGround() const { return background; }
604 virtual void invalidate();
605
606 int verticalAlignmentOffset() const;
607 int horizontalAlignmentOffset() const;
608
609private:
610 QRect geom;
611 QTextTable* parent;
612 QTextDocument* richtext;
613 int row_;
614 int col_;
615 int rowspan_;
616 int colspan_;
617 int stretch_;
618 int maxw;
619 int minw;
620 bool hasFixedWidth;
621 QBrush *background;
622 int cached_width;
623 int cached_sizehint;
624 QMap<QString, QString> attributes;
625 int align;
626};
627#endif
628
629#if defined(Q_TEMPLATEDLL)
630// MOC_SKIP_BEGIN
631Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextTableCell>;
632Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<QTextCursor*, int>;
633// MOC_SKIP_END
634#endif
635
636#ifndef QT_NO_TEXTCUSTOMITEM
637class Q_EXPORT QTextTable: public QTextCustomItem
638{
639 friend class QTextTableCell;
640
641public:
642 QTextTable( QTextDocument *p, const QMap<QString, QString> &attr );
643 virtual ~QTextTable();
644
645 void adjustToPainter( QPainter *p );
646 void pageBreak( int y, QTextFlow* flow );
647 void draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch,
648 const QColorGroup& cg, bool selected );
649
650 bool noErase() const { return TRUE; }
651 bool ownLine() const { return TRUE; }
652 Placement placement() const { return place; }
653 bool isNested() const { return TRUE; }
654 void resize( int nwidth );
655 virtual void invalidate();
656
657 virtual bool enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE );
658 virtual bool enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos );
659 virtual bool next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
660 virtual bool prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
661 virtual bool down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
662 virtual bool up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy );
663
664 QString richText() const;
665
666 int minimumWidth() const;
667
668 QPtrList<QTextTableCell> tableCells() const { return cells; }
669
670 bool isStretching() const { return stretch; }
671
672private:
673 void format( int w );
674 void addCell( QTextTableCell* cell );
675
676private:
677 QGridLayout* layout;
678 QPtrList<QTextTableCell> cells;
679 int cachewidth;
680 int fixwidth;
681 int cellpadding;
682 int cellspacing;
683 int border;
684 int outerborder;
685 int stretch;
686 int innerborder;
687 int us_cp, us_ib, us_b, us_ob, us_cs;
688 QMap<QString, QString> attributes;
689 QMap<QTextCursor*, int> currCell;
690 Placement place;
691 void adjustCells( int y , int shift );
692 int pageBreakFor;
693};
694#endif
695// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
696
697#ifndef QT_NO_TEXTCUSTOMITEM
698class QTextTableCell;
699class QTextParagraph;
700#endif
701
702struct Q_EXPORT QTextDocumentSelection
703{
704 QTextCursor startCursor, endCursor;
705 bool swapped;
706};
707
708#if defined(Q_TEMPLATEDLL)
709// MOC_SKIP_BEGIN
710Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QColor>;
711Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, bool>;
712Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QTextDocumentSelection>;
713Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<QTextDocument>;
714// MOC_SKIP_END
715#endif
716
717class Q_EXPORT QTextDocument : public QObject
718{
719 Q_OBJECT
720
721#ifndef QT_NO_TEXTCUSTOMITEM
722 friend class QTextTableCell;
723#endif
724 friend class QTextCursor;
725 friend class QTextEdit;
726 friend class QTextParagraph;
727
728public:
729 enum SelectionIds {
730 Standard = 0,
731 IMSelectionText = 31998,
732 IMCompositionText= 31999, // this must be higher!
733 Temp = 32000 // This selection must not be drawn, it's used e.g. by undo/redo to
734 // remove multiple lines with removeSelectedText()
735 };
736
737 QTextDocument( QTextDocument *p );
738 QTextDocument( QTextDocument *d, QTextFormatCollection *f );
739 virtual ~QTextDocument();
740
741 QTextDocument *parent() const { return par; }
742 QTextParagraph *parentParagraph() const { return parentPar; }
743
744 void setText( const QString &text, const QString &context );
745 QMap<QString, QString> attributes() const { return attribs; }
746 void setAttributes( const QMap<QString, QString> &attr ) { attribs = attr; }
747
748 QString text() const;
749 QString text( int parag ) const;
750 QString originalText() const;
751
752 int x() const;
753 int y() const;
754 int width() const;
755 int widthUsed() const;
756 int visibleWidth() const;
757 int height() const;
758 void setWidth( int w );
759 int minimumWidth() const;
760 bool setMinimumWidth( int needed, int used = -1, QTextParagraph *parag = 0 );
761
762 void setY( int y );
763 int leftMargin() const;
764 void setLeftMargin( int lm );
765 int rightMargin() const;
766 void setRightMargin( int rm );
767
768 QTextParagraph *firstParagraph() const;
769 QTextParagraph *lastParagraph() const;
770 void setFirstParagraph( QTextParagraph *p );
771 void setLastParagraph( QTextParagraph *p );
772
773 void invalidate();
774
775 void setPreProcessor( QTextPreProcessor *sh );
776 QTextPreProcessor *preProcessor() const;
777
778 void setFormatter( QTextFormatter *f );
779 QTextFormatter *formatter() const;
780
781 void setIndent( QTextIndent *i );
782 QTextIndent *indent() const;
783
784 QColor selectionColor( int id ) const;
785 bool invertSelectionText( int id ) const;
786 void setSelectionColor( int id, const QColor &c );
787 void setInvertSelectionText( int id, bool b );
788 bool hasSelection( int id, bool visible = FALSE ) const;
789 void setSelectionStart( int id, const QTextCursor &cursor );
790 bool setSelectionEnd( int id, const QTextCursor &cursor );
791 void selectAll( int id );
792 bool removeSelection( int id );
793 void selectionStart( int id, int &paragId, int &index );
794 QTextCursor selectionStartCursor( int id );
795 QTextCursor selectionEndCursor( int id );
796 void selectionEnd( int id, int &paragId, int &index );
797 void setFormat( int id, QTextFormat *f, int flags );
798 int numSelections() const { return nSelections; }
799 void addSelection( int id );
800
801 QString selectedText( int id, bool asRichText = FALSE ) const;
802 void removeSelectedText( int id, QTextCursor *cursor );
803 void indentSelection( int id );
804
805 QTextParagraph *paragAt( int i ) const;
806
807 void addCommand( QTextCommand *cmd );
808 QTextCursor *undo( QTextCursor *c = 0 );
809 QTextCursor *redo( QTextCursor *c = 0 );
810 QTextCommandHistory *commands() const { return commandHistory; }
811
812 QTextFormatCollection *formatCollection() const;
813
814 bool find( QTextCursor &cursor, const QString &expr, bool cs, bool wo, bool forward);
815
816 void setTextFormat( Qt::TextFormat f );
817 Qt::TextFormat textFormat() const;
818
819 bool inSelection( int selId, const QPoint &pos ) const;
820
821 QStyleSheet *styleSheet() const { return sheet_; }
822#ifndef QT_NO_MIME
823 QMimeSourceFactory *mimeSourceFactory() const { return factory_; }
824#endif
825 QString context() const { return contxt; }
826
827 void setStyleSheet( QStyleSheet *s );
828 void setDefaultFormat( const QFont &font, const QColor &color );
829#ifndef QT_NO_MIME
830 void setMimeSourceFactory( QMimeSourceFactory *f ) { if ( f ) factory_ = f; }
831#endif
832 void setContext( const QString &c ) { if ( !c.isEmpty() ) contxt = c; }
833
834 void setUnderlineLinks( bool b );
835 bool underlineLinks() const { return underlLinks; }
836
837 void setPaper( QBrush *brush ) { if ( backBrush ) delete backBrush; backBrush = brush; }
838 QBrush *paper() const { return backBrush; }
839
840 void doLayout( QPainter *p, int w );
841 void draw( QPainter *p, const QRect& rect, const QColorGroup &cg, const QBrush *paper = 0 );
842 void drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch,
843 QPixmap *&doubleBuffer, const QColorGroup &cg,
844 bool drawCursor, QTextCursor *cursor, bool resetChanged = TRUE );
845 QTextParagraph *draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg,
846 bool onlyChanged = FALSE, bool drawCursor = FALSE, QTextCursor *cursor = 0,
847 bool resetChanged = TRUE );
848
849#ifndef QT_NO_TEXTCUSTOMITEM
850 void registerCustomItem( QTextCustomItem *i, QTextParagraph *p );
851 void unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p );
852#endif
853
854 void setFlow( QTextFlow *f );
855 void takeFlow();
856 QTextFlow *flow() const { return flow_; }
857 bool isPageBreakEnabled() const { return pages; }
858 void setPageBreakEnabled( bool b ) { pages = b; }
859
860 void setUseFormatCollection( bool b ) { useFC = b; }
861 bool useFormatCollection() const { return useFC; }
862
863#ifndef QT_NO_TEXTCUSTOMITEM
864 QTextTableCell *tableCell() const { return tc; }
865 void setTableCell( QTextTableCell *c ) { tc = c; }
866#endif
867
868 void setPlainText( const QString &text );
869 void setRichText( const QString &text, const QString &context );
870 QString richText() const;
871 QString plainText() const;
872
873 bool focusNextPrevChild( bool next );
874
875 int alignment() const;
876 void setAlignment( int a );
877
878 int *tabArray() const;
879 int tabStopWidth() const;
880 void setTabArray( int *a );
881 void setTabStops( int tw );
882
883 void setUndoDepth( int d ) { commandHistory->setUndoDepth( d ); }
884 int undoDepth() const { return commandHistory->undoDepth(); }
885
886 int length() const;
887 void clear( bool createEmptyParag = FALSE );
888
889 virtual QTextParagraph *createParagraph( QTextDocument *d, QTextParagraph *pr = 0, QTextParagraph *nx = 0, bool updateIds = TRUE );
890 void insertChild( QObject *o ) { QObject::insertChild( o ); }
891 void removeChild( QObject *o ) { QObject::removeChild( o ); }
892 void insertChild( QTextDocument *d ) { childList.append( d ); }
893 void removeChild( QTextDocument *d ) { childList.removeRef( d ); }
894 QPtrList<QTextDocument> children() const { return childList; }
895
896 bool hasFocusParagraph() const;
897 QString focusHref() const;
898 QString focusName() const;
899
900 void invalidateOriginalText() { oTextValid = FALSE; oText = ""; }
901
902signals:
903 void minimumWidthChanged( int );
904
905private:
906 void init();
907 QPixmap *bufferPixmap( const QSize &s );
908 // HTML parser
909 bool hasPrefix(const QChar* doc, int length, int pos, QChar c);
910 bool hasPrefix(const QChar* doc, int length, int pos, const QString& s);
911#ifndef QT_NO_TEXTCUSTOMITEM
912 QTextCustomItem* parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt,
913 const QChar* doc, int length, int& pos, QTextParagraph *curpar );
914#endif
915 bool eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp = FALSE );
916 bool eat(const QChar* doc, int length, int& pos, QChar c);
917 QString parseOpenTag(const QChar* doc, int length, int& pos, QMap<QString, QString> &attr, bool& emptyTag);
918 QString parseCloseTag( const QChar* doc, int length, int& pos );
919 QChar parseHTMLSpecialChar(const QChar* doc, int length, int& pos);
920 QString parseWord(const QChar* doc, int length, int& pos, bool lower = TRUE);
921 QChar parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm );
922 void setRichTextInternal( const QString &text, QTextCursor* cursor = 0 );
923 void setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar );
924
925private:
926 struct Q_EXPORT Focus {
927 QTextParagraph *parag;
928 int start, len;
929 QString href;
930 QString name;
931 };
932
933 int cx, cy, cw, vw;
934 QTextParagraph *fParag, *lParag;
935 QTextPreProcessor *pProcessor;
936 QMap<int, QColor> selectionColors;
937 QMap<int, QTextDocumentSelection> selections;
938 QMap<int, bool> selectionText;
939 QTextCommandHistory *commandHistory;
940 QTextFormatter *pFormatter;
941 QTextIndent *indenter;
942 QTextFormatCollection *fCollection;
943 Qt::TextFormat txtFormat;
944 uint preferRichText : 1;
945 uint pages : 1;
946 uint useFC : 1;
947 uint withoutDoubleBuffer : 1;
948 uint underlLinks : 1;
949 uint nextDoubleBuffered : 1;
950 uint oTextValid : 1;
951 uint mightHaveCustomItems : 1;
952 int align;
953 int nSelections;
954 QTextFlow *flow_;
955 QTextDocument *par;
956 QTextParagraph *parentPar;
957#ifndef QT_NO_TEXTCUSTOMITEM
958 QTextTableCell *tc;
959#endif
960 QBrush *backBrush;
961 QPixmap *buf_pixmap;
962 Focus focusIndicator;
963 int minw;
964 int wused;
965 int leftmargin;
966 int rightmargin;
967 QTextParagraph *minwParag, *curParag;
968 QStyleSheet* sheet_;
969#ifndef QT_NO_MIME
970 QMimeSourceFactory* factory_;
971#endif
972 QString contxt;
973 QMap<QString, QString> attribs;
974 int *tArray;
975 int tStopWidth;
976 int uDepth;
977 QString oText;
978 QPtrList<QTextDocument> childList;
979 QColor linkColor;
980 double scaleFontsFactor;
981
982 short list_tm,list_bm, list_lm, li_tm, li_bm, par_tm, par_bm;
983#if defined(Q_DISABLE_COPY) // Disabled copy constructor and operator=
984 QTextDocument( const QTextDocument & );
985 QTextDocument &operator=( const QTextDocument & );
986#endif
987};
988
989// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
990
991
992class Q_EXPORT QTextDeleteCommand : public QTextCommand
993{
994public:
995 QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str,
996 const QByteArray& oldStyle );
997 QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str );
998 virtual ~QTextDeleteCommand();
999
1000 Commands type() const { return Delete; }
1001 QTextCursor *execute( QTextCursor *c );
1002 QTextCursor *unexecute( QTextCursor *c );
1003
1004protected:
1005 int id, index;
1006 QTextParagraph *parag;
1007 QMemArray<QTextStringChar> text;
1008 QByteArray styleInformation;
1009
1010};
1011
1012class Q_EXPORT QTextInsertCommand : public QTextDeleteCommand
1013{
1014public:
1015 QTextInsertCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str,
1016 const QByteArray& oldStyleInfo )
1017 : QTextDeleteCommand( d, i, idx, str, oldStyleInfo ) {}
1018 QTextInsertCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str )
1019 : QTextDeleteCommand( p, idx, str ) {}
1020 virtual ~QTextInsertCommand() {}
1021
1022 Commands type() const { return Insert; }
1023 QTextCursor *execute( QTextCursor *c ) { return QTextDeleteCommand::unexecute( c ); }
1024 QTextCursor *unexecute( QTextCursor *c ) { return QTextDeleteCommand::execute( c ); }
1025
1026};
1027
1028class Q_EXPORT QTextFormatCommand : public QTextCommand
1029{
1030public:
1031 QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl );
1032 virtual ~QTextFormatCommand();
1033
1034 Commands type() const { return Format; }
1035 QTextCursor *execute( QTextCursor *c );
1036 QTextCursor *unexecute( QTextCursor *c );
1037
1038protected:
1039 int startId, startIndex, endId, endIndex;
1040 QTextFormat *format;
1041 QMemArray<QTextStringChar> oldFormats;
1042 int flags;
1043
1044};
1045
1046class Q_EXPORT QTextStyleCommand : public QTextCommand
1047{
1048public:
1049 QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange );
1050 virtual ~QTextStyleCommand() {}
1051
1052 Commands type() const { return Style; }
1053 QTextCursor *execute( QTextCursor *c );
1054 QTextCursor *unexecute( QTextCursor *c );
1055
1056 static QByteArray readStyleInformation( QTextDocument* d, int fParag, int lParag );
1057 static void writeStyleInformation( QTextDocument* d, int fParag, const QByteArray& style );
1058
1059private:
1060 int firstParag, lastParag;
1061 QByteArray before;
1062 QByteArray after;
1063};
1064
1065// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1066
1067struct Q_EXPORT QTextParagraphSelection
1068{
1069 int start, end;
1070};
1071
1072struct Q_EXPORT QTextLineStart
1073{
1074 QTextLineStart() : y( 0 ), baseLine( 0 ), h( 0 )
1075#ifndef QT_NO_COMPLEXTEXT
1076 , bidicontext( 0 )
1077#endif
1078 { }
1079 QTextLineStart( ushort y_, ushort bl, ushort h_ ) : y( y_ ), baseLine( bl ), h( h_ ),
1080 w( 0 )
1081#ifndef QT_NO_COMPLEXTEXT
1082 , bidicontext( 0 )
1083#endif
1084 { }
1085#ifndef QT_NO_COMPLEXTEXT
1086 QTextLineStart( QBidiContext *c, QBidiStatus s ) : y(0), baseLine(0), h(0),
1087 status( s ), bidicontext( c ) { if ( bidicontext ) bidicontext->ref(); }
1088#endif
1089
1090 virtual ~QTextLineStart()
1091 {
1092#ifndef QT_NO_COMPLEXTEXT
1093 if ( bidicontext && bidicontext->deref() )
1094 delete bidicontext;
1095#endif
1096 }
1097
1098#ifndef QT_NO_COMPLEXTEXT
1099 void setContext( QBidiContext *c ) {
1100 if ( c == bidicontext )
1101 return;
1102 if ( bidicontext && bidicontext->deref() )
1103 delete bidicontext;
1104 bidicontext = c;
1105 if ( bidicontext )
1106 bidicontext->ref();
1107 }
1108 QBidiContext *context() const { return bidicontext; }
1109#endif
1110
1111public:
1112 ushort y, baseLine, h;
1113#ifndef QT_NO_COMPLEXTEXT
1114 QBidiStatus status;
1115#endif
1116 int w;
1117
1118private:
1119#ifndef QT_NO_COMPLEXTEXT
1120 QBidiContext *bidicontext;
1121#endif
1122};
1123
1124#if defined(Q_TEMPLATEDLL)
1125// MOC_SKIP_BEGIN
1126Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QTextParagraphSelection>;
1127Q_TEMPLATE_EXTERN template class Q_EXPORT QMap<int, QTextLineStart*>;
1128// MOC_SKIP_END
1129#endif
1130
1131class Q_EXPORT QTextParagraphData
1132{
1133public:
1134 QTextParagraphData() {}
1135 virtual ~QTextParagraphData();
1136 virtual void join( QTextParagraphData * );
1137};
1138
1139class Q_EXPORT QTextParagraphPseudoDocument
1140{
1141public:
1142 QTextParagraphPseudoDocument();
1143 ~QTextParagraphPseudoDocument();
1144 QRect docRect;
1145 QTextFormatter *pFormatter;
1146 QTextCommandHistory *commandHistory;
1147 int minw;
1148 int wused;
1149};
1150
1151//nase
1152class Q_EXPORT QTextParagraph
1153{
1154 friend class QTextDocument;
1155 friend class QTextCursor;
1156
1157public:
1158 QTextParagraph( QTextDocument *d, QTextParagraph *pr = 0, QTextParagraph *nx = 0, bool updateIds = TRUE );
1159 virtual ~QTextParagraph();
1160
1161 QTextString *string() const;
1162 QTextStringChar *at( int i ) const; // maybe remove later
1163 int leftGap() const;
1164 int length() const; // maybe remove later
1165
1166 void setListStyle( QStyleSheetItem::ListStyle ls ) { lstyle = ls; changed = TRUE; }
1167 QStyleSheetItem::ListStyle listStyle() const { return lstyle; }
1168 void setListItem( bool li );
1169 bool isListItem() const { return litem; }
1170 void setListValue( int v ) { list_val = v; }
1171 int listValue() const { return list_val > 0 ? list_val : -1; }
1172
1173 void setListDepth( int depth );
1174 int listDepth() const { return ldepth; }
1175
1176// void setFormat( QTextFormat *fm );
1177// QTextFormat *paragFormat() const;
1178
1179 QTextDocument *document() const;
1180 QTextParagraphPseudoDocument *pseudoDocument() const;
1181
1182 QRect rect() const;
1183 void setHeight( int h ) { r.setHeight( h ); }
1184 void show();
1185 void hide();
1186 bool isVisible() const { return visible; }
1187
1188 QTextParagraph *prev() const;
1189 QTextParagraph *next() const;
1190 void setPrev( QTextParagraph *s );
1191 void setNext( QTextParagraph *s );
1192
1193 void insert( int index, const QString &s );
1194 void insert( int index, const QChar *unicode, int len );
1195 void append( const QString &s, bool reallyAtEnd = FALSE );
1196 void truncate( int index );
1197 void remove( int index, int len );
1198 void join( QTextParagraph *s );
1199
1200 void invalidate( int chr );
1201
1202 void move( int &dy );
1203 void format( int start = -1, bool doMove = TRUE );
1204
1205 bool isValid() const;
1206 bool hasChanged() const;
1207 void setChanged( bool b, bool recursive = FALSE );
1208
1209 int lineHeightOfChar( int i, int *bl = 0, int *y = 0 ) const;
1210 QTextStringChar *lineStartOfChar( int i, int *index = 0, int *line = 0 ) const;
1211 int lines() const;
1212 QTextStringChar *lineStartOfLine( int line, int *index = 0 ) const;
1213 int lineY( int l ) const;
1214 int lineBaseLine( int l ) const;
1215 int lineHeight( int l ) const;
1216 void lineInfo( int l, int &y, int &h, int &bl ) const;
1217
1218 void setSelection( int id, int start, int end );
1219 void removeSelection( int id );
1220 int selectionStart( int id ) const;
1221 int selectionEnd( int id ) const;
1222 bool hasSelection( int id ) const;
1223 bool hasAnySelection() const;
1224 bool fullSelected( int id ) const;
1225
1226 void setEndState( int s );
1227 int endState() const;
1228
1229 void setParagId( int i );
1230 int paragId() const;
1231
1232 bool firstPreProcess() const;
1233 void setFirstPreProcess( bool b );
1234
1235 void indent( int *oldIndent = 0, int *newIndent = 0 );
1236
1237 void setExtraData( QTextParagraphData *data );
1238 QTextParagraphData *extraData() const;
1239
1240 QMap<int, QTextLineStart*> &lineStartList();
1241
1242 void setFormat( int index, int len, QTextFormat *f, bool useCollection = TRUE, int flags = -1 );
1243
1244 void setAlignment( int a );
1245 int alignment() const;
1246
1247 virtual void paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor = 0, bool drawSelections = FALSE,
1248 int clipx = -1, int clipy = -1, int clipw = -1, int cliph = -1 );
1249
1250 virtual int topMargin() const;
1251 virtual int bottomMargin() const;
1252 virtual int leftMargin() const;
1253 virtual int firstLineMargin() const;
1254 virtual int rightMargin() const;
1255 virtual int lineSpacing() const;
1256
1257#ifndef QT_NO_TEXTCUSTOMITEM
1258 void registerFloatingItem( QTextCustomItem *i );
1259 void unregisterFloatingItem( QTextCustomItem *i );
1260#endif
1261
1262 void setFullWidth( bool b ) { fullWidth = b; }
1263 bool isFullWidth() const { return fullWidth; }
1264
1265#ifndef QT_NO_TEXTCUSTOMITEM
1266 QTextTableCell *tableCell() const;
1267#endif
1268
1269 QBrush *background() const;
1270
1271 int documentWidth() const;
1272 int documentVisibleWidth() const;
1273 int documentX() const;
1274 int documentY() const;
1275 QTextFormatCollection *formatCollection() const;
1276 QTextFormatter *formatter() const;
1277
1278 virtual int nextTab( int i, int x );
1279 int *tabArray() const;
1280 void setTabArray( int *a );
1281 void setTabStops( int tw );
1282
1283 void adjustToPainter( QPainter *p );
1284
1285 void setNewLinesAllowed( bool b );
1286 bool isNewLinesAllowed() const;
1287
1288 QString richText() const;
1289
1290 void addCommand( QTextCommand *cmd );
1291 QTextCursor *undo( QTextCursor *c = 0 );
1292 QTextCursor *redo( QTextCursor *c = 0 );
1293 QTextCommandHistory *commands() const;
1294 virtual void copyParagData( QTextParagraph *parag );
1295
1296 void setBreakable( bool b ) { breakable = b; }
1297 bool isBreakable() const { return breakable; }
1298
1299 void setBackgroundColor( const QColor &c );
1300 QColor *backgroundColor() const { return bgcol; }
1301 void clearBackgroundColor();
1302
1303 void setMovedDown( bool b ) { movedDown = b; }
1304 bool wasMovedDown() const { return movedDown; }
1305
1306 void setDirection( QChar::Direction d );
1307 QChar::Direction direction() const;
1308 void setPaintDevice( QPaintDevice *pd ) { paintdevice = pd; }
1309
1310 void readStyleInformation( QDataStream& stream );
1311 void writeStyleInformation( QDataStream& stream ) const;
1312
1313protected:
1314 virtual void setColorForSelection( QColor &c, QPainter &p, const QColorGroup& cg, int selection );
1315 virtual void drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg );
1316 virtual void drawString( QPainter &painter, const QString &str, int start, int len, int xstart,
1317 int y, int baseLine, int w, int h, int selection,
1318 QTextStringChar *formatChar, const QColorGroup& cg,
1319 bool rightToLeft );
1320
1321private:
1322 QMap<int, QTextParagraphSelection> &selections() const;
1323#ifndef QT_NO_TEXTCUSTOMITEM
1324 QPtrList<QTextCustomItem> &floatingItems() const;
1325#endif
1326 QBrush backgroundBrush( const QColorGroup&cg ) { if ( bgcol ) return *bgcol; return cg.brush( QColorGroup::Base ); }
1327 void invalidateStyleCache();
1328
1329 QMap<int, QTextLineStart*> lineStarts;
1330 int invalid;
1331 QRect r;
1332 QTextParagraph *p, *n;
1333 void *docOrPseudo;
1334 uint changed : 1;
1335 uint firstFormat : 1;
1336 uint firstPProcess : 1;
1337 uint needPreProcess : 1;
1338 uint fullWidth : 1;
1339 uint lastInFrame : 1;
1340 uint visible : 1;
1341 uint breakable : 1;
1342 uint movedDown : 1;
1343 uint mightHaveCustomItems : 1;
1344 uint hasdoc : 1;
1345 uint litem : 1; // whether the paragraph is a list item
1346 uint rtext : 1; // whether the paragraph needs rich text margin
1347 int align : 4;
1348 int state, id;
1349 QTextString *str;
1350 QMap<int, QTextParagraphSelection> *mSelections;
1351#ifndef QT_NO_TEXTCUSTOMITEM
1352 QPtrList<QTextCustomItem> *mFloatingItems;
1353#endif
1354 QStyleSheetItem::ListStyle lstyle;
1355 short utm, ubm, ulm, urm, uflm, ulinespacing;
1356 int *tArray;
1357 short tabStopWidth;
1358 QTextParagraphData *eData;
1359 short list_val;
1360 QColor *bgcol;
1361 ushort ldepth;
1362 QPaintDevice *paintdevice;
1363};
1364
1365// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1366
1367class Q_EXPORT QTextFormatter
1368{
1369public:
1370 QTextFormatter();
1371 virtual ~QTextFormatter();
1372
1373 virtual int format( QTextDocument *doc, QTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts ) = 0;
1374 virtual int formatVertically( QTextDocument* doc, QTextParagraph* parag );
1375
1376 bool isWrapEnabled( QTextParagraph *p ) const { if ( !wrapEnabled ) return FALSE; if ( p && !p->isBreakable() ) return FALSE; return TRUE;}
1377 int wrapAtColumn() const { return wrapColumn;}
1378 virtual void setWrapEnabled( bool b );
1379 virtual void setWrapAtColumn( int c );
1380 virtual void setAllowBreakInWords( bool b ) { biw = b; }
1381 bool allowBreakInWords() const { return biw; }
1382
1383 int minimumWidth() const { return thisminw; }
1384 int widthUsed() const { return thiswused; }
1385
1386 static bool isBreakable( QTextString *string, int pos );
1387
1388protected:
1389 virtual QTextLineStart *formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, QTextStringChar *start,
1390 QTextStringChar *last, int align = Qt::AlignAuto, int space = 0 );
1391#ifndef QT_NO_COMPLEXTEXT
1392 virtual QTextLineStart *bidiReorderLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, QTextStringChar *start,
1393 QTextStringChar *last, int align, int space );
1394#endif
1395 void insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls );
1396
1397 int thisminw;
1398 int thiswused;
1399
1400private:
1401 bool wrapEnabled;
1402 int wrapColumn;
1403 bool biw;
1404
1405#ifdef HAVE_THAI_BREAKS
1406 static QCString *thaiCache;
1407 static QTextString *cachedString;
1408 static ThBreakIterator *thaiIt;
1409#endif
1410};
1411
1412// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1413
1414class Q_EXPORT QTextFormatterBreakInWords : public QTextFormatter
1415{
1416public:
1417 QTextFormatterBreakInWords();
1418 virtual ~QTextFormatterBreakInWords() {}
1419
1420 int format( QTextDocument *doc, QTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts );
1421
1422};
1423
1424// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1425
1426class Q_EXPORT QTextFormatterBreakWords : public QTextFormatter
1427{
1428public:
1429 QTextFormatterBreakWords();
1430 virtual ~QTextFormatterBreakWords() {}
1431
1432 int format( QTextDocument *doc, QTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts );
1433
1434};
1435
1436// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1437
1438class Q_EXPORT QTextIndent
1439{
1440public:
1441 QTextIndent();
1442 virtual ~QTextIndent() {}
1443
1444 virtual void indent( QTextDocument *doc, QTextParagraph *parag, int *oldIndent = 0, int *newIndent = 0 ) = 0;
1445
1446};
1447
1448// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1449
1450class Q_EXPORT QTextPreProcessor
1451{
1452public:
1453 enum Ids {
1454 Standard = 0
1455 };
1456
1457 QTextPreProcessor();
1458 virtual ~QTextPreProcessor() {}
1459
1460 virtual void process( QTextDocument *doc, QTextParagraph *, int, bool = TRUE ) = 0;
1461 virtual QTextFormat *format( int id ) = 0;
1462
1463};
1464
1465// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1466
1467class Q_EXPORT QTextFormat
1468{
1469 friend class QTextFormatCollection;
1470 friend class QTextDocument;
1471
1472public:
1473 enum Flags {
1474 NoFlags,
1475 Bold = 1,
1476 Italic = 2,
1477 Underline = 4,
1478 Family = 8,
1479 Size = 16,
1480 Color = 32,
1481 Misspelled = 64,
1482 VAlign = 128,
1483 StrikeOut= 256,
1484 Font = Bold | Italic | Underline | Family | Size | StrikeOut,
1485 Format = Font | Color | Misspelled | VAlign
1486 };
1487
1488 enum VerticalAlignment { AlignNormal, AlignSuperScript, AlignSubScript };
1489
1490 QTextFormat();
1491 virtual ~QTextFormat();
1492
1493 QTextFormat( const QStyleSheetItem *s );
1494 QTextFormat( const QFont &f, const QColor &c, QTextFormatCollection *parent = 0 );
1495 QTextFormat( const QTextFormat &fm );
1496 QTextFormat makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const;
1497 QTextFormat& operator=( const QTextFormat &fm );
1498 QColor color() const;
1499 QFont font() const;
1500 bool isMisspelled() const;
1501 VerticalAlignment vAlign() const;
1502 int minLeftBearing() const;
1503 int minRightBearing() const;
1504 int width( const QChar &c ) const;
1505 int width( const QString &str, int pos ) const;
1506 int height() const;
1507 int ascent() const;
1508 int descent() const;
1509 int leading() const;
1510 bool useLinkColor() const;
1511
1512 void setBold( bool b );
1513 void setItalic( bool b );
1514 void setUnderline( bool b );
1515 void setStrikeOut( bool b );
1516 void setFamily( const QString &f );
1517 void setPointSize( int s );
1518 void setFont( const QFont &f );
1519 void setColor( const QColor &c );
1520 void setMisspelled( bool b );
1521 void setVAlign( VerticalAlignment a );
1522
1523 bool operator==( const QTextFormat &f ) const;
1524 QTextFormatCollection *parent() const;
1525 const QString &key() const;
1526
1527 static QString getKey( const QFont &f, const QColor &c, bool misspelled, VerticalAlignment vAlign );
1528
1529 void addRef();
1530 void removeRef();
1531
1532 QString makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, const QString& oldAnchorHref, const QString& anchorHref ) const;
1533 QString makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const;
1534
1535 static void setPainter( QPainter *p );
1536 static QPainter* painter();
1537
1538 bool fontSizesInPixels() { return usePixelSizes; }
1539
1540protected:
1541 virtual void generateKey();
1542
1543private:
1544 void update();
1545 static void applyFont( const QFont &f );
1546
1547private:
1548 QFont fn;
1549 QColor col;
1550 QFontMetrics fm;
1551 uint missp : 1;
1552 uint linkColor : 1;
1553 uint usePixelSizes : 1;
1554 int leftBearing, rightBearing;
1555 VerticalAlignment ha;
1556 uchar widths[ 256 ];
1557 int hei, asc, dsc;
1558 QTextFormatCollection *collection;
1559 int ref;
1560 QString k;
1561 int logicalFontSize;
1562 int stdSize;
1563 static QPainter *pntr;
1564 static QFontMetrics *pntr_fm;
1565 static int pntr_asc;
1566 static int pntr_hei;
1567 static int pntr_ldg;
1568 static int pntr_dsc;
1569
1570};
1571
1572// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1573
1574#if defined(Q_TEMPLATEDLL)
1575// MOC_SKIP_BEGIN
1576Q_TEMPLATE_EXTERN template class Q_EXPORT QDict<QTextFormat>;
1577// MOC_SKIP_END
1578#endif
1579
1580class Q_EXPORT QTextFormatCollection
1581{
1582 friend class QTextDocument;
1583 friend class QTextFormat;
1584
1585public:
1586 QTextFormatCollection();
1587 virtual ~QTextFormatCollection();
1588
1589 void setDefaultFormat( QTextFormat *f );
1590 QTextFormat *defaultFormat() const;
1591 virtual QTextFormat *format( QTextFormat *f );
1592 virtual QTextFormat *format( QTextFormat *of, QTextFormat *nf, int flags );
1593 virtual QTextFormat *format( const QFont &f, const QColor &c );
1594 virtual void remove( QTextFormat *f );
1595 virtual QTextFormat *createFormat( const QTextFormat &f ) { return new QTextFormat( f ); }
1596 virtual QTextFormat *createFormat( const QFont &f, const QColor &c ) { return new QTextFormat( f, c, this ); }
1597
1598 void updateDefaultFormat( const QFont &font, const QColor &c, QStyleSheet *sheet );
1599 QDict<QTextFormat> dict() const { return cKey; }
1600
1601 QPaintDevice *paintDevice() const { return paintdevice; }
1602 void setPaintDevice( QPaintDevice * );
1603
1604private:
1605 void updateKeys();
1606
1607private:
1608 QTextFormat *defFormat, *lastFormat, *cachedFormat;
1609 QDict<QTextFormat> cKey;
1610 QTextFormat *cres;
1611 QFont cfont;
1612 QColor ccol;
1613 QString kof, knf;
1614 int cflags;
1615
1616 QPaintDevice *paintdevice;
1617};
1618
1619// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1620
1621inline int QTextString::length() const
1622{
1623 return data.size();
1624}
1625
1626inline int QTextParagraph::length() const
1627{
1628 return str->length();
1629}
1630
1631inline QRect QTextParagraph::rect() const
1632{
1633 return r;
1634}
1635
1636inline QTextParagraph *QTextCursor::paragraph() const
1637{
1638 return para;
1639}
1640
1641inline int QTextCursor::index() const
1642{
1643 return idx;
1644}
1645
1646
1647// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1648
1649inline int QTextDocument::x() const
1650{
1651 return cx;
1652}
1653
1654inline int QTextDocument::y() const
1655{
1656 return cy;
1657}
1658
1659inline int QTextDocument::width() const
1660{
1661 return QMAX( cw, flow_->width() );
1662}
1663
1664inline int QTextDocument::visibleWidth() const
1665{
1666 return vw;
1667}
1668
1669inline QTextParagraph *QTextDocument::firstParagraph() const
1670{
1671 return fParag;
1672}
1673
1674inline QTextParagraph *QTextDocument::lastParagraph() const
1675{
1676 return lParag;
1677}
1678
1679inline void QTextDocument::setFirstParagraph( QTextParagraph *p )
1680{
1681 fParag = p;
1682}
1683
1684inline void QTextDocument::setLastParagraph( QTextParagraph *p )
1685{
1686 lParag = p;
1687}
1688
1689inline void QTextDocument::setWidth( int w )
1690{
1691 cw = QMAX( w, minw );
1692 flow_->setWidth( cw );
1693 vw = w;
1694}
1695
1696inline int QTextDocument::minimumWidth() const
1697{
1698 return minw;
1699}
1700
1701inline void QTextDocument::setY( int y )
1702{
1703 cy = y;
1704}
1705
1706inline int QTextDocument::leftMargin() const
1707{
1708 return leftmargin;
1709}
1710
1711inline void QTextDocument::setLeftMargin( int lm )
1712{
1713 leftmargin = lm;
1714}
1715
1716inline int QTextDocument::rightMargin() const
1717{
1718 return rightmargin;
1719}
1720
1721inline void QTextDocument::setRightMargin( int rm )
1722{
1723 rightmargin = rm;
1724}
1725
1726inline QTextPreProcessor *QTextDocument::preProcessor() const
1727{
1728 return pProcessor;
1729}
1730
1731inline void QTextDocument::setPreProcessor( QTextPreProcessor * sh )
1732{
1733 pProcessor = sh;
1734}
1735
1736inline void QTextDocument::setFormatter( QTextFormatter *f )
1737{
1738 delete pFormatter;
1739 pFormatter = f;
1740}
1741
1742inline QTextFormatter *QTextDocument::formatter() const
1743{
1744 return pFormatter;
1745}
1746
1747inline void QTextDocument::setIndent( QTextIndent *i )
1748{
1749 indenter = i;
1750}
1751
1752inline QTextIndent *QTextDocument::indent() const
1753{
1754 return indenter;
1755}
1756
1757inline QColor QTextDocument::selectionColor( int id ) const
1758{
1759 return selectionColors[ id ];
1760}
1761
1762inline bool QTextDocument::invertSelectionText( int id ) const
1763{
1764 return selectionText[ id ];
1765}
1766
1767inline void QTextDocument::setSelectionColor( int id, const QColor &c )
1768{
1769 selectionColors[ id ] = c;
1770}
1771
1772inline void QTextDocument::setInvertSelectionText( int id, bool b )
1773{
1774 selectionText[ id ] = b;
1775}
1776
1777inline QTextFormatCollection *QTextDocument::formatCollection() const
1778{
1779 return fCollection;
1780}
1781
1782inline int QTextDocument::alignment() const
1783{
1784 return align;
1785}
1786
1787inline void QTextDocument::setAlignment( int a )
1788{
1789 align = a;
1790}
1791
1792inline int *QTextDocument::tabArray() const
1793{
1794 return tArray;
1795}
1796
1797inline int QTextDocument::tabStopWidth() const
1798{
1799 return tStopWidth;
1800}
1801
1802inline void QTextDocument::setTabArray( int *a )
1803{
1804 tArray = a;
1805}
1806
1807inline void QTextDocument::setTabStops( int tw )
1808{
1809 tStopWidth = tw;
1810}
1811
1812inline QString QTextDocument::originalText() const
1813{
1814 if ( oTextValid )
1815 return oText;
1816 return text();
1817}
1818
1819inline void QTextDocument::setFlow( QTextFlow *f )
1820{
1821 if ( flow_ )
1822 delete flow_;
1823 flow_ = f;
1824}
1825
1826inline void QTextDocument::takeFlow()
1827{
1828 flow_ = 0;
1829}
1830
1831// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1832
1833inline QColor QTextFormat::color() const
1834{
1835 return col;
1836}
1837
1838inline QFont QTextFormat::font() const
1839{
1840 return fn;
1841}
1842
1843inline bool QTextFormat::isMisspelled() const
1844{
1845 return missp;
1846}
1847
1848inline QTextFormat::VerticalAlignment QTextFormat::vAlign() const
1849{
1850 return ha;
1851}
1852
1853inline bool QTextFormat::operator==( const QTextFormat &f ) const
1854{
1855 return k == f.k;
1856}
1857
1858inline QTextFormatCollection *QTextFormat::parent() const
1859{
1860 return collection;
1861}
1862
1863inline void QTextFormat::addRef()
1864{
1865 ref++;
1866}
1867
1868inline void QTextFormat::removeRef()
1869{
1870 ref--;
1871 if ( !collection )
1872 return;
1873 if ( this == collection->defFormat )
1874 return;
1875 if ( ref == 0 )
1876 collection->remove( this );
1877}
1878
1879inline const QString &QTextFormat::key() const
1880{
1881 return k;
1882}
1883
1884inline bool QTextFormat::useLinkColor() const
1885{
1886 return linkColor;
1887}
1888
1889
1890// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1891
1892inline QTextStringChar &QTextString::at( int i ) const
1893{
1894 return data[ i ];
1895}
1896
1897// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1898
1899inline QTextStringChar *QTextParagraph::at( int i ) const
1900{
1901 return &str->at( i );
1902}
1903
1904inline bool QTextParagraph::isValid() const
1905{
1906 return invalid == -1;
1907}
1908
1909inline bool QTextParagraph::hasChanged() const
1910{
1911 return changed;
1912}
1913
1914inline void QTextParagraph::setBackgroundColor( const QColor & c )
1915{
1916 delete bgcol;
1917 bgcol = new QColor( c );
1918 setChanged( TRUE );
1919}
1920
1921inline void QTextParagraph::clearBackgroundColor()
1922{
1923 delete bgcol; bgcol = 0; setChanged( TRUE );
1924}
1925
1926inline void QTextParagraph::append( const QString &s, bool reallyAtEnd )
1927{
1928 if ( reallyAtEnd )
1929 insert( str->length(), s );
1930 else
1931 insert( QMAX( str->length() - 1, 0 ), s );
1932}
1933
1934inline QTextParagraph *QTextParagraph::prev() const
1935{
1936 return p;
1937}
1938
1939inline QTextParagraph *QTextParagraph::next() const
1940{
1941 return n;
1942}
1943
1944inline bool QTextParagraph::hasAnySelection() const
1945{
1946 return mSelections ? !selections().isEmpty() : FALSE;
1947}
1948
1949inline void QTextParagraph::setEndState( int s )
1950{
1951 if ( s == state )
1952 return;
1953 state = s;
1954}
1955
1956inline int QTextParagraph::endState() const
1957{
1958 return state;
1959}
1960
1961inline void QTextParagraph::setParagId( int i )
1962{
1963 id = i;
1964}
1965
1966inline int QTextParagraph::paragId() const
1967{
1968 if ( id == -1 )
1969 qWarning( "invalid parag id!!!!!!!! (%p)", (void*)this );
1970 return id;
1971}
1972
1973inline bool QTextParagraph::firstPreProcess() const
1974{
1975 return firstPProcess;
1976}
1977
1978inline void QTextParagraph::setFirstPreProcess( bool b )
1979{
1980 firstPProcess = b;
1981}
1982
1983inline QMap<int, QTextLineStart*> &QTextParagraph::lineStartList()
1984{
1985 return lineStarts;
1986}
1987
1988inline QTextString *QTextParagraph::string() const
1989{
1990 return str;
1991}
1992
1993inline QTextDocument *QTextParagraph::document() const
1994{
1995 if ( hasdoc )
1996 return (QTextDocument*) docOrPseudo;
1997 return 0;
1998}
1999
2000inline QTextParagraphPseudoDocument *QTextParagraph::pseudoDocument() const
2001{
2002 if ( hasdoc )
2003 return 0;
2004 return (QTextParagraphPseudoDocument*) docOrPseudo;
2005}
2006
2007
2008#ifndef QT_NO_TEXTCUSTOMITEM
2009inline QTextTableCell *QTextParagraph::tableCell() const
2010{
2011 return hasdoc ? document()->tableCell () : 0;
2012}
2013#endif
2014
2015inline QTextCommandHistory *QTextParagraph::commands() const
2016{
2017 return hasdoc ? document()->commands() : pseudoDocument()->commandHistory;
2018}
2019
2020
2021inline int QTextParagraph::alignment() const
2022{
2023 return align;
2024}
2025
2026#ifndef QT_NO_TEXTCUSTOMITEM
2027inline void QTextParagraph::registerFloatingItem( QTextCustomItem *i )
2028{
2029 floatingItems().append( i );
2030}
2031
2032inline void QTextParagraph::unregisterFloatingItem( QTextCustomItem *i )
2033{
2034 floatingItems().removeRef( i );
2035}
2036#endif
2037
2038inline QBrush *QTextParagraph::background() const
2039{
2040#ifndef QT_NO_TEXTCUSTOMITEM
2041 return tableCell() ? tableCell()->backGround() : 0;
2042#else
2043 return 0;
2044#endif
2045}
2046
2047inline int QTextParagraph::documentWidth() const
2048{
2049 return hasdoc ? document()->width() : pseudoDocument()->docRect.width();
2050}
2051
2052inline int QTextParagraph::documentVisibleWidth() const
2053{
2054 return hasdoc ? document()->visibleWidth() : pseudoDocument()->docRect.width();
2055}
2056
2057inline int QTextParagraph::documentX() const
2058{
2059 return hasdoc ? document()->x() : pseudoDocument()->docRect.x();
2060}
2061
2062inline int QTextParagraph::documentY() const
2063{
2064 return hasdoc ? document()->y() : pseudoDocument()->docRect.y();
2065}
2066
2067inline void QTextParagraph::setExtraData( QTextParagraphData *data )
2068{
2069 eData = data;
2070}
2071
2072inline QTextParagraphData *QTextParagraph::extraData() const
2073{
2074 return eData;
2075}
2076
2077// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2078
2079inline void QTextFormatCollection::setDefaultFormat( QTextFormat *f )
2080{
2081 defFormat = f;
2082}
2083
2084inline QTextFormat *QTextFormatCollection::defaultFormat() const
2085{
2086 return defFormat;
2087}
2088
2089// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2090
2091inline QTextFormat *QTextStringChar::format() const
2092{
2093 return (type == Regular) ? d.format : d.custom->format;
2094}
2095
2096
2097#ifndef QT_NO_TEXTCUSTOMITEM
2098inline QTextCustomItem *QTextStringChar::customItem() const
2099{
2100 return isCustom() ? d.custom->custom : 0;
2101}
2102#endif
2103
2104inline int QTextStringChar::height() const
2105{
2106#ifndef QT_NO_TEXTCUSTOMITEM
2107 return !isCustom() ? format()->height() : ( customItem()->placement() == QTextCustomItem::PlaceInline ? customItem()->height : 0 );
2108#else
2109 return format()->height();
2110#endif
2111}
2112
2113inline int QTextStringChar::ascent() const
2114{
2115#ifndef QT_NO_TEXTCUSTOMITEM
2116 return !isCustom() ? format()->ascent() : ( customItem()->placement() == QTextCustomItem::PlaceInline ? customItem()->ascent() : 0 );
2117#else
2118 return format()->ascent();
2119#endif
2120}
2121
2122inline int QTextStringChar::descent() const
2123{
2124#ifndef QT_NO_TEXTCUSTOMITEM
2125 return !isCustom() ? format()->descent() : 0;
2126#else
2127 return format()->descent();
2128#endif
2129}
2130
2131#endif //QT_NO_RICHTEXT
2132
2133#endif
diff --git a/qmake/include/private/qsettings_p.h b/qmake/include/private/qsettings_p.h
new file mode 100644
index 0000000..18d118b
--- a/dev/null
+++ b/qmake/include/private/qsettings_p.h
@@ -0,0 +1,133 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QSettings related classes
5**
6** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the tools module of the Qt GUI Toolkit.
9**
10** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
11** licenses for Windows may use this file in accordance with the Qt Commercial
12** License Agreement provided with the Software.
13**
14** This file is not available for use under any other license without
15** express written permission from the copyright holder.
16**
17** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19**
20** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
21** information about Qt Commercial License Agreements.
22**
23** Contact info@trolltech.com if any conditions of this licensing are
24** not clear to you.
25**
26**********************************************************************/
27
28#ifndef QSETTINGS_P_H
29#define QSETTINGS_P_H
30
31//
32// W A R N I N G
33// -------------
34//
35// This file is not part of the Qt API. It exists for the convenience
36// of QSettings. This header file may change from version to
37// version without notice, or even be removed.
38//
39// We mean it.
40//
41//
42
43#ifndef QT_H
44#include "qstringlist.h"
45#include "qmap.h"
46#include "qvaluestack.h"
47#endif // QT_H
48
49class QSettingsSysPrivate;
50
51// QSettingsGroup is a map of key/value pairs
52class QSettingsGroup : public QMap<QString,QString>
53{
54public:
55 QSettingsGroup();
56
57 bool modified;
58};
59
60// QSettingsHeading is a map of heading/group pairs
61class QSettingsHeading : public QMap<QString,QSettingsGroup>
62{
63public:
64 QSettingsHeading::Iterator git;
65 void read(const QString &);
66 void parseLine(QTextStream &);
67};
68
69
70class QSettingsPrivate
71{
72public:
73 QSettingsPrivate( QSettings::Format format );
74 ~QSettingsPrivate();
75
76 QSettingsGroup readGroup();
77 void removeGroup(const QString &);
78 void writeGroup(const QString &, const QString &);
79 QDateTime modificationTime();
80
81 QStringList searchPaths;
82 QMap<QString,QSettingsHeading> headings;
83 QString group;
84 QString heading;
85
86 /*### static data brings threading trouble
87 static QString *defProduct;
88 static QString *defDomain;
89 */
90 QValueStack<QString> groupStack;
91 QString groupPrefix;
92
93 bool groupDirty :1;
94 bool modified :1;
95 bool globalScope :1;
96
97#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
98 // system dependent implementations to use the
99 // system specific setting database (ie. registry on Windows)
100
101 QSettingsSysPrivate *sysd;
102 voidsysInit();
103 voidsysClear();
104
105#if !defined(Q_NO_BOOL_TYPE)
106 boolsysWriteEntry( const QString &, bool );
107#endif
108 boolsysWriteEntry( const QString &, double );
109 boolsysWriteEntry( const QString &, int );
110 boolsysWriteEntry( const QString &, const QString & );
111 boolsysWriteEntry( const QString &, const QStringList & );
112 boolsysWriteEntry( const QString &, const QStringList &, const QChar& sep );
113
114 QStringList sysEntryList(const QString &) const;
115 QStringList sysSubkeyList(const QString &) const;
116
117 QStringList sysReadListEntry( const QString &, bool * = 0 ) const;
118 QStringList sysReadListEntry( const QString &, const QChar& sep, bool * = 0 ) const;
119 QStringsysReadEntry( const QString &, const QString &def = QString::null, bool * = 0 ) const;
120 int sysReadNumEntry( const QString &, int def = 0, bool * = 0 ) const;
121 doublesysReadDoubleEntry( const QString &, double def = 0, bool * = 0 ) const;
122 boolsysReadBoolEntry( const QString &, bool def = 0, bool * = 0 ) const;
123
124 boolsysRemoveEntry( const QString & );
125
126 boolsysSync();
127
128 voidsysInsertSearchPath( QSettings::System, const QString & );
129 voidsysRemoveSearchPath( QSettings::System, const QString & );
130#endif
131};
132
133#endif // QSETTINGS_P_H
diff --git a/qmake/include/private/qsharedmemory_p.h b/qmake/include/private/qsharedmemory_p.h
new file mode 100644
index 0000000..4a8339d
--- a/dev/null
+++ b/qmake/include/private/qsharedmemory_p.h
@@ -0,0 +1,84 @@
1/****************************************************************************
2** $Id$
3**
4** Includes system files for shared memory
5**
6** Created : 020124
7**
8** Copyright (C) 1992-2000 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 and/or modified under the terms of the
13** GNU General Public License version 2 as published by the Free Software
14** Foundation and appearing in the file LICENSE.GPL included in the
15** packaging of this file.
16**
17** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
18** licenses for Qt/Embedded may use this file in accordance with the
19** Qt Embedded Commercial License Agreement provided with the Software.
20**
21** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
22** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23**
24** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
25** information about Qt Commercial License Agreements.
26** See http://www.trolltech.com/gpl/ for GPL licensing information.
27**
28** Contact info@trolltech.com if any conditions of this licensing are
29** not clear to you.
30**
31**********************************************************************/
32
33//
34// W A R N I N G
35// -------------
36//
37// This file is not part of the Qt API. It exists for the convenience
38// of qapplication_qws.cpp and qgfxvnc_qws.cpp. This header file may
39// change from version to version without notice, or even be removed.
40//
41//
42
43#if !defined(QT_QSHM_H)
44#define QT_QSHM_H
45
46#include <qstring.h>
47
48#if !defined (QT_QWS_NO_SHM)
49
50#include <sys/types.h>
51#include <sys/ipc.h>
52
53class QSharedMemory {
54public:
55 QSharedMemory(){};
56 QSharedMemory(int, QString, char c = 'Q');
57 ~QSharedMemory(){};
58
59 bool create();
60 void destroy();
61
62 bool attach();
63 void detach();
64
65 void setPermissions(mode_t mode);
66 int size();
67 void * base() { return shmBase; };
68
69private:
70 void *shmBase;
71 int shmSize;
72 QString shmFile;
73 char character;
74#if defined(QT_POSIX_QSHM)
75 int shmFD;
76#else
77 int shmId;
78 key_t key;
79 int idInitted;
80#endif
81};
82
83#endif
84#endif
diff --git a/qmake/include/private/qsqldriverinterface_p.h b/qmake/include/private/qsqldriverinterface_p.h
new file mode 100644
index 0000000..8957b86
--- a/dev/null
+++ b/qmake/include/private/qsqldriverinterface_p.h
@@ -0,0 +1,69 @@
1/****************************************************************************
2**
3** Definition of QSqlDriverInterface class
4**
5** Created : 2000-11-03
6**
7** Copyright (C) 2000 Trolltech AS. All rights reserved.
8**
9** This file is part of the sql module of the Qt GUI Toolkit.
10**
11** This file may be distributed under the terms of the Q Public License
12** as defined by Trolltech AS of Norway and appearing in the file
13** LICENSE.QPL included in the packaging of this file.
14**
15** This file may be distributed and/or modified under the terms of the
16** GNU General Public License version 2 as published by the Free Software
17** Foundation and appearing in the file LICENSE.GPL included in the
18** packaging of this file.
19**
20** Licensees holding valid Qt Enterprise Edition licenses may use this
21** file in accordance with the Qt Commercial License Agreement provided
22** with the Software.
23**
24** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26**
27** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
28** information about Qt Commercial License Agreements.
29** See http://www.trolltech.com/qpl/ for QPL licensing information.
30** See http://www.trolltech.com/gpl/ for GPL licensing information.
31**
32** Contact info@trolltech.com if any conditions of this licensing are
33** not clear to you.
34**
35**********************************************************************/
36
37#ifndef QSQLDRIVERINTERFACE_H
38#define QSQLDRIVERINTERFACE_H
39
40#ifndef QT_H
41#include <private/qcom_p.h>
42#endif // QT_H
43
44#if !defined( QT_MODULE_SQL ) || defined( QT_LICENSE_PROFESSIONAL )
45#define QM_EXPORT_SQL
46#else
47#define QM_EXPORT_SQL Q_EXPORT
48#endif
49
50#ifndef QT_NO_SQL
51
52#ifndef QT_NO_COMPONENT
53
54// {EDDD5AD5-DF3C-400c-A711-163B72FE5F61}
55#ifndef IID_QSqlDriverFactory
56#define IID_QSqlDriverFactory QUuid(0xeddd5ad5, 0xdf3c, 0x400c, 0xa7, 0x11, 0x16, 0x3b, 0x72, 0xfe, 0x5f, 0x61)
57#endif
58
59class QSqlDriver;
60
61struct QM_EXPORT_SQL QSqlDriverFactoryInterface : public QFeatureListInterface
62{
63 virtual QSqlDriver* create( const QString& name ) = 0;
64};
65
66#endif //QT_NO_COMPONENT
67#endif // QT_NO_SQL
68
69#endif // QSQLDRIVERINTERFACE_H
diff --git a/qmake/include/private/qsqlextension_p.h b/qmake/include/private/qsqlextension_p.h
new file mode 100644
index 0000000..597b266
--- a/dev/null
+++ b/qmake/include/private/qsqlextension_p.h
@@ -0,0 +1,101 @@
1/****************************************************************************
2**
3** Definition of the QSqlExtension class
4**
5** Created : 2002-06-03
6**
7** Copyright (C) 2002 Trolltech AS. All rights reserved.
8**
9** This file is part of the sql module of the Qt GUI Toolkit.
10**
11** This file may be distributed under the terms of the Q Public License
12** as defined by Trolltech AS of Norway and appearing in the file
13** LICENSE.QPL included in the packaging of this file.
14**
15** This file may be distributed and/or modified under the terms of the
16** GNU General Public License version 2 as published by the Free Software
17** Foundation and appearing in the file LICENSE.GPL included in the
18** packaging of this file.
19**
20** Licensees holding valid Qt Enterprise Edition licenses may use this
21** file in accordance with the Qt Commercial License Agreement provided
22** with the Software.
23**
24** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26**
27** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
28** information about Qt Commercial License Agreements.
29** See http://www.trolltech.com/qpl/ for QPL licensing information.
30** See http://www.trolltech.com/gpl/ for GPL licensing information.
31**
32** Contact info@trolltech.com if any conditions of this licensing are
33** not clear to you.
34**
35**********************************************************************/
36
37#ifndef QSQLEXTENSION_P_H
38#define QSQLEXTENSION_P_H
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists for the convenience
45// of other Qt classes. This header file may change from version to
46// version without notice, or even be removed.
47//
48// We mean it.
49//
50//
51
52#ifndef QT_H
53#include "qmap.h"
54#include "qstring.h"
55#include "qvariant.h"
56#endif // QT_H
57
58#ifndef QT_NO_SQL
59
60#if !defined( QT_MODULE_SQL ) || defined( QT_LICENSE_PROFESSIONAL )
61#define QM_EXPORT_SQL
62#else
63#define QM_EXPORT_SQL Q_EXPORT
64#endif
65
66#if defined(Q_TEMPLATEDLL)
67Q_TEMPLATE_EXTERN template class QM_EXPORT_SQL QMap<QString,QVariant>;
68Q_TEMPLATE_EXTERN template class QM_EXPORT_SQL QMap<int,QString>;
69#endif
70
71class QM_EXPORT_SQL QSqlExtension {
72public:
73 QSqlExtension();
74 virtual ~QSqlExtension();
75 virtual bool prepare( const QString& query );
76 virtual bool exec();
77 virtual void bindValue( const QString& holder, const QVariant& value );
78 virtual void bindValue( int pos, const QVariant& value );
79 virtual void addBindValue( const QVariant& value );
80 void clearValues();
81 void clearIndex();
82
83 enum BindMethod { BindByPosition, BindByName };
84 BindMethod bindMethod();
85 BindMethod bindm;
86 int bindCount;
87
88 QMap<int, QString> index;
89 QMap<QString, QVariant> values;
90};
91
92class QM_EXPORT_SQL QSqlDriverExtension
93{
94public:
95 QSqlDriverExtension();
96 virtual ~QSqlDriverExtension();
97 virtual bool isOpen() const = 0;
98};
99
100#endif
101#endif
diff --git a/qmake/include/private/qsqlmanager_p.h b/qmake/include/private/qsqlmanager_p.h
new file mode 100644
index 0000000..e5f45b8
--- a/dev/null
+++ b/qmake/include/private/qsqlmanager_p.h
@@ -0,0 +1,159 @@
1/****************************************************************************
2**
3** Definition of QSqlManager class
4**
5** Created : 2000-11-03
6**
7** Copyright (C) 2000 Trolltech AS. All rights reserved.
8**
9** This file is part of the sql module of the Qt GUI Toolkit.
10**
11** This file may be distributed under the terms of the Q Public License
12** as defined by Trolltech AS of Norway and appearing in the file
13** LICENSE.QPL included in the packaging of this file.
14**
15** This file may be distributed and/or modified under the terms of the
16** GNU General Public License version 2 as published by the Free Software
17** Foundation and appearing in the file LICENSE.GPL included in the
18** packaging of this file.
19**
20** Licensees holding valid Qt Enterprise Edition licenses may use this
21** file in accordance with the Qt Commercial License Agreement provided
22** with the Software.
23**
24** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26**
27** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
28** information about Qt Commercial License Agreements.
29** See http://www.trolltech.com/qpl/ for QPL licensing information.
30** See http://www.trolltech.com/gpl/ for GPL licensing information.
31**
32** Contact info@trolltech.com if any conditions of this licensing are
33** not clear to you.
34**
35**********************************************************************/
36
37#ifndef QSQLMANAGER_P_H
38#define QSQLMANAGER_P_H
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists for the convenience
45// of other Qt classes. This header file may change from version to
46// version without notice, or even be removed.
47//
48// We mean it.
49//
50//
51
52#ifndef QT_H
53#include "qglobal.h"
54#include "qstring.h"
55#include "qstringlist.h"
56#include "qsql.h"
57#include "qsqlerror.h"
58#include "qsqlindex.h"
59#include "qsqlcursor.h"
60#endif // QT_H
61
62#if !defined( QT_MODULE_SQL ) || defined( QT_LICENSE_PROFESSIONAL )
63#define QM_EXPORT_SQL
64#else
65#define QM_EXPORT_SQL Q_EXPORT
66#endif
67
68#ifndef QT_NO_SQL
69
70class QSqlCursor;
71class QSqlForm;
72class QSqlCursorManagerPrivate;
73
74class QM_EXPORT_SQL QSqlCursorManager
75{
76public:
77 QSqlCursorManager();
78 virtual ~QSqlCursorManager();
79
80 virtual void setSort( const QSqlIndex& sort );
81 virtual void setSort( const QStringList& sort );
82 QStringList sort() const;
83 virtual void setFilter( const QString& filter );
84 QString filter() const;
85 virtual void setCursor( QSqlCursor* cursor, bool autoDelete = FALSE );
86 QSqlCursor* cursor() const;
87
88 virtual void setAutoDelete( bool enable );
89 bool autoDelete() const;
90
91 virtual bool refresh();
92 virtual bool findBuffer( const QSqlIndex& idx, int atHint = 0 );
93
94private:
95 QSqlCursorManagerPrivate* d;
96};
97
98#ifndef QT_NO_SQL_FORM
99
100class QSqlFormManagerPrivate;
101
102class QM_EXPORT_SQL QSqlFormManager
103{
104public:
105 QSqlFormManager();
106 virtual ~QSqlFormManager();
107
108 virtual void setForm( QSqlForm* form );
109 QSqlForm* form();
110 virtual void setRecord( QSqlRecord* record );
111 QSqlRecord* record();
112
113 virtual void clearValues();
114 virtual void readFields();
115 virtual void writeFields();
116
117private:
118 QSqlFormManagerPrivate* d;
119};
120
121#endif
122
123class QWidget;
124class QDataManagerPrivate;
125
126class QM_EXPORT_SQL QDataManager
127{
128public:
129 QDataManager();
130 virtual ~QDataManager();
131
132 virtual void setMode( QSql::Op m );
133 QSql::Op mode() const;
134 virtual void setAutoEdit( bool autoEdit );
135 bool autoEdit() const;
136
137 virtual void handleError( QWidget* parent, const QSqlError& error );
138 virtual QSql::Confirm confirmEdit( QWidget* parent, QSql::Op m );
139 virtual QSql::Confirm confirmCancel( QWidget* parent, QSql::Op m );
140
141 virtual void setConfirmEdits( bool confirm );
142 virtual void setConfirmInsert( bool confirm );
143 virtual void setConfirmUpdate( bool confirm );
144 virtual void setConfirmDelete( bool confirm );
145 virtual void setConfirmCancels( bool confirm );
146
147 bool confirmEdits() const;
148 bool confirmInsert() const;
149 bool confirmUpdate() const;
150 bool confirmDelete() const;
151 bool confirmCancels() const;
152
153private:
154 QDataManagerPrivate* d;
155};
156
157
158#endif
159#endif
diff --git a/qmake/include/private/qstyleinterface_p.h b/qmake/include/private/qstyleinterface_p.h
new file mode 100644
index 0000000..4aaedc7
--- a/dev/null
+++ b/qmake/include/private/qstyleinterface_p.h
@@ -0,0 +1,61 @@
1/****************************************************************************
2** $Id$
3**
4** ...
5**
6** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the widgets 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#ifndef QSTYLEINTERFACE_H
37#define QSTYLEINTERFACE_H
38
39#ifndef QT_H
40#include <private/qcom_p.h>
41#endif // QT_H
42
43#ifndef QT_NO_STYLE
44#ifndef QT_NO_COMPONENT
45
46class QStyle;
47
48// {FC1B6EBE-053C-49c1-A483-C377739AB9A5}
49#ifndef IID_QStyleFactory
50#define IID_QStyleFactory QUuid(0xfc1b6ebe, 0x53c, 0x49c1, 0xa4, 0x83, 0xc3, 0x77, 0x73, 0x9a, 0xb9, 0xa5)
51#endif
52
53struct Q_EXPORT QStyleFactoryInterface : public QFeatureListInterface
54{
55 virtual QStyle* create( const QString& style ) = 0;
56};
57
58#endif //QT_NO_COMPONENT
59#endif //QT_NO_STYLE
60
61#endif //QSTYLEINTERFACE_H
diff --git a/qmake/include/private/qsvgdevice_p.h b/qmake/include/private/qsvgdevice_p.h
new file mode 100644
index 0000000..c1cc389
--- a/dev/null
+++ b/qmake/include/private/qsvgdevice_p.h
@@ -0,0 +1,134 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of the QSvgDevice class
5**
6** Created : 20001024
7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the xml 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef QSVGDEVICE_H
39#define QSVGDEVICE_H
40
41//
42// W A R N I N G
43// -------------
44//
45// This file is not part of the Qt API. It exists for the convenience
46// of the QPicture class. This header file may change from
47// version to version without notice, or even be removed.
48//
49// We mean it.
50//
51//
52
53#ifndef QT_H
54#include "qpaintdevice.h"
55#include "qrect.h"
56#include "qdom.h"
57#endif // QT_H
58
59#if !defined(QT_MODULE_XML) || defined( QT_LICENSE_PROFESSIONAL ) || defined( QT_INTERNAL_XML )
60#define QM_EXPORT_SVG
61#else
62#define QM_EXPORT_SVG Q_EXPORT
63#endif
64
65#ifndef QT_NO_SVG
66
67class QPainter;
68class QDomNode;
69class QDomNamedNodeMap;
70struct QSvgDeviceState;
71class QSvgDevicePrivate;
72
73class QM_EXPORT_SVG QSvgDevice : public QPaintDevice
74{
75public:
76 QSvgDevice();
77 ~QSvgDevice();
78
79 bool play( QPainter *p );
80
81 QString toString() const;
82
83 bool load( QIODevice *dev );
84 bool save( QIODevice *dev );
85 bool save( const QString &fileName );
86
87 QRect boundingRect() const;
88 void setBoundingRect( const QRect &r );
89
90protected:
91 virtual bool cmd ( int, QPainter*, QPDevCmdParam* );
92 virtual int metric( int ) const;
93
94private:
95 // reading
96 bool play( const QDomNode &node );
97 void saveAttributes();
98 void restoreAttributes();
99 QColor parseColor( const QString &col );
100 double parseLen( const QString &str, bool *ok=0, bool horiz=TRUE ) const;
101 int lenToInt( const QDomNamedNodeMap &map, const QString &attr,
102 int def=0 ) const;
103 void setStyleProperty( const QString &prop, const QString &val,
104 QPen *pen, QFont *font, int *talign );
105 void setStyle( const QString &s );
106 void setTransform( const QString &tr );
107 void drawPath( const QString &data );
108
109 // writing
110 void applyStyle( QDomElement *e, int c ) const;
111 void applyTransform( QDomElement *e ) const;
112
113 // reading
114 QRect brect; // bounding rectangle
115 QDomDocument doc; // document tree
116 QDomNode current;
117 QPoint curPt;
118 QSvgDeviceState *curr;
119 QPainter *pt; // used by play() et al
120
121 // writing
122 bool dirtyTransform, dirtyStyle;
123
124 QSvgDevicePrivate *d;
125};
126
127inline QRect QSvgDevice::boundingRect() const
128{
129 return brect;
130}
131
132#endif // QT_NO_SVG
133
134#endif // QSVGDEVICE_H
diff --git a/qmake/include/private/qtextcodecinterface_p.h b/qmake/include/private/qtextcodecinterface_p.h
new file mode 100644
index 0000000..d2a2cb9
--- a/dev/null
+++ b/qmake/include/private/qtextcodecinterface_p.h
@@ -0,0 +1,79 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QTextCodecFactoryInterface interface
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#ifndef QTEXTCODECINTERFACE_P_H
37#define QTEXTCODECINTERFACE_P_H
38
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the Qt API. It exists for the convenience
45// of qpsprinter.cpp and qprinter_x11.cpp.
46// This header file may change from version to version without notice,
47// or even be removed.
48//
49// We mean it.
50//
51//
52
53
54#ifndef QT_H
55#include <private/qcom_p.h>
56#endif // QT_H
57
58#ifndef QT_NO_TEXTCODEC
59#ifndef QT_NO_COMPONENT
60
61class QTextCodec;
62
63
64// {F55BFA60-F695-11D4-823E-009027DC0F37}
65#ifndef IID_QTextCodecFactory
66#define IID_QTextCodecFactory QUuid( 0xf55bfa60, 0xf695, 0x11d4, 0x82, 0x3e, 0x00, 0x90, 0x27, 0xdc, 0x0f, 0x37)
67#endif
68
69
70struct Q_EXPORT QTextCodecFactoryInterface : public QFeatureListInterface
71{
72 virtual QTextCodec *createForMib( int mib ) = 0;
73 virtual QTextCodec *createForName( const QString &name ) = 0;
74};
75
76#endif // QT_NO_COMPONENT
77#endif // QT_NO_TEXTCODEC
78
79#endif // QTEXTCODECINTERFACE_P_H
diff --git a/qmake/include/private/qtitlebar_p.h b/qmake/include/private/qtitlebar_p.h
new file mode 100644
index 0000000..dabb6bf
--- a/dev/null
+++ b/qmake/include/private/qtitlebar_p.h
@@ -0,0 +1,136 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of some Qt private functions.
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 widgets 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#ifndef QTITLEBAR_P_H
39#define QTITLEBAR_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qworkspace.cpp and qdockwindow.cpp. This header file may change
48// from version to version without notice, or even be removed.
49//
50// We mean it.
51//
52//
53
54
55#ifndef QT_H
56#include "qbutton.h"
57#include "qlabel.h"
58#endif // QT_H
59
60#if !defined(QT_NO_TITLEBAR)
61
62class QToolTip;
63class QTitleBarPrivate;
64class QPixmap;
65
66class Q_EXPORT QTitleBar : public QWidget
67{
68 Q_OBJECT
69 Q_PROPERTY( bool autoRaise READ autoRaise WRITE setAutoRaise )
70 Q_PROPERTY( bool movable READ isMovable WRITE setMovable )
71
72public:
73 QTitleBar (QWidget* w, QWidget* parent, const char* name=0);
74 ~QTitleBar();
75
76 bool isActive() const;
77 bool usesActiveColor() const;
78 virtual QString visibleText() const;
79
80 bool isMovable() const;
81 void setMovable(bool);
82
83 bool autoRaise() const;
84 void setAutoRaise(bool);
85
86 QWidget *window() const;
87
88 QSize sizeHint() const;
89
90#ifdef QT_NO_WIDGET_TOPEXTRA
91 // We provide one, since titlebar is useless otherwise.
92 QString caption() const;
93#endif
94
95public slots:
96 void setActive( bool );
97 void setCaption( const QString& title );
98 void setIcon( const QPixmap& icon );
99
100signals:
101 void doActivate();
102 void doNormal();
103 void doClose();
104 void doMaximize();
105 void doMinimize();
106 void doShade();
107 void showOperationMenu();
108 void popupOperationMenu( const QPoint& );
109 void doubleClicked();
110
111protected:
112 bool event( QEvent *);
113 void resizeEvent( QResizeEvent *);
114 void contextMenuEvent( QContextMenuEvent * );
115 void mousePressEvent( QMouseEvent * );
116 void mouseDoubleClickEvent( QMouseEvent * );
117 void mouseReleaseEvent( QMouseEvent * );
118 void mouseMoveEvent( QMouseEvent * );
119 void enterEvent( QEvent *e );
120 void leaveEvent( QEvent *e );
121 void paintEvent( QPaintEvent *p );
122
123 virtual void cutText();
124
125private:
126 void readColors();
127
128 QTitleBarPrivate *d;
129#if defined(Q_DISABLE_COPY) // Disabled copy constructor and operator=
130 QTitleBar( const QTitleBar & );
131 QTitleBar &operator=( const QTitleBar & );
132#endif
133};
134
135#endif
136#endif //QTITLEBAR_P_H
diff --git a/qmake/include/private/qucom_p.h b/qmake/include/private/qucom_p.h
new file mode 100644
index 0000000..d2ff48e
--- a/dev/null
+++ b/qmake/include/private/qucom_p.h
@@ -0,0 +1,499 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of the QUcom interfaces
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#ifndef QUCOM_H
39#define QUCOM_H
40
41#ifndef QT_H
42#include <qstring.h>
43#include "quuid.h"
44#endif // QT_H
45
46//
47// W A R N I N G
48// -------------
49//
50// This file is not part of the Qt API. It exists for the convenience
51// of a number of Qt sources files. This header file may change from
52// version to version without notice, or even be removed.
53//
54// We mean it.
55//
56//
57
58#ifdef check
59#undef check
60#endif
61
62struct QUObject;
63struct QUInterfaceDescription;
64struct QUnknownInterface;
65struct QDispatchInterface;
66
67
68struct Q_EXPORT QUBuffer
69{
70 virtual long read( char *data, ulong maxlen ) = 0;
71 virtual long write( const char *data, ulong len ) = 0;
72};
73
74
75// A type for a QUObject
76struct Q_EXPORT QUType
77{
78 virtual const QUuid *uuid() const = 0;
79 virtual const char *desc() const = 0;
80
81
82 virtual bool canConvertFrom( QUObject *, QUType * ) = 0;
83 // virtual private, only called by canConvertFrom
84 virtual bool canConvertTo( QUObject *, QUType * ) = 0;
85
86
87 virtual bool convertFrom( QUObject *, QUType * ) = 0;
88 // virtual private, only called by convertFrom
89 virtual bool convertTo( QUObject *, QUType * ) = 0;
90
91 virtual void clear( QUObject * ) = 0;
92
93 virtual int serializeTo( QUObject *, QUBuffer * ) = 0;
94 virtual int serializeFrom( QUObject *, QUBuffer * ) = 0;
95
96 static bool isEqual( const QUType *t1, const QUType *t2 );
97 static bool check( QUObject* o, QUType* t );
98};
99
100
101// {DE56510E-4E9F-4b76-A3C2-D1E2EF42F1AC}
102extern Q_EXPORT const QUuid TID_QUType_Null;
103struct Q_EXPORT QUType_Null : public QUType
104{
105 const QUuid *uuid() const;
106 const char *desc() const;
107
108 bool canConvertFrom( QUObject *, QUType * );
109 bool canConvertTo( QUObject *, QUType * );
110 bool convertFrom( QUObject *, QUType * );
111 bool convertTo( QUObject *, QUType * );
112 void clear( QUObject * );
113 int serializeTo( QUObject *, QUBuffer * );
114 int serializeFrom( QUObject *, QUBuffer * );
115};
116extern Q_EXPORT QUType_Null static_QUType_Null;
117
118
119// The magic QUObject
120struct Q_EXPORT QUObject
121{
122public: // scary MSVC bug makes this necessary
123 QUObject() : type( &static_QUType_Null ) {}
124 ~QUObject() { type->clear( this ); }
125
126 QUType *type;
127
128 // the unavoidable union
129 union
130 {
131 bool b;
132
133 char c;
134 short s;
135 int i;
136 long l;
137
138 unsigned char uc;
139 unsigned short us;
140 unsigned int ui;
141 unsigned long ul;
142
143 float f;
144 double d;
145
146 char byte[16];
147
148 struct {
149 char* data;
150 unsigned long size;
151 } bytearray;
152
153 void* ptr;
154
155 struct {
156 void *ptr;
157 bool owner;
158 } voidstar;
159
160 struct {
161 char *ptr;
162 bool owner;
163 } charstar;
164
165 struct {
166 char *ptr;
167 bool owner;
168 } utf8;
169
170 struct {
171 char *ptr;
172 bool owner;
173 } local8bit;
174
175 QUnknownInterface* iface;
176 QDispatchInterface* idisp;
177
178 } payload;
179
180};
181
182
183// A parameter description describes one method parameters. A
184// parameter has a name, a type and a flag describing whether it's an
185// in parameter, an out parameter, or both ways
186struct Q_EXPORT QUParameter
187{
188 const char* name;
189 QUType *type;
190 const void* typeExtra; //Usually 0, UEnum* for QUType_enum, const char* for QUType_ptr, int* for QUType_varptr
191 enum { In = 1, Out = 2, InOut = In | Out };
192 int inOut;
193};
194
195// A method description describes one method. A method has a name and
196// an array of parameters.
197struct Q_EXPORT QUMethod
198{
199 const char* name;
200 int count;
201 const QUParameter* parameters;
202};
203
204// A Property description. Not used yet in the example.
205struct Q_EXPORT QUProperty
206{
207 const char* name;
208 QUType* type;
209 const void* typeExtra; //type dependend. Usually 0, but UEnum for QUTypeenum or const char* for QUTypeptr
210
211 int set; // -1 undefined
212 int get; // -1 undefined
213
214 int designable; // -1 FALSE, -2 TRUE, else method
215 int stored; // -1 FALSE, -2 TRUE, else method
216};
217
218// An interface description describes one interface, that is all its
219// methods and properties.
220struct Q_EXPORT QUInterfaceDescription
221{
222 int methodCount;
223 const QUMethod* methods;
224 int propertyCount;
225 const QUProperty* properties;
226};
227
228
229// A component description describe one component, that is its name,
230// vendor, release, info, its component uuid and all its interface
231// uuids.
232struct Q_EXPORT QUComponentDescription
233{
234 const char* name;
235 const char* vendor;
236 const char* release;
237 const char* info;
238 QUuid cid;
239 int count;
240 const QUuid* interfaces;
241};
242
243
244// A component server description describe one component server, that
245// is its name, vendor, release, info and the descriptions of all
246// components it can instantiate.
247struct Q_EXPORT QUComponentServerDescription
248{
249 const char* name;
250 const char* vendor;
251 const char* release;
252 const char* info;
253 int count;
254 const QUComponentDescription* components;
255};
256
257
258
259 struct Q_EXPORT QUEnumItem // - a name/value pair
260{
261 const char *key;
262 int value;
263};
264
265struct Q_EXPORT QUEnum
266 {
267 const char *name; // - enumerator name
268 unsigned int count; // - number of values
269 const QUEnumItem *items; // - the name/value pairs
270 bool set; // whether enum has to be treated as a set
271};
272
273inline bool QUType::isEqual( const QUType *t1, const QUType *t2 ) {
274 return t1 == t2 || t1->uuid() == t2->uuid() ||
275 *(t1->uuid()) == *(t2->uuid());
276}
277
278inline bool QUType::check( QUObject* o, QUType* t ) {
279 return isEqual( o->type, t ) || t->convertFrom( o, o->type );
280}
281
282
283
284// {7EE17B08-5419-47e2-9776-8EEA112DCAEC}
285extern Q_EXPORT const QUuid TID_QUType_enum;
286struct Q_EXPORT QUType_enum : public QUType
287{
288 const QUuid *uuid() const;
289 const char *desc() const;
290
291 void set( QUObject *, int );
292 int &get( QUObject * o ) { return o->payload.i; }
293 bool canConvertFrom( QUObject *, QUType * );
294 bool canConvertTo( QUObject *, QUType * );
295 bool convertFrom( QUObject *, QUType * );
296 bool convertTo( QUObject *, QUType * );
297 void clear( QUObject * ) {}
298 int serializeTo( QUObject *, QUBuffer * );
299 int serializeFrom( QUObject *, QUBuffer * );
300};
301extern Q_EXPORT QUType_enum static_QUType_enum;
302
303
304// {8AC26448-5AB4-49eb-968C-8F30AB13D732}
305extern Q_EXPORT const QUuid TID_QUType_ptr;
306struct Q_EXPORT QUType_ptr : public QUType
307{
308 const QUuid *uuid() const;
309 const char *desc() const;
310
311 void set( QUObject *, const void* );
312 void* &get( QUObject * o ) { return o->payload.ptr; }
313 bool canConvertFrom( QUObject *, QUType * );
314 bool canConvertTo( QUObject *, QUType * );
315 bool convertFrom( QUObject *, QUType * );
316 bool convertTo( QUObject *, QUType * );
317 void clear( QUObject * ) {}
318 int serializeTo( QUObject *, QUBuffer * );
319 int serializeFrom( QUObject *, QUBuffer * );
320};
321extern Q_EXPORT QUType_ptr static_QUType_ptr;
322
323// {97A2594D-6496-4402-A11E-55AEF2D4D25C}
324extern Q_EXPORT const QUuid TID_QUType_iface;
325struct Q_EXPORT QUType_iface : public QUType
326{
327 const QUuid *uuid() const;
328 const char *desc() const;
329
330 void set( QUObject *, QUnknownInterface* );
331 QUnknownInterface* &get( QUObject *o ){ return o->payload.iface; }
332 bool canConvertFrom( QUObject *, QUType * );
333 bool canConvertTo( QUObject *, QUType * );
334 bool convertFrom( QUObject *, QUType * );
335 bool convertTo( QUObject *, QUType * );
336 void clear( QUObject * ) {}
337 int serializeTo( QUObject *, QUBuffer * );
338 int serializeFrom( QUObject *, QUBuffer * );
339};
340extern Q_EXPORT QUType_iface static_QUType_iface;
341
342// {2F358164-E28F-4bf4-9FA9-4E0CDCABA50B}
343extern Q_EXPORT const QUuid TID_QUType_idisp;
344struct Q_EXPORT QUType_idisp : public QUType
345{
346 const QUuid *uuid() const;
347 const char *desc() const;
348
349 void set( QUObject *, QDispatchInterface* );
350 QDispatchInterface* &get( QUObject *o ){ return o->payload.idisp; }
351 bool canConvertFrom( QUObject *, QUType * );
352 bool canConvertTo( QUObject *, QUType * );
353 bool convertFrom( QUObject *, QUType * );
354 bool convertTo( QUObject *, QUType * );
355 void clear( QUObject * ) {}
356 int serializeTo( QUObject *, QUBuffer * );
357 int serializeFrom( QUObject *, QUBuffer * );
358};
359extern Q_EXPORT QUType_idisp static_QUType_idisp;
360
361// {CA42115D-13D0-456c-82B5-FC10187F313E}
362extern Q_EXPORT const QUuid TID_QUType_bool;
363struct Q_EXPORT QUType_bool : public QUType
364{
365 const QUuid *uuid() const;
366 const char *desc() const;
367
368 void set( QUObject *, bool );
369 bool &get( QUObject *o ) { return o->payload.b; }
370 bool canConvertFrom( QUObject *, QUType * );
371 bool canConvertTo( QUObject *, QUType * );
372 bool convertFrom( QUObject *, QUType * );
373 bool convertTo( QUObject *, QUType * );
374 void clear( QUObject * ) {}
375 int serializeTo( QUObject *, QUBuffer * );
376 int serializeFrom( QUObject *, QUBuffer * );
377};
378extern Q_EXPORT QUType_bool static_QUType_bool;
379
380// {53C1F3BE-73C3-4c7d-9E05-CCF09EB676B5}
381extern Q_EXPORT const QUuid TID_QUType_int;
382struct Q_EXPORT QUType_int : public QUType
383{
384 const QUuid *uuid() const;
385 const char *desc() const;
386
387 void set( QUObject *, int );
388 int &get( QUObject *o ) { return o->payload.i; }
389 bool canConvertFrom( QUObject *, QUType * );
390 bool canConvertTo( QUObject *, QUType * );
391 bool convertFrom( QUObject *, QUType * );
392 bool convertTo( QUObject *, QUType * );
393 void clear( QUObject * ) {}
394 int serializeTo( QUObject *, QUBuffer * );
395 int serializeFrom( QUObject *, QUBuffer * );
396};
397extern Q_EXPORT QUType_int static_QUType_int;
398
399// {5938712A-C496-11D5-8CB2-00C0F03BC0F3}
400extern Q_EXPORT const QUuid TID_QUType_uint;
401struct Q_EXPORT QUType_uint : public QUType
402{
403 const QUuid *uuid() const;
404 const char *desc() const;
405
406 void set( QUObject *, uint );
407 uint &get( QUObject *o ) { return o->payload.ui; }
408 bool canConvertFrom( QUObject *, QUType * );
409 bool canConvertTo( QUObject *, QUType * );
410 bool convertFrom( QUObject *, QUType * );
411 bool convertTo( QUObject *, QUType * );
412 void clear( QUObject * ) {}
413 int serializeTo( QUObject *, QUBuffer * );
414 int serializeFrom( QUObject *, QUBuffer * );
415};
416extern Q_EXPORT QUType_uint static_QUType_uint;
417
418// {2D0974E5-0BA6-4ec2-8837-C198972CB48C}
419extern Q_EXPORT const QUuid TID_QUType_double;
420struct Q_EXPORT QUType_double : public QUType
421{
422 const QUuid *uuid() const;
423 const char *desc() const;
424
425 void set( QUObject *, double );
426 double &get( QUObject *o ) { return o->payload.d; }
427 bool canConvertFrom( QUObject *, QUType * );
428 bool canConvertTo( QUObject *, QUType * );
429 bool convertFrom( QUObject *, QUType * );
430 bool convertTo( QUObject *, QUType * );
431 void clear( QUObject * ) {}
432 int serializeTo( QUObject *, QUBuffer * );
433 int serializeFrom( QUObject *, QUBuffer * );
434};
435extern Q_EXPORT QUType_double static_QUType_double;
436
437// {544C5175-6993-4486-B04D-CEC4D21BF4B9 }
438extern Q_EXPORT const QUuid TID_QUType_float;
439struct Q_EXPORT QUType_float : public QUType
440{
441 const QUuid *uuid() const;
442 const char *desc() const;
443
444 void set( QUObject *, float );
445 float &get( QUObject *o ) { return o->payload.f; }
446 bool canConvertFrom( QUObject *, QUType * );
447 bool canConvertTo( QUObject *, QUType * );
448 bool convertFrom( QUObject *, QUType * );
449 bool convertTo( QUObject *, QUType * );
450 void clear( QUObject * ) {}
451 int serializeTo( QUObject *, QUBuffer * );
452 int serializeFrom( QUObject *, QUBuffer * );
453};
454extern Q_EXPORT QUType_float static_QUType_float;
455
456// {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9}
457extern Q_EXPORT const QUuid TID_QUType_charstar;
458struct Q_EXPORT QUType_charstar : public QUType
459{
460 const QUuid *uuid() const;
461 const char *desc() const;
462
463 void set( QUObject *, const char*, bool take = FALSE );
464 char* get( QUObject *o ){ return o->payload.charstar.ptr; }
465 bool canConvertFrom( QUObject *, QUType * );
466 bool canConvertTo( QUObject *, QUType * );
467 bool convertFrom( QUObject *, QUType * );
468 bool convertTo( QUObject *, QUType * );
469 void clear( QUObject * );
470 int serializeTo( QUObject *, QUBuffer * );
471 int serializeFrom( QUObject *, QUBuffer * );
472
473};
474extern Q_EXPORT QUType_charstar static_QUType_charstar;
475
476// {44C2A547-01E7-4e56-8559-35AF9D2F42B7}
477extern const QUuid TID_QUType_QString;
478
479struct Q_EXPORT QUType_QString : public QUType
480{
481 const QUuid *uuid() const;
482 const char *desc() const;
483
484 void set( QUObject *, const QString & );
485 QString &get( QUObject * o ) { return *(QString*)o->payload.ptr; }
486
487 bool canConvertFrom( QUObject *, QUType * );
488 bool canConvertTo( QUObject *, QUType * );
489 bool convertFrom( QUObject *, QUType * );
490 bool convertTo( QUObject *, QUType * );
491 void clear( QUObject * );
492 int serializeTo( QUObject *, QUBuffer * );
493 int serializeFrom( QUObject *, QUBuffer * );
494
495};
496extern Q_EXPORT QUType_QString static_QUType_QString;
497
498
499#endif // QUCOM_H
diff --git a/qmake/include/private/qucomextra_p.h b/qmake/include/private/qucomextra_p.h
new file mode 100644
index 0000000..3de6104
--- a/dev/null
+++ b/qmake/include/private/qucomextra_p.h
@@ -0,0 +1,93 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of extra 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 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#ifndef QUCOMEXTRA_H
39#define QUCOMEXTRA_H
40
41#ifndef QT_H
42#include <private/qucom_p.h>
43#endif // QT_H
44
45
46class QVariant;
47
48#ifndef QT_NO_VARIANT
49// 6dc75d58-a1d9-4417-b591-d45c63a3a4ea
50extern const QUuid TID_QUType_QVariant;
51
52struct Q_EXPORT QUType_QVariant : public QUType
53{
54 const QUuid *uuid() const;
55 const char *desc() const;
56
57 void set( QUObject *, const QVariant & );
58 QVariant &get( QUObject * o );
59
60 bool canConvertFrom( QUObject *, QUType * );
61 bool canConvertTo( QUObject *, QUType * );
62 bool convertFrom( QUObject *, QUType * );
63 bool convertTo( QUObject *, QUType * );
64 void clear( QUObject * );
65 int serializeTo( QUObject *, QUBuffer * );
66 int serializeFrom( QUObject *, QUBuffer * );
67};
68extern Q_EXPORT QUType_QVariant static_QUType_QVariant;
69#endif //QT_NO_VARIANT
70
71
72// {0x8d48b3a8, 0xbd7f, 0x11d5, 0x8d, 0x74, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3 }
73extern Q_EXPORT const QUuid TID_QUType_varptr;
74struct Q_EXPORT QUType_varptr : public QUType
75{
76 const QUuid *uuid() const;
77 const char *desc() const;
78
79 void set( QUObject *, const void* );
80 void* &get( QUObject * o ) { return o->payload.ptr; }
81 bool canConvertFrom( QUObject *, QUType * );
82 bool canConvertTo( QUObject *, QUType * );
83 bool convertFrom( QUObject *, QUType * );
84 bool convertTo( QUObject *, QUType * );
85 void clear( QUObject * ) {}
86 int serializeTo( QUObject *, QUBuffer * );
87 int serializeFrom( QUObject *, QUBuffer * );
88};
89extern Q_EXPORT QUType_varptr static_QUType_varptr;
90
91
92#endif // QUCOMEXTRA_H
93
diff --git a/qmake/include/private/qwidget_p.h b/qmake/include/private/qwidget_p.h
new file mode 100644
index 0000000..80368d0
--- a/dev/null
+++ b/qmake/include/private/qwidget_p.h
@@ -0,0 +1,61 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of some Qt private functions.
5**
6** Created : 000903
7**
8** Copyright (C) 2000 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#ifndef QWIDGET_P_H
39#define QWIDGET_P_H
40
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists for the convenience
47// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
48// file may change from version to version without notice, or even be removed.
49//
50// We mean it.
51//
52//
53
54#ifndef QT_H
55#endif // QT_H
56
57#if defined (Q_WS_X11) || defined (Q_WS_QWS)
58extern int qt_widget_tlw_gravity;
59#endif
60
61#endif
diff --git a/qmake/include/private/qwidgetinterface_p.h b/qmake/include/private/qwidgetinterface_p.h
new file mode 100644
index 0000000..5b5776b
--- a/dev/null
+++ b/qmake/include/private/qwidgetinterface_p.h
@@ -0,0 +1,111 @@
1 /**********************************************************************
2** Copyright (C) 2000-2001 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Designer.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef QWIDGETINTERFACE_H
22#define QWIDGETINTERFACE_H
23
24
25#ifndef QT_H
26#include <private/qcom_p.h>
27#include <qiconset.h>
28#endif // QT_H
29
30#ifndef QT_NO_WIDGETPLUGIN
31
32//
33// W A R N I N G
34// -------------
35//
36// This file is not part of the Qt API. It exists for the convenience
37// of a number of Qt sources files. This header file may change from
38// version to version without notice, or even be removed.
39//
40// We mean it.
41//
42//
43
44class QWidget;
45
46// {55184143-f18f-42c0-a8eb-71c01516019a}
47#ifndef IID_QWidgetFactory
48#define IID_QWidgetFactory QUuid( 0x55184143, 0xf18f, 0x42c0, 0xa8, 0xeb, 0x71, 0xc0, 0x15, 0x16, 0x1, 0x9a )
49#endif
50
51/*! To add custom widgets to the Qt Designer, implement that interface
52 in your custom widget plugin.
53
54 You also have to implement the function featureList() (\sa
55 QFeatureListInterface) and return there all widgets (names of it)
56 which this interface provides.
57*/
58
59struct QWidgetFactoryInterface : public QFeatureListInterface
60{
61public:
62
63 /*! In the implementation create and return the widget \a widget
64 here, use \a parent and \a name when creating the widget */
65 virtual QWidget* create( const QString &widget, QWidget* parent = 0, const char* name = 0 ) = 0;
66
67 /*! In the implementation return the name of the group of the
68 widget \a widget */
69 virtual QString group( const QString &widget ) const = 0;
70
71 /*! In the implementation return the iconset, which should be used
72 in the Qt Designer menubar and toolbar to represent the widget
73 \a widget */
74 virtual QIconSet iconSet( const QString &widget ) const = 0;
75
76 /*! In the implementation return the include file which is needed
77 for the widget \a widget in the generated code which uic
78 generates. */
79 virtual QString includeFile( const QString &widget ) const = 0;
80
81 /*! In the implementation return the text which should be
82 displayed as tooltip for the widget \a widget */
83 virtual QString toolTip( const QString &widget ) const = 0;
84
85 /*! In the implementation return the text which should be used for
86 what's this help for the widget \a widget. */
87 virtual QString whatsThis( const QString &widget ) const = 0;
88
89 /*! In the implementation return TRUE here, of the \a widget
90 should be able to contain other widget in the Qt Designer, else
91 FALSE. */
92 virtual bool isContainer( const QString &widget ) const = 0;
93};
94
95#if CONTAINER_CUSTOM_WIDGETS
96// {15976628-e3c3-47f4-b525-d124a3caf30e}
97#ifndef IID_QWidgetContainer
98#define IID_QWidgetContainer QUuid( 0x15976628, 0xe3c3, 0x47f4, 0xb5, 0x25, 0xd1, 0x24, 0xa3, 0xca, 0xf3, 0x0e )
99#endif
100
101struct QWidgetContainerInterfacePrivate : public QUnknownInterface
102{
103public:
104 virtual QWidget *containerOfWidget( QWidget *widget ) const = 0;
105 virtual QWidgetList containersOf( QWidget *widget ) const = 0;
106 virtual bool isPassiveInteractor( QWidget *widget ) const = 0;
107};
108#endif
109
110#endif // QT_NO_WIDGETPLUGIN
111#endif // QWIDGETINTERFACE_H
diff --git a/qmake/include/private/qwidgetresizehandler_p.h b/qmake/include/private/qwidgetresizehandler_p.h
new file mode 100644
index 0000000..ca229db
--- a/dev/null
+++ b/qmake/include/private/qwidgetresizehandler_p.h
@@ -0,0 +1,113 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of the QWidgetResizeHandler class
5**
6** Created : 001010
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the workspace 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef QWIDGETRESIZEHANDLER_H
39#define QWIDGETRESIZEHANDLER_H
40
41#ifndef QT_H
42#include "qobject.h"
43#endif // QT_H
44#ifndef QT_NO_RESIZEHANDLER
45class QMouseEvent;
46class QKeyEvent;
47
48class Q_EXPORT QWidgetResizeHandler : public QObject
49{
50 Q_OBJECT
51
52public:
53 QWidgetResizeHandler( QWidget *parent, QWidget *cw = 0, const char *name = 0 );
54 void setActive( bool b ) { active = b; if ( !active ) setMouseCursor( Nowhere ); }
55 bool isActive() const { return active; }
56 void setMovingEnabled( bool b ) { moving = b; }
57 bool isMovingEnabled() const { return moving; }
58
59 bool isButtonDown() const { return buttonDown; }
60
61 void setExtraHeight( int h ) { extrahei = h; }
62 void setSizeProtection( bool b ) { sizeprotect = b; }
63
64 void doResize();
65 void doMove();
66
67signals:
68 void activate();
69
70protected:
71 bool eventFilter( QObject *o, QEvent *e );
72 void mouseMoveEvent( QMouseEvent *e );
73 void keyPressEvent( QKeyEvent *e );
74
75private:
76 enum MousePosition {
77 Nowhere,
78 TopLeft, BottomRight, BottomLeft, TopRight,
79 Top, Bottom, Left, Right,
80 Center
81 };
82
83 QWidget *widget;
84 QWidget *childWidget;
85 QPoint moveOffset;
86 QPoint invertedMoveOffset;
87 MousePosition mode;
88 int extrahei;
89 int range;
90 uint buttonDown :1;
91 uint moveResizeMode :1;
92 uint active :1;
93 uint sizeprotect :1;
94 uint moving :1;
95
96 void setMouseCursor( MousePosition m );
97 bool isMove() const {
98 return moveResizeMode && mode == Center;
99 }
100 bool isResize() const {
101 return moveResizeMode && !isMove();
102 }
103
104 private:// Disabled copy constructor and operator=
105#if defined(Q_DISABLE_COPY)
106 QWidgetResizeHandler( const QWidgetResizeHandler & );
107 QWidgetResizeHandler& operator=( const QWidgetResizeHandler & );
108#endif
109
110};
111
112#endif //QT_NO_RESIZEHANDLER
113#endif
diff --git a/qmake/include/qasciidict.h b/qmake/include/qasciidict.h
new file mode 100644
index 0000000..8f344cd
--- a/dev/null
+++ b/qmake/include/qasciidict.h
@@ -0,0 +1,118 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QAsciiDict template class
5**
6** Created : 920821
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#ifndef QASCIIDICT_H
39#define QASCIIDICT_H
40
41#ifndef QT_H
42#include "qgdict.h"
43#endif // QT_H
44
45template<class type>
46class QAsciiDict
47#ifdef Q_QDOC
48 : public QPtrCollection
49#else
50 : public QGDict
51#endif
52{
53public:
54 QAsciiDict(int size=17, bool caseSensitive=TRUE, bool copyKeys=TRUE )
55 : QGDict(size,AsciiKey,caseSensitive,copyKeys) {}
56 QAsciiDict( const QAsciiDict<type> &d ) : QGDict(d) {}
57 ~QAsciiDict() { clear(); }
58 QAsciiDict<type> &operator=(const QAsciiDict<type> &d)
59 { return (QAsciiDict<type>&)QGDict::operator=(d); }
60 uint count() const { return QGDict::count(); }
61 uint size() const { return QGDict::size(); }
62 bool isEmpty() const { return QGDict::count() == 0; }
63
64 void insert( const char *k, const type *d )
65 { QGDict::look_ascii(k,(Item)d,1); }
66 void replace( const char *k, const type *d )
67 { QGDict::look_ascii(k,(Item)d,2); }
68 bool remove( const char *k ){ return QGDict::remove_ascii(k); }
69 type *take( const char *k ) { return (type *)QGDict::take_ascii(k); }
70 type *find( const char *k ) const
71 { return (type *)((QGDict*)this)->QGDict::look_ascii(k,0,0); }
72 type *operator[]( const char *k ) const
73 { return (type *)((QGDict*)this)->QGDict::look_ascii(k,0,0); }
74
75 void clear() { QGDict::clear(); }
76 void resize( uint n ) { QGDict::resize(n); }
77 void statistics() const { QGDict::statistics(); }
78
79#ifdef Q_QDOC
80protected:
81 virtual QDataStream& read( QDataStream &, QPtrCollection::Item & );
82 virtual QDataStream& write( QDataStream &, QPtrCollection::Item ) const;
83#endif
84
85private:
86 void deleteItem( Item d );
87};
88
89#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION)
90template<> inline void QAsciiDict<void>::deleteItem( QPtrCollection::Item )
91{
92}
93#endif
94
95template<class type> inline void QAsciiDict<type>::deleteItem( QPtrCollection::Item d )
96{
97 if ( del_item ) delete (type *)d;
98}
99
100template<class type>
101class QAsciiDictIterator : public QGDictIterator
102{
103public:
104 QAsciiDictIterator(const QAsciiDict<type> &d)
105 : QGDictIterator((QGDict &)d) {}
106 ~QAsciiDictIterator() {}
107 uint count() const { return dict->count(); }
108 bool isEmpty() const { return dict->count() == 0; }
109 type *toFirst() { return (type *)QGDictIterator::toFirst(); }
110 operator type *() const { return (type *)QGDictIterator::get(); }
111 type *current() const { return (type *)QGDictIterator::get(); }
112 const char *currentKey() const { return QGDictIterator::getKeyAscii(); }
113 type *operator()() { return (type *)QGDictIterator::operator()(); }
114 type *operator++() { return (type *)QGDictIterator::operator++(); }
115 type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
116};
117
118#endif // QASCIIDICT_H
diff --git a/qmake/include/qbitarray.h b/qmake/include/qbitarray.h
new file mode 100644
index 0000000..65c5cd3
--- a/dev/null
+++ b/qmake/include/qbitarray.h
@@ -0,0 +1,166 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QBITARRAY_H
39#define QBITARRAY_H
40
41#ifndef QT_H
42#include "qstring.h"
43#endif // QT_H
44
45
46/*****************************************************************************
47 QBitVal class; a context class for QBitArray::operator[]
48 *****************************************************************************/
49
50class QBitArray;
51
52class Q_EXPORT QBitVal
53{
54private:
55 QBitArray *array;
56 uint index;
57public:
58 QBitVal( QBitArray *a, uint i ) : array(a), index(i) {}
59 operator int();
60 QBitVal &operator=( const QBitVal &v );
61 QBitVal &operator=( bool v );
62};
63
64
65/*****************************************************************************
66 QBitArray class
67 *****************************************************************************/
68
69class Q_EXPORT QBitArray : public QByteArray
70{
71public:
72 QBitArray();
73 QBitArray( uint size );
74 QBitArray( const QBitArray &a ) : QByteArray( a ) {}
75
76 QBitArray &operator=( const QBitArray & );
77
78 uint size() const;
79 bool resize( uint size );
80
81 bool fill( bool v, int size = -1 );
82
83 void detach();
84 QBitArray copy() const;
85
86 bool testBit( uint index ) const;
87 void setBit( uint index );
88 void setBit( uint index, bool value );
89 void clearBit( uint index );
90 bool toggleBit( uint index );
91
92 bool at( uint index ) const;
93 QBitVal operator[]( int index );
94 bool operator[]( int index ) const;
95
96 QBitArray &operator&=( const QBitArray & );
97 QBitArray &operator|=( const QBitArray & );
98 QBitArray &operator^=( const QBitArray & );
99 QBitArray operator~() const;
100
101protected:
102 struct bitarr_data : public QGArray::array_data {
103 uint nbits;
104 };
105 array_data *newData() { return new bitarr_data; }
106 voiddeleteData( array_data *d ) { delete (bitarr_data*)d; }
107private:
108 void pad0();
109};
110
111
112inline QBitArray &QBitArray::operator=( const QBitArray &a )
113{ return (QBitArray&)assign( a ); }
114
115inline uint QBitArray::size() const
116{ return ((bitarr_data*)sharedBlock())->nbits; }
117
118inline void QBitArray::setBit( uint index, bool value )
119{ if ( value ) setBit(index); else clearBit(index); }
120
121inline bool QBitArray::at( uint index ) const
122{ return testBit(index); }
123
124inline QBitVal QBitArray::operator[]( int index )
125{ return QBitVal( (QBitArray*)this, index ); }
126
127inline bool QBitArray::operator[]( int index ) const
128{ return testBit( index ); }
129
130
131/*****************************************************************************
132 Misc. QBitArray operator functions
133 *****************************************************************************/
134
135Q_EXPORT QBitArray operator&( const QBitArray &, const QBitArray & );
136Q_EXPORT QBitArray operator|( const QBitArray &, const QBitArray & );
137Q_EXPORT QBitArray operator^( const QBitArray &, const QBitArray & );
138
139
140inline QBitVal::operator int()
141{
142 return array->testBit( index );
143}
144
145inline QBitVal &QBitVal::operator=( const QBitVal &v )
146{
147 array->setBit( index, v.array->testBit(v.index) );
148 return *this;
149}
150
151inline QBitVal &QBitVal::operator=( bool v )
152{
153 array->setBit( index, v );
154 return *this;
155}
156
157
158/*****************************************************************************
159 QBitArray stream functions
160 *****************************************************************************/
161#ifndef QT_NO_DATASTREAM
162Q_EXPORT QDataStream &operator<<( QDataStream &, const QBitArray & );
163Q_EXPORT QDataStream &operator>>( QDataStream &, QBitArray & );
164#endif
165
166#endif // QBITARRAY_H
diff --git a/qmake/include/qbuffer.h b/qmake/include/qbuffer.h
new file mode 100644
index 0000000..f1b869b
--- a/dev/null
+++ b/qmake/include/qbuffer.h
@@ -0,0 +1,100 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QBuffer class
5**
6** Created : 930812
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#ifndef QBUFFER_H
39#define QBUFFER_H
40
41#ifndef QT_H
42#include "qiodevice.h"
43#include "qstring.h"
44#endif // QT_H
45
46
47class Q_EXPORT QBuffer : public QIODevice
48{
49public:
50 QBuffer();
51 QBuffer( QByteArray );
52 ~QBuffer();
53
54 QByteArray buffer() const;
55 bool setBuffer( QByteArray );
56
57 bool open( int );
58 void close();
59 void flush();
60
61 Offset size() const;
62 Offset at() const;
63 bool at( Offset );
64
65 Q_LONG readBlock( char *p, Q_ULONG );
66 Q_LONG writeBlock( const char *p, Q_ULONG );
67 Q_LONG writeBlock( const QByteArray& data )
68 { return QIODevice::writeBlock(data); }
69 Q_LONG readLine( char *p, Q_ULONG );
70
71 int getch();
72 int putch( int );
73 int ungetch( int );
74
75protected:
76 QByteArray a;
77
78private:
79 uint a_len;
80 uint a_inc;
81
82 private:// Disabled copy constructor and operator=
83#if defined(Q_DISABLE_COPY)
84 QBuffer( const QBuffer & );
85 QBuffer &operator=( const QBuffer & );
86#endif
87};
88
89
90inline QByteArray QBuffer::buffer() const
91{ return a; }
92
93inline QIODevice::Offset QBuffer::size() const
94{ return (Offset)a.size(); }
95
96inline QIODevice::Offset QBuffer::at() const
97{ return ioIndex; }
98
99
100#endif // QBUFFER_H
diff --git a/qmake/include/qcache.h b/qmake/include/qcache.h
new file mode 100644
index 0000000..94ba323
--- a/dev/null
+++ b/qmake/include/qcache.h
@@ -0,0 +1,118 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QCache template class
5**
6** Created : 950209
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#ifndef QCACHE_H
39#define QCACHE_H
40
41#ifndef QT_H
42#include "qgcache.h"
43#endif // QT_H
44
45template<class type>
46class QCache
47#ifdef Q_QDOC
48 : public QPtrCollection
49#else
50 : public QGCache
51#endif
52{
53public:
54 QCache( const QCache<type> &c ) : QGCache(c) {}
55 QCache( int maxCost=100, int size=17, bool caseSensitive=TRUE )
56 : QGCache( maxCost, size, StringKey, caseSensitive, FALSE ) {}
57 ~QCache() { clear(); }
58 QCache<type> &operator=( const QCache<type> &c )
59 { return (QCache<type>&)QGCache::operator=(c); }
60 int maxCost() const { return QGCache::maxCost(); }
61 int totalCost() const { return QGCache::totalCost(); }
62 void setMaxCost( int m ) { QGCache::setMaxCost(m); }
63 uint count() const { return QGCache::count(); }
64 uint size() const { return QGCache::size(); }
65 bool isEmpty() const { return QGCache::count() == 0; }
66 void clear() { QGCache::clear(); }
67 bool insert( const QString &k, const type *d, int c=1, int p=0 )
68 { return QGCache::insert_string(k,(Item)d,c,p);}
69 bool remove( const QString &k )
70 { return QGCache::remove_string(k); }
71 type *take( const QString &k )
72 { return (type *)QGCache::take_string(k); }
73 type *find( const QString &k, bool ref=TRUE ) const
74 { return (type *)QGCache::find_string(k,ref);}
75 type *operator[]( const QString &k ) const
76 { return (type *)QGCache::find_string(k);}
77 void statistics() const { QGCache::statistics(); }
78private:
79 void deleteItem( Item d );
80};
81
82#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION)
83template<> inline void QCache<void>::deleteItem( QPtrCollection::Item )
84{
85}
86#endif
87
88template<class type> inline void QCache<type>::deleteItem( QPtrCollection::Item d )
89{
90 if ( del_item ) delete (type *)d;
91}
92
93template<class type>
94class QCacheIterator : public QGCacheIterator
95{
96public:
97 QCacheIterator( const QCache<type> &c ):QGCacheIterator((QGCache &)c) {}
98 QCacheIterator( const QCacheIterator<type> &ci)
99 : QGCacheIterator( (QGCacheIterator &)ci ) {}
100 QCacheIterator<type> &operator=(const QCacheIterator<type>&ci)
101 { return ( QCacheIterator<type>&)QGCacheIterator::operator=( ci ); }
102 uint count() const { return QGCacheIterator::count(); }
103 bool isEmpty() const { return QGCacheIterator::count() == 0; }
104 bool atFirst() const { return QGCacheIterator::atFirst(); }
105 bool atLast() const { return QGCacheIterator::atLast(); }
106 type *toFirst() { return (type *)QGCacheIterator::toFirst(); }
107 type *toLast() { return (type *)QGCacheIterator::toLast(); }
108 operator type *() const { return (type *)QGCacheIterator::get(); }
109 type *current() const { return (type *)QGCacheIterator::get(); }
110 QString currentKey() const{ return QGCacheIterator::getKeyString(); }
111 type *operator()() { return (type *)QGCacheIterator::operator()();}
112 type *operator++() { return (type *)QGCacheIterator::operator++(); }
113 type *operator+=(uint j) { return (type *)QGCacheIterator::operator+=(j);}
114 type *operator--() { return (type *)QGCacheIterator::operator--(); }
115 type *operator-=(uint j) { return (type *)QGCacheIterator::operator-=(j);}
116};
117
118#endif // QCACHE_H
diff --git a/qmake/include/qcleanuphandler.h b/qmake/include/qcleanuphandler.h
new file mode 100644
index 0000000..471dc7b
--- a/dev/null
+++ b/qmake/include/qcleanuphandler.h
@@ -0,0 +1,127 @@
1/****************************************************************************
2** $Id$
3**
4** ...
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#ifndef QCLEANUPHANDLER_H
37#define QCLEANUPHANDLER_H
38
39#ifndef QT_H
40#include <qptrlist.h>
41#endif // QT_H
42
43template<class Type>
44class QCleanupHandler
45{
46public:
47 QCleanupHandler() : cleanupObjects( 0 ) {}
48 ~QCleanupHandler() { clear(); }
49
50 Type* add( Type **object ) {
51 if ( !cleanupObjects )
52 cleanupObjects = new QPtrList<Type*>;
53 cleanupObjects->insert( 0, object );
54 return *object;
55 }
56
57 void remove( Type **object ) {
58 if ( !cleanupObjects )
59 return;
60 if ( cleanupObjects->findRef( object ) >= 0 )
61 (void) cleanupObjects->take();
62 }
63
64 bool isEmpty() const {
65 return cleanupObjects ? cleanupObjects->isEmpty() : TRUE;
66 }
67
68 void clear() {
69 if ( !cleanupObjects )
70 return;
71 QPtrListIterator<Type*> it( *cleanupObjects );
72 Type **object;
73 while ( ( object = it.current() ) ) {
74 delete *object;
75 *object = 0;
76 cleanupObjects->remove( object );
77 }
78 delete cleanupObjects;
79 cleanupObjects = 0;
80 }
81
82private:
83 QPtrList<Type*> *cleanupObjects;
84};
85
86template<class Type>
87class QSingleCleanupHandler
88{
89public:
90 QSingleCleanupHandler() : object( 0 ) {}
91 ~QSingleCleanupHandler() {
92 if ( object ) {
93 delete *object;
94 *object = 0;
95 }
96 }
97 Type* set( Type **o ) {
98 object = o;
99 return *object;
100 }
101 void reset() { object = 0; }
102private:
103 Type **object;
104};
105
106template<class Type>
107class QSharedCleanupHandler
108{
109public:
110 QSharedCleanupHandler() : object( 0 ) {}
111 ~QSharedCleanupHandler() {
112 if ( object ) {
113 if ( (*object)->deref() )
114 delete *object;
115 *object = 0;
116 }
117 }
118 Type* set( Type **o ) {
119 object = o;
120 return *object;
121 }
122 void reset() { object = 0; }
123private:
124 Type **object;
125};
126
127#endif //QCLEANUPHANDLER_H
diff --git a/qmake/include/qcstring.h b/qmake/include/qcstring.h
new file mode 100644
index 0000000..004bb3b
--- a/dev/null
+++ b/qmake/include/qcstring.h
@@ -0,0 +1,391 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of the extended char array operations,
5** and QByteArray and QCString classes
6**
7** Created : 920609
8**
9** Copyright (C) 1992-2002 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#ifndef QCSTRING_H
40#define QCSTRING_H
41
42#ifndef QT_H
43#include "qmemarray.h"
44#endif // QT_H
45
46#include <string.h>
47
48
49/*****************************************************************************
50 Safe and portable C string functions; extensions to standard string.h
51 *****************************************************************************/
52
53Q_EXPORT void *qmemmove( void *dst, const void *src, uint len );
54
55Q_EXPORT char *qstrdup( const char * );
56
57Q_EXPORT inline uint qstrlen( const char *str )
58{ return str ? (uint)strlen(str) : 0; }
59
60Q_EXPORT inline char *qstrcpy( char *dst, const char *src )
61{ return src ? strcpy(dst, src) : 0; }
62
63Q_EXPORT char *qstrncpy( char *dst, const char *src, uint len );
64
65Q_EXPORT inline int qstrcmp( const char *str1, const char *str2 )
66{
67 return ( str1 && str2 ) ? strcmp( str1, str2 )
68 : ( str1 ? 1 : ( str2 ? -1 : 0 ) );
69}
70
71Q_EXPORT inline int qstrncmp( const char *str1, const char *str2, uint len )
72{
73 return ( str1 && str2 ) ? strncmp( str1, str2, len )
74 : ( str1 ? 1 : ( str2 ? -1 : 0 ) );
75}
76
77Q_EXPORT int qstricmp( const char *, const char * );
78
79Q_EXPORT int qstrnicmp( const char *, const char *, uint len );
80
81#ifndef QT_CLEAN_NAMESPACE
82Q_EXPORT inline uint cstrlen( const char *str )
83{ return (uint)strlen(str); }
84
85Q_EXPORT inline char *cstrcpy( char *dst, const char *src )
86{ return strcpy(dst,src); }
87
88Q_EXPORT inline int cstrcmp( const char *str1, const char *str2 )
89{ return strcmp(str1,str2); }
90
91Q_EXPORT inline int cstrncmp( const char *str1, const char *str2, uint len )
92{ return strncmp(str1,str2,len); }
93#endif
94
95
96// qChecksum: Internet checksum
97
98Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len );
99
100/*****************************************************************************
101 QByteArray class
102 *****************************************************************************/
103
104#if defined(Q_TEMPLATEDLL)
105Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<char>;
106#endif
107
108#if defined(Q_QDOC)
109/*
110 We want qdoc to document QByteArray as a real class that inherits
111 QMemArray<char> and that is inherited by QBitArray.
112*/
113class QByteArray : public QMemArray<char>
114{
115public:
116 QByteArray();
117 QByteArray( int size );
118};
119#else
120typedef QMemArray<char> QByteArray;
121#endif
122
123#ifndef QT_NO_COMPRESS
124Q_EXPORT QByteArray qCompress( const uchar* data, int nbytes );
125Q_EXPORT QByteArray qUncompress( const uchar* data, int nbytes );
126Q_EXPORT inline QByteArray qCompress( const QByteArray& data)
127{ return qCompress( (const uchar*)data.data(), data.size() ); }
128Q_EXPORT inline QByteArray qUncompress( const QByteArray& data )
129{ return qUncompress( (const uchar*)data.data(), data.size() ); }
130#endif
131
132/*****************************************************************************
133 QByteArray stream functions
134 *****************************************************************************/
135#ifndef QT_NO_DATASTREAM
136Q_EXPORT QDataStream &operator<<( QDataStream &, const QByteArray & );
137Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & );
138#endif
139
140/*****************************************************************************
141 QCString class
142 *****************************************************************************/
143
144class QRegExp;
145
146 class Q_EXPORT QCString : public QByteArray// C string class
147{
148public:
149 QCString() {} // make null string
150 QCString( int size ); // allocate size incl. \0
151 QCString( const QCString &s ) : QByteArray( s ) {}
152 QCString( const char *str ); // deep copy
153 QCString( const char *str, uint maxlen );// deep copy, max length
154 ~QCString();
155
156 QCString &operator=( const QCString &s );// shallow copy
157 QCString &operator=( const char *str );// deep copy
158
159 bool isNull()const;
160 bool isEmpty()const;
161 uint length()const;
162 boolresize( uint newlen );
163 booltruncate( uint pos );
164 boolfill( char c, int len = -1 );
165
166 QCString copy()const;
167
168 QCString &sprintf( const char *format, ... );
169
170 int find( char c, int index=0, bool cs=TRUE ) const;
171 int find( const char *str, int index=0, bool cs=TRUE ) const;
172#ifndef QT_NO_REGEXP
173 int find( const QRegExp &, int index=0 ) const;
174#endif
175 int findRev( char c, int index=-1, bool cs=TRUE) const;
176 int findRev( const char *str, int index=-1, bool cs=TRUE) const;
177#ifndef QT_NO_REGEXP_CAPTURE
178 int findRev( const QRegExp &, int index=-1 ) const;
179#endif
180 int contains( char c, bool cs=TRUE ) const;
181 int contains( const char *str, bool cs=TRUE ) const;
182#ifndef QT_NO_REGEXP
183 int contains( const QRegExp & ) const;
184#endif
185 QCStringleft( uint len ) const;
186 QCStringright( uint len ) const;
187 QCStringmid( uint index, uint len=0xffffffff) const;
188
189 QCStringleftJustify( uint width, char fill=' ', bool trunc=FALSE)const;
190 QCStringrightJustify( uint width, char fill=' ',bool trunc=FALSE)const;
191
192 QCStringlower() const;
193 QCStringupper() const;
194
195 QCString stripWhiteSpace()const;
196 QCString simplifyWhiteSpace()const;
197
198 QCString &insert( uint index, const char * );
199 QCString &insert( uint index, char );
200 QCString &append( const char * );
201 QCString &prepend( const char * );
202 QCString &remove( uint index, uint len );
203 QCString &replace( uint index, uint len, const char * );
204#ifndef QT_NO_REGEXP
205 QCString &replace( const QRegExp &, const char * );
206#endif
207 QCString &replace( char c, const char *after );
208 QCString &replace( const char *, const char * );
209 QCString &replace( char, char );
210
211 short toShort( bool *ok=0 )const;
212 ushort toUShort( bool *ok=0 )const;
213 int toInt( bool *ok=0 )const;
214 uint toUInt( bool *ok=0 )const;
215 long toLong( bool *ok=0 )const;
216 ulong toULong( bool *ok=0 )const;
217 float toFloat( bool *ok=0 )const;
218 double toDouble( bool *ok=0 )const;
219
220 QCString &setStr( const char *s );
221 QCString &setNum( short );
222 QCString &setNum( ushort );
223 QCString &setNum( int );
224 QCString &setNum( uint );
225 QCString &setNum( long );
226 QCString &setNum( ulong );
227 QCString &setNum( float, char f='g', int prec=6 );
228 QCString &setNum( double, char f='g', int prec=6 );
229
230 boolsetExpand( uint index, char c );
231
232 operator const char *() const;
233 QCString &operator+=( const char *str );
234 QCString &operator+=( char c );
235};
236
237
238/*****************************************************************************
239 QCString stream functions
240 *****************************************************************************/
241#ifndef QT_NO_DATASTREAM
242Q_EXPORT QDataStream &operator<<( QDataStream &, const QCString & );
243Q_EXPORT QDataStream &operator>>( QDataStream &, QCString & );
244#endif
245
246/*****************************************************************************
247 QCString inline functions
248 *****************************************************************************/
249
250inline QCString &QCString::operator=( const QCString &s )
251{ return (QCString&)assign( s ); }
252
253inline QCString &QCString::operator=( const char *str )
254{ return (QCString&)duplicate( str, qstrlen(str)+1 ); }
255
256inline bool QCString::isNull() const
257{ return data() == 0; }
258
259inline bool QCString::isEmpty() const
260{ return data() == 0 || *data() == '\0'; }
261
262inline uint QCString::length() const
263{ return qstrlen( data() ); }
264
265inline bool QCString::truncate( uint pos )
266{ return resize(pos+1); }
267
268inline QCString QCString::copy() const
269{ return QCString( data() ); }
270
271inline QCString &QCString::prepend( const char *s )
272{ return insert(0,s); }
273
274inline QCString &QCString::append( const char *s )
275{ return operator+=(s); }
276
277inline QCString &QCString::setNum( short n )
278{ return setNum((long)n); }
279
280inline QCString &QCString::setNum( ushort n )
281{ return setNum((ulong)n); }
282
283inline QCString &QCString::setNum( int n )
284{ return setNum((long)n); }
285
286inline QCString &QCString::setNum( uint n )
287{ return setNum((ulong)n); }
288
289inline QCString &QCString::setNum( float n, char f, int prec )
290{ return setNum((double)n,f,prec); }
291
292inline QCString::operator const char *() const
293{ return (const char *)data(); }
294
295
296/*****************************************************************************
297 QCString non-member operators
298 *****************************************************************************/
299
300Q_EXPORT inline bool operator==( const QCString &s1, const QCString &s2 )
301{ return qstrcmp( s1.data(), s2.data() ) == 0; }
302
303Q_EXPORT inline bool operator==( const QCString &s1, const char *s2 )
304{ return qstrcmp( s1.data(), s2 ) == 0; }
305
306Q_EXPORT inline bool operator==( const char *s1, const QCString &s2 )
307{ return qstrcmp( s1, s2.data() ) == 0; }
308
309Q_EXPORT inline bool operator!=( const QCString &s1, const QCString &s2 )
310{ return qstrcmp( s1.data(), s2.data() ) != 0; }
311
312Q_EXPORT inline bool operator!=( const QCString &s1, const char *s2 )
313{ return qstrcmp( s1.data(), s2 ) != 0; }
314
315Q_EXPORT inline bool operator!=( const char *s1, const QCString &s2 )
316{ return qstrcmp( s1, s2.data() ) != 0; }
317
318Q_EXPORT inline bool operator<( const QCString &s1, const QCString& s2 )
319{ return qstrcmp( s1.data(), s2.data() ) < 0; }
320
321Q_EXPORT inline bool operator<( const QCString &s1, const char *s2 )
322{ return qstrcmp( s1.data(), s2 ) < 0; }
323
324Q_EXPORT inline bool operator<( const char *s1, const QCString &s2 )
325{ return qstrcmp( s1, s2.data() ) < 0; }
326
327Q_EXPORT inline bool operator<=( const QCString &s1, const QCString &s2 )
328{ return qstrcmp( s1.data(), s2.data() ) <= 0; }
329
330Q_EXPORT inline bool operator<=( const QCString &s1, const char *s2 )
331{ return qstrcmp( s1.data(), s2 ) <= 0; }
332
333Q_EXPORT inline bool operator<=( const char *s1, const QCString &s2 )
334{ return qstrcmp( s1, s2.data() ) <= 0; }
335
336Q_EXPORT inline bool operator>( const QCString &s1, const QCString &s2 )
337{ return qstrcmp( s1.data(), s2.data() ) > 0; }
338
339Q_EXPORT inline bool operator>( const QCString &s1, const char *s2 )
340{ return qstrcmp( s1.data(), s2 ) > 0; }
341
342Q_EXPORT inline bool operator>( const char *s1, const QCString &s2 )
343{ return qstrcmp( s1, s2.data() ) > 0; }
344
345Q_EXPORT inline bool operator>=( const QCString &s1, const QCString& s2 )
346{ return qstrcmp( s1.data(), s2.data() ) >= 0; }
347
348Q_EXPORT inline bool operator>=( const QCString &s1, const char *s2 )
349{ return qstrcmp( s1.data(), s2 ) >= 0; }
350
351Q_EXPORT inline bool operator>=( const char *s1, const QCString &s2 )
352{ return qstrcmp( s1, s2.data() ) >= 0; }
353
354Q_EXPORT inline const QCString operator+( const QCString &s1,
355 const QCString &s2 )
356{
357 QCString tmp( s1.data() );
358 tmp += s2;
359 return tmp;
360}
361
362Q_EXPORT inline const QCString operator+( const QCString &s1, const char *s2 )
363{
364 QCString tmp( s1.data() );
365 tmp += s2;
366 return tmp;
367}
368
369Q_EXPORT inline const QCString operator+( const char *s1, const QCString &s2 )
370{
371 QCString tmp( s1 );
372 tmp += s2;
373 return tmp;
374}
375
376Q_EXPORT inline const QCString operator+( const QCString &s1, char c2 )
377{
378 QCString tmp( s1.data() );
379 tmp += c2;
380 return tmp;
381}
382
383Q_EXPORT inline const QCString operator+( char c1, const QCString &s2 )
384{
385 QCString tmp;
386 tmp += c1;
387 tmp += s2;
388 return tmp;
389}
390
391#endif // QCSTRING_H
diff --git a/qmake/include/qdatastream.h b/qmake/include/qdatastream.h
new file mode 100644
index 0000000..09d7bef
--- a/dev/null
+++ b/qmake/include/qdatastream.h
@@ -0,0 +1,173 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QDATASTREAM_H
39#define QDATASTREAM_H
40
41#ifndef QT_H
42#include "qiodevice.h"
43#include "qstring.h"
44#endif // QT_H
45
46#ifndef QT_NO_DATASTREAM
47 class Q_EXPORT QDataStream // data stream class
48{
49public:
50 QDataStream();
51 QDataStream( QIODevice * );
52 QDataStream( QByteArray, int mode );
53 virtual ~QDataStream();
54
55 QIODevice*device() const;
56 void setDevice( QIODevice * );
57 void unsetDevice();
58
59 bool atEnd() const;
60 bool eof() const;
61
62 enum ByteOrder { BigEndian, LittleEndian };
63 int byteOrder()const;
64 void setByteOrder( int );
65
66 bool isPrintableData() const;
67 void setPrintableData( bool );
68
69 int version() const;
70 void setVersion( int );
71
72 QDataStream &operator>>( Q_INT8 &i );
73 QDataStream &operator>>( Q_UINT8 &i );
74 QDataStream &operator>>( Q_INT16 &i );
75 QDataStream &operator>>( Q_UINT16 &i );
76 QDataStream &operator>>( Q_INT32 &i );
77 QDataStream &operator>>( Q_UINT32 &i );
78 QDataStream &operator>>( Q_LONG &i );
79 QDataStream &operator>>( Q_ULONG &i );
80
81 QDataStream &operator>>( float &f );
82 QDataStream &operator>>( double &f );
83 QDataStream &operator>>( char *&str );
84
85 QDataStream &operator<<( Q_INT8 i );
86 QDataStream &operator<<( Q_UINT8 i );
87 QDataStream &operator<<( Q_INT16 i );
88 QDataStream &operator<<( Q_UINT16 i );
89 QDataStream &operator<<( Q_INT32 i );
90 QDataStream &operator<<( Q_UINT32 i );
91 QDataStream &operator<<( Q_LONG i );
92 QDataStream &operator<<( Q_ULONG i );
93 QDataStream &operator<<( float f );
94 QDataStream &operator<<( double f );
95 QDataStream &operator<<( const char *str );
96
97 QDataStream &readBytes( char *&, uint &len );
98 QDataStream &readRawBytes( char *, uint len );
99
100 QDataStream &writeBytes( const char *, uint len );
101 QDataStream &writeRawBytes( const char *, uint len );
102
103private:
104 QIODevice*dev;
105 bool owndev;
106 int byteorder;
107 bool printable;
108 bool noswap;
109 int ver;
110
111 private:// Disabled copy constructor and operator=
112#if defined(Q_DISABLE_COPY)
113 QDataStream( const QDataStream & );
114 QDataStream &operator=( const QDataStream & );
115#endif
116};
117
118
119/*****************************************************************************
120 QDataStream inline functions
121 *****************************************************************************/
122
123inline QIODevice *QDataStream::device() const
124{ return dev; }
125
126inline bool QDataStream::atEnd() const
127{ return dev ? dev->atEnd() : TRUE; }
128
129inline bool QDataStream::eof() const
130{ return atEnd(); }
131
132inline int QDataStream::byteOrder() const
133{ return byteorder; }
134
135inline bool QDataStream::isPrintableData() const
136{ return printable; }
137
138inline void QDataStream::setPrintableData( bool p )
139{ printable = p; }
140
141inline int QDataStream::version() const
142{ return ver; }
143
144inline void QDataStream::setVersion( int v )
145{ ver = v; }
146
147inline QDataStream &QDataStream::operator>>( Q_UINT8 &i )
148{ return *this >> (Q_INT8&)i; }
149
150inline QDataStream &QDataStream::operator>>( Q_UINT16 &i )
151{ return *this >> (Q_INT16&)i; }
152
153inline QDataStream &QDataStream::operator>>( Q_UINT32 &i )
154{ return *this >> (Q_INT32&)i; }
155
156inline QDataStream &QDataStream::operator>>( Q_ULONG &i )
157{ return *this >> (Q_LONG&)i; }
158
159inline QDataStream &QDataStream::operator<<( Q_UINT8 i )
160{ return *this << (Q_INT8)i; }
161
162inline QDataStream &QDataStream::operator<<( Q_UINT16 i )
163{ return *this << (Q_INT16)i; }
164
165inline QDataStream &QDataStream::operator<<( Q_UINT32 i )
166{ return *this << (Q_INT32)i; }
167
168inline QDataStream &QDataStream::operator<<( Q_ULONG i )
169{ return *this << (Q_LONG)i; }
170
171
172#endif // QT_NO_DATASTREAM
173#endif // QDATASTREAM_H
diff --git a/qmake/include/qdatetime.h b/qmake/include/qdatetime.h
new file mode 100644
index 0000000..4f01760
--- a/dev/null
+++ b/qmake/include/qdatetime.h
@@ -0,0 +1,250 @@
1/*************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QDATETIME_H
39#define QDATETIME_H
40
41#ifndef QT_H
42#include "qstring.h"
43#include "qnamespace.h"
44#endif // QT_H
45
46
47/*****************************************************************************
48 QDate class
49 *****************************************************************************/
50
51class Q_EXPORT QDate
52{
53public:
54 QDate() { jd = 0; }
55 QDate( int y, int m, int d );
56
57 bool isNull() const { return jd == 0; }
58 bool isValid() const;
59
60 int year() const;
61 int month() const;
62 int day() const;
63 int dayOfWeek() const;
64 int dayOfYear() const;
65 int daysInMonth() const;
66 int daysInYear() const;
67 int weekNumber( int *yearNum = 0 ) const;
68
69#ifndef QT_NO_TEXTDATE
70#ifndef QT_NO_COMPAT
71 static QString monthName( int month ) { return shortMonthName( month ); }
72 static QString dayName( int weekday ) { return shortDayName( weekday ); }
73#endif
74 static QString shortMonthName( int month );
75 static QString shortDayName( int weekday );
76 static QString longMonthName( int month );
77 static QString longDayName( int weekday );
78#endif //QT_NO_TEXTDATE
79#ifndef QT_NO_TEXTSTRING
80#if !defined(QT_NO_SPRINTF)
81 QString toString( Qt::DateFormat f = Qt::TextDate ) const;
82#endif
83 QString toString( const QString& format ) const;
84#endif
85 bool setYMD( int y, int m, int d );
86
87 QDate addDays( int days ) const;
88 QDate addMonths( int months ) const;
89 QDate addYears( int years ) const;
90 int daysTo( const QDate & )const;
91
92 bool operator==( const QDate &d ) const { return jd == d.jd; }
93 bool operator!=( const QDate &d ) const { return jd != d.jd; }
94 bool operator<( const QDate &d )const { return jd < d.jd; }
95 bool operator<=( const QDate &d ) const { return jd <= d.jd; }
96 bool operator>( const QDate &d )const { return jd > d.jd; }
97 bool operator>=( const QDate &d ) const { return jd >= d.jd; }
98
99 static QDate currentDate();
100 static QDate currentDate( Qt::TimeSpec );
101#ifndef QT_NO_DATESTRING
102 static QDate fromString( const QString& s, Qt::DateFormat f = Qt::TextDate );
103#endif
104 static bool isValid( int y, int m, int d );
105 static bool leapYear( int year );
106
107 static uint gregorianToJulian( int y, int m, int d );
108 static void julianToGregorian( uint jd, int &y, int &m, int &d );
109private:
110 uint jd;
111 friend class QDateTime;
112#ifndef QT_NO_DATASTREAM
113 friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QDate & );
114 friend Q_EXPORT QDataStream &operator>>( QDataStream &, QDate & );
115#endif
116};
117
118
119/*****************************************************************************
120 QTime class
121 *****************************************************************************/
122
123class Q_EXPORT QTime
124{
125public:
126 QTime() { ds=0; } // set null time
127 QTime( int h, int m, int s=0, int ms=0 );// set time
128
129 bool isNull() const { return ds == 0; }
130 bool isValid() const; // valid time
131
132 int hour() const; // 0..23
133 int minute() const; // 0..59
134 int second() const; // 0..59
135 int msec() const; // 0..999
136#ifndef QT_NO_DATESTRING
137#ifndef QT_NO_SPRINTF
138 QString toString( Qt::DateFormat f = Qt::TextDate ) const;
139#endif
140 QString toString( const QString& format ) const;
141#endif
142 bool setHMS( int h, int m, int s, int ms=0 );
143
144 QTime addSecs( int secs ) const;
145 int secsTo( const QTime & )const;
146 QTime addMSecs( int ms ) const;
147 int msecsTo( const QTime & )const;
148
149 bool operator==( const QTime &d ) const { return ds == d.ds; }
150 bool operator!=( const QTime &d ) const { return ds != d.ds; }
151 bool operator<( const QTime &d )const { return ds < d.ds; }
152 bool operator<=( const QTime &d ) const { return ds <= d.ds; }
153 bool operator>( const QTime &d )const { return ds > d.ds; }
154 bool operator>=( const QTime &d ) const { return ds >= d.ds; }
155
156 static QTime currentTime();
157 static QTime currentTime( Qt::TimeSpec );
158#ifndef QT_NO_DATESTRING
159 static QTime fromString( const QString& s, Qt::DateFormat f = Qt::TextDate );
160#endif
161 static bool isValid( int h, int m, int s, int ms=0 );
162
163 void start();
164 int restart();
165 int elapsed() const;
166
167private:
168 static bool currentTime( QTime * );
169 static bool currentTime( QTime *, Qt::TimeSpec );
170
171 uint ds;
172 friend class QDateTime;
173#ifndef QT_NO_DATASTREAM
174 friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QTime & );
175 friend Q_EXPORT QDataStream &operator>>( QDataStream &, QTime & );
176#endif
177};
178
179
180/*****************************************************************************
181 QDateTime class
182 *****************************************************************************/
183
184class Q_EXPORT QDateTime
185{
186public:
187 QDateTime() {} // set null date and null time
188 QDateTime( const QDate & );
189 QDateTime( const QDate &, const QTime & );
190
191 bool isNull() const { return d.isNull() && t.isNull(); }
192 bool isValid() const { return d.isValid() && t.isValid(); }
193
194 QDate date() const { return d; }
195 QTime time() const { return t; }
196 uint toTime_t()const;
197 void setDate( const QDate &date ) { d = date; }
198 void setTime( const QTime &time ) { t = time; }
199 void setTime_t( uint secsSince1Jan1970UTC );
200 void setTime_t( uint secsSince1Jan1970UTC, Qt::TimeSpec );
201#ifndef QT_NO_DATESTRING
202#ifndef QT_NO_SPRINTF
203 QString toString( Qt::DateFormat f = Qt::TextDate )const;
204#endif
205 QString toString( const QString& format ) const;
206#endif
207 QDateTime addDays( int days )const;
208 QDateTime addMonths( int months ) const;
209 QDateTime addYears( int years ) const;
210 QDateTime addSecs( int secs )const;
211 int daysTo( const QDateTime & )const;
212 int secsTo( const QDateTime & )const;
213
214 bool operator==( const QDateTime &dt ) const;
215 bool operator!=( const QDateTime &dt ) const;
216 bool operator<( const QDateTime &dt ) const;
217 bool operator<=( const QDateTime &dt ) const;
218 bool operator>( const QDateTime &dt ) const;
219 bool operator>=( const QDateTime &dt ) const;
220
221 static QDateTime currentDateTime();
222 static QDateTime currentDateTime( Qt::TimeSpec );
223#ifndef QT_NO_DATESTRING
224 static QDateTime fromString( const QString& s, Qt::DateFormat f = Qt::TextDate );
225#endif
226private:
227 QDate d;
228 QTime t;
229#ifndef QT_NO_DATASTREAM
230 friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QDateTime &);
231 friend Q_EXPORT QDataStream &operator>>( QDataStream &, QDateTime & );
232#endif
233};
234
235
236/*****************************************************************************
237 Date and time stream functions
238 *****************************************************************************/
239
240#ifndef QT_NO_DATASTREAM
241Q_EXPORT QDataStream &operator<<( QDataStream &, const QDate & );
242Q_EXPORT QDataStream &operator>>( QDataStream &, QDate & );
243Q_EXPORT QDataStream &operator<<( QDataStream &, const QTime & );
244Q_EXPORT QDataStream &operator>>( QDataStream &, QTime & );
245Q_EXPORT QDataStream &operator<<( QDataStream &, const QDateTime & );
246Q_EXPORT QDataStream &operator>>( QDataStream &, QDateTime & );
247#endif // QT_NO_DATASTREAM
248
249#endif // QDATETIME_H
250
diff --git a/qmake/include/qdict.h b/qmake/include/qdict.h
new file mode 100644
index 0000000..04ae7bf
--- a/dev/null
+++ b/qmake/include/qdict.h
@@ -0,0 +1,118 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QDict template class
5**
6** Created : 920821
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#ifndef QDICT_H
39#define QDICT_H
40
41#ifndef QT_H
42#include "qgdict.h"
43#endif // QT_H
44
45template<class type>
46class QDict
47#ifdef Q_QDOC
48 : public QPtrCollection
49#else
50 : public QGDict
51#endif
52{
53public:
54 QDict( int size = 17, bool caseSensitive = TRUE )
55 : QGDict( size, StringKey, caseSensitive, FALSE ) { }
56 QDict( const QDict<type> &d ) : QGDict( d ) { }
57 ~QDict() { clear(); }
58 QDict<type> &operator=(const QDict<type> &d)
59 { return (QDict<type>&)QGDict::operator=(d); }
60 uint count() const { return QGDict::count(); }
61 uint size() const { return QGDict::size(); }
62 bool isEmpty() const { return QGDict::count() == 0; }
63
64 void insert( const QString &k, const type *d )
65 { QGDict::look_string(k,(Item)d,1); }
66 void replace( const QString &k, const type *d )
67 { QGDict::look_string(k,(Item)d,2); }
68 bool remove( const QString &k ){ return QGDict::remove_string(k); }
69 type *take( const QString &k ){ return (type *)QGDict::take_string(k); }
70 type *find( const QString &k ) const
71 { return (type *)((QGDict*)this)->QGDict::look_string(k,0,0); }
72 type *operator[]( const QString &k ) const
73 { return (type *)((QGDict*)this)->QGDict::look_string(k,0,0); }
74
75 void clear() { QGDict::clear(); }
76 void resize( uint n ) { QGDict::resize(n); }
77 void statistics() const { QGDict::statistics(); }
78
79#ifdef Q_QDOC
80protected:
81 virtual QDataStream& read( QDataStream &, QPtrCollection::Item & );
82 virtual QDataStream& write( QDataStream &, QPtrCollection::Item ) const;
83#endif
84
85private:
86 void deleteItem( Item d );
87};
88
89#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION)
90template<> inline void QDict<void>::deleteItem( Item )
91{
92}
93#endif
94
95template<class type> inline void QDict<type>::deleteItem( QPtrCollection::Item d )
96{
97 if ( del_item ) delete (type *)d;
98}
99
100template<class type>
101class QDictIterator : public QGDictIterator
102{
103public:
104 QDictIterator(const QDict<type> &d) : QGDictIterator((QGDict &)d) { }
105 ~QDictIterator() {}
106 uint count() const { return dict->count(); }
107 bool isEmpty() const { return dict->count() == 0; }
108 type *toFirst() { return (type *)QGDictIterator::toFirst(); }
109 operator type *() const { return (type *)QGDictIterator::get(); }
110 type *operator*() { return (type *)QGDictIterator::get(); }
111 type *current() const { return (type *)QGDictIterator::get(); }
112 QString currentKey() const{ return QGDictIterator::getKeyString(); }
113 type *operator()() { return (type *)QGDictIterator::operator()(); }
114 type *operator++() { return (type *)QGDictIterator::operator++(); }
115 type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j); }
116};
117
118#endif // QDICT_H
diff --git a/qmake/include/qdir.h b/qmake/include/qdir.h
new file mode 100644
index 0000000..6e9f1ab
--- a/dev/null
+++ b/qmake/include/qdir.h
@@ -0,0 +1,241 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QDIR_H
39#define QDIR_H
40
41#ifndef QT_H
42#include "qglobal.h"
43#include "qstrlist.h"
44#include "qfileinfo.h"
45#endif // QT_H
46
47
48#ifndef QT_NO_DIR
49typedef QPtrList<QFileInfo> QFileInfoList;
50typedef QPtrListIterator<QFileInfo> QFileInfoListIterator;
51class QStringList;
52
53
54class Q_EXPORT QDir
55{
56public:
57 enum FilterSpec { Dirs = 0x001,
58 Files = 0x002,
59 Drives = 0x004,
60 NoSymLinks = 0x008,
61 All = 0x007,
62 TypeMask = 0x00F,
63
64 Readable = 0x010,
65 Writable = 0x020,
66 Executable = 0x040,
67 RWEMask = 0x070,
68
69 Modified = 0x080,
70 Hidden = 0x100,
71 System = 0x200,
72 AccessMask = 0x3F0,
73
74 DefaultFilter = -1 };
75
76 enum SortSpec { Name = 0x00,
77 Time = 0x01,
78 Size = 0x02,
79 Unsorted = 0x03,
80 SortByMask = 0x03,
81
82 DirsFirst = 0x04,
83 Reversed = 0x08,
84 IgnoreCase = 0x10,
85 DefaultSort = -1 };
86
87 QDir();
88 QDir( const QString &path, const QString &nameFilter = QString::null,
89 int sortSpec = Name | IgnoreCase, int filterSpec = All );
90 QDir( const QDir & );
91
92 virtual ~QDir();
93
94 QDir &operator=( const QDir & );
95 QDir &operator=( const QString &path );
96
97 virtual void setPath( const QString &path );
98 virtual QString path() const;
99 virtual QString absPath()const;
100 virtual QString canonicalPath()const;
101
102 virtual QString dirName() const;
103 virtual QString filePath( const QString &fileName,
104 bool acceptAbsPath = TRUE ) const;
105 virtual QString absFilePath( const QString &fileName,
106 bool acceptAbsPath = TRUE ) const;
107
108 static QString convertSeparators( const QString &pathName );
109
110 virtual bool cd( const QString &dirName, bool acceptAbsPath = TRUE );
111 virtual bool cdUp();
112
113 QStringnameFilter() const;
114 virtual void setNameFilter( const QString &nameFilter );
115 FilterSpec filter() const;
116 virtual void setFilter( int filterSpec );
117 SortSpec sorting() const;
118 virtual void setSorting( int sortSpec );
119
120 boolmatchAllDirs() const;
121 virtual void setMatchAllDirs( bool );
122
123 uint count() const;
124 QStringoperator[]( int ) const;
125
126 virtual QStrList encodedEntryList( int filterSpec = DefaultFilter,
127 int sortSpec = DefaultSort ) const;
128 virtual QStrList encodedEntryList( const QString &nameFilter,
129 int filterSpec = DefaultFilter,
130 int sortSpec = DefaultSort ) const;
131 virtual QStringList entryList( int filterSpec = DefaultFilter,
132 int sortSpec = DefaultSort ) const;
133 virtual QStringList entryList( const QString &nameFilter,
134 int filterSpec = DefaultFilter,
135 int sortSpec = DefaultSort ) const;
136
137 virtual const QFileInfoList *entryInfoList( int filterSpec = DefaultFilter,
138 int sortSpec = DefaultSort ) const;
139 virtual const QFileInfoList *entryInfoList( const QString &nameFilter,
140 int filterSpec = DefaultFilter,
141 int sortSpec = DefaultSort ) const;
142
143 static const QFileInfoList *drives();
144
145 virtual bool mkdir( const QString &dirName,
146 bool acceptAbsPath = TRUE ) const;
147 virtual bool rmdir( const QString &dirName,
148 bool acceptAbsPath = TRUE ) const;
149
150 virtual bool isReadable() const;
151 virtual bool exists() const;
152 virtual bool isRoot() const;
153
154 virtual bool isRelative() const;
155 virtual void convertToAbs();
156
157 virtual bool operator==( const QDir & ) const;
158 virtual bool operator!=( const QDir & ) const;
159
160 virtual bool remove( const QString &fileName,
161 bool acceptAbsPath = TRUE );
162 virtual bool rename( const QString &name, const QString &newName,
163 bool acceptAbsPaths = TRUE );
164 virtual bool exists( const QString &name,
165 bool acceptAbsPath = TRUE );
166
167 static char separator();
168
169 static bool setCurrent( const QString &path );
170 static QDir current();
171 static QDir home();
172 static QDir root();
173 static QString currentDirPath();
174 static QString homeDirPath();
175 static QString rootDirPath();
176
177 static bool match( const QStringList &filters, const QString &fileName );
178 static bool match( const QString &filter, const QString &fileName );
179 static QString cleanDirPath( const QString &dirPath );
180 static bool isRelativePath( const QString &path );
181
182private:
183#ifdef Q_OS_MAC
184 typedef struct FSSpec FSSpec;
185 static FSSpec *make_spec(const QString &);
186#endif
187 void init();
188 virtual bool readDirEntries( const QString &nameFilter,
189 int FilterSpec, int SortSpec );
190
191 static void slashify ( QString &);
192
193 QStringdPath;
194 QStringList *fList;
195 QFileInfoList *fiList;
196 QStringnameFilt;
197 FilterSpecfiltS;
198 SortSpecsortS;
199 uint dirty: 1;
200 uintallDirs : 1;
201};
202
203
204inline QString QDir::path() const
205{
206 return dPath;
207}
208
209inline QString QDir::nameFilter() const
210{
211 return nameFilt;
212}
213
214inline QDir::FilterSpec QDir::filter() const
215{
216 return filtS;
217}
218
219inline QDir::SortSpec QDir::sorting() const
220{
221 return sortS;
222}
223
224inline bool QDir::matchAllDirs() const
225{
226 return allDirs;
227}
228
229inline bool QDir::operator!=( const QDir &d ) const
230{
231 return !(*this == d);
232}
233
234
235struct QDirSortItem {
236 QString filename_cache;
237 QFileInfo* item;
238};
239
240#endif // QT_NO_DIR
241#endif // QDIR_H
diff --git a/qmake/include/qfeatures.h b/qmake/include/qfeatures.h
new file mode 100644
index 0000000..57502f9
--- a/dev/null
+++ b/qmake/include/qfeatures.h
@@ -0,0 +1,959 @@
1// All feature and their dependencies
2//
3// This list is generated from $QTDIR/src/tools/qfeatures.txt
4//
5// Asynchronous I/O
6//#define QT_NO_ASYNC_IO
7
8// Bezier curves
9//#define QT_NO_BEZIER
10
11// Buttons
12//#define QT_NO_BUTTON
13
14// Named colors
15//#define QT_NO_COLORNAMES
16
17// Cursors
18//#define QT_NO_CURSOR
19
20// QDataStream
21//#define QT_NO_DATASTREAM
22
23// QDate/QTime/QDateTime toString() and fromString()
24//#define QT_NO_DATESTRING
25
26// Dialogs
27//#define QT_NO_DIALOG
28
29// QDirectPainter
30//#define QT_NO_DIRECTPAINTER
31
32// Special widget effects (fading, scrolling)
33//#define QT_NO_EFFECTS
34
35// Freetype font engine
36//#define QT_NO_FREETYPE
37
38// Dither QImage to 1-bit image
39//#define QT_NO_IMAGE_DITHER_TO_1
40
41// QImage::createHeuristicMask()
42//#define QT_NO_IMAGE_HEURISTIC_MASK
43
44// QImage mirroring
45//#define QT_NO_IMAGE_MIRROR
46
47// Smooth QImage scaling
48//#define QT_NO_IMAGE_SMOOTHSCALE
49
50// TrueColor QImage
51//#define QT_NO_IMAGE_TRUECOLOR
52
53// Automatic widget layout
54//#define QT_NO_LAYOUT
55
56// Networking
57//#define QT_NO_NETWORK
58
59// Palettes
60//#define QT_NO_PALETTE
61
62// Alpha-blended cursor
63//#define QT_NO_QWS_ALPHA_CURSOR
64
65// 1-bit monochrome
66//#define QT_NO_QWS_DEPTH_1
67
68// 15 or 16-bit color
69//#define QT_NO_QWS_DEPTH_16
70
71// 24-bit color
72//#define QT_NO_QWS_DEPTH_24
73
74// 32-bit color
75//#define QT_NO_QWS_DEPTH_32
76
77// 4-bit greyscale
78//#define QT_NO_QWS_DEPTH_4
79
80// 8-bit color
81//#define QT_NO_QWS_DEPTH_8
82
83// 8-bit grayscale
84//#define QT_NO_QWS_DEPTH_8GRAYSCALE
85
86// Favour code size over graphics speed
87//#define QT_NO_QWS_GFX_SPEED
88
89// Console keyboard
90//#define QT_NO_QWS_KEYBOARD
91
92// Linux framebuffer
93//#define QT_NO_QWS_LINUXFB
94
95// Mach64 acceleration
96//#define QT_NO_QWS_MACH64
97
98// Window Manager
99//#define QT_NO_QWS_MANAGER
100
101// Matrox MGA acceleration
102//#define QT_NO_QWS_MATROX
103
104// Autodetecting mouse driver
105//#define QT_NO_QWS_MOUSE_AUTO
106
107// Non-autodetecting mouse driver
108//#define QT_NO_QWS_MOUSE_MANUAL
109
110// Qt/Embedded window system properties.
111//#define QT_NO_QWS_PROPERTIES
112
113// Repeater display
114//#define QT_NO_QWS_REPEATER
115
116// Saving of fonts
117//#define QT_NO_QWS_SAVEFONTS
118
119// Shadow frame buffer
120//#define QT_NO_QWS_SHADOWFB
121
122// Virtual frame buffer
123//#define QT_NO_QWS_VFB
124
125// 4-bit VGA
126//#define QT_NO_QWS_VGA_16
127
128// Voodoo3 acceleration
129//#define QT_NO_QWS_VOODOO3
130
131// Range-control widgets
132//#define QT_NO_RANGECONTROL
133
134// Regular expression capture
135//#define QT_NO_REGEXP
136
137// QSignalMapper
138//#define QT_NO_SIGNALMAPPER
139
140// Playing sounds
141//#define QT_NO_SOUND
142
143// Standard template library compatiblity
144//#define QT_NO_STL
145
146// QStringList
147//#define QT_NO_STRINGLIST
148
149// Character set conversions
150//#define QT_NO_TEXTCODEC
151
152// QTextStream
153//#define QT_NO_TEXTSTREAM
154
155// Unicode property tables
156//#define QT_NO_UNICODETABLES
157
158// Input validators
159//#define QT_NO_VALIDATOR
160
161// QVariant
162//#define QT_NO_VARIANT
163
164// Wheel-mouse events
165//#define QT_NO_WHEELEVENT
166
167// QWMatrix
168//#define QT_NO_WMATRIX
169
170// Non-Unicode text conversions
171#if !defined(QT_NO_CODECS) && (defined(QT_NO_TEXTCODEC))
172#define QT_NO_CODECS
173#endif
174
175// QCop IPC
176#if !defined(QT_NO_COP) && (defined(QT_NO_DATASTREAM))
177#define QT_NO_COP
178#endif
179
180// QFontDatabase
181#if !defined(QT_NO_FONTDATABASE) && (defined(QT_NO_STRINGLIST))
182#define QT_NO_FONTDATABASE
183#endif
184
185// Image formats
186#if !defined(QT_NO_IMAGEIO) && (defined(QT_NO_REGEXP))
187#define QT_NO_IMAGEIO
188#endif
189
190// 16-bit QImage
191#if !defined(QT_NO_IMAGE_16_BIT) && (defined(QT_NO_IMAGE_TRUECOLOR))
192#define QT_NO_IMAGE_16_BIT
193#endif
194
195// Image file text strings
196#if !defined(QT_NO_IMAGE_TEXT) && (defined(QT_NO_STRINGLIST))
197#define QT_NO_IMAGE_TEXT
198#endif
199
200// Shared library wrapper
201#if !defined(QT_NO_LIBRARY) && (defined(QT_NO_REGEXP))
202#define QT_NO_LIBRARY
203#endif
204
205// Pixmap transformations
206#if !defined(QT_NO_PIXMAP_TRANSFORMATION) && (defined(QT_NO_WMATRIX))
207#define QT_NO_PIXMAP_TRANSFORMATION
208#endif
209
210// Convert UUID to/from string
211#if !defined(QT_NO_QUUID_STRING) && (defined(QT_NO_STRINGLIST))
212#define QT_NO_QUUID_STRING
213#endif
214
215// The "BeOS" style
216#if !defined(QT_NO_QWS_BEOS_WM_STYLE) && (defined(QT_NO_QWS_MANAGER))
217#define QT_NO_QWS_BEOS_WM_STYLE
218#endif
219
220// Visible cursor
221#if !defined(QT_NO_QWS_CURSOR) && (defined(QT_NO_CURSOR))
222#define QT_NO_QWS_CURSOR
223#endif
224
225// 32-bit color, BGR order
226#if !defined(QT_NO_QWS_DEPTH_32_BGR) && (defined(QT_NO_QWS_DEPTH_32))
227#define QT_NO_QWS_DEPTH_32_BGR
228#endif
229
230// The "Hydro" style
231#if !defined(QT_NO_QWS_HYDRO_WM_STYLE) && (defined(QT_NO_QWS_MANAGER))
232#define QT_NO_QWS_HYDRO_WM_STYLE
233#endif
234
235// The "KDE2" style
236#if !defined(QT_NO_QWS_KDE2_WM_STYLE) && (defined(QT_NO_QWS_MANAGER))
237#define QT_NO_QWS_KDE2_WM_STYLE
238#endif
239
240// The "KDE" style
241#if !defined(QT_NO_QWS_KDE_WM_STYLE) && (defined(QT_NO_QWS_MANAGER))
242#define QT_NO_QWS_KDE_WM_STYLE
243#endif
244
245// Multi-process architecture
246#if !defined(QT_NO_QWS_MULTIPROCESS) && (defined(QT_NO_NETWORK))
247#define QT_NO_QWS_MULTIPROCESS
248#endif
249
250// Transformed frame buffer
251#if !defined(QT_NO_QWS_TRANSFORMED) && (defined(QT_NO_QWS_LINUXFB))
252#define QT_NO_QWS_TRANSFORMED
253#endif
254
255// Remote frame buffer (VNC)
256#if !defined(QT_NO_QWS_VNC) && (defined(QT_NO_NETWORK))
257#define QT_NO_QWS_VNC
258#endif
259
260// The "Windows" style
261#if !defined(QT_NO_QWS_WINDOWS_WM_STYLE) && (defined(QT_NO_QWS_MANAGER))
262#define QT_NO_QWS_WINDOWS_WM_STYLE
263#endif
264
265// Regular expression anchors
266#if !defined(QT_NO_REGEXP_ANCHOR_ALT) && (defined(QT_NO_REGEXP))
267#define QT_NO_REGEXP_ANCHOR_ALT
268#endif
269
270// Regular expression back-reference
271#if !defined(QT_NO_REGEXP_BACKREF) && (defined(QT_NO_REGEXP))
272#define QT_NO_REGEXP_BACKREF
273#endif
274
275// Regular expression character-class
276#if !defined(QT_NO_REGEXP_CCLASS) && (defined(QT_NO_REGEXP))
277#define QT_NO_REGEXP_CCLASS
278#endif
279
280// Regular expression escape
281#if !defined(QT_NO_REGEXP_ESCAPE) && (defined(QT_NO_REGEXP))
282#define QT_NO_REGEXP_ESCAPE
283#endif
284
285// Regular expression interval
286#if !defined(QT_NO_REGEXP_INTERVAL) && (defined(QT_NO_REGEXP))
287#define QT_NO_REGEXP_INTERVAL
288#endif
289
290// Regular expression lookahead
291#if !defined(QT_NO_REGEXP_LOOKAHEAD) && (defined(QT_NO_REGEXP))
292#define QT_NO_REGEXP_LOOKAHEAD
293#endif
294
295// Regular expression optimization
296#if !defined(QT_NO_REGEXP_OPTIM) && (defined(QT_NO_REGEXP))
297#define QT_NO_REGEXP_OPTIM
298#endif
299
300// Regular expression wildcard
301#if !defined(QT_NO_REGEXP_WILDCARD) && (defined(QT_NO_REGEXP))
302#define QT_NO_REGEXP_WILDCARD
303#endif
304
305// Semi-modal dialogs
306#if !defined(QT_NO_SEMIMODAL) && (defined(QT_NO_DIALOG))
307#define QT_NO_SEMIMODAL
308#endif
309
310// Session management
311#if !defined(QT_NO_SESSIONMANAGER) && (defined(QT_NO_STRINGLIST))
312#define QT_NO_SESSIONMANAGER
313#endif
314
315// QString::sprintf()
316#if !defined(QT_NO_SPRINTF) && (defined(QT_NO_REGEXP))
317#define QT_NO_SPRINTF
318#endif
319
320// Scaling and rotation
321#if !defined(QT_NO_TRANSFORMATIONS) && (defined(QT_NO_WMATRIX))
322#define QT_NO_TRANSFORMATIONS
323#endif
324
325// Translations via QObject::tr()
326#if !defined(QT_NO_TRANSLATION) && (defined(QT_NO_DATASTREAM))
327#define QT_NO_TRANSLATION
328#endif
329
330// Window icon and caption
331#if !defined(QT_NO_WIDGET_TOPEXTRA) && (defined(QT_NO_IMAGE_HEURISTIC_MASK))
332#define QT_NO_WIDGET_TOPEXTRA
333#endif
334
335// Keyboard accelerators and shortcuts
336#if !defined(QT_NO_ACCEL) && (defined(QT_NO_SPRINTF))
337#define QT_NO_ACCEL
338#endif
339
340// Asynchronous image I/O
341#if !defined(QT_NO_ASYNC_IMAGE_IO) && (defined(QT_NO_IMAGEIO))
342#define QT_NO_ASYNC_IMAGE_IO
343#endif
344
345// BDF font files
346#if !defined(QT_NO_BDF) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_STRINGLIST))
347#define QT_NO_BDF
348#endif
349
350// QDir
351#if !defined(QT_NO_DIR) && (defined(QT_NO_STRINGLIST) || defined(QT_NO_REGEXP))
352#define QT_NO_DIR
353#endif
354
355// JPEG image I/O
356#if !defined(QT_NO_IMAGEIO_JPEG) && (defined(QT_NO_IMAGEIO))
357#define QT_NO_IMAGEIO_JPEG
358#endif
359
360// MNG image I/O
361#if !defined(QT_NO_IMAGEIO_MNG) && (defined(QT_NO_IMAGEIO))
362#define QT_NO_IMAGEIO_MNG
363#endif
364
365// PNG image I/O
366#if !defined(QT_NO_IMAGEIO_PNG) && (defined(QT_NO_IMAGEIO))
367#define QT_NO_IMAGEIO_PNG
368#endif
369
370// PPM image I/O
371#if !defined(QT_NO_IMAGEIO_PPM) && (defined(QT_NO_IMAGEIO))
372#define QT_NO_IMAGEIO_PPM
373#endif
374
375// XBM image I/O
376#if !defined(QT_NO_IMAGEIO_XBM) && (defined(QT_NO_IMAGEIO))
377#define QT_NO_IMAGEIO_XBM
378#endif
379
380// Image transformations
381#if !defined(QT_NO_IMAGE_TRANSFORMATION) && (defined(QT_NO_PIXMAP_TRANSFORMATION))
382#define QT_NO_IMAGE_TRANSFORMATION
383#endif
384
385// External process invocation.
386#if !defined(QT_NO_PROCESS) && (defined(QT_NO_STRINGLIST) || defined(QT_NO_REGEXP))
387#define QT_NO_PROCESS
388#endif
389
390// Regular expression capture
391#if !defined(QT_NO_REGEXP_CAPTURE) && (defined(QT_NO_REGEXP) || defined(QT_NO_STRINGLIST))
392#define QT_NO_REGEXP_CAPTURE
393#endif
394
395// Template classes in QVariant
396#if !defined(QT_NO_TEMPLATE_VARIANT) && (defined(QT_NO_VARIANT) || defined(QT_NO_STRINGLIST))
397#define QT_NO_TEMPLATE_VARIANT
398#endif
399
400// Month and day names in dates
401#if !defined(QT_NO_TEXTDATE) && (defined(QT_NO_STRINGLIST) || defined(QT_NO_DATESTRING))
402#define QT_NO_TEXTDATE
403#endif
404
405// Drawing utility functions
406#if !defined(QT_NO_DRAWUTIL) && (defined(QT_NO_SPRINTF) || defined(QT_NO_PALETTE))
407#define QT_NO_DRAWUTIL
408#endif
409
410// BMP image I/O
411#if !defined(QT_NO_IMAGEIO_BMP) && (defined(QT_NO_IMAGEIO) || defined(QT_NO_DATASTREAM))
412#define QT_NO_IMAGEIO_BMP
413#endif
414
415// QPicture
416#if !defined(QT_NO_PICTURE) && (defined(QT_NO_DATASTREAM) || defined(QT_NO_IMAGEIO))
417#define QT_NO_PICTURE
418#endif
419
420// Translations via QObject::trUtf8()
421#if !defined(QT_NO_TRANSLATION_UTF8) && (defined(QT_NO_TRANSLATION) || defined(QT_NO_TEXTCODEC))
422#define QT_NO_TRANSLATION_UTF8
423#endif
424
425// URL parser
426#if !defined(QT_NO_URL) && (defined(QT_NO_DIR))
427#define QT_NO_URL
428#endif
429
430// Animated images
431#if !defined(QT_NO_MOVIE) && (defined(QT_NO_ASYNC_IO) || defined(QT_NO_ASYNC_IMAGE_IO))
432#define QT_NO_MOVIE
433#endif
434
435// Persistent application settings
436#if !defined(QT_NO_SETTINGS) && (defined(QT_NO_DIR) || defined(QT_NO_TEXTSTREAM))
437#define QT_NO_SETTINGS
438#endif
439
440// QStyle
441#if !defined(QT_NO_STYLE) && (defined(QT_NO_DRAWUTIL))
442#define QT_NO_STYLE
443#endif
444
445// DNS
446#if !defined(QT_NO_DNS) && (defined(QT_NO_NETWORK) || defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_SPRINTF))
447#define QT_NO_DNS
448#endif
449
450// Framed widgets
451#if !defined(QT_NO_FRAME) && (defined(QT_NO_STYLE))
452#define QT_NO_FRAME
453#endif
454
455// QIconSet
456#if !defined(QT_NO_ICONSET) && (defined(QT_NO_IMAGEIO) || defined(QT_NO_IMAGE_SMOOTHSCALE) || defined(QT_NO_PALETTE) || defined(QT_NO_IMAGE_HEURISTIC_MASK))
457#define QT_NO_ICONSET
458#endif
459
460// XPM image I/O
461#if !defined(QT_NO_IMAGEIO_XPM) && (defined(QT_NO_IMAGEIO) || defined(QT_NO_SPRINTF) || defined(QT_NO_TEXTSTREAM))
462#define QT_NO_IMAGEIO_XPM
463#endif
464
465// QSizeGrip
466#if !defined(QT_NO_SIZEGRIP) && (defined(QT_NO_STYLE))
467#define QT_NO_SIZEGRIP
468#endif
469
470// Motif style
471#if !defined(QT_NO_STYLE_MOTIF) && (defined(QT_NO_STYLE))
472#define QT_NO_STYLE_MOTIF
473#endif
474
475// Windows style
476#if !defined(QT_NO_STYLE_WINDOWS) && (defined(QT_NO_STYLE))
477#define QT_NO_STYLE_WINDOWS
478#endif
479
480// Internal titlebar widget
481#if !defined(QT_NO_TITLEBAR) && (defined(QT_NO_STYLE))
482#define QT_NO_TITLEBAR
483#endif
484
485// XML
486#if !defined(QT_NO_XML) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_TEXTCODEC) || defined(QT_NO_REGEXP_CAPTURE))
487#define QT_NO_XML
488#endif
489
490// Check-boxes
491#if !defined(QT_NO_CHECKBOX) && (defined(QT_NO_BUTTON) || defined(QT_NO_STYLE))
492#define QT_NO_CHECKBOX
493#endif
494
495// Dials
496#if !defined(QT_NO_DIAL) && (defined(QT_NO_RANGECONTROL) || defined(QT_NO_STYLE))
497#define QT_NO_DIAL
498#endif
499
500// QLabel
501#if !defined(QT_NO_LABEL) && (defined(QT_NO_FRAME))
502#define QT_NO_LABEL
503#endif
504
505// QLCDNumber
506#if !defined(QT_NO_LCDNUMBER) && (defined(QT_NO_FRAME))
507#define QT_NO_LCDNUMBER
508#endif
509
510// MIME
511#if !defined(QT_NO_MIME) && (defined(QT_NO_DIR) || defined(QT_NO_IMAGEIO) || defined(QT_NO_TEXTCODEC))
512#define QT_NO_MIME
513#endif
514
515// Printing
516#if !defined(QT_NO_PRINTER) && (defined(QT_NO_TEXTSTREAM) || defined(QT_NO_SPRINTF) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_DATESTRING))
517#define QT_NO_PRINTER
518#endif
519
520// Progress bars
521#if !defined(QT_NO_PROGRESSBAR) && (defined(QT_NO_FRAME))
522#define QT_NO_PROGRESSBAR
523#endif
524
525// Radio-buttons
526#if !defined(QT_NO_RADIOBUTTON) && (defined(QT_NO_BUTTON) || defined(QT_NO_STYLE))
527#define QT_NO_RADIOBUTTON
528#endif
529
530// Internal resize handler
531#if !defined(QT_NO_RESIZEHANDLER) && (defined(QT_NO_FRAME))
532#define QT_NO_RESIZEHANDLER
533#endif
534
535// Scroll bars
536#if !defined(QT_NO_SCROLLBAR) && (defined(QT_NO_RANGECONTROL) || defined(QT_NO_STYLE))
537#define QT_NO_SCROLLBAR
538#endif
539
540// Sliders
541#if !defined(QT_NO_SLIDER) && (defined(QT_NO_RANGECONTROL) || defined(QT_NO_STYLE))
542#define QT_NO_SLIDER
543#endif
544
545// Spinbox control widget
546#if !defined(QT_NO_SPINWIDGET) && (defined(QT_NO_FRAME))
547#define QT_NO_SPINWIDGET
548#endif
549
550// Status bars
551#if !defined(QT_NO_STATUSBAR) && (defined(QT_NO_LAYOUT) || defined(QT_NO_STYLE))
552#define QT_NO_STATUSBAR
553#endif
554
555// Compact Windows style
556#if !defined(QT_NO_STYLE_COMPACT) && (defined(QT_NO_STYLE_WINDOWS))
557#define QT_NO_STYLE_COMPACT
558#endif
559
560// Interlace-friendly style
561#if !defined(QT_NO_STYLE_INTERLACE) && (defined(QT_NO_STYLE_MOTIF))
562#define QT_NO_STYLE_INTERLACE
563#endif
564
565// Platinum style
566#if !defined(QT_NO_STYLE_PLATINUM) && (defined(QT_NO_STYLE_WINDOWS))
567#define QT_NO_STYLE_PLATINUM
568#endif
569
570// Widget stacks
571#if !defined(QT_NO_WIDGETSTACK) && (defined(QT_NO_FRAME))
572#define QT_NO_WIDGETSTACK
573#endif
574
575// Grid layout widgets
576#if !defined(QT_NO_GRID) && (defined(QT_NO_LAYOUT) || defined(QT_NO_FRAME))
577#define QT_NO_GRID
578#endif
579
580// Group boxes
581#if !defined(QT_NO_GROUPBOX) && (defined(QT_NO_FRAME) || defined(QT_NO_LAYOUT))
582#define QT_NO_GROUPBOX
583#endif
584
585// Horizonal box layout widgets
586#if !defined(QT_NO_HBOX) && (defined(QT_NO_LAYOUT) || defined(QT_NO_FRAME))
587#define QT_NO_HBOX
588#endif
589
590// Menu-oriented widgets
591#if !defined(QT_NO_MENUDATA) && (defined(QT_NO_ICONSET) || defined(QT_NO_VARIANT))
592#define QT_NO_MENUDATA
593#endif
594
595// RichText (HTML) display
596#if !defined(QT_NO_RICHTEXT) && (defined(QT_NO_DRAWUTIL) || defined(QT_NO_LAYOUT) || defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM))
597#define QT_NO_RICHTEXT
598#endif
599
600// Splitters
601#if !defined(QT_NO_SPLITTER) && (defined(QT_NO_FRAME) || defined(QT_NO_LAYOUT))
602#define QT_NO_SPLITTER
603#endif
604
605// Table-like widgets
606#if !defined(QT_NO_TABLEVIEW) && (defined(QT_NO_SCROLLBAR))
607#define QT_NO_TABLEVIEW
608#endif
609
610// Tool tips
611#if !defined(QT_NO_TOOLTIP) && (defined(QT_NO_LABEL))
612#define QT_NO_TOOLTIP
613#endif
614
615// Cut and paste
616#if !defined(QT_NO_CLIPBOARD) && (defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME))
617#define QT_NO_CLIPBOARD
618#endif
619
620// Complex scripts (eg. BiDi)
621#if !defined(QT_NO_COMPLEXTEXT) && (defined(QT_NO_RICHTEXT))
622#define QT_NO_COMPLEXTEXT
623#endif
624
625// Horizontal group boxes
626#if !defined(QT_NO_HGROUPBOX) && (defined(QT_NO_GROUPBOX))
627#define QT_NO_HGROUPBOX
628#endif
629
630// Network file access
631#if !defined(QT_NO_NETWORKPROTOCOL) && (defined(QT_NO_DIR) || defined(QT_NO_TEXTCODEC) || defined(QT_NO_URL))
632#define QT_NO_NETWORKPROTOCOL
633#endif
634
635// Properties
636#if !defined(QT_NO_PROPERTIES) && (defined(QT_NO_VARIANT) || defined(QT_NO_STRINGLIST) || defined(QT_NO_ICONSET))
637#define QT_NO_PROPERTIES
638#endif
639
640// CDE style
641#if !defined(QT_NO_STYLE_CDE) && (defined(QT_NO_STYLE_MOTIF) || defined(QT_NO_TRANSFORMATIONS))
642#define QT_NO_STYLE_CDE
643#endif
644
645// Motif-plus style
646#if !defined(QT_NO_STYLE_MOTIFPLUS) && (defined(QT_NO_STYLE_MOTIF) || defined(QT_NO_TRANSFORMATIONS))
647#define QT_NO_STYLE_MOTIFPLUS
648#endif
649
650// SGI style
651#if !defined(QT_NO_STYLE_SGI) && (defined(QT_NO_STYLE_MOTIF) || defined(QT_NO_TRANSFORMATIONS))
652#define QT_NO_STYLE_SGI
653#endif
654
655// Vertical box layout widgets
656#if !defined(QT_NO_VBOX) && (defined(QT_NO_HBOX))
657#define QT_NO_VBOX
658#endif
659
660// Button groups
661#if !defined(QT_NO_BUTTONGROUP) && (defined(QT_NO_GROUPBOX) || defined(QT_NO_BUTTON))
662#define QT_NO_BUTTONGROUP
663#endif
664
665// Cut and paste non-text
666#if !defined(QT_NO_MIMECLIPBOARD) && (defined(QT_NO_CLIPBOARD))
667#define QT_NO_MIMECLIPBOARD
668#endif
669
670// Aqua style
671#if !defined(QT_NO_STYLE_AQUA) && (defined(QT_NO_STYLE_WINDOWS) || defined(QT_NO_IMAGE_TRANSFORMATION))
672#define QT_NO_STYLE_AQUA
673#endif
674
675// Vertical group boxes
676#if !defined(QT_NO_VGROUPBOX) && (defined(QT_NO_HGROUPBOX))
677#define QT_NO_VGROUPBOX
678#endif
679
680// Horizontal button groups
681#if !defined(QT_NO_HBUTTONGROUP) && (defined(QT_NO_BUTTONGROUP))
682#define QT_NO_HBUTTONGROUP
683#endif
684
685// Server to play sound
686#if !defined(QT_NO_QWS_SOUNDSERVER) && (defined(QT_NO_SOUND) || defined(QT_NO_DIR) || defined(QT_NO_DNS))
687#define QT_NO_QWS_SOUNDSERVER
688#endif
689
690// Hebrew Codec
691#if !defined(QT_NO_CODEC_HEBREW) && (defined(QT_NO_CODECS) || defined(QT_NO_COMPLEXTEXT))
692#define QT_NO_CODEC_HEBREW
693#endif
694
695// Dynamic module linking
696#if !defined(QT_NO_COMPONENT) && (defined(QT_NO_QUUID_STRING) || defined(QT_NO_SETTINGS) || defined(QT_NO_SPRINTF) || defined(QT_NO_LIBRARY))
697#define QT_NO_COMPONENT
698#endif
699
700// QHeader
701#if !defined(QT_NO_HEADER) && (defined(QT_NO_STYLE) || defined(QT_NO_ICONSET))
702#define QT_NO_HEADER
703#endif
704
705// Vertical button groups
706#if !defined(QT_NO_VBUTTONGROUP) && (defined(QT_NO_HBUTTONGROUP))
707#define QT_NO_VBUTTONGROUP
708#endif
709
710// Big Codecs (eg. CJK)
711#if !defined(QT_NO_BIG_CODECS) && (defined(QT_NO_CODEC_HEBREW))
712#define QT_NO_BIG_CODECS
713#endif
714
715// Tool-buttons
716#if !defined(QT_NO_TOOLBUTTON) && (defined(QT_NO_BUTTON) || defined(QT_NO_ICONSET) || defined(QT_NO_STYLE))
717#define QT_NO_TOOLBUTTON
718#endif
719
720// Document Object Model
721#if !defined(QT_NO_DOM) && (defined(QT_NO_XML) || defined(QT_NO_MIME))
722#define QT_NO_DOM
723#endif
724
725// Scrollable view widgets
726#if !defined(QT_NO_SCROLLVIEW) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_FRAME))
727#define QT_NO_SCROLLVIEW
728#endif
729
730// Tab-bars
731#if !defined(QT_NO_TABBAR) && (defined(QT_NO_TOOLBUTTON))
732#define QT_NO_TABBAR
733#endif
734
735// QTextCodecPlugin
736#if !defined(QT_NO_TEXTCODECPLUGIN) && (defined(QT_NO_COMPONENT) || defined(QT_NO_TEXTCODEC))
737#define QT_NO_TEXTCODECPLUGIN
738#endif
739
740// Drag and drop
741#if !defined(QT_NO_DRAGANDDROP) && (defined(QT_NO_MIME) || defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_IMAGEIO_XPM))
742#define QT_NO_DRAGANDDROP
743#endif
744
745// QGridView
746#if !defined(QT_NO_GRIDVIEW) && (defined(QT_NO_SCROLLVIEW))
747#define QT_NO_GRIDVIEW
748#endif
749
750// QImageFormatPlugin
751#if !defined(QT_NO_IMAGEFORMATPLUGIN) && (defined(QT_NO_COMPONENT) || defined(QT_NO_IMAGEIO))
752#define QT_NO_IMAGEFORMATPLUGIN
753#endif
754
755// Single-line edits
756#if !defined(QT_NO_LINEEDIT) && (defined(QT_NO_FRAME) || defined(QT_NO_RICHTEXT))
757#define QT_NO_LINEEDIT
758#endif
759
760// Popup-menus
761#if !defined(QT_NO_POPUPMENU) && (defined(QT_NO_MENUDATA) || defined(QT_NO_FRAME))
762#define QT_NO_POPUPMENU
763#endif
764
765// QCanvas
766#if !defined(QT_NO_CANVAS) && (defined(QT_NO_SCROLLVIEW) || defined(QT_NO_BEZIER))
767#define QT_NO_CANVAS
768#endif
769
770// QListBox
771#if !defined(QT_NO_LISTBOX) && (defined(QT_NO_SCROLLVIEW) || defined(QT_NO_STRINGLIST))
772#define QT_NO_LISTBOX
773#endif
774
775// Menu bars
776#if !defined(QT_NO_MENUBAR) && (defined(QT_NO_POPUPMENU))
777#define QT_NO_MENUBAR
778#endif
779
780// HTTP file access
781#if !defined(QT_NO_NETWORKPROTOCOL_HTTP) && (defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_DNS))
782#define QT_NO_NETWORKPROTOCOL_HTTP
783#endif
784
785// RichText (HTML) tables and images
786#if !defined(QT_NO_TEXTCUSTOMITEM) && (defined(QT_NO_RICHTEXT) || defined(QT_NO_MIME))
787#define QT_NO_TEXTCUSTOMITEM
788#endif
789
790// QDateTimeEdit
791#if !defined(QT_NO_DATETIMEEDIT) && (defined(QT_NO_RICHTEXT) || defined(QT_NO_SPINWIDGET) || defined(QT_NO_DATESTRING))
792#define QT_NO_DATETIMEEDIT
793#endif
794
795// Push-buttons
796#if !defined(QT_NO_PUSHBUTTON) && (defined(QT_NO_BUTTON) || defined(QT_NO_POPUPMENU))
797#define QT_NO_PUSHBUTTON
798#endif
799
800// FTP file access
801#if !defined(QT_NO_NETWORKPROTOCOL_FTP) && (defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_DNS) || defined(QT_NO_TEXTDATE))
802#define QT_NO_NETWORKPROTOCOL_FTP
803#endif
804
805// Scalable Vector Graphics (SVG)
806#if !defined(QT_NO_SVG) && (defined(QT_NO_DOM) || defined(QT_NO_TRANSFORMATIONS) || defined(QT_NO_SPRINTF))
807#define QT_NO_SVG
808#endif
809
810// QWidgetPlugin
811#if !defined(QT_NO_WIDGETPLUGIN) && (defined(QT_NO_COMPONENT) || defined(QT_NO_ICONSET))
812#define QT_NO_WIDGETPLUGIN
813#endif
814
815// QIconView
816#if !defined(QT_NO_ICONVIEW) && (defined(QT_NO_SCROLLVIEW) || defined(QT_NO_IMAGEIO_XPM) || defined(QT_NO_IMAGE_HEURISTIC_MASK))
817#define QT_NO_ICONVIEW
818#endif
819
820// Tab widgets
821#if !defined(QT_NO_TABWIDGET) && (defined(QT_NO_TABBAR) || defined(QT_NO_WIDGETSTACK))
822#define QT_NO_TABWIDGET
823#endif
824
825// "What's this" help
826#if !defined(QT_NO_WHATSTHIS) && (defined(QT_NO_TOOLTIP) || defined(QT_NO_TOOLBUTTON))
827#define QT_NO_WHATSTHIS
828#endif
829
830// Rich text edit
831#if !defined(QT_NO_TEXTEDIT) && (defined(QT_NO_RICHTEXT) || defined(QT_NO_SCROLLVIEW))
832#define QT_NO_TEXTEDIT
833#endif
834
835// Multi-line edits
836#if !defined(QT_NO_MULTILINEEDIT) && (defined(QT_NO_TEXTEDIT))
837#define QT_NO_MULTILINEEDIT
838#endif
839
840// QTextView
841#if !defined(QT_NO_TEXTVIEW) && (defined(QT_NO_TEXTEDIT))
842#define QT_NO_TEXTVIEW
843#endif
844
845// Spin boxes
846#if !defined(QT_NO_SPINBOX) && (defined(QT_NO_RANGECONTROL) || defined(QT_NO_SPINWIDGET) || defined(QT_NO_LINEEDIT) || defined(QT_NO_VALIDATOR))
847#define QT_NO_SPINBOX
848#endif
849
850// QMessageBox
851#if !defined(QT_NO_MESSAGEBOX) && (defined(QT_NO_DIALOG) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_LABEL))
852#define QT_NO_MESSAGEBOX
853#endif
854
855// SQL classes
856#if !defined(QT_NO_SQL) && (defined(QT_NO_MESSAGEBOX))
857#define QT_NO_SQL
858#endif
859
860// QTextBrowser
861#if !defined(QT_NO_TEXTBROWSER) && (defined(QT_NO_TEXTVIEW) || defined(QT_NO_MIME))
862#define QT_NO_TEXTBROWSER
863#endif
864
865// QProgressDialog
866#if !defined(QT_NO_PROGRESSDIALOG) && (defined(QT_NO_SEMIMODAL) || defined(QT_NO_LABEL) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_PROGRESSBAR))
867#define QT_NO_PROGRESSDIALOG
868#endif
869
870// QWizard
871#if !defined(QT_NO_WIZARD) && (defined(QT_NO_DIALOG) || defined(QT_NO_WIDGETSTACK) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL))
872#define QT_NO_WIZARD
873#endif
874
875// QSqlForm
876#if !defined(QT_NO_SQL_FORM) && (defined(QT_NO_SQL) || defined(QT_NO_PROPERTIES))
877#define QT_NO_SQL_FORM
878#endif
879
880// QListView
881#if !defined(QT_NO_LISTVIEW) && (defined(QT_NO_SCROLLVIEW) || defined(QT_NO_HEADER) || defined(QT_NO_LINEEDIT))
882#define QT_NO_LISTVIEW
883#endif
884
885// QTabDialog
886#if !defined(QT_NO_TABDIALOG) && (defined(QT_NO_DIALOG) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_LAYOUT) || defined(QT_NO_TABWIDGET))
887#define QT_NO_TABDIALOG
888#endif
889
890// QComboBox
891#if !defined(QT_NO_COMBOBOX) && (defined(QT_NO_LISTBOX) || defined(QT_NO_LINEEDIT) || defined(QT_NO_POPUPMENU))
892#define QT_NO_COMBOBOX
893#endif
894
895// Main-windows
896#if !defined(QT_NO_MAINWINDOW) && (defined(QT_NO_STRINGLIST) || defined(QT_NO_POPUPMENU) || defined(QT_NO_TITLEBAR) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_STATUSBAR))
897#define QT_NO_MAINWINDOW
898#endif
899
900// Toolbars
901#if !defined(QT_NO_TOOLBAR) && (defined(QT_NO_MAINWINDOW))
902#define QT_NO_TOOLBAR
903#endif
904
905// QColorDialog
906#if !defined(QT_NO_COLORDIALOG) && (defined(QT_NO_DIALOG) || defined(QT_NO_LABEL) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_LINEEDIT) || defined(QT_NO_VALIDATOR) || defined(QT_NO_GRIDVIEW))
907#define QT_NO_COLORDIALOG
908#endif
909
910// QErrorMessage
911#if !defined(QT_NO_ERRORMESSAGE) && (defined(QT_NO_DIALOG) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_LABEL) || defined(QT_NO_CHECKBOX) || defined(QT_NO_TEXTVIEW))
912#define QT_NO_ERRORMESSAGE
913#endif
914
915// QAction
916#if !defined(QT_NO_ACTION) && (defined(QT_NO_TOOLBUTTON) || defined(QT_NO_COMBOBOX))
917#define QT_NO_ACTION
918#endif
919
920// QWorkSpace
921#if !defined(QT_NO_WORKSPACE) && (defined(QT_NO_SCROLLBAR) || defined(QT_NO_VBOX) || defined(QT_NO_TITLEBAR) || defined(QT_NO_RESIZEHANDLER) || defined(QT_NO_POPUPMENU) || defined(QT_NO_LABEL) || defined(QT_NO_TOOLBUTTON))
922#define QT_NO_WORKSPACE
923#endif
924
925// QTable
926#if !defined(QT_NO_TABLE) && (defined(QT_NO_COMBOBOX) || defined(QT_NO_HEADER) || defined(QT_NO_CHECKBOX))
927#define QT_NO_TABLE
928#endif
929
930// QFontDialog
931#if !defined(QT_NO_FONTDIALOG) && (defined(QT_NO_DIALOG) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_COMBOBOX) || defined(QT_NO_LABEL) || defined(QT_NO_CHECKBOX) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_VGROUPBOX))
932#define QT_NO_FONTDIALOG
933#endif
934
935// QInputDialog
936#if !defined(QT_NO_INPUTDIALOG) && (defined(QT_NO_DIALOG) || defined(QT_NO_COMBOBOX) || defined(QT_NO_LABEL) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_SPINBOX) || defined(QT_NO_WIDGETSTACK))
937#define QT_NO_INPUTDIALOG
938#endif
939
940// SQL value editor widgets
941#if !defined(QT_NO_SQL_EDIT_WIDGETS) && (defined(QT_NO_SQL) || defined(QT_NO_SPINBOX) || defined(QT_NO_COMBOBOX) || defined(QT_NO_CHECKBOX) || defined(QT_NO_DATETIMEEDIT))
942#define QT_NO_SQL_EDIT_WIDGETS
943#endif
944
945// QPrintDialog
946#if !defined(QT_NO_PRINTDIALOG) && (defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_LABEL) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_SPINBOX) || defined(QT_NO_RADIOBUTTON) || defined(QT_NO_PUSHBUTTON))
947#define QT_NO_PRINTDIALOG
948#endif
949
950// QFileDialog
951#if !defined(QT_NO_FILEDIALOG) && (defined(QT_NO_MESSAGEBOX) || defined(QT_NO_LISTVIEW) || defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_SEMIMODAL) || defined(QT_NO_REGEXP_CAPTURE) || defined(QT_NO_TOOLBUTTON) || defined(QT_NO_BUTTONGROUP) || defined(QT_NO_VBOX) || defined(QT_NO_SPLITTER) || defined(QT_NO_PROGRESSBAR) || defined(QT_NO_WIDGETSTACK) || defined(QT_NO_DATESTRING))
952#define QT_NO_FILEDIALOG
953#endif
954
955// SQL table widgets
956#if !defined(QT_NO_SQL_VIEW_WIDGETS) && (defined(QT_NO_SQL_FORM) || defined(QT_NO_SQL_EDIT_WIDGETS) || defined(QT_NO_TABLE))
957#define QT_NO_SQL_VIEW_WIDGETS
958#endif
959
diff --git a/qmake/include/qfile.h b/qmake/include/qfile.h
new file mode 100644
index 0000000..14a917b
--- a/dev/null
+++ b/qmake/include/qfile.h
@@ -0,0 +1,124 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QFile class
5**
6** Created : 930831
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#ifndef QFILE_H
39#define QFILE_H
40
41#ifndef QT_H
42#include "qiodevice.h"
43#include "qstring.h"
44#include <stdio.h>
45#endif // QT_H
46
47class QDir;
48
49
50 class Q_EXPORT QFile : public QIODevice // file I/O device class
51{
52public:
53 QFile();
54 QFile( const QString &name );
55 ~QFile();
56
57 QString name()const;
58 voidsetName( const QString &name );
59
60 typedef QCString (*EncoderFn)( const QString &fileName );
61 typedef QString (*DecoderFn)( const QCString &localfileName );
62 static QCString encodeName( const QString &fileName );
63 static QString decodeName( const QCString &localFileName );
64 static void setEncodingFunction( EncoderFn );
65 static void setDecodingFunction( DecoderFn );
66
67 boolexists() const;
68 static bool exists( const QString &fileName );
69
70 boolremove();
71 static bool remove( const QString &fileName );
72
73 boolopen( int );
74 boolopen( int, FILE * );
75 boolopen( int, int );
76 voidclose();
77 voidflush();
78
79 Offsetsize() const;
80 Offsetat() const;
81 boolat( Offset );
82 boolatEnd() const;
83
84 Q_LONGreadBlock( char *data, Q_ULONG len );
85 Q_LONGwriteBlock( const char *data, Q_ULONG len );
86 Q_LONGwriteBlock( const QByteArray& data )
87 { return QIODevice::writeBlock(data); }
88 Q_LONGreadLine( char *data, Q_ULONG maxlen );
89 Q_LONGreadLine( QString &, Q_ULONG maxlen );
90
91 int getch();
92 int putch( int );
93 int ungetch( int );
94
95 int handle() const;
96
97protected:
98 QStringfn;
99 FILE *fh;
100 int fd;
101 Offsetlength;
102 boolext_f;
103 void * d;
104
105private:
106 voidinit();
107 QCStringungetchBuffer;
108
109 private:// Disabled copy constructor and operator=
110#if defined(Q_DISABLE_COPY)
111 QFile( const QFile & );
112 QFile &operator=( const QFile & );
113#endif
114};
115
116
117inline QString QFile::name() const
118{ return fn; }
119
120inline QIODevice::Offset QFile::at() const
121{ return ioIndex; }
122
123
124#endif // QFILE_H
diff --git a/qmake/include/qfileinfo.h b/qmake/include/qfileinfo.h
new file mode 100644
index 0000000..d6605b6
--- a/dev/null
+++ b/qmake/include/qfileinfo.h
@@ -0,0 +1,150 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QFILEINFO_H
39#define QFILEINFO_H
40
41#ifndef QT_H
42#include "qfile.h"
43#include "qdatetime.h"
44#endif // QT_H
45
46
47class QDir;
48struct QFileInfoCache;
49
50
51class Q_EXPORT QFileInfo
52{
53public:
54 enum PermissionSpec {
55 ReadUser = 0400, WriteUser = 0200, ExeUser = 0100,
56 ReadGroup = 0040, WriteGroup = 0020, ExeGroup = 0010,
57 ReadOther = 0004, WriteOther = 0002, ExeOther = 0001 };
58
59 QFileInfo();
60 QFileInfo( const QString &file );
61 QFileInfo( const QFile & );
62#ifndef QT_NO_DIR
63 QFileInfo( const QDir &, const QString &fileName );
64#endif
65 QFileInfo( const QFileInfo & );
66 ~QFileInfo();
67
68 QFileInfo &operator=( const QFileInfo & );
69
70 voidsetFile( const QString &file );
71 voidsetFile( const QFile & );
72#ifndef QT_NO_DIR
73 voidsetFile( const QDir &, const QString &fileName );
74#endif
75 bool exists()const;
76 void refresh()const;
77 bool caching()const;
78 voidsetCaching( bool );
79
80 QString filePath()const;
81 QString fileName()const;
82#ifndef QT_NO_DIR //###
83 QString absFilePath()const;
84#endif
85 QStringbaseName( bool complete = FALSE ) const;
86 QStringextension( bool complete = TRUE ) const;
87
88#ifndef QT_NO_DIR //###
89 QStringdirPath( bool absPath = FALSE ) const;
90#endif
91#ifndef QT_NO_DIR
92 QDir dir( bool absPath = FALSE )const;
93#endif
94 bool isReadable()const;
95 bool isWritable()const;
96 bool isExecutable()const;
97 bool isHidden() const;
98
99#ifndef QT_NO_DIR //###
100 bool isRelative()const;
101 boolconvertToAbs();
102#endif
103
104 bool isFile()const;
105 bool isDir() const;
106 bool isSymLink()const;
107
108 QString readLink()const;
109
110 QString owner() const;
111 uint ownerId()const;
112 QString group() const;
113 uint groupId()const;
114
115 boolpermission( int permissionSpec ) const;
116
117#if (QT_VERSION-0 >= 0x040000)
118#error "QFileInfo::size() should return QIODevice::Offset instead of uint"
119#elif defined(QT_ABI_QT4)
120 QIODevice::Offset size()const;
121#else
122 uint size() const;
123#endif
124
125 QDateTime created()const;
126 QDateTime lastModified()const;
127 QDateTime lastRead()const;
128
129private:
130 voiddoStat() const;
131 static void slashify( QString & );
132 static void makeAbs( QString & );
133
134 QStringfn;
135 QFileInfoCache *fic;
136 boolcache;
137#if defined(Q_OS_UNIX)
138 bool symLink;
139#endif
140
141};
142
143
144inline bool QFileInfo::caching() const
145{
146 return cache;
147}
148
149
150#endif // QFILEINFO_H
diff --git a/qmake/include/qgarray.h b/qmake/include/qgarray.h
new file mode 100644
index 0000000..12edea6
--- a/dev/null
+++ b/qmake/include/qgarray.h
@@ -0,0 +1,121 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QGARRAY_H
39#define QGARRAY_H
40
41#ifndef QT_H
42#include "qshared.h"
43#endif // QT_H
44
45
46 class Q_EXPORT QGArray // generic array
47{
48friend class QBuffer;
49public:
50 //### DO NOT USE THIS. IT IS PUBLIC BUT DO NOT USE IT IN NEW CODE.
51 struct array_data : public QShared {// shared array
52 array_data(){ data=0; len=0; }
53 char *data; // actual array data
54 uint len;
55 };
56 QGArray();
57protected:
58 QGArray( int, int ); // dummy; does not alloc
59 QGArray( int size ); // allocate 'size' bytes
60 QGArray( const QGArray &a ); // shallow copy
61 virtual ~QGArray();
62
63 QGArray &operator=( const QGArray &a ) { return assign( a ); }
64
65 virtual void detach(){ duplicate(*this); }
66
67 // ### Qt 4.0: maybe provide two versions of data(), at(), etc.
68 char *data() const{ return shd->data; }
69 uint nrefs() const{ return shd->count; }
70 uint size() const{ return shd->len; }
71 boolisEqual( const QGArray &a ) const;
72
73 boolresize( uint newsize );
74
75 boolfill( const char *d, int len, uint sz );
76
77 QGArray &assign( const QGArray &a );
78 QGArray &assign( const char *d, uint len );
79 QGArray &duplicate( const QGArray &a );
80 QGArray &duplicate( const char *d, uint len );
81 voidstore( const char *d, uint len );
82
83 array_data *sharedBlock() const { return shd; }
84 voidsetSharedBlock( array_data *p ) { shd=(array_data*)p; }
85
86 QGArray &setRawData( const char *d, uint len );
87 voidresetRawData( const char *d, uint len );
88
89 int find( const char *d, uint index, uint sz ) const;
90 int contains( const char *d, uint sz ) const;
91
92 voidsort( uint sz );
93 int bsearch( const char *d, uint sz ) const;
94
95 char *at( uint index ) const;
96
97 boolsetExpand( uint index, const char *d, uint sz );
98
99protected:
100 virtual array_data *newData();
101 virtual void deleteData( array_data *p );
102
103private:
104 static void msg_index( uint );
105 array_data *shd;
106};
107
108
109inline char *QGArray::at( uint index ) const
110{
111#if defined(QT_CHECK_RANGE)
112 if ( index >= size() ) {
113 msg_index( index );
114 index = 0;
115 }
116#endif
117 return &shd->data[index];
118}
119
120
121#endif // QGARRAY_H
diff --git a/qmake/include/qgcache.h b/qmake/include/qgcache.h
new file mode 100644
index 0000000..093f7a7
--- a/dev/null
+++ b/qmake/include/qgcache.h
@@ -0,0 +1,128 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QGCACHE_H
39#define QGCACHE_H
40
41#ifndef QT_H
42#include "qptrcollection.h"
43#include "qglist.h"
44#include "qgdict.h"
45#endif // QT_H
46
47
48 class QCList; // internal classes
49class QCListIt;
50class QCDict;
51
52
53 class Q_EXPORT QGCache : public QPtrCollection// generic LRU cache
54{
55friend class QGCacheIterator;
56protected:
57 enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
58 // identical to QGDict's, but PtrKey is not used at the moment
59
60 QGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
61 bool copyKeys );
62 QGCache( const QGCache & ); // not allowed, calls fatal()
63 ~QGCache();
64 QGCache &operator=( const QGCache & );// not allowed, calls fatal()
65
66 uint count()const;
67 uint size()const;
68 int maxCost() const{ return mCost; }
69 int totalCost() const{ return tCost; }
70 void setMaxCost( int maxCost );
71 void clear();
72
73 bool insert_string( const QString &key, QPtrCollection::Item,
74 int cost, int priority );
75 bool insert_other( const char *key, QPtrCollection::Item,
76 int cost, int priority );
77 bool remove_string( const QString &key );
78 bool remove_other( const char *key );
79 QPtrCollection::Item take_string( const QString &key );
80 QPtrCollection::Item take_other( const char *key );
81
82 QPtrCollection::Item find_string( const QString &key, bool ref=TRUE ) const;
83 QPtrCollection::Item find_other( const char *key, bool ref=TRUE ) const;
84
85 void statistics() const;
86
87private:
88 bool makeRoomFor( int cost, int priority = -1 );
89 KeyType keytype;
90 QCList *lruList;
91 QCDict *dict;
92 int mCost;
93 int tCost;
94 bool copyk;
95};
96
97
98 class Q_EXPORT QGCacheIterator // generic cache iterator
99{
100protected:
101 QGCacheIterator( const QGCache & );
102 QGCacheIterator( const QGCacheIterator & );
103 ~QGCacheIterator();
104 QGCacheIterator &operator=( const QGCacheIterator & );
105
106 uint count() const;
107 bool atFirst() const;
108 bool atLast() const;
109 QPtrCollection::Item toFirst();
110 QPtrCollection::Item toLast();
111
112 QPtrCollection::Item get() const;
113 QString getKeyString() const;
114 const char *getKeyAscii() const;
115 long getKeyInt() const;
116
117 QPtrCollection::Item operator()();
118 QPtrCollection::Item operator++();
119 QPtrCollection::Item operator+=( uint );
120 QPtrCollection::Item operator--();
121 QPtrCollection::Item operator-=( uint );
122
123protected:
124 QCListIt *it; // iterator on cache list
125};
126
127
128#endif // QGCACHE_H
diff --git a/qmake/include/qgdict.h b/qmake/include/qgdict.h
new file mode 100644
index 0000000..40b4568
--- a/dev/null
+++ b/qmake/include/qgdict.h
@@ -0,0 +1,222 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QGDICT_H
39#define QGDICT_H
40
41#ifndef QT_H
42#include "qptrcollection.h"
43#include "qstring.h"
44#endif // QT_H
45
46class QGDictIterator;
47class QGDItList;
48
49
50 class QBaseBucket // internal dict node
51{
52public:
53 QPtrCollection::Item getData() { return data; }
54 QPtrCollection::Item setData( QPtrCollection::Item d ) { return data = d; }
55 QBaseBucket *getNext() { return next; }
56 void setNext( QBaseBucket *n){ next = n; }
57protected:
58 QBaseBucket( QPtrCollection::Item d, QBaseBucket *n ) : data(d), next(n) {}
59 QPtrCollection::Item data;
60 QBaseBucket *next;
61};
62
63class QStringBucket : public QBaseBucket
64{
65public:
66 QStringBucket( const QString &k, QPtrCollection::Item d, QBaseBucket *n )
67 : QBaseBucket(d,n), key(k) {}
68 const QString &getKey() const { return key; }
69private:
70 QString key;
71};
72
73class QAsciiBucket : public QBaseBucket
74{
75public:
76 QAsciiBucket( const char *k, QPtrCollection::Item d, QBaseBucket *n )
77 : QBaseBucket(d,n), key(k) {}
78 const char *getKey() const { return key; }
79private:
80 const char *key;
81};
82
83class QIntBucket : public QBaseBucket
84{
85public:
86 QIntBucket( long k, QPtrCollection::Item d, QBaseBucket *n )
87 : QBaseBucket(d,n), key(k) {}
88 long getKey() const { return key; }
89private:
90 long key;
91};
92
93class QPtrBucket : public QBaseBucket
94{
95public:
96 QPtrBucket( void *k, QPtrCollection::Item d, QBaseBucket *n )
97 : QBaseBucket(d,n), key(k) {}
98 void *getKey() const { return key; }
99private:
100 void *key;
101};
102
103
104 class Q_EXPORT QGDict : public QPtrCollection// generic dictionary class
105{
106public:
107 uint count() const{ return numItems; }
108 uint size() const{ return vlen; }
109 QPtrCollection::Item look_string( const QString& key, QPtrCollection::Item,
110 int );
111 QPtrCollection::Item look_ascii( const char *key, QPtrCollection::Item, int );
112 QPtrCollection::Item look_int( long key, QPtrCollection::Item, int );
113 QPtrCollection::Item look_ptr( void *key, QPtrCollection::Item, int );
114#ifndef QT_NO_DATASTREAM
115 QDataStream &read( QDataStream & );
116 QDataStream &write( QDataStream & ) const;
117#endif
118protected:
119 enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
120
121 QGDict( uint len, KeyType kt, bool cs, bool ck );
122 QGDict( const QGDict & );
123 ~QGDict();
124
125 QGDict &operator=( const QGDict & );
126
127 boolremove_string( const QString &key, QPtrCollection::Item item=0 );
128 boolremove_ascii( const char *key, QPtrCollection::Item item=0 );
129 boolremove_int( long key, QPtrCollection::Item item=0 );
130 boolremove_ptr( void *key, QPtrCollection::Item item=0 );
131 QPtrCollection::Item take_string( const QString &key );
132 QPtrCollection::Item take_ascii( const char *key );
133 QPtrCollection::Item take_int( long key );
134 QPtrCollection::Item take_ptr( void *key );
135
136 voidclear();
137 voidresize( uint );
138
139 int hashKeyString( const QString & );
140 int hashKeyAscii( const char * );
141
142 voidstatistics() const;
143
144#ifndef QT_NO_DATASTREAM
145 virtual QDataStream &read( QDataStream &, QPtrCollection::Item & );
146 virtual QDataStream &write( QDataStream &, QPtrCollection::Item ) const;
147#endif
148private:
149 QBaseBucket **vec;
150 uintvlen;
151 uintnumItems;
152 uint keytype: 2;
153 uint cases: 1;
154 uint copyk: 1;
155 QGDItList *iterators;
156 void unlink_common( int, QBaseBucket *, QBaseBucket * );
157 QStringBucket *unlink_string( const QString &,
158 QPtrCollection::Item item = 0 );
159 QAsciiBucket *unlink_ascii( const char *, QPtrCollection::Item item = 0 );
160 QIntBucket *unlink_int( long, QPtrCollection::Item item = 0 );
161 QPtrBucket *unlink_ptr( void *, QPtrCollection::Item item = 0 );
162 voidinit( uint, KeyType, bool, bool );
163 friend class QGDictIterator;
164};
165
166
167 class Q_EXPORT QGDictIterator // generic dictionary iterator
168{
169friend class QGDict;
170public:
171 QGDictIterator( const QGDict & );
172 QGDictIterator( const QGDictIterator & );
173 QGDictIterator &operator=( const QGDictIterator & );
174 ~QGDictIterator();
175
176 QPtrCollection::Item toFirst();
177
178 QPtrCollection::Item get() const;
179 QString getKeyString() const;
180 const char *getKeyAscii() const;
181 long getKeyInt() const;
182 void *getKeyPtr() const;
183
184 QPtrCollection::Item operator()();
185 QPtrCollection::Item operator++();
186 QPtrCollection::Item operator+=(uint);
187
188protected:
189 QGDict *dict;
190
191private:
192 QBaseBucket *curNode;
193 uint curIndex;
194};
195
196inline QPtrCollection::Item QGDictIterator::get() const
197{
198 return curNode ? curNode->getData() : 0;
199}
200
201inline QString QGDictIterator::getKeyString() const
202{
203 return curNode ? ((QStringBucket*)curNode)->getKey() : QString::null;
204}
205
206inline const char *QGDictIterator::getKeyAscii() const
207{
208 return curNode ? ((QAsciiBucket*)curNode)->getKey() : 0;
209}
210
211inline long QGDictIterator::getKeyInt() const
212{
213 return curNode ? ((QIntBucket*)curNode)->getKey() : 0;
214}
215
216inline void *QGDictIterator::getKeyPtr() const
217{
218 return curNode ? ((QPtrBucket*)curNode)->getKey() : 0;
219}
220
221
222#endif // QGDICT_H
diff --git a/qmake/include/qglist.h b/qmake/include/qglist.h
new file mode 100644
index 0000000..d6db3ed
--- a/dev/null
+++ b/qmake/include/qglist.h
@@ -0,0 +1,252 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QGLIST_H
39#define QGLIST_H
40
41#ifndef QT_H
42#include "qptrcollection.h"
43#endif // QT_H
44
45class Q_EXPORT QLNode
46{
47friend class QGList;
48friend class QGListIterator;
49public:
50 QPtrCollection::Item getData(){ return data; }
51private:
52 QPtrCollection::Item data;
53 QLNode *prev;
54 QLNode *next;
55 QLNode( QPtrCollection::Item d ) { data = d; }
56};
57
58class QGListIteratorList; // internal helper class
59
60 class Q_EXPORT QGList : public QPtrCollection// doubly linked generic list
61{
62friend class QGListIterator;
63friend class QGListIteratorList;
64 friend class QGVector; // needed by QGVector::toList
65public:
66 uint count() const; // return number of nodes
67
68#ifndef QT_NO_DATASTREAM
69 QDataStream &read( QDataStream & ); // read list from stream
70 QDataStream &write( QDataStream & ) const;// write list to stream
71#endif
72protected:
73 QGList(); // create empty list
74 QGList( const QGList & ); // make copy of other list
75 virtual ~QGList();
76
77 QGList &operator=( const QGList & );// assign from other list
78 bool operator==( const QGList& ) const;
79
80 void inSort( QPtrCollection::Item ); // add item sorted in list
81 void append( QPtrCollection::Item ); // add item at end of list
82 bool insertAt( uint index, QPtrCollection::Item ); // add item at i'th position
83 void relinkNode( QLNode * ); // relink as first item
84 bool removeNode( QLNode * ); // remove node
85 bool remove( QPtrCollection::Item = 0 );// remove item (0=current)
86 bool removeRef( QPtrCollection::Item = 0 );// remove item (0=current)
87 bool removeFirst(); // remove first item
88 bool removeLast(); // remove last item
89 bool removeAt( uint ); // remove item at i'th position
90 bool replaceAt( uint, QPtrCollection::Item ); // replace item at position i with item
91 QPtrCollection::Item takeNode( QLNode * );// take out node
92 QPtrCollection::Item take(); // take out current item
93 QPtrCollection::Item takeAt( uint index );// take out item at i'th pos
94 QPtrCollection::Item takeFirst(); // take out first item
95 QPtrCollection::Item takeLast(); // take out last item
96
97 void sort(); // sort all items;
98 void clear(); // remove all items
99
100 int findRef( QPtrCollection::Item, bool = TRUE ); // find exact item in list
101 int find( QPtrCollection::Item, bool = TRUE ); // find equal item in list
102
103 uint containsRef( QPtrCollection::Item ) const;// get number of exact matches
104 uint contains( QPtrCollection::Item ) const;// get number of equal matches
105
106 QPtrCollection::Item at( uint index );// access item at i'th pos
107 int at() const; // get current index
108 QLNode *currentNode() const; // get current node
109
110 QPtrCollection::Item get() const; // get current item
111
112 QPtrCollection::Item cfirst() const;// get ptr to first list item
113 QPtrCollection::Item clast() const;// get ptr to last list item
114 QPtrCollection::Item first(); // set first item in list curr
115 QPtrCollection::Item last(); // set last item in list curr
116 QPtrCollection::Item next(); // set next item in list curr
117 QPtrCollection::Item prev(); // set prev item in list curr
118
119 void toVector( QGVector * ) const; // put items in vector
120
121 virtual int compareItems( QPtrCollection::Item, QPtrCollection::Item );
122
123#ifndef QT_NO_DATASTREAM
124 virtual QDataStream &read( QDataStream &, QPtrCollection::Item & );
125 virtual QDataStream &write( QDataStream &, QPtrCollection::Item ) const;
126#endif
127private:
128 void prepend( QPtrCollection::Item );// add item at start of list
129
130 void heapSortPushDown( QPtrCollection::Item* heap, int first, int last );
131
132 QLNode *firstNode; // first node
133 QLNode *lastNode; // last node
134 QLNode *curNode; // current node
135 int curIndex; // current index
136 uint numNodes; // number of nodes
137 QGListIteratorList *iterators; // list of iterators
138
139 QLNode *locate( uint ); // get node at i'th pos
140 QLNode *unlink(); // unlink node
141};
142
143
144inline uint QGList::count() const
145{
146 return numNodes;
147}
148
149inline bool QGList::removeFirst()
150{
151 first();
152 return remove();
153}
154
155inline bool QGList::removeLast()
156{
157 last();
158 return remove();
159}
160
161inline int QGList::at() const
162{
163 return curIndex;
164}
165
166inline QPtrCollection::Item QGList::at( uint index )
167{
168 QLNode *n = locate( index );
169 return n ? n->data : 0;
170}
171
172inline QLNode *QGList::currentNode() const
173{
174 return curNode;
175}
176
177inline QPtrCollection::Item QGList::get() const
178{
179 return curNode ? curNode->data : 0;
180}
181
182inline QPtrCollection::Item QGList::cfirst() const
183{
184 return firstNode ? firstNode->data : 0;
185}
186
187inline QPtrCollection::Item QGList::clast() const
188{
189 return lastNode ? lastNode->data : 0;
190}
191
192
193/*****************************************************************************
194 QGList stream functions
195 *****************************************************************************/
196
197#ifndef QT_NO_DATASTREAM
198Q_EXPORT QDataStream &operator>>( QDataStream &, QGList & );
199Q_EXPORT QDataStream &operator<<( QDataStream &, const QGList & );
200#endif
201
202/*****************************************************************************
203 QGListIterator class
204 *****************************************************************************/
205
206 class Q_EXPORT QGListIterator // QGList iterator
207{
208friend class QGList;
209friend class QGListIteratorList;
210protected:
211 QGListIterator( const QGList & );
212 QGListIterator( const QGListIterator & );
213 QGListIterator &operator=( const QGListIterator & );
214 ~QGListIterator();
215
216 bool atFirst() const; // test if at first item
217 bool atLast() const; // test if at last item
218 QPtrCollection::Item toFirst(); // move to first item
219 QPtrCollection::Item toLast(); // move to last item
220
221 QPtrCollection::Item get() const; // get current item
222 QPtrCollection::Item operator()(); // get current and move to next
223 QPtrCollection::Item operator++(); // move to next item (prefix)
224 QPtrCollection::Item operator+=(uint); // move n positions forward
225 QPtrCollection::Item operator--(); // move to prev item (prefix)
226 QPtrCollection::Item operator-=(uint); // move n positions backward
227
228protected:
229 QGList *list; // reference to list
230
231private:
232 QLNode *curNode; // current node in list
233};
234
235
236inline bool QGListIterator::atFirst() const
237{
238 return curNode == list->firstNode;
239}
240
241inline bool QGListIterator::atLast() const
242{
243 return curNode == list->lastNode;
244}
245
246inline QPtrCollection::Item QGListIterator::get() const
247{
248 return curNode ? curNode->data : 0;
249}
250
251
252 #endif// QGLIST_H
diff --git a/qmake/include/qglobal.h b/qmake/include/qglobal.h
new file mode 100644
index 0000000..13cff64
--- a/dev/null
+++ b/qmake/include/qglobal.h
@@ -0,0 +1,1006 @@
1/****************************************************************************
2** $Id$
3**
4** Global type declarations and definitions
5**
6** Created : 920529
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#ifndef QGLOBAL_H
39#define QGLOBAL_H
40
41#define QT_VERSION_STR "3.1.0-b2"
42/*
43 QT_VERSION is (major << 16) + (minor << 8) + patch.
44 */
45#define QT_VERSION 0x030100
46
47/*
48 The operating system, must be one of: (Q_OS_x)
49
50 MACX- Mac OS X
51 MAC9- Mac OS 9
52 MSDOS- MS-DOS and Windows
53 OS2- OS/2
54 OS2EMX- XFree86 on OS/2 (not PM)
55 WIN32- Win32 (Windows 95/98/ME and Windows NT/2000/XP)
56 CYGWIN- Cygwin
57 SOLARIS- Sun Solaris
58 HPUX- HP-UX
59 ULTRIX- DEC Ultrix
60 LINUX- Linux
61 FREEBSD- FreeBSD
62 NETBSD- NetBSD
63 OPENBSD- OpenBSD
64 BSDI- BSD/OS
65 IRIX- SGI Irix
66 OSF- HP Tru64 UNIX
67 SCO- SCO OpenServer 5
68 UNIXWARE- UnixWare 7, Open UNIX 8
69 AIX- AIX
70 HURD- GNU Hurd
71 DGUX- DG/UX
72 RELIANT- Reliant UNIX
73 DYNIX- DYNIX/ptx
74 QNX- QNX
75 QNX6- QNX RTP 6.1
76 LYNX- LynxOS
77 BSD4- Any BSD 4.4 system
78 UNIX- Any UNIX BSD/SYSV system
79*/
80
81#if defined(__APPLE__) && defined(__GNUC__)
82# define Q_OS_MACX
83#elif defined(__MACOSX__)
84# define Q_OS_MACX
85#elif defined(macintosh)
86# define Q_OS_MAC9
87#elif defined(__CYGWIN__)
88# define Q_OS_CYGWIN
89#elif defined(MSDOS) || defined(_MSDOS)
90# define Q_OS_MSDOS
91#elif defined(__OS2__)
92# if defined(__EMX__)
93# define Q_OS_OS2EMX
94# else
95# define Q_OS_OS2
96# endif
97#elif !defined(SAG_COM) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
98# define Q_OS_WIN32
99# define Q_OS_WIN64
100#elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
101# define Q_OS_WIN32
102#elif defined(__MWERKS__) && defined(__INTEL__)
103# define Q_OS_WIN32
104#elif defined(__sun) || defined(sun)
105# define Q_OS_SOLARIS
106#elif defined(hpux) || defined(__hpux)
107# define Q_OS_HPUX
108#elif defined(__ultrix) || defined(ultrix)
109# define Q_OS_ULTRIX
110#elif defined(sinix)
111# define Q_OS_RELIANT
112#elif defined(__linux__) || defined(__linux)
113# define Q_OS_LINUX
114#elif defined(__FreeBSD__)
115# define Q_OS_FREEBSD
116# define Q_OS_BSD4
117#elif defined(__NetBSD__)
118# define Q_OS_NETBSD
119# define Q_OS_BSD4
120#elif defined(__OpenBSD__)
121# define Q_OS_OPENBSD
122# define Q_OS_BSD4
123#elif defined(__bsdi__)
124# define Q_OS_BSDI
125# define Q_OS_BSD4
126#elif defined(__sgi)
127# define Q_OS_IRIX
128#elif defined(__osf__)
129# define Q_OS_OSF
130#elif defined(_AIX)
131# define Q_OS_AIX
132#elif defined(__Lynx__)
133# define Q_OS_LYNX
134#elif defined(__GNU_HURD__)
135# define Q_OS_HURD
136#elif defined(__DGUX__)
137# define Q_OS_DGUX
138#elif defined(__QNXNTO__)
139# define Q_OS_QNX6
140#elif defined(__QNX__)
141# define Q_OS_QNX
142#elif defined(_SEQUENT_)
143# define Q_OS_DYNIX
144#elif defined(_SCO_DS) /* SCO OpenServer 5 */
145# define Q_OS_SCO
146#elif defined(__UNIXWARE__) /* UnixWare 7 + GCC, Open UNIX 8 + GCC */
147# define Q_OS_UNIXWARE
148# define Q_OS_UNIXWARE7
149#elif defined(__USLC__) /* UnixWare 7 + UDK, Open UNIX 8 + OUDK */
150# define Q_OS_UNIXWARE
151# define Q_OS_UNIXWARE7
152#else
153# error "Qt has not been ported to this OS - talk to qt-bugs@trolltech.com"
154#endif
155
156#if defined(Q_OS_MAC9) || defined(Q_OS_MACX)
157# define Q_OS_MAC
158#endif
159
160#if defined(Q_OS_MAC9) || defined(Q_OS_MSDOS) || defined(Q_OS_OS2) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
161# undef Q_OS_UNIX
162#elif !defined(Q_OS_UNIX)
163# define Q_OS_UNIX
164#endif
165
166
167/*
168 The compiler, must be one of: (Q_CC_x)
169
170 SYM- Symantec C++ for both PC and Macintosh
171 MPW- MPW C++
172 MWERKS- Metrowerks CodeWarrior
173 MSVC- Microsoft Visual C/C++
174 BOR- Borland/Turbo C++
175 WAT- Watcom C++
176 GNU- GNU C++
177 COMEAU- Comeau C++
178 EDG- Edison Design Group C++
179 OC - CenterLine C++
180 SUN- Sun WorkShop, Forte Developer, or Sun ONE Studio C++
181 MIPS- MIPSpro C++
182 DEC- DEC C++
183 HP - HPUX C++
184 HPACC- HPUX ANSI C++
185 USLC- SCO OUDK, UDK, and UnixWare 2.X C++
186 CDS- Reliant C++
187 KAI- KAI C++
188 INTEL- Intel C++
189 HIGHC- MetaWare High C/C++
190 PGI- Portland Group C++
191 GHS- Green Hills Optimizing C++ Compilers
192
193 Should be sorted most to least authoritative.
194*/
195
196/* Symantec C++ is now Digital Mars */
197#if defined(__DMC__) || defined(__SC__)
198# define Q_CC_SYM
199/* "explicit" semantics implemented in 8.1e but keyword recognized since 7.5 */
200# if defined(__SC__) && __SC__ < 0x750
201# define Q_NO_EXPLICIT_KEYWORD
202# endif
203# define Q_NO_USING_KEYWORD
204# if !defined(_CPPUNWIND)
205# define Q_NO_EXCEPTIONS
206# endif
207
208#elif defined(applec)
209# define Q_CC_MPW
210# define Q_NO_BOOL_TYPE
211# define Q_NO_EXPLICIT_KEYWORD
212# define Q_NO_USING_KEYWORD
213
214#elif defined(__MWERKS__)
215# define Q_CC_MWERKS
216/* "explicit" recognized since 4.0d1 */
217# define QMAC_PASCAL pascal
218# define Q_NO_USING_KEYWORD /* ### check "using" status */
219
220#elif defined(_MSC_VER)
221# define Q_CC_MSVC
222/* proper support of bool for _MSC_VER >= 1100 */
223# define Q_CANNOT_DELETE_CONSTANT
224# define Q_INLINE_TEMPLATES inline
225/* Visual C++.Net issues for _MSC_VER >= 1300 */
226# if _MSC_VER >= 1300
227# define Q_CC_MSVC_NET
228# define Q_TYPENAME
229# endif
230# define Q_NO_USING_KEYWORD /* ### check "using" status */
231
232#elif defined(__BORLANDC__) || defined(__TURBOC__)
233# define Q_CC_BOR
234# if __BORLANDC__ < 0x502
235# define Q_NO_BOOL_TYPE
236# define Q_NO_EXPLICIT_KEYWORD
237# endif
238# define Q_NO_USING_KEYWORD /* ### check "using" status */
239
240#elif defined(__WATCOMC__)
241# define Q_CC_WAT
242# if defined(Q_OS_QNX4)
243/* compiler flags */
244# define Q_TYPENAME
245# define Q_NO_BOOL_TYPE
246# define Q_CANNOT_DELETE_CONSTANT
247# define mutable
248/* ??? */
249# define Q_BROKEN_TEMPLATE_SPECIALIZATION
250/* no template classes in QVariant */
251# define QT_NO_TEMPLATE_VARIANT
252/* Wcc does not fill in functions needed by valuelists, maps, and
253 valuestacks implicitly */
254# define Q_FULL_TEMPLATE_INSTANTIATION
255/* can we just compare the structures? */
256# define Q_FULL_TEMPLATE_INSTANTIATION_MEMCMP
257/* these are not useful to our customers */
258# define QT_QWS_NO_SHM
259# define QT_NO_QWS_MULTIPROCESS
260# define QT_NO_SQL
261# define QT_NO_QWS_CURSOR
262# endif
263
264#elif defined(__GNUC__)
265# define Q_CC_GNU
266# define Q_C_CALLBACKS
267# if __GNUC__ == 2 && __GNUC_MINOR__ <= 7
268# define Q_FULL_TEMPLATE_INSTANTIATION
269# endif
270/* GCC 2.95 knows "using" but does not support it correctly */
271# if __GNUC__ == 2 && __GNUC_MINOR__ <= 95
272# define Q_NO_USING_KEYWORD
273# endif
274# if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP)
275# define Q_PACKED __attribute__ ((packed))
276# endif
277# if !defined(__EXCEPTIONS)
278# define Q_NO_EXCEPTIONS
279# endif
280
281/* IBM compiler versions are a bit messy. There are actually two products:
282 the C product, and the C++ product. The C++ compiler is always packaged
283 with the latest version of the C compiler. Version numbers do not always
284 match. This little table (I'm not sure it's accurate) should be helpful:
285
286 C++ product C product
287
288 C Set 3.1 C Compiler 3.0
289 ... ...
290 C++ Compiler 3.6.6 C Compiler 4.3
291 ... ...
292 Visual Age C++ 4.0 ...
293 ... ...
294 Visual Age C++ 5.0 C Compiler 5.0
295
296 Now:
297 __xlC__ is the version of the C compiler in hexadecimal notation
298 is only an approximation of the C++ compiler version
299 __IBMCPP__ is the version of the C++ compiler in decimal notation
300 but it is not defined on older compilers like C Set 3.1 */
301#elif defined(__xlC__)
302# define Q_CC_XLC
303# define Q_FULL_TEMPLATE_INSTANTIATION
304# if __xlC__ < 0x400
305# define Q_NO_BOOL_TYPE
306# define Q_NO_EXPLICIT_KEYWORD
307# define Q_NO_USING_KEYWORD
308# define Q_TYPENAME
309# define Q_INLINE_TEMPLATES inline
310# define Q_BROKEN_TEMPLATE_SPECIALIZATION
311# define Q_CANNOT_DELETE_CONSTANT
312# endif
313
314/* Older versions of DEC C++ do not define __EDG__ or __EDG - observed
315 on DEC C++ V5.5-004. New versions do define __EDG__ - observed on
316 Compaq C++ V6.3-002.
317 This compiler is different enough from other EDG compilers to handle
318 it separately anyway. */
319#elif defined(__DECCXX)
320# define Q_CC_DEC
321/* Compaq C++ V6 compilers are EDG-based but I'm not sure about older
322 DEC C++ V5 compilers. */
323# if defined(__EDG__)
324# define Q_CC_EDG
325# endif
326/* Compaq have disabled EDG's _BOOL macro and use _BOOL_EXISTS instead
327 - observed on Compaq C++ V6.3-002.
328 In any case versions prior to Compaq C++ V6.0-005 do not have bool. */
329# if !defined(_BOOL_EXISTS)
330# define Q_NO_BOOL_TYPE
331# endif
332/* Spurious (?) error messages observed on Compaq C++ V6.5-014. */
333# define Q_NO_USING_KEYWORD
334/* Apply to all versions prior to Compaq C++ V6.0-000 - observed on
335 DEC C++ V5.5-004. */
336# if __DECCXX_VER < 60060000
337# define Q_TYPENAME
338# define Q_BROKEN_TEMPLATE_SPECIALIZATION
339# define Q_CANNOT_DELETE_CONSTANT
340# endif
341/* avoid undefined symbol problems with out-of-line template members */
342# define Q_INLINE_TEMPLATES inline
343
344/* Compilers with EDG front end are similar. To detect them we test:
345 __EDG documented by SGI, observed on MIPSpro 7.3.1.1 and KAI C++ 4.0b
346 __EDG__ documented in EDG online docs, observed on Compaq C++ V6.3-002 */
347#elif defined(__EDG) || defined(__EDG__)
348# define Q_CC_EDG
349/* From the EDG documentation (does not seem to apply to Compaq C++):
350 _BOOL
351 Defined in C++ mode when bool is a keyword. The name of this
352 predefined macro is specified by a configuration flag. _BOOL
353 is the default.
354 __BOOL_DEFINED
355 Defined in Microsoft C++ mode when bool is a keyword. */
356# if !defined(_BOOL) && !defined(__BOOL_DEFINED)
357# define Q_NO_BOOL_TYPE
358# endif
359
360/* The Portland Group compiler is based on EDG and does define __EDG__ */
361# if defined(__COMO__)
362# define Q_CC_COMEAU
363# define Q_C_CALLBACKS
364
365/* Using the `using' keyword avoids KAI C++ warnings */
366# elif defined(__KCC)
367# define Q_CC_KAI
368# if !defined(_EXCEPTIONS)
369# define Q_NO_EXCEPTIONS
370# endif
371
372/* Using the `using' keyword avoids Intel C++ warnings */
373# elif defined(__INTEL_COMPILER)
374# define Q_CC_INTEL
375# if !defined(__EXCEPTIONS)
376# define Q_NO_EXCEPTIONS
377# endif
378
379/* The Portland Group compiler is based on EDG and does define __EDG__ */
380# elif defined(__PGI)
381# define Q_CC_PGI
382# if !defined(__EXCEPTIONS)
383# define Q_NO_EXCEPTIONS
384# endif
385
386/* Never tested! */
387# elif defined(__ghs)
388# define Q_CC_GHS
389
390/* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */
391# elif defined(__USLC__) && defined(__SCO_VERSION__)
392# define Q_CC_USLC
393# define Q_NO_USING_KEYWORD /* ### check "using" status */
394
395/* Never tested! */
396# elif defined(CENTERLINE_CLPP) || defined(OBJECTCENTER)
397# define Q_CC_OC
398# define Q_NO_USING_KEYWORD
399
400/* CDS++ is not documented to define __EDG__ or __EDG in the Reliant
401 documentation but we suppose it does, in any case it does follow
402 conventions like _BOOL */
403# elif defined(sinix)
404# define Q_CC_CDS
405# define Q_NO_USING_KEYWORD
406# if defined(__cplusplus) && (__cplusplus < 2) /* Cfront C++ mode */
407# define Q_NO_EXCEPTIONS
408# endif
409
410/* The MIPSpro compiler in o32 mode is based on EDG but disables features
411 such as template specialization nevertheless */
412# elif defined(__sgi)
413# define Q_CC_MIPS
414# if defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32) /* o32 ABI */
415# define Q_TYPENAME
416# define Q_BROKEN_TEMPLATE_SPECIALIZATION
417# define Q_STRICT_INLINING_RULES
418# elif defined(_COMPILER_VERSION) && (_COMPILER_VERSION < 730) /* 7.2 */
419# define Q_TYPENAME
420# define Q_BROKEN_TEMPLATE_SPECIALIZATION
421# endif
422# define Q_NO_USING_KEYWORD /* ### check "using" status */
423# endif
424
425/* The older UnixWare 2.X compiler? */
426#elif defined(__USLC__) && !defined(__SCO_VERSION__)
427# define Q_CC_USLC
428# define Q_NO_BOOL_TYPE
429# define Q_NO_EXPLICIT_KEYWORD
430# define Q_NO_USING_KEYWORD
431
432/* Never tested! */
433#elif defined(__HIGHC__)
434# define Q_CC_HIGHC
435
436#elif defined(__SUNPRO_CC)
437# define Q_CC_SUN
438/* 5.0 compiler or better
439 'bool' is enabled by default but can be disabled using -features=nobool
440 in which case _BOOL is not defined
441 this is the default in 4.2 compatibility mode triggered by -compat=4 */
442# if __SUNPRO_CC >= 0x500
443# if !defined(_BOOL)
444# define Q_NO_BOOL_TYPE
445# endif
446# if defined(__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT <= 4)
447# define Q_NO_USING_KEYWORD
448# endif
449# define Q_C_CALLBACKS
450/* 4.2 compiler or older */
451# else
452# define Q_NO_BOOL_TYPE
453# define Q_NO_EXPLICIT_KEYWORD
454# define Q_NO_USING_KEYWORD
455# endif
456
457#elif defined(Q_OS_HPUX)
458/* __HP_aCC was not defined in first aCC releases */
459# if defined(__HP_aCC) || __cplusplus >= 199707L
460# define Q_CC_HPACC
461# else
462# define Q_CC_HP
463# define Q_NO_BOOL_TYPE
464# define Q_FULL_TEMPLATE_INSTANTIATION
465# define Q_BROKEN_TEMPLATE_SPECIALIZATION
466# define Q_NO_EXPLICIT_KEYWORD
467# endif
468# define Q_NO_USING_KEYWORD /* ### check "using" status */
469
470#else
471# error "Qt has not been tested with this compiler - talk to qt-bugs@trolltech.com"
472#endif
473
474#ifndef Q_PACKED
475# define Q_PACKED
476#endif
477
478
479/*
480 The window system, must be one of: (Q_WS_x)
481
482 MACX- Mac OS X
483 MAC9- Mac OS 9
484 QWS- Qt/Embedded
485 WIN32- Windows
486 X11- X Window System
487 PM - unsupported
488 WIN16- unsupported
489*/
490
491#if defined(Q_OS_MAC9)
492# define Q_WS_MAC9
493#elif defined(Q_OS_MSDOS)
494# define Q_WS_WIN16
495# error "Qt requires Win32 and does not work with Windows 3.x"
496#elif defined(_WIN32_X11_)
497# define Q_WS_X11
498#elif defined(Q_OS_WIN32)
499# define Q_WS_WIN32
500# if defined(Q_OS_WIN64)
501# define Q_WS_WIN64
502# endif
503#elif defined(Q_OS_OS2)
504# define Q_WS_PM
505# error "Qt does not work with OS/2 Presentation Manager or Workplace Shell"
506#elif defined(Q_OS_UNIX)
507# if defined(QWS)
508# define Q_WS_QWS
509# elif defined(Q_OS_MACX)
510# define Q_WS_MACX
511# else
512# define Q_WS_X11
513# endif
514#endif
515#if defined(Q_OS_MAC) && !defined(QMAC_PASCAL)
516# define QMAC_PASCAL
517#endif
518
519#if defined(Q_WS_WIN16) || defined(Q_WS_WIN32)
520# define Q_WS_WIN
521#endif
522
523#if (defined(Q_WS_MAC9) || defined(Q_WS_MACX)) && !defined(Q_WS_QWS) && !defined(Q_WS_X11)
524# define Q_WS_MAC
525#endif
526
527
528/*
529 Some classes do not permit copies to be made of an object.
530 These classes contains a private copy constructor and operator=
531 to disable copying (the compiler gives an error message).
532 Undefine Q_DISABLE_COPY to turn off this checking.
533*/
534
535#define Q_DISABLE_COPY
536
537#if defined(__cplusplus)
538
539
540//
541// Useful type definitions for Qt
542//
543
544#if defined(Q_NO_BOOL_TYPE)
545#if defined(Q_CC_HP)
546// bool is an unsupported reserved keyword in later versions
547#define bool int
548#else
549typedef int bool;
550#endif
551#endif
552
553typedef unsigned char uchar;
554typedef unsigned short ushort;
555 typedef unsigneduint;
556typedef unsigned long ulong;
557 typedef char *pchar;
558 typedef uchar *puchar;
559typedef const char *pcchar;
560
561
562//
563// Constant bool values
564//
565
566#ifndef TRUE
567const bool FALSE = 0;
568const bool TRUE = !0;
569#endif
570#if defined(__WATCOMC__)
571# if defined(Q_OS_QNX4)
572const bool false = FALSE;
573const bool true = TRUE;
574# endif
575#endif
576
577
578//
579// Use the "explicit" keyword on platforms that support it.
580//
581
582#if !defined(Q_NO_EXPLICIT_KEYWORD)
583# define Q_EXPLICIT explicit
584#else
585# define Q_EXPLICIT
586#endif
587
588
589//
590// Workaround for static const members on MSVC++.
591//
592
593#if defined(Q_CC_MSVC)
594# define QT_STATIC_CONST static
595# define QT_STATIC_CONST_IMPL
596#else
597# define QT_STATIC_CONST static const
598# define QT_STATIC_CONST_IMPL const
599#endif
600
601
602//
603// Utility macros and inline functions
604//
605
606 #define QMAX(a, b)((b) < (a) ? (a) : (b))
607 #define QMIN(a, b)((a) < (b) ? (a) : (b))
608 #define QABS(a)((a) >= 0 ? (a) : -(a))
609
610inline int qRound( double d )
611{
612 return d >= 0.0 ? int(d + 0.5) : int( d - ((int)d-1) + 0.5 ) + ((int)d-1);
613}
614
615
616//
617// Size-dependent types (architechture-dependent byte order)
618//
619
620#if !defined(QT_CLEAN_NAMESPACE)
621// source compatibility with Qt 1.x
622 typedef signed char INT8; // 8 bit signed
623 typedef unsigned char UINT8; // 8 bit unsigned
624 typedef short INT16; // 16 bit signed
625 typedef unsigned short UINT16; // 16 bit unsigned
626 typedef int INT32; // 32 bit signed
627 typedef unsigned int UINT32; // 32 bit unsigned
628#endif
629
630 typedef signed char Q_INT8; // 8 bit signed
631 typedef unsigned char Q_UINT8;// 8 bit unsigned
632 typedef short Q_INT16;// 16 bit signed
633 typedef unsigned short Q_UINT16;// 16 bit unsigned
634 typedef int Q_INT32;// 32 bit signed
635 typedef unsigned int Q_UINT32;// 32 bit unsigned
636#if defined(Q_OS_WIN64)
637// LLP64 64-bit model on Windows
638 typedef __int64 Q_LONG; // word up to 64 bit signed
639 typedef unsigned __int64 Q_ULONG;// word up to 64 bit unsigned
640#else
641// LP64 64-bit model on Linux
642 typedef long Q_LONG;
643 typedef unsigned long Q_ULONG;
644#endif
645
646#if !defined(QT_CLEAN_NAMESPACE)
647// mininum size of 64 bits is not guaranteed
648 #define Q_INT64 Q_LONG
649 #define Q_UINT64 Q_ULONG
650#endif
651
652#if defined(Q_OS_MACX) && !defined(QT_LARGEFILE_SUPPORT)
653# define QT_LARGEFILE_SUPPORT 64
654#endif
655#if defined(QT_LARGEFILE_SUPPORT)
656 typedef unsigned long long QtOffset;
657#else
658 typedef Q_ULONG QtOffset;
659#endif
660
661
662//
663// Data stream functions is provided by many classes (defined in qdatastream.h)
664//
665
666class QDataStream;
667
668
669//
670// Feature subsetting
671//
672// Note that disabling some features will produce a libqt that is not
673// compatible with other libqt builds. Such modifications are only
674// supported on Qt/Embedded where reducing the library size is important
675// and where the application-suite is often a fixed set.
676//
677
678#if !defined(QT_MOC)
679#if defined(QCONFIG_LOCAL)
680#include <qconfig-local.h>
681#elif defined(QCONFIG_MINIMAL)
682#include <qconfig-minimal.h>
683#elif defined(QCONFIG_SMALL)
684#include <qconfig-small.h>
685#elif defined(QCONFIG_MEDIUM)
686#include <qconfig-medium.h>
687#elif defined(QCONFIG_LARGE)
688#include <qconfig-large.h>
689#else // everything...
690#include <qconfig.h>
691#endif
692#endif
693
694
695#ifndef QT_BUILD_KEY
696#define QT_BUILD_KEY "unspecified"
697#endif
698
699// prune to local config
700#include "qmodules.h"
701#ifndef QT_MODULE_ICONVIEW
702# define QT_NO_ICONVIEW
703#endif
704#ifndef QT_MODULE_WORKSPACE
705# define QT_NO_WORKSPACE
706#endif
707#ifndef QT_MODULE_NETWORK
708#define QT_NO_NETWORK
709#endif
710#ifndef QT_MODULE_CANVAS
711# define QT_NO_CANVAS
712#endif
713#ifndef QT_MODULE_TABLE
714#define QT_NO_TABLE
715#endif
716#ifndef QT_MODULE_XML
717# define QT_NO_XML
718#endif
719#ifndef QT_MODULE_OPENGL
720# define QT_NO_OPENGL
721#endif
722#if !defined(QT_MODULE_SQL)
723# define QT_NO_SQL
724#endif
725
726#if defined(Q_WS_MAC9)
727//No need for menu merging
728# ifndef QMAC_QMENUBAR_NO_MERGE
729# define QMAC_QMENUBAR_NO_MERGE
730# endif
731//Mac9 does not use quartz
732# ifndef QMAC_NO_QUARTZ
733# define QMAC_NO_QUARTZ
734# endif
735# ifndef QMAC_QMENUBAR_NO_EVENT
736# define QMAC_QMENUBAR_NO_EVENT
737# endif
738#endif
739#if defined(Q_WS_MACX) //for no nobody uses quartz, just putting in first level hooks
740# ifndef QMAC_NO_QUARTZ
741# define QMAC_NO_QUARTZ
742# endif
743# ifndef QMAC_QMENUBAR_NO_EVENT
744# define QMAC_QMENUBAR_NO_EVENT
745# endif
746#endif
747
748#ifndef QT_H
749#include <qfeatures.h>
750#endif // QT_H
751
752
753//
754// Create Qt DLL if QT_DLL is defined (Windows only)
755//
756
757#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
758# if defined(QT_NODLL)
759# undef QT_MAKEDLL
760# undef QT_DLL
761 # elif defined(QT_MAKEDLL)/* create a Qt DLL library */
762# if defined(QT_DLL)
763# undef QT_DLL
764# endif
765# define Q_EXPORT __declspec(dllexport)
766# define Q_TEMPLATEDLL
767# define Q_TEMPLATE_EXTERN
768 # undef Q_DISABLE_COPY/* avoid unresolved externals */
769 # elif defined(QT_DLL) /* use a Qt DLL library */
770# define Q_EXPORT __declspec(dllimport)
771# define Q_TEMPLATEDLL
772# ifndef Q_TEMPLATE_EXTERN
773# if defined(Q_CC_MSVC)
774# define Q_TEMPLATE_EXTERN /*extern*/ //### too many warnings, even though disabled
775# else
776# define Q_TEMPLATE_EXTERN
777# endif
778# endif
779# undef Q_DISABLE_COPY /* avoid unresolved externals */
780# endif
781#else
782 # undef QT_MAKEDLL /* ignore these for other platforms */
783# undef QT_DLL
784#endif
785
786#ifndef Q_EXPORT
787# define Q_EXPORT
788#endif
789
790
791//
792// Some platform specific stuff
793//
794
795#if defined(Q_WS_WIN)
796extern Q_EXPORT bool qt_winunicode;
797#endif
798
799
800//
801// System information
802//
803
804Q_EXPORT const char *qVersion();
805Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian );
806#if defined(Q_WS_WIN)
807Q_EXPORT int qWinVersion();
808#if defined(UNICODE)
809#define QT_WA( uni, ansi ) if ( qt_winunicode ) { uni } else { ansi }
810#define QT_WA_INLINE( uni, ansi ) ( qt_winunicode ? uni : ansi )
811#else
812#define QT_WA( uni, ansi ) ansi
813#define QT_WA_INLINE( uni, ansi ) ansi
814#endif
815#endif
816
817#ifdef Q_OS_TEMP
818#ifdef QT_WA
819#undef QT_WA
820#undef QT_WA_INLINE
821#endif
822#define QT_WA( uni, ansi ) uni
823#define QT_WA_INLINE( uni, ansi ) ( uni )
824#endif
825
826#ifndef Q_INLINE_TEMPLATES
827# define Q_INLINE_TEMPLATES
828#endif
829
830#ifndef Q_TYPENAME
831# define Q_TYPENAME typename
832#endif
833
834//
835// Use to avoid "unused parameter" warnings
836//
837
838#define Q_UNUSED(x) (void)x;
839
840//
841// Debugging and error handling
842//
843
844#if !defined(QT_NO_CHECK)
845 # define QT_CHECK_STATE // check state of objects etc.
846 # define QT_CHECK_RANGE // check range of indexes etc.
847 # define QT_CHECK_NULL // check null pointers
848 # define QT_CHECK_MATH // check math functions
849#endif
850
851#if !defined(QT_NO_DEBUG) && !defined(QT_DEBUG)
852 # define QT_DEBUG // display debug messages
853 # if !defined(QT_NO_COMPAT) // compatibility with Qt 2
854# if !defined(NO_DEBUG) && !defined(DEBUG)
855 # if !defined(Q_OS_MACX) // clash with MacOS X headers
856# define DEBUG
857# endif
858# endif
859# endif
860#endif
861
862
863 Q_EXPORT void qDebug( const char *, ... )// print debug message
864#if defined(Q_CC_GNU) && !defined(__INSURE__)
865 __attribute__ ((format (printf, 1, 2)))
866#endif
867;
868
869 Q_EXPORT void qWarning( const char *, ... )// print warning message
870#if defined(Q_CC_GNU) && !defined(__INSURE__)
871 __attribute__ ((format (printf, 1, 2)))
872#endif
873;
874
875 Q_EXPORT void qFatal( const char *, ... )// print fatal message and exit
876#if defined(Q_CC_GNU)
877 __attribute__ ((format (printf, 1, 2)))
878#endif
879;
880
881Q_EXPORT void qSystemWarning( const char *, int code = -1 );
882
883 #if !defined(QT_CLEAN_NAMESPACE) // compatibility with Qt 1
884
885 Q_EXPORT void debug( const char *, ... )// print debug message
886#if defined(Q_CC_GNU) && !defined(__INSURE__)
887 __attribute__ ((format (printf, 1, 2)))
888#endif
889;
890
891 Q_EXPORT void warning( const char *, ... )// print warning message
892#if defined(Q_CC_GNU) && !defined(__INSURE__)
893 __attribute__ ((format (printf, 1, 2)))
894#endif
895;
896
897 Q_EXPORT void fatal( const char *, ... )// print fatal message and exit
898#if defined(Q_CC_GNU) && !defined(__INSURE__)
899 __attribute__ ((format (printf, 1, 2)))
900#endif
901;
902
903#endif // QT_CLEAN_NAMESPACE
904
905
906#if !defined(Q_ASSERT)
907# if defined(QT_CHECK_STATE)
908# if defined(QT_FATAL_ASSERT)
909# define Q_ASSERT(x) ((x) ? (void)0 : qFatal("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__))
910# else
911# define Q_ASSERT(x) ((x) ? (void)0 : qWarning("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__))
912# endif
913# else
914# define Q_ASSERT(x)
915# endif
916#endif
917
918 #if !defined(QT_NO_COMPAT) // compatibility with Qt 2
919# if !defined(ASSERT)
920# if !defined(Q_OS_TEMP)
921# define ASSERT(x) Q_ASSERT(x)
922# endif
923# endif
924#endif // QT_NO_COMPAT
925
926
927Q_EXPORT bool qt_check_pointer( bool c, const char *, int );
928
929#if defined(QT_CHECK_NULL)
930# define Q_CHECK_PTR(p) (qt_check_pointer((p)==0,__FILE__,__LINE__))
931#else
932# define Q_CHECK_PTR(p)
933#endif
934
935 #if !defined(QT_NO_COMPAT) // compatibility with Qt 2
936# if !defined(CHECK_PTR)
937# define CHECK_PTR(x) Q_CHECK_PTR(x)
938# endif
939#endif // QT_NO_COMPAT
940
941enum QtMsgType { QtDebugMsg, QtWarningMsg, QtFatalMsg };
942
943typedef void (*QtMsgHandler)(QtMsgType, const char *);
944Q_EXPORT QtMsgHandler qInstallMsgHandler( QtMsgHandler );
945
946 #if !defined(QT_NO_COMPAT) // compatibility with Qt 2
947typedef QtMsgHandler msg_handler;
948#endif // QT_NO_COMPAT
949
950Q_EXPORT void qSuppressObsoleteWarnings( bool = TRUE );
951
952Q_EXPORT void qObsolete( const char *obj, const char *oldfunc,
953 const char *newfunc );
954Q_EXPORT void qObsolete( const char *obj, const char *oldfunc );
955Q_EXPORT void qObsolete( const char *message );
956
957
958//
959// Install paths from configure
960//
961
962Q_EXPORT const char *qInstallPath();
963Q_EXPORT const char *qInstallPathDocs();
964Q_EXPORT const char *qInstallPathHeaders();
965Q_EXPORT const char *qInstallPathLibs();
966Q_EXPORT const char *qInstallPathBins();
967Q_EXPORT const char *qInstallPathPlugins();
968Q_EXPORT const char *qInstallPathData();
969
970#endif // __cplusplus
971
972#endif // QGLOBAL_H
973
974//
975// Avoid some particularly useless warnings from some stupid compilers.
976// To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out
977// the line "#define QT_NO_WARNINGS"
978//
979
980#if !defined(QT_CC_WARNINGS)
981# define QT_NO_WARNINGS
982#endif
983#if defined(QT_NO_WARNINGS)
984# if defined(Q_CC_MSVC)
985# pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
986# pragma warning(disable: 4275) // non - DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier'
987# pragma warning(disable: 4514) // unreferenced inline/local function has been removed
988# pragma warning(disable: 4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning)
989# pragma warning(disable: 4097) // typedef-name 'identifier1' used as synonym for class-name 'identifier2'
990# pragma warning(disable: 4706) // assignment within conditional expression
991# pragma warning(disable: 4786) // truncating debug info after 255 characters
992# pragma warning(disable: 4660) // template-class specialization 'identifier' is already instantiated
993# pragma warning(disable: 4355) // 'this' : used in base member initializer list
994# pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation
995# elif defined(Q_CC_BOR)
996# pragma option -w-inl
997# pragma option -w-aus
998# pragma warn -inl
999# pragma warn -pia
1000# pragma warn -ccc
1001# pragma warn -rch
1002# pragma warn -sig
1003# elif defined(Q_CC_MWERKS)
1004# pragma warn_possunwant off
1005# endif
1006#endif
diff --git a/qmake/include/qgvector.h b/qmake/include/qgvector.h
new file mode 100644
index 0000000..6e8bdfc
--- a/dev/null
+++ b/qmake/include/qgvector.h
@@ -0,0 +1,121 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QGVECTOR_H
39#define QGVECTOR_H
40
41#ifndef QT_H
42#include "qptrcollection.h"
43#endif // QT_H
44
45
46 class Q_EXPORT QGVector : public QPtrCollection// generic vector
47{
48 friend class QGList; // needed by QGList::toVector
49public:
50#ifndef QT_NO_DATASTREAM
51 QDataStream &read( QDataStream & ); // read vector from stream
52 QDataStream &write( QDataStream & ) const;// write vector to stream
53#endif
54 virtual int compareItems( Item, Item );
55
56protected:
57 QGVector(); // create empty vector
58 QGVector( uint size ); // create vector with nullptrs
59 QGVector( const QGVector &v ); // make copy of other vector
60 ~QGVector();
61
62 QGVector &operator=( const QGVector &v );// assign from other vector
63 bool operator==( const QGVector &v ) const;
64
65 Item *data() const{ return vec; }
66 uint size() const{ return len; }
67 uint count() const{ return numItems; }
68
69 bool insert( uint index, Item ); // insert item at index
70 bool remove( uint index ); // remove item
71 Item take( uint index ); // take out item
72
73 void clear(); // clear vector
74 bool resize( uint newsize ); // resize vector
75
76 bool fill( Item, int flen ); // resize and fill vector
77
78 void sort(); // sort vector
79 int bsearch( Item ) const; // binary search (when sorted)
80
81 int findRef( Item, uint index ) const;// find exact item in vector
82 int find( Item, uint index ) const;// find equal item in vector
83 uint containsRef( Item ) const; // get number of exact matches
84 uint contains( Item ) const; // get number of equal matches
85
86 Item at( uint index ) const // return indexed item
87 {
88#if defined(QT_CHECK_RANGE)
89 if ( index >= len )
90 warningIndexRange( index );
91#endif
92 return vec[index];
93 }
94
95 bool insertExpand( uint index, Item );// insert, expand if necessary
96
97 void toList( QGList * ) const; // put items in list
98
99#ifndef QT_NO_DATASTREAM
100 virtual QDataStream &read( QDataStream &, Item & );
101 virtual QDataStream &write( QDataStream &, Item ) const;
102#endif
103private:
104 Item *vec;
105 uint len;
106 uint numItems;
107
108 static void warningIndexRange( uint );
109};
110
111
112/*****************************************************************************
113 QGVector stream functions
114 *****************************************************************************/
115
116#ifndef QT_NO_DATASTREAM
117Q_EXPORT QDataStream &operator>>( QDataStream &, QGVector & );
118Q_EXPORT QDataStream &operator<<( QDataStream &, const QGVector & );
119#endif
120
121#endif // QGVECTOR_H
diff --git a/qmake/include/qintdict.h b/qmake/include/qintdict.h
new file mode 100644
index 0000000..b4cb223
--- a/dev/null
+++ b/qmake/include/qintdict.h
@@ -0,0 +1,114 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QIntDict template class
5**
6** Created : 940624
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#ifndef QINTDICT_H
39#define QINTDICT_H
40
41#ifndef QT_H
42#include "qgdict.h"
43#endif // QT_H
44
45template<class type>
46class QIntDict
47#ifdef Q_QDOC
48 : public QPtrCollection
49#else
50 : public QGDict
51#endif
52{
53public:
54 QIntDict(int size=17) : QGDict(size,IntKey,0,0) {}
55 QIntDict( const QIntDict<type> &d ) : QGDict(d) {}
56 ~QIntDict() { clear(); }
57 QIntDict<type> &operator=(const QIntDict<type> &d)
58 { return (QIntDict<type>&)QGDict::operator=(d); }
59 uint count() const { return QGDict::count(); }
60 uint size() const { return QGDict::size(); }
61 bool isEmpty() const { return QGDict::count() == 0; }
62 void insert( long k, const type *d )
63 { QGDict::look_int(k,(Item)d,1); }
64 void replace( long k, const type *d )
65 { QGDict::look_int(k,(Item)d,2); }
66 bool remove( long k ) { return QGDict::remove_int(k); }
67 type *take( long k ) { return (type*)QGDict::take_int(k); }
68 type *find( long k ) const
69 { return (type *)((QGDict*)this)->QGDict::look_int(k,0,0); }
70 type *operator[]( long k ) const
71 { return (type *)((QGDict*)this)->QGDict::look_int(k,0,0); }
72 void clear() { QGDict::clear(); }
73 void resize( uint n ) { QGDict::resize(n); }
74 void statistics() const { QGDict::statistics(); }
75
76#ifdef Q_QDOC
77protected:
78 virtual QDataStream& read( QDataStream &, QPtrCollection::Item & );
79 virtual QDataStream& write( QDataStream &, QPtrCollection::Item ) const;
80#endif
81
82private:
83 void deleteItem( Item d );
84};
85
86#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION)
87template<> inline void QIntDict<void>::deleteItem( QPtrCollection::Item )
88{
89}
90#endif
91
92template<class type> inline void QIntDict<type>::deleteItem( QPtrCollection::Item d )
93{
94 if ( del_item ) delete (type*)d;
95}
96
97template<class type>
98class QIntDictIterator : public QGDictIterator
99{
100public:
101 QIntDictIterator(const QIntDict<type> &d) :QGDictIterator((QGDict &)d) {}
102 ~QIntDictIterator() {}
103 uint count() const { return dict->count(); }
104 bool isEmpty() const { return dict->count() == 0; }
105 type *toFirst() { return (type *)QGDictIterator::toFirst(); }
106 operator type *() const { return (type *)QGDictIterator::get(); }
107 type *current() const { return (type *)QGDictIterator::get(); }
108 long currentKey() const { return QGDictIterator::getKeyInt(); }
109 type *operator()() { return (type *)QGDictIterator::operator()(); }
110 type *operator++() { return (type *)QGDictIterator::operator++(); }
111 type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
112};
113
114#endif // QINTDICT_H
diff --git a/qmake/include/qiodevice.h b/qmake/include/qiodevice.h
new file mode 100644
index 0000000..cb83463
--- a/dev/null
+++ b/qmake/include/qiodevice.h
@@ -0,0 +1,161 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QIODEVICE_H
39#define QIODEVICE_H
40
41#ifndef QT_H
42#include "qglobal.h"
43#include "qcstring.h"
44#endif // QT_H
45
46
47// IO device access types
48
49 #define IO_Direct 0x0100 // direct access device
50 #define IO_Sequential 0x0200 // sequential access device
51 #define IO_Combined 0x0300 // combined direct/sequential
52 #define IO_TypeMask 0x0f00
53
54// IO handling modes
55
56 #define IO_Raw 0x0040 // raw access (not buffered)
57 #define IO_Async 0x0080 // asynchronous mode
58
59// IO device open modes
60
61 #define IO_ReadOnly 0x0001 // readable device
62 #define IO_WriteOnly 0x0002 // writable device
63 #define IO_ReadWrite 0x0003 // read+write device
64 #define IO_Append 0x0004 // append
65 #define IO_Truncate 0x0008 // truncate device
66 #define IO_Translate 0x0010 // translate CR+LF
67 #define IO_ModeMask 0x00ff
68
69// IO device state
70
71 #define IO_Open 0x1000 // device is open
72 #define IO_StateMask 0xf000
73
74// IO device status
75
76 #define IO_Ok 0
77 #define IO_ReadError 1 // read error
78 #define IO_WriteError 2 // write error
79 #define IO_FatalError 3 // fatal unrecoverable error
80 #define IO_ResourceError 4 // resource limitation
81 #define IO_OpenError 5 // cannot open device
82 #define IO_ConnectError 5 // cannot connect to device
83 #define IO_AbortError 6 // abort error
84 #define IO_TimeOutError 7 // time out
85 #define IO_UnspecifiedError 8 // unspecified error
86
87
88class Q_EXPORT QIODevice
89{
90public:
91#if defined(QT_ABI_64BITOFFSET)
92 typedef QtOffset Offset;
93#else
94 typedef Q_ULONG Offset;
95#endif
96
97 QIODevice();
98 virtual ~QIODevice();
99
100 int flags() const { return ioMode; }
101 int mode() const { return ioMode & IO_ModeMask; }
102 int state() const { return ioMode & IO_StateMask; }
103
104 bool isDirectAccess() const { return ((ioMode & IO_Direct) == IO_Direct); }
105 bool isSequentialAccess() const { return ((ioMode & IO_Sequential) == IO_Sequential); }
106 bool isCombinedAccess() const { return ((ioMode & IO_Combined) == IO_Combined); }
107 bool isBuffered() const { return ((ioMode & IO_Raw) != IO_Raw); }
108 bool isRaw() const { return ((ioMode & IO_Raw) == IO_Raw); }
109 bool isSynchronous() const { return ((ioMode & IO_Async) != IO_Async); }
110 bool isAsynchronous() const { return ((ioMode & IO_Async) == IO_Async); }
111 bool isTranslated() const { return ((ioMode & IO_Translate) == IO_Translate); }
112 bool isReadable() const { return ((ioMode & IO_ReadOnly) == IO_ReadOnly); }
113 bool isWritable() const { return ((ioMode & IO_WriteOnly) == IO_WriteOnly); }
114 bool isReadWrite() const { return ((ioMode & IO_ReadWrite) == IO_ReadWrite); }
115 bool isInactive() const { return state() == 0; }
116 bool isOpen() const { return state() == IO_Open; }
117
118 int status() const { return ioSt; }
119 void resetStatus(){ ioSt = IO_Ok; }
120
121 virtual bool open( int mode ) = 0;
122 virtual void close() = 0;
123 virtual void flush() = 0;
124
125 virtual Offset size() const = 0;
126 virtual Offset at() const;
127 virtual bool at( Offset );
128 virtual bool atEnd() const;
129 bool reset() { return at(0); }
130
131 virtual Q_LONG readBlock( char *data, Q_ULONG maxlen ) = 0;
132 virtual Q_LONG writeBlock( const char *data, Q_ULONG len ) = 0;
133 virtual Q_LONG readLine( char *data, Q_ULONG maxlen );
134 Q_LONG writeBlock( const QByteArray& data );
135 virtual QByteArray readAll();
136
137 virtual int getch() = 0;
138 virtual int putch( int ) = 0;
139 virtual int ungetch( int ) = 0;
140
141protected:
142 void setFlags( int f ) { ioMode = f; }
143 void setType( int );
144 void setMode( int );
145 void setState( int );
146 void setStatus( int );
147 Offset ioIndex;
148
149private:
150 int ioMode;
151 int ioSt;
152
153 private:// Disabled copy constructor and operator=
154#if defined(Q_DISABLE_COPY)
155 QIODevice( const QIODevice & );
156 QIODevice &operator=( const QIODevice & );
157#endif
158};
159
160
161#endif // QIODEVICE_H
diff --git a/qmake/include/qmap.h b/qmake/include/qmap.h
new file mode 100644
index 0000000..269bd6b
--- a/dev/null
+++ b/qmake/include/qmap.h
@@ -0,0 +1,883 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QMap class
5**
6** Created : 990406
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#ifndef QMAP_H
39#define QMAP_H
40
41#ifndef QT_H
42#include "qglobal.h"
43#include "qshared.h"
44#include "qdatastream.h"
45#include "qpair.h"
46#include "qvaluelist.h"
47#endif // QT_H
48
49#ifndef QT_NO_STL
50#include <iterator>
51#include <map>
52#endif
53
54//#define QT_CHECK_MAP_RANGE
55
56struct Q_EXPORT QMapNodeBase
57{
58 enum Color { Red, Black };
59
60 QMapNodeBase* left;
61 QMapNodeBase* right;
62 QMapNodeBase* parent;
63
64 Color color;
65
66 QMapNodeBase* minimum() {
67 QMapNodeBase* x = this;
68 while ( x->left )
69 x = x->left;
70 return x;
71 }
72
73 QMapNodeBase* maximum() {
74 QMapNodeBase* x = this;
75 while ( x->right )
76 x = x->right;
77 return x;
78 }
79};
80
81
82template <class K, class T>
83struct QMapNode : public QMapNodeBase
84{
85 QMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
86 QMapNode( const K& _key ) { key = _key; }
87 QMapNode( const QMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
88 QMapNode() { }
89 T data;
90 K key;
91};
92
93
94template<class K, class T>
95class QMapIterator
96{
97 public:
98 /**
99 * Typedefs
100 */
101 typedef QMapNode< K, T >* NodePtr;
102#ifndef QT_NO_STL
103 typedef std::bidirectional_iterator_tag iterator_category;
104#endif
105 typedef T value_type;
106#ifndef QT_NO_STL
107 typedef ptrdiff_t difference_type;
108#else
109 typedef int difference_type;
110#endif
111 typedef T* pointer;
112 typedef T& reference;
113
114 /**
115 * Variables
116 */
117 QMapNode<K,T>* node;
118
119 /**
120 * Functions
121 */
122 QMapIterator() : node( 0 ) {}
123 QMapIterator( QMapNode<K,T>* p ) : node( p ) {}
124 QMapIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
125
126 bool operator==( const QMapIterator<K,T>& it ) const { return node == it.node; }
127 bool operator!=( const QMapIterator<K,T>& it ) const { return node != it.node; }
128 T& operator*() { return node->data; }
129 const T& operator*() const { return node->data; }
130 // UDT for T = x*
131 // T* operator->() const { return &node->data; }
132
133 const K& key() const { return node->key; }
134 T& data() { return node->data; }
135 const T& data() const { return node->data; }
136
137private:
138 int inc();
139 int dec();
140
141public:
142 QMapIterator<K,T>& operator++() {
143 inc();
144 return *this;
145 }
146
147 QMapIterator<K,T> operator++(int) {
148 QMapIterator<K,T> tmp = *this;
149 inc();
150 return tmp;
151 }
152
153 QMapIterator<K,T>& operator--() {
154 dec();
155 return *this;
156 }
157
158 QMapIterator<K,T> operator--(int) {
159 QMapIterator<K,T> tmp = *this;
160 dec();
161 return tmp;
162 }
163};
164
165template <class K, class T>
166Q_INLINE_TEMPLATES int QMapIterator<K,T>::inc()
167{
168 QMapNodeBase* tmp = node;
169 if ( tmp->right ) {
170 tmp = tmp->right;
171 while ( tmp->left )
172 tmp = tmp->left;
173 } else {
174 QMapNodeBase* y = tmp->parent;
175 while (tmp == y->right) {
176 tmp = y;
177 y = y->parent;
178 }
179 if (tmp->right != y)
180 tmp = y;
181 }
182 node = (NodePtr)tmp;
183 return 0;
184}
185
186template <class K, class T>
187Q_INLINE_TEMPLATES int QMapIterator<K,T>::dec()
188{
189 QMapNodeBase* tmp = node;
190 if (tmp->color == QMapNodeBase::Red &&
191 tmp->parent->parent == tmp ) {
192 tmp = tmp->right;
193 } else if (tmp->left != 0) {
194 QMapNodeBase* y = tmp->left;
195 while ( y->right )
196 y = y->right;
197 tmp = y;
198 } else {
199 QMapNodeBase* y = tmp->parent;
200 while (tmp == y->left) {
201 tmp = y;
202 y = y->parent;
203 }
204 tmp = y;
205 }
206 node = (NodePtr)tmp;
207 return 0;
208}
209
210template<class K, class T>
211class QMapConstIterator
212{
213 public:
214 /**
215 * Typedefs
216 */
217 typedef QMapNode< K, T >* NodePtr;
218#ifndef QT_NO_STL
219 typedef std::bidirectional_iterator_tag iterator_category;
220#endif
221 typedef T value_type;
222#ifndef QT_NO_STL
223 typedef ptrdiff_t difference_type;
224#else
225 typedef int difference_type;
226#endif
227 typedef const T* pointer;
228 typedef const T& reference;
229
230
231 /**
232 * Variables
233 */
234 QMapNode<K,T>* node;
235
236 /**
237 * Functions
238 */
239 QMapConstIterator() : node( 0 ) {}
240 QMapConstIterator( QMapNode<K,T>* p ) : node( p ) {}
241 QMapConstIterator( const QMapConstIterator<K,T>& it ) : node( it.node ) {}
242 QMapConstIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
243
244 bool operator==( const QMapConstIterator<K,T>& it ) const { return node == it.node; }
245 bool operator!=( const QMapConstIterator<K,T>& it ) const { return node != it.node; }
246 const T& operator*() const { return node->data; }
247 // UDT for T = x*
248 // const T* operator->() const { return &node->data; }
249
250 const K& key() const { return node->key; }
251 const T& data() const { return node->data; }
252
253private:
254 int inc();
255 int dec();
256
257public:
258 QMapConstIterator<K,T>& operator++() {
259 inc();
260 return *this;
261 }
262
263 QMapConstIterator<K,T> operator++(int) {
264 QMapConstIterator<K,T> tmp = *this;
265 inc();
266 return tmp;
267 }
268
269 QMapConstIterator<K,T>& operator--() {
270 dec();
271 return *this;
272 }
273
274 QMapConstIterator<K,T> operator--(int) {
275 QMapConstIterator<K,T> tmp = *this;
276 dec();
277 return tmp;
278 }
279};
280
281template <class K, class T>
282Q_INLINE_TEMPLATES int QMapConstIterator<K,T>::inc()
283{
284 QMapNodeBase* tmp = node;
285 if ( tmp->right ) {
286 tmp = tmp->right;
287 while ( tmp->left )
288 tmp = tmp->left;
289 } else {
290 QMapNodeBase* y = tmp->parent;
291 while (tmp == y->right) {
292 tmp = y;
293 y = y->parent;
294 }
295 if (tmp->right != y)
296 tmp = y;
297 }
298 node = (NodePtr)tmp;
299 return 0;
300}
301
302template <class K, class T>
303Q_INLINE_TEMPLATES int QMapConstIterator<K,T>::dec()
304{
305 QMapNodeBase* tmp = node;
306 if (tmp->color == QMapNodeBase::Red &&
307 tmp->parent->parent == tmp ) {
308 tmp = tmp->right;
309 } else if (tmp->left != 0) {
310 QMapNodeBase* y = tmp->left;
311 while ( y->right )
312 y = y->right;
313 tmp = y;
314 } else {
315 QMapNodeBase* y = tmp->parent;
316 while (tmp == y->left) {
317 tmp = y;
318 y = y->parent;
319 }
320 tmp = y;
321 }
322 node = (NodePtr)tmp;
323 return 0;
324}
325
326class Q_EXPORT QMapPrivateBase : public QShared
327{
328public:
329 QMapPrivateBase() {
330 node_count = 0;
331 }
332 QMapPrivateBase( const QMapPrivateBase* _map) {
333 node_count = _map->node_count;
334 }
335
336 /**
337 * Implementations of basic tree algorithms
338 */
339 void rotateLeft( QMapNodeBase* x, QMapNodeBase*& root);
340 void rotateRight( QMapNodeBase* x, QMapNodeBase*& root );
341 void rebalance( QMapNodeBase* x, QMapNodeBase*& root );
342 QMapNodeBase* removeAndRebalance( QMapNodeBase* z, QMapNodeBase*& root,
343 QMapNodeBase*& leftmost,
344 QMapNodeBase*& rightmost );
345
346 /**
347 * Variables
348 */
349 int node_count;
350};
351
352
353template <class Key, class T>
354class QMapPrivate : public QMapPrivateBase
355{
356public:
357 /**
358 * Typedefs
359 */
360 typedef QMapIterator< Key, T > Iterator;
361 typedef QMapConstIterator< Key, T > ConstIterator;
362 typedef QMapNode< Key, T > Node;
363 typedef QMapNode< Key, T >* NodePtr;
364
365 /**
366 * Functions
367 */
368 QMapPrivate();
369 QMapPrivate( const QMapPrivate< Key, T >* _map );
370 ~QMapPrivate() { clear(); delete header; }
371
372 NodePtr copy( NodePtr p );
373 void clear();
374 void clear( NodePtr p );
375
376 Iterator begin(){ return Iterator( (NodePtr)(header->left ) ); }
377 Iterator end(){ return Iterator( header ); }
378 ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
379 ConstIterator end() const { return ConstIterator( header ); }
380
381 ConstIterator find(const Key& k) const;
382
383 void remove( Iterator it ) {
384 NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right );
385 delete del;
386 --node_count;
387 }
388
389#ifdef QT_QMAP_DEBUG
390 void inorder( QMapNodeBase* x = 0, int level = 0 ){
391 if ( !x )
392 x = header->parent;
393 if ( x->left )
394 inorder( x->left, level + 1 );
395 //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
396 if ( x->right )
397 inorder( x->right, level + 1 );
398 }
399#endif
400
401#if 0
402 Iterator insertMulti(const Key& v){
403 QMapNodeBase* y = header;
404 QMapNodeBase* x = header->parent;
405 while (x != 0){
406 y = x;
407 x = ( v < key(x) ) ? x->left : x->right;
408 }
409 return insert(x, y, v);
410 }
411#endif
412
413 Iterator insertSingle( const Key& k );
414 Iterator insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k );
415
416protected:
417 /**
418 * Helpers
419 */
420 const Key& key( QMapNodeBase* b ) const { return ((NodePtr)b)->key; }
421
422 /**
423 * Variables
424 */
425 NodePtr header;
426};
427
428
429template <class Key, class T>
430Q_INLINE_TEMPLATES QMapPrivate<Key,T>::QMapPrivate() {
431 header = new Node;
432 header->color = QMapNodeBase::Red; // Mark the header
433 header->parent = 0;
434 header->left = header->right = header;
435}
436template <class Key, class T>
437Q_INLINE_TEMPLATES QMapPrivate<Key,T>::QMapPrivate( const QMapPrivate< Key, T >* _map ) : QMapPrivateBase( _map ) {
438 header = new Node;
439 header->color = QMapNodeBase::Red; // Mark the header
440 if ( _map->header->parent == 0 ) {
441 header->parent = 0;
442 header->left = header->right = header;
443 } else {
444 header->parent = copy( (NodePtr)(_map->header->parent) );
445 header->parent->parent = header;
446 header->left = header->parent->minimum();
447 header->right = header->parent->maximum();
448 }
449}
450
451template <class Key, class T>
452Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::NodePtr QMapPrivate<Key,T>::copy( Q_TYPENAME QMapPrivate<Key,T>::NodePtr p )
453{
454 if ( !p )
455 return 0;
456 NodePtr n = new Node( *p );
457 n->color = p->color;
458 if ( p->left ) {
459 n->left = copy( (NodePtr)(p->left) );
460 n->left->parent = n;
461 } else {
462 n->left = 0;
463 }
464 if ( p->right ) {
465 n->right = copy( (NodePtr)(p->right) );
466 n->right->parent = n;
467 } else {
468 n->right = 0;
469 }
470 return n;
471}
472
473template <class Key, class T>
474Q_INLINE_TEMPLATES void QMapPrivate<Key,T>::clear()
475{
476 clear( (NodePtr)(header->parent) );
477 header->color = QMapNodeBase::Red;
478 header->parent = 0;
479 header->left = header->right = header;
480 node_count = 0;
481}
482
483template <class Key, class T>
484Q_INLINE_TEMPLATES void QMapPrivate<Key,T>::clear( Q_TYPENAME QMapPrivate<Key,T>::NodePtr p )
485{
486 while ( p != 0 ) {
487 clear( (NodePtr)p->right );
488 NodePtr y = (NodePtr)p->left;
489 delete p;
490 p = y;
491 }
492}
493
494template <class Key, class T>
495Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::ConstIterator QMapPrivate<Key,T>::find(const Key& k) const
496{
497 QMapNodeBase* y = header; // Last node
498 QMapNodeBase* x = header->parent; // Root node.
499
500 while ( x != 0 ) {
501 // If as k <= key(x) go left
502 if ( !( key(x) < k ) ) {
503 y = x;
504 x = x->left;
505 } else {
506 x = x->right;
507 }
508 }
509
510 // Was k bigger/smaller then the biggest/smallest
511 // element of the tree ? Return end()
512 if ( y == header || k < key(y) )
513 return ConstIterator( header );
514 return ConstIterator( (NodePtr)y );
515}
516
517template <class Key, class T>
518Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::Iterator QMapPrivate<Key,T>::insertSingle( const Key& k )
519{
520 // Search correct position in the tree
521 QMapNodeBase* y = header;
522 QMapNodeBase* x = header->parent;
523 bool result = TRUE;
524 while ( x != 0 ) {
525 result = ( k < key(x) );
526 y = x;
527 x = result ? x->left : x->right;
528 }
529 // Get iterator on the last not empty one
530 Iterator j( (NodePtr)y );
531 if ( result ) {
532 // Smaller then the leftmost one ?
533 if ( j == begin() ) {
534 return insert(x, y, k );
535 } else {
536 // Perhaps daddy is the right one ?
537 --j;
538 }
539 }
540 // Really bigger ?
541 if ( (j.node->key) < k )
542 return insert(x, y, k );
543 // We are going to replace a node
544 return j;
545}
546
547
548template <class Key, class T>
549Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::Iterator QMapPrivate<Key,T>::insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k )
550{
551 NodePtr z = new Node( k );
552 if (y == header || x != 0 || k < key(y) ) {
553 y->left = z; // also makes leftmost = z when y == header
554 if ( y == header ) {
555 header->parent = z;
556 header->right = z;
557 } else if ( y == header->left )
558 header->left = z; // maintain leftmost pointing to min node
559 } else {
560 y->right = z;
561 if ( y == header->right )
562 header->right = z; // maintain rightmost pointing to max node
563 }
564 z->parent = y;
565 z->left = 0;
566 z->right = 0;
567 rebalance( z, header->parent );
568 ++node_count;
569 return Iterator(z);
570}
571
572
573#ifdef QT_CHECK_RANGE
574# if !defined( QT_NO_DEBUG ) && defined( QT_CHECK_MAP_RANGE )
575# define QT_CHECK_INVALID_MAP_ELEMENT if ( empty() ) qWarning( "QMap: Warning invalid element" )
576# define QT_CHECK_INVALID_MAP_ELEMENT_FATAL Q_ASSERT( !empty() );
577# else
578# define QT_CHECK_INVALID_MAP_ELEMENT
579# define QT_CHECK_INVALID_MAP_ELEMENT_FATAL
580# endif
581#else
582# define QT_CHECK_INVALID_MAP_ELEMENT
583# define QT_CHECK_INVALID_MAP_ELEMENT_FATAL
584#endif
585
586template <class T> class QDeepCopy;
587
588template<class Key, class T>
589class QMap
590{
591public:
592 /**
593 * Typedefs
594 */
595 typedef Key key_type;
596 typedef T mapped_type;
597 typedef QPair<const key_type, mapped_type> value_type;
598 typedef value_type* pointer;
599 typedef const value_type* const_pointer;
600 typedef value_type& reference;
601 typedef const value_type& const_reference;
602#ifndef QT_NO_STL
603 typedef ptrdiff_t difference_type;
604#else
605 typedef int difference_type;
606#endif
607 typedef size_t size_type;
608 typedef QMapIterator<Key,T> iterator;
609 typedef QMapConstIterator<Key,T> const_iterator;
610 typedef QPair<iterator,bool> insert_pair;
611
612 typedef QMapIterator< Key, T > Iterator;
613 typedef QMapConstIterator< Key, T > ConstIterator;
614 typedef T ValueType;
615 typedef QMapPrivate< Key, T > Priv;
616
617 /**
618 * API
619 */
620 QMap()
621 {
622 sh = new QMapPrivate< Key, T >;
623 }
624 QMap( const QMap<Key,T>& m )
625 {
626 sh = m.sh; sh->ref();
627 }
628
629#ifndef QT_NO_STL
630# ifdef Q_CC_HPACC // HP-UX aCC does require typename in some place
631# undef Q_TYPENAME // but not accept them at others.
632# define Q_TYPENAME // also doesn't like re-defines ...
633# endif
634 QMap( const Q_TYPENAME std::map<Key,T>& m )
635 {
636 sh = new QMapPrivate<Key,T>;
637#if defined(Q_OS_WIN32)
638 std::map<Key,T>::const_iterator it = m.begin();
639#else
640 QMapConstIterator<Key,T> it = m.begin();
641#endif
642 for ( ; it != m.end(); ++it ) {
643 value_type p( (*it).first, (*it).second );
644 insert( p );
645 }
646 }
647#endif
648 ~QMap()
649 {
650 if ( sh->deref() )
651 delete sh;
652 }
653 QMap<Key,T>& operator= ( const QMap<Key,T>& m );
654#ifndef QT_NO_STL
655 QMap<Key,T>& operator= ( const Q_TYPENAME std::map<Key,T>& m )
656 {
657 clear();
658#if defined(Q_OS_WIN32)
659 std::map<Key,T>::const_iterator it = m.begin();
660#else
661 QMapConstIterator<Key,T> it = m.begin();
662#endif
663 for ( ; it != m.end(); ++it ) {
664 value_type p( (*it).first, (*it).second );
665 insert( p );
666 }
667 return *this;
668 }
669# ifdef Q_CC_HPACC // undo the HP-UX aCC hackery done above
670# undef Q_TYPENAME
671# define Q_TYPENAME typename
672# endif
673#endif
674
675 iterator begin() { detach(); return sh->begin(); }
676 iterator end() { detach(); return sh->end(); }
677 const_iterator begin() const { return ((const Priv*)sh)->begin(); }
678 const_iterator end() const { return ((const Priv*)sh)->end(); }
679 iterator replace( const Key& k, const T& v )
680 {
681 remove( k );
682 return insert( k, v );
683 }
684
685 size_type size() const
686 {
687 return sh->node_count;
688 }
689 bool empty() const
690 {
691 return sh->node_count == 0;
692 }
693 QPair<iterator,bool> insert( const value_type& x );
694
695 void erase( iterator it )
696 {
697 detach();
698 sh->remove( it );
699 }
700 void erase( const key_type& k );
701 size_type count( const key_type& k ) const;
702 T& operator[] ( const Key& k );
703 void clear();
704
705 iterator find ( const Key& k )
706 {
707 detach();
708 return iterator( sh->find( k ).node );
709 }
710 const_iterator find ( const Key& k ) const {return sh->find( k ); }
711
712 const T& operator[] ( const Key& k ) const
713 { QT_CHECK_INVALID_MAP_ELEMENT; return sh->find( k ).data(); }
714 bool contains ( const Key& k ) const
715 { return find( k ) != end(); }
716 //{ return sh->find( k ) != ((const Priv*)sh)->end(); }
717
718 size_type count() const { return sh->node_count; }
719
720 QValueList<Key> keys() const {
721 QValueList<Key> r;
722 for (const_iterator i=begin(); i!=end(); ++i)
723 r.append(i.key());
724 return r;
725 }
726
727 QValueList<T> values() const {
728 QValueList<T> r;
729 for (const_iterator i=begin(); i!=end(); ++i)
730 r.append(*i);
731 return r;
732 }
733
734 bool isEmpty() const { return sh->node_count == 0; }
735
736 iterator insert( const Key& key, const T& value, bool overwrite = TRUE );
737 void remove( iterator it ) { detach(); sh->remove( it ); }
738 void remove( const Key& k );
739
740#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
741 bool operator==( const QMap<Key,T>& ) const { return FALSE; }
742#ifndef QT_NO_STL
743 bool operator==( const Q_TYPENAME std::map<Key,T>& ) const { return FALSE; }
744#endif
745#endif
746
747protected:
748 /**
749 * Helpers
750 */
751 void detach() { if ( sh->count > 1 ) detachInternal(); }
752
753 Priv* sh;
754private:
755 void detachInternal();
756
757 friend class QDeepCopy< QMap<Key,T> >;
758};
759
760template<class Key, class T>
761Q_INLINE_TEMPLATES QMap<Key,T>& QMap<Key,T>::operator= ( const QMap<Key,T>& m )
762{
763 m.sh->ref();
764 if ( sh->deref() )
765 delete sh;
766 sh = m.sh;
767 return *this;
768}
769
770template<class Key, class T>
771Q_INLINE_TEMPLATES Q_TYPENAME QMap<Key,T>::insert_pair QMap<Key,T>::insert( const Q_TYPENAME QMap<Key,T>::value_type& x )
772{
773 detach();
774 size_type n = size();
775 iterator it = sh->insertSingle( x.first );
776 bool inserted = FALSE;
777 if ( n < size() ) {
778 inserted = TRUE;
779 it.data() = x.second;
780 }
781 return QPair<iterator,bool>( it, inserted );
782}
783
784template<class Key, class T>
785Q_INLINE_TEMPLATES void QMap<Key,T>::erase( const Key& k )
786{
787 detach();
788 iterator it( sh->find( k ).node );
789 if ( it != end() )
790 sh->remove( it );
791}
792
793template<class Key, class T>
794Q_INLINE_TEMPLATES Q_TYPENAME QMap<Key,T>::size_type QMap<Key,T>::count( const Key& k ) const
795{
796 const_iterator it( sh->find( k ).node );
797 if ( it != end() ) {
798 size_type c = 0;
799 while ( it != end() ) {
800 ++it;
801 ++c;
802 }
803 return c;
804 }
805 return 0;
806}
807
808template<class Key, class T>
809Q_INLINE_TEMPLATES T& QMap<Key,T>::operator[] ( const Key& k )
810{
811 detach();
812 QMapNode<Key,T>* p = sh->find( k ).node;
813 if ( p != sh->end().node )
814 return p->data;
815 return insert( k, T() ).data();
816}
817
818template<class Key, class T>
819Q_INLINE_TEMPLATES void QMap<Key,T>::clear()
820{
821 if ( sh->count == 1 )
822 sh->clear();
823 else {
824 sh->deref();
825 sh = new QMapPrivate<Key,T>;
826 }
827}
828
829template<class Key, class T>
830Q_INLINE_TEMPLATES Q_TYPENAME QMap<Key,T>::iterator QMap<Key,T>::insert( const Key& key, const T& value, bool overwrite )
831{
832 detach();
833 size_type n = size();
834 iterator it = sh->insertSingle( key );
835 if ( overwrite || n < size() )
836 it.data() = value;
837 return it;
838}
839
840template<class Key, class T>
841Q_INLINE_TEMPLATES void QMap<Key,T>::remove( const Key& k )
842{
843 detach();
844 iterator it( sh->find( k ).node );
845 if ( it != end() )
846 sh->remove( it );
847}
848
849template<class Key, class T>
850Q_INLINE_TEMPLATES void QMap<Key,T>::detachInternal()
851{
852 sh->deref(); sh = new QMapPrivate<Key,T>( sh );
853}
854
855
856#ifndef QT_NO_DATASTREAM
857template<class Key, class T>
858Q_INLINE_TEMPLATES QDataStream& operator>>( QDataStream& s, QMap<Key,T>& m ) {
859 m.clear();
860 Q_UINT32 c;
861 s >> c;
862 for( Q_UINT32 i = 0; i < c; ++i ) {
863 Key k; T t;
864 s >> k >> t;
865 m.insert( k, t );
866 if ( s.atEnd() )
867 break;
868 }
869 return s;
870}
871
872
873template<class Key, class T>
874Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m ) {
875 s << (Q_UINT32)m.size();
876 QMapConstIterator<Key,T> it = m.begin();
877 for( ; it != m.end(); ++it )
878 s << it.key() << it.data();
879 return s;
880}
881#endif
882
883#endif // QMAP_H
diff --git a/qmake/include/qmemarray.h b/qmake/include/qmemarray.h
new file mode 100644
index 0000000..a5baf99
--- a/dev/null
+++ b/qmake/include/qmemarray.h
@@ -0,0 +1,122 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QMemArray template/macro 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#ifndef QMEMARRAY_H
39#define QMEMARRAY_H
40
41#ifndef QT_H
42#include "qgarray.h"
43#endif // QT_H
44
45
46template<class type>
47class QMemArray : public QGArray
48{
49public:
50 typedef type* Iterator;
51 typedef const type* ConstIterator;
52 typedef type ValueType;
53
54protected:
55 QMemArray( int, int ) : QGArray( 0, 0 ) {}
56
57public:
58 QMemArray() {}
59 QMemArray( int size ) : QGArray(size*sizeof(type)) {}
60 QMemArray( const QMemArray<type> &a ) : QGArray(a) {}
61 ~QMemArray() {}
62 QMemArray<type> &operator=(const QMemArray<type> &a)
63 { return (QMemArray<type>&)QGArray::assign(a); }
64 type *data() const{ return (type *)QGArray::data(); }
65 uint nrefs() const{ return QGArray::nrefs(); }
66 uint size() const{ return QGArray::size()/sizeof(type); }
67 uint count() const{ return size(); }
68 bool isEmpty() const{ return QGArray::size() == 0; }
69 bool isNull() const{ return QGArray::data() == 0; }
70 bool resize( uint size ){ return QGArray::resize(size*sizeof(type)); }
71 bool truncate( uint pos ){ return QGArray::resize(pos*sizeof(type)); }
72 bool fill( const type &d, int size = -1 )
73 { return QGArray::fill((char*)&d,size,sizeof(type) ); }
74 void detach() { QGArray::detach(); }
75 QMemArray<type> copy() const
76 { QMemArray<type> tmp; return tmp.duplicate(*this); }
77 QMemArray<type>& assign( const QMemArray<type>& a )
78 { return (QMemArray<type>&)QGArray::assign(a); }
79 QMemArray<type>& assign( const type *a, uint n )
80 { return (QMemArray<type>&)QGArray::assign((char*)a,n*sizeof(type)); }
81 QMemArray<type>& duplicate( const QMemArray<type>& a )
82 { return (QMemArray<type>&)QGArray::duplicate(a); }
83 QMemArray<type>& duplicate( const type *a, uint n )
84 { return (QMemArray<type>&)QGArray::duplicate((char*)a,n*sizeof(type)); }
85 QMemArray<type>& setRawData( const type *a, uint n )
86 { return (QMemArray<type>&)QGArray::setRawData((char*)a,
87 n*sizeof(type)); }
88 void resetRawData( const type *a, uint n )
89 { QGArray::resetRawData((char*)a,n*sizeof(type)); }
90 int find( const type &d, uint i=0 ) const
91 { return QGArray::find((char*)&d,i,sizeof(type)); }
92 int contains( const type &d ) const
93 { return QGArray::contains((char*)&d,sizeof(type)); }
94 void sort() { QGArray::sort(sizeof(type)); }
95 int bsearch( const type &d ) const
96 { return QGArray::bsearch((const char*)&d,sizeof(type)); }
97 // ### Qt 4.0: maybe provide uint overload as work-around for MSVC bug
98 type& operator[]( int i ) const
99 { return (type &)(*(type *)QGArray::at(i*sizeof(type))); }
100 type& at( uint i ) const
101 { return (type &)(*(type *)QGArray::at(i*sizeof(type))); }
102 operator const type*() const { return (const type *)QGArray::data(); }
103 bool operator==( const QMemArray<type> &a ) const { return isEqual(a); }
104 bool operator!=( const QMemArray<type> &a ) const { return !isEqual(a); }
105 Iterator begin() { return data(); }
106 Iterator end() { return data() + size(); }
107 ConstIterator begin() const { return data(); }
108 ConstIterator end() const { return data() + size(); }
109};
110
111#if defined(Q_TEMPLATEDLL)
112// MOC_SKIP_BEGIN
113Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<int>;
114Q_TEMPLATE_EXTERN template class Q_EXPORT QMemArray<bool>;
115// MOC_SKIP_END
116#endif
117
118#ifndef QT_NO_COMPAT
119#define QArray QMemArray
120#endif
121
122#endif // QARRAY_H
diff --git a/qmake/include/qnamespace.h b/qmake/include/qnamespace.h
new file mode 100644
index 0000000..58b485f
--- a/dev/null
+++ b/qmake/include/qnamespace.h
@@ -0,0 +1,843 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of Qt namespace (as class for compiler compatibility)
5**
6** Created : 980927
7**
8** Copyright (C) 1992-2000 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#ifndef QNAMESPACE_H
39#define QNAMESPACE_H
40
41#ifndef QT_H
42#include "qglobal.h"
43#endif // QT_H
44
45
46class QColor;
47class QCursor;
48
49
50class Q_EXPORT Qt {
51public:
52 QT_STATIC_CONST QColor & color0;
53 QT_STATIC_CONST QColor & color1;
54 QT_STATIC_CONST QColor & black;
55 QT_STATIC_CONST QColor & white;
56 QT_STATIC_CONST QColor & darkGray;
57 QT_STATIC_CONST QColor & gray;
58 QT_STATIC_CONST QColor & lightGray;
59 QT_STATIC_CONST QColor & red;
60 QT_STATIC_CONST QColor & green;
61 QT_STATIC_CONST QColor & blue;
62 QT_STATIC_CONST QColor & cyan;
63 QT_STATIC_CONST QColor & magenta;
64 QT_STATIC_CONST QColor & yellow;
65 QT_STATIC_CONST QColor & darkRed;
66 QT_STATIC_CONST QColor & darkGreen;
67 QT_STATIC_CONST QColor & darkBlue;
68 QT_STATIC_CONST QColor & darkCyan;
69 QT_STATIC_CONST QColor & darkMagenta;
70 QT_STATIC_CONST QColor & darkYellow;
71
72 // documented in qevent.cpp
73 enum ButtonState { // mouse/keyboard state values
74 NoButton= 0x0000,
75 LeftButton= 0x0001,
76 RightButton= 0x0002,
77 MidButton= 0x0004,
78 MouseButtonMask = 0x0007,
79 ShiftButton= 0x0100,
80 ControlButton = 0x0200,
81 AltButton= 0x0400,
82 MetaButton= 0x0800,
83 KeyButtonMask= 0x0f00,
84 Keypad = 0x4000
85 };
86
87 // documented in qobject.cpp
88 // ideally would start at 1, as in QSizePolicy, but that breaks other things
89 enum Orientation {
90 Horizontal = 0,
91 Vertical
92 };
93
94 // Text formatting flags for QPainter::drawText and QLabel
95 // the following four enums can be combined to one integer which
96 // is passed as textflag to drawText and qt_format_text.
97
98 // documented in qpainter.cpp
99 enum AlignmentFlags {
100 AlignAuto = 0x0000, // text alignment
101 AlignLeft = 0x0001,
102 AlignRight = 0x0002,
103 AlignHCenter = 0x0004,
104 AlignJustify = 0x0008,
105 AlignHorizontal_Mask= AlignLeft | AlignRight | AlignHCenter | AlignJustify,
106 AlignTop = 0x0010,
107 AlignBottom = 0x0020,
108 AlignVCenter = 0x0040,
109 AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter,
110 AlignCenter = AlignVCenter | AlignHCenter
111 };
112
113 // documented in qpainter.cpp
114 enum TextFlags {
115 SingleLine = 0x0080, // misc. flags
116 DontClip= 0x0100,
117 ExpandTabs= 0x0200,
118 ShowPrefix= 0x0400,
119 WordBreak= 0x0800,
120 BreakAnywhere = 0x1000,
121 DontPrint = 0x2000, // internal
122 NoAccel = 0x4000
123 };
124
125 // Widget flags; documented in qwidget.cpp
126 typedef uint WState;
127
128 // QWidget state flags (internal, barely documented in qwidget.cpp)
129 enum WidgetState {
130 WState_Created = 0x00000001,
131 WState_Disabled = 0x00000002,
132 WState_Visible = 0x00000004,
133 WState_ForceHide= 0x00000008,
134 WState_OwnCursor= 0x00000010,
135 WState_MouseTracking= 0x00000020,
136 WState_CompressKeys= 0x00000040,
137 WState_BlockUpdates= 0x00000080,
138 WState_InPaintEvent= 0x00000100,
139 WState_Reparented= 0x00000200,
140 WState_ConfigPending= 0x00000400,
141 WState_Resized = 0x00000800,
142 WState_AutoMask = 0x00001000,
143 WState_Polished = 0x00002000,
144 WState_DND = 0x00004000,
145 WState_Reserved0= 0x00008000,
146 WState_Reserved1= 0x00010000,
147 WState_Reserved2= 0x00020000,
148 WState_CreatedHidden= 0x00040000,
149 WState_Maximized= 0x00080000,
150 WState_Minimized= 0x00100000,
151 WState_ForceDisabled= 0x00200000,
152 WState_Exposed = 0x00400000,
153 WState_HasMouse = 0x00800000
154 };
155
156 // Widget flags2; documented in qwidget.cpp
157 typedef uint WFlags;
158
159 // documented in qwidget.cpp
160 enum WidgetFlags {
161 WType_TopLevel = 0x00000001,// widget type flags
162 WType_Dialog = 0x00000002,
163 WType_Popup = 0x00000004,
164 WType_Desktop = 0x00000008,
165 WType_Mask = 0x0000000f,
166
167 WStyle_Customize = 0x00000010,// window style flags
168 WStyle_NormalBorder= 0x00000020,
169 WStyle_DialogBorder= 0x00000040, // MS-Windows only
170 WStyle_NoBorder = 0x00002000,
171 WStyle_Title = 0x00000080,
172 WStyle_SysMenu = 0x00000100,
173 WStyle_Minimize = 0x00000200,
174 WStyle_Maximize = 0x00000400,
175 WStyle_MinMax = WStyle_Minimize | WStyle_Maximize,
176 WStyle_Tool = 0x00000800,
177 WStyle_StaysOnTop= 0x00001000,
178 WStyle_ContextHelp= 0x00004000,
179 WStyle_Reserved = 0x00008000,
180 WStyle_Mask = 0x0000fff0,
181
182 WDestructiveClose = 0x00010000,// misc flags
183 WPaintDesktop = 0x00020000,
184 WPaintUnclipped = 0x00040000,
185 WPaintClever = 0x00080000,
186 WResizeNoErase = 0x00100000,
187 WMouseNoMask = 0x00200000,
188 WStaticContents = 0x00400000,
189 WRepaintNoErase = 0x00800000,
190#ifdef Q_WS_X11
191 WX11BypassWM = 0x01000000,
192 WWinOwnDC = 0x00000000,
193#else
194 WX11BypassWM = 0x00000000,
195 WWinOwnDC = 0x01000000,
196#endif
197 WGroupLeader = 0x02000000,
198 WShowModal = 0x04000000,
199 WNoMousePropagation= 0x08000000,
200 WSubWindow = 0x10000000
201#ifndef QT_NO_COMPAT
202 ,
203 WNorthWestGravity= WStaticContents,
204 WType_Modal = WType_Dialog | WShowModal,
205 WStyle_Dialog = WType_Dialog,
206 WStyle_NoBorderEx= WStyle_NoBorder
207#endif
208 };
209
210 // Image conversion flags. The unusual ordering is caused by
211 // compatibility and default requirements.
212 // Documented in qimage.cpp
213
214 enum ImageConversionFlags {
215 ColorMode_Mask = 0x00000003,
216 AutoColor = 0x00000000,
217 ColorOnly = 0x00000003,
218 MonoOnly = 0x00000002,
219 // Reserved= 0x00000001,
220
221 AlphaDither_Mask= 0x0000000c,
222 ThresholdAlphaDither= 0x00000000,
223 OrderedAlphaDither= 0x00000004,
224 DiffuseAlphaDither= 0x00000008,
225 NoAlpha = 0x0000000c, // Not supported
226
227 Dither_Mask = 0x00000030,
228 DiffuseDither = 0x00000000,
229 OrderedDither = 0x00000010,
230 ThresholdDither = 0x00000020,
231 // ReservedDither= 0x00000030,
232
233 DitherMode_Mask = 0x000000c0,
234 AutoDither = 0x00000000,
235 PreferDither = 0x00000040,
236 AvoidDither = 0x00000080
237 };
238
239 // documented in qpainter.cpp
240 enum BGMode { // background mode
241 TransparentMode,
242 OpaqueMode
243 };
244
245#ifndef QT_NO_COMPAT
246 // documented in qpainter.cpp
247 enum PaintUnit { // paint unit
248 PixelUnit,
249 LoMetricUnit, // OBSOLETE
250 HiMetricUnit, // OBSOLETE
251 LoEnglishUnit, // OBSOLETE
252 HiEnglishUnit, // OBSOLETE
253 TwipsUnit // OBSOLETE
254 };
255#endif
256
257 // documented in qstyle.cpp
258#ifdef QT_NO_COMPAT
259 enum GUIStyle {
260 WindowsStyle = 1, // ### Qt 4.0: either remove the obsolete enums or clean up compat vs.
261 MotifStyle = 4 // ### QT_NO_COMPAT by reordering or combination into one enum.
262 };
263#else
264 enum GUIStyle {
265 MacStyle, // OBSOLETE
266 WindowsStyle,
267 Win3Style, // OBSOLETE
268 PMStyle, // OBSOLETE
269 MotifStyle
270 };
271#endif
272
273 // documented in qkeysequence.cpp
274 enum SequenceMatch {
275 NoMatch,
276 PartialMatch,
277 Identical
278 };
279
280 // documented in qevent.cpp
281 enum Modifier { // accelerator modifiers
282 META = 0x00100000,
283 SHIFT = 0x00200000,
284 CTRL = 0x00400000,
285 ALT = 0x00800000,
286 MODIFIER_MASK = 0x00f00000,
287 UNICODE_ACCEL = 0x10000000,
288
289 ASCII_ACCEL = UNICODE_ACCEL // 1.x compat
290 };
291
292 // documented in qevent.cpp
293 enum Key {
294 Key_Escape = 0x1000, // misc keys
295 Key_Tab = 0x1001,
296 Key_Backtab = 0x1002, Key_BackTab = Key_Backtab,
297 Key_Backspace = 0x1003, Key_BackSpace = Key_Backspace,
298 Key_Return = 0x1004,
299 Key_Enter = 0x1005,
300 Key_Insert = 0x1006,
301 Key_Delete = 0x1007,
302 Key_Pause = 0x1008,
303 Key_Print = 0x1009,
304 Key_SysReq = 0x100a,
305 Key_Clear = 0x100b,
306 Key_Home = 0x1010, // cursor movement
307 Key_End = 0x1011,
308 Key_Left = 0x1012,
309 Key_Up = 0x1013,
310 Key_Right = 0x1014,
311 Key_Down = 0x1015,
312 Key_Prior = 0x1016, Key_PageUp = Key_Prior,
313 Key_Next = 0x1017, Key_PageDown = Key_Next,
314 Key_Shift = 0x1020, // modifiers
315 Key_Control = 0x1021,
316 Key_Meta = 0x1022,
317 Key_Alt = 0x1023,
318 Key_CapsLock = 0x1024,
319 Key_NumLock = 0x1025,
320 Key_ScrollLock = 0x1026,
321 Key_F1 = 0x1030, // function keys
322 Key_F2 = 0x1031,
323 Key_F3 = 0x1032,
324 Key_F4 = 0x1033,
325 Key_F5 = 0x1034,
326 Key_F6 = 0x1035,
327 Key_F7 = 0x1036,
328 Key_F8 = 0x1037,
329 Key_F9 = 0x1038,
330 Key_F10 = 0x1039,
331 Key_F11 = 0x103a,
332 Key_F12 = 0x103b,
333 Key_F13 = 0x103c,
334 Key_F14 = 0x103d,
335 Key_F15 = 0x103e,
336 Key_F16 = 0x103f,
337 Key_F17 = 0x1040,
338 Key_F18 = 0x1041,
339 Key_F19 = 0x1042,
340 Key_F20 = 0x1043,
341 Key_F21 = 0x1044,
342 Key_F22 = 0x1045,
343 Key_F23 = 0x1046,
344 Key_F24 = 0x1047,
345 Key_F25 = 0x1048, // F25 .. F35 only on X11
346 Key_F26 = 0x1049,
347 Key_F27 = 0x104a,
348 Key_F28 = 0x104b,
349 Key_F29 = 0x104c,
350 Key_F30 = 0x104d,
351 Key_F31 = 0x104e,
352 Key_F32 = 0x104f,
353 Key_F33 = 0x1050,
354 Key_F34 = 0x1051,
355 Key_F35 = 0x1052,
356 Key_Super_L = 0x1053, // extra keys
357 Key_Super_R = 0x1054,
358 Key_Menu = 0x1055,
359 Key_Hyper_L = 0x1056,
360 Key_Hyper_R = 0x1057,
361 Key_Help = 0x1058,
362 Key_Direction_L = 0x1059,
363 Key_Direction_R = 0x1060,
364 Key_Space = 0x20, // 7 bit printable ASCII
365 Key_Any = Key_Space,
366 Key_Exclam = 0x21,
367 Key_QuoteDbl = 0x22,
368 Key_NumberSign = 0x23,
369 Key_Dollar = 0x24,
370 Key_Percent = 0x25,
371 Key_Ampersand = 0x26,
372 Key_Apostrophe = 0x27,
373 Key_ParenLeft = 0x28,
374 Key_ParenRight = 0x29,
375 Key_Asterisk = 0x2a,
376 Key_Plus = 0x2b,
377 Key_Comma = 0x2c,
378 Key_Minus = 0x2d,
379 Key_Period = 0x2e,
380 Key_Slash = 0x2f,
381 Key_0 = 0x30,
382 Key_1 = 0x31,
383 Key_2 = 0x32,
384 Key_3 = 0x33,
385 Key_4 = 0x34,
386 Key_5 = 0x35,
387 Key_6 = 0x36,
388 Key_7 = 0x37,
389 Key_8 = 0x38,
390 Key_9 = 0x39,
391 Key_Colon = 0x3a,
392 Key_Semicolon = 0x3b,
393 Key_Less = 0x3c,
394 Key_Equal = 0x3d,
395 Key_Greater = 0x3e,
396 Key_Question = 0x3f,
397 Key_At = 0x40,
398 Key_A = 0x41,
399 Key_B = 0x42,
400 Key_C = 0x43,
401 Key_D = 0x44,
402 Key_E = 0x45,
403 Key_F = 0x46,
404 Key_G = 0x47,
405 Key_H = 0x48,
406 Key_I = 0x49,
407 Key_J = 0x4a,
408 Key_K = 0x4b,
409 Key_L = 0x4c,
410 Key_M = 0x4d,
411 Key_N = 0x4e,
412 Key_O = 0x4f,
413 Key_P = 0x50,
414 Key_Q = 0x51,
415 Key_R = 0x52,
416 Key_S = 0x53,
417 Key_T = 0x54,
418 Key_U = 0x55,
419 Key_V = 0x56,
420 Key_W = 0x57,
421 Key_X = 0x58,
422 Key_Y = 0x59,
423 Key_Z = 0x5a,
424 Key_BracketLeft = 0x5b,
425 Key_Backslash = 0x5c,
426 Key_BracketRight = 0x5d,
427 Key_AsciiCircum = 0x5e,
428 Key_Underscore = 0x5f,
429 Key_QuoteLeft = 0x60,
430 Key_BraceLeft = 0x7b,
431 Key_Bar = 0x7c,
432 Key_BraceRight = 0x7d,
433 Key_AsciiTilde = 0x7e,
434
435 // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06
436
437 Key_nobreakspace = 0x0a0,
438 Key_exclamdown = 0x0a1,
439 Key_cent = 0x0a2,
440 Key_sterling = 0x0a3,
441 Key_currency = 0x0a4,
442 Key_yen = 0x0a5,
443 Key_brokenbar = 0x0a6,
444 Key_section = 0x0a7,
445 Key_diaeresis = 0x0a8,
446 Key_copyright = 0x0a9,
447 Key_ordfeminine = 0x0aa,
448 Key_guillemotleft = 0x0ab,// left angle quotation mark
449 Key_notsign = 0x0ac,
450 Key_hyphen = 0x0ad,
451 Key_registered = 0x0ae,
452 Key_macron = 0x0af,
453 Key_degree = 0x0b0,
454 Key_plusminus = 0x0b1,
455 Key_twosuperior = 0x0b2,
456 Key_threesuperior = 0x0b3,
457 Key_acute = 0x0b4,
458 Key_mu = 0x0b5,
459 Key_paragraph = 0x0b6,
460 Key_periodcentered = 0x0b7,
461 Key_cedilla = 0x0b8,
462 Key_onesuperior = 0x0b9,
463 Key_masculine = 0x0ba,
464 Key_guillemotright = 0x0bb,// right angle quotation mark
465 Key_onequarter = 0x0bc,
466 Key_onehalf = 0x0bd,
467 Key_threequarters = 0x0be,
468 Key_questiondown = 0x0bf,
469 Key_Agrave = 0x0c0,
470 Key_Aacute = 0x0c1,
471 Key_Acircumflex = 0x0c2,
472 Key_Atilde = 0x0c3,
473 Key_Adiaeresis = 0x0c4,
474 Key_Aring = 0x0c5,
475 Key_AE = 0x0c6,
476 Key_Ccedilla = 0x0c7,
477 Key_Egrave = 0x0c8,
478 Key_Eacute = 0x0c9,
479 Key_Ecircumflex = 0x0ca,
480 Key_Ediaeresis = 0x0cb,
481 Key_Igrave = 0x0cc,
482 Key_Iacute = 0x0cd,
483 Key_Icircumflex = 0x0ce,
484 Key_Idiaeresis = 0x0cf,
485 Key_ETH = 0x0d0,
486 Key_Ntilde = 0x0d1,
487 Key_Ograve = 0x0d2,
488 Key_Oacute = 0x0d3,
489 Key_Ocircumflex = 0x0d4,
490 Key_Otilde = 0x0d5,
491 Key_Odiaeresis = 0x0d6,
492 Key_multiply = 0x0d7,
493 Key_Ooblique = 0x0d8,
494 Key_Ugrave = 0x0d9,
495 Key_Uacute = 0x0da,
496 Key_Ucircumflex = 0x0db,
497 Key_Udiaeresis = 0x0dc,
498 Key_Yacute = 0x0dd,
499 Key_THORN = 0x0de,
500 Key_ssharp = 0x0df,
501 Key_agrave = 0x0e0,
502 Key_aacute = 0x0e1,
503 Key_acircumflex = 0x0e2,
504 Key_atilde = 0x0e3,
505 Key_adiaeresis = 0x0e4,
506 Key_aring = 0x0e5,
507 Key_ae = 0x0e6,
508 Key_ccedilla = 0x0e7,
509 Key_egrave = 0x0e8,
510 Key_eacute = 0x0e9,
511 Key_ecircumflex = 0x0ea,
512 Key_ediaeresis = 0x0eb,
513 Key_igrave = 0x0ec,
514 Key_iacute = 0x0ed,
515 Key_icircumflex = 0x0ee,
516 Key_idiaeresis = 0x0ef,
517 Key_eth = 0x0f0,
518 Key_ntilde = 0x0f1,
519 Key_ograve = 0x0f2,
520 Key_oacute = 0x0f3,
521 Key_ocircumflex = 0x0f4,
522 Key_otilde = 0x0f5,
523 Key_odiaeresis = 0x0f6,
524 Key_division = 0x0f7,
525 Key_oslash = 0x0f8,
526 Key_ugrave = 0x0f9,
527 Key_uacute = 0x0fa,
528 Key_ucircumflex = 0x0fb,
529 Key_udiaeresis = 0x0fc,
530 Key_yacute = 0x0fd,
531 Key_thorn = 0x0fe,
532 Key_ydiaeresis = 0x0ff,
533
534 // multimedia/internet keys - ignored by default - see QKeyEvent c'tor
535
536 Key_Back = 0x1061,
537 Key_Forward = 0x1062,
538 Key_Stop = 0x1063,
539 Key_Refresh = 0x1064,
540
541 Key_VolumeDown = 0x1070,
542 Key_VolumeMute = 0x1071,
543 Key_VolumeUp = 0x1072,
544 Key_BassBoost = 0x1073,
545 Key_BassUp = 0x1074,
546 Key_BassDown = 0x1075,
547 Key_TrebleUp = 0x1076,
548 Key_TrebleDown = 0x1077,
549
550 Key_MediaPlay = 0x1080,
551 Key_MediaStop = 0x1081,
552 Key_MediaPrev = 0x1082,
553 Key_MediaNext = 0x1083,
554 Key_MediaRecord = 0x1084,
555
556 Key_HomePage = 0x1090,
557 Key_Favorites = 0x1091,
558 Key_Search = 0x1092,
559 Key_Standby = 0x1093,
560 Key_OpenUrl = 0x1094,
561
562 Key_LaunchMail = 0x10a0,
563 Key_LaunchMedia = 0x10a1,
564 Key_Launch0 = 0x10a2,
565 Key_Launch1 = 0x10a3,
566 Key_Launch2 = 0x10a4,
567 Key_Launch3 = 0x10a5,
568 Key_Launch4 = 0x10a6,
569 Key_Launch5 = 0x10a7,
570 Key_Launch6 = 0x10a8,
571 Key_Launch7 = 0x10a9,
572 Key_Launch8 = 0x10aa,
573 Key_Launch9 = 0x10ab,
574 Key_LaunchA = 0x10ac,
575 Key_LaunchB = 0x10ad,
576 Key_LaunchC = 0x10ae,
577 Key_LaunchD = 0x10af,
578 Key_LaunchE = 0x10b0,
579 Key_LaunchF = 0x10b1,
580
581 Key_MediaLast = 0x1fff,
582
583 Key_unknown = 0xffff
584 };
585
586 // documented in qcommonstyle.cpp
587 enum ArrowType {
588 UpArrow,
589 DownArrow,
590 LeftArrow,
591 RightArrow
592 };
593
594 // documented in qpainter.cpp
595 enum RasterOp { // raster op mode
596 CopyROP,
597 OrROP,
598 XorROP,
599 NotAndROP, EraseROP=NotAndROP,
600 NotCopyROP,
601 NotOrROP,
602 NotXorROP,
603 AndROP,NotEraseROP=AndROP,
604 NotROP,
605 ClearROP,
606 SetROP,
607 NopROP,
608 AndNotROP,
609 OrNotROP,
610 NandROP,
611 NorROP,LastROP=NorROP
612 };
613
614 // documented in qpainter.cpp
615 enum PenStyle { // pen style
616 NoPen,
617 SolidLine,
618 DashLine,
619 DotLine,
620 DashDotLine,
621 DashDotDotLine,
622 MPenStyle = 0x0f
623 };
624
625 // documented in qpainter.cpp
626 enum PenCapStyle { // line endcap style
627 FlatCap = 0x00,
628 SquareCap = 0x10,
629 RoundCap = 0x20,
630 MPenCapStyle = 0x30
631 };
632
633 // documented in qpainter.cpp
634 enum PenJoinStyle { // line join style
635 MiterJoin = 0x00,
636 BevelJoin = 0x40,
637 RoundJoin = 0x80,
638 MPenJoinStyle = 0xc0
639 };
640
641 // documented in qpainter.cpp
642 enum BrushStyle { // brush style
643 NoBrush,
644 SolidPattern,
645 Dense1Pattern,
646 Dense2Pattern,
647 Dense3Pattern,
648 Dense4Pattern,
649 Dense5Pattern,
650 Dense6Pattern,
651 Dense7Pattern,
652 HorPattern,
653 VerPattern,
654 CrossPattern,
655 BDiagPattern,
656 FDiagPattern,
657 DiagCrossPattern,
658 CustomPattern=24
659 };
660
661 // documented in qapplication_win.cpp
662 enum WindowsVersion {
663 WV_32s = 0x0001,
664 WV_95 = 0x0002,
665 WV_98 = 0x0003,
666 WV_Me = 0x0004,
667 WV_DOS_based= 0x000f,
668
669 WV_NT = 0x0010,
670 WV_2000 = 0x0020,
671 WV_XP = 0x0030,
672 WV_NT_based= 0x00f0
673 };
674
675 // documented in qstyle.cpp
676 enum UIEffect {
677 UI_General,
678 UI_AnimateMenu,
679 UI_FadeMenu,
680 UI_AnimateCombo,
681 UI_AnimateTooltip,
682 UI_FadeTooltip
683 };
684
685 // documented in qcursor.cpp
686 enum CursorShape {
687 ArrowCursor,
688 UpArrowCursor,
689 CrossCursor,
690 WaitCursor,
691 IbeamCursor,
692 SizeVerCursor,
693 SizeHorCursor,
694 SizeBDiagCursor,
695 SizeFDiagCursor,
696 SizeAllCursor,
697 BlankCursor,
698 SplitVCursor,
699 SplitHCursor,
700 PointingHandCursor,
701 ForbiddenCursor,
702 WhatsThisCursor,
703 LastCursor= WhatsThisCursor,
704 BitmapCursor= 24
705 };
706
707 // Global cursors
708
709 QT_STATIC_CONST QCursor & arrowCursor;// standard arrow cursor
710 QT_STATIC_CONST QCursor & upArrowCursor;// upwards arrow
711 QT_STATIC_CONST QCursor & crossCursor;// crosshair
712 QT_STATIC_CONST QCursor & waitCursor;// hourglass/watch
713 QT_STATIC_CONST QCursor & ibeamCursor;// ibeam/text entry
714 QT_STATIC_CONST QCursor & sizeVerCursor;// vertical resize
715 QT_STATIC_CONST QCursor & sizeHorCursor;// horizontal resize
716 QT_STATIC_CONST QCursor & sizeBDiagCursor;// diagonal resize (/)
717 QT_STATIC_CONST QCursor & sizeFDiagCursor;// diagonal resize (\)
718 QT_STATIC_CONST QCursor & sizeAllCursor;// all directions resize
719 QT_STATIC_CONST QCursor & blankCursor;// blank/invisible cursor
720 QT_STATIC_CONST QCursor & splitVCursor;// vertical bar with left-right
721 // arrows
722 QT_STATIC_CONST QCursor & splitHCursor;// horizontal bar with up-down
723 // arrows
724 QT_STATIC_CONST QCursor & pointingHandCursor;// pointing hand
725 QT_STATIC_CONST QCursor & forbiddenCursor;// forbidden cursor (slashed circle)
726 QT_STATIC_CONST QCursor & whatsThisCursor; // arrow with a question mark
727
728
729 enum TextFormat {
730 PlainText,
731 RichText,
732 AutoText,
733 LogText
734 };
735
736 // Documented in qtextedit.cpp
737 enum AnchorAttribute {
738 AnchorName,
739 AnchorHref
740 };
741
742 // Documented in qmainwindow.cpp
743 enum Dock {
744 DockUnmanaged,
745 DockTornOff,
746 DockTop,
747 DockBottom,
748 DockRight,
749 DockLeft,
750 DockMinimized
751#ifndef QT_NO_COMPAT
752 ,
753 Unmanaged = DockUnmanaged,
754 TornOff = DockTornOff,
755 Top = DockTop,
756 Bottom = DockBottom,
757 Right = DockRight,
758 Left = DockLeft,
759 Minimized = DockMinimized
760#endif
761 };
762 // compatibility
763 typedef Dock ToolBarDock;
764
765 // documented in qdatetime.cpp
766 enum DateFormat {
767 TextDate, // default Qt
768 ISODate, // ISO 8601
769 LocalDate // locale dependant
770 };
771
772 // documented in qdatetime.cpp
773 enum TimeSpec {
774 LocalTime,
775 UTC
776 };
777
778 // documented in qwidget.cpp
779 enum BackgroundMode {
780 FixedColor,
781 FixedPixmap,
782 NoBackground,
783 PaletteForeground,
784 PaletteButton,
785 PaletteLight,
786 PaletteMidlight,
787 PaletteDark,
788 PaletteMid,
789 PaletteText,
790 PaletteBrightText,
791 PaletteBase,
792 PaletteBackground,
793 PaletteShadow,
794 PaletteHighlight,
795 PaletteHighlightedText,
796 PaletteButtonText,
797 PaletteLink,
798 PaletteLinkVisited,
799 X11ParentRelative
800 };
801
802 typedef uint ComparisonFlags;
803
804 // Documented in qstring.cpp
805 enum StringComparisonMode {
806 CaseSensitive = 0x00001, // 0 0001
807 BeginsWith = 0x00002, // 0 0010
808 EndsWith = 0x00004, // 0 0100
809 Contains = 0x00008, // 0 1000
810 ExactMatch = 0x00010 // 1 0000
811 };
812
813 // "handle" type for system objects. Documented as \internal in
814 // qapplication.cpp
815#if defined(Q_WS_MAC)
816 typedef void * HANDLE;
817#elif defined(Q_WS_WIN)
818 typedef void *HANDLE;
819#elif defined(Q_WS_X11)
820 typedef unsigned long HANDLE;
821#elif defined(Q_WS_QWS)
822 typedef void * HANDLE;
823#endif
824};
825
826
827class Q_EXPORT QInternal {
828public:
829 enum PaintDeviceFlags {
830 UndefinedDevice = 0x00,
831 Widget = 0x01,
832 Pixmap = 0x02,
833 Printer = 0x03,
834 Picture = 0x04,
835 System = 0x05,
836 DeviceTypeMask = 0x0f,
837 ExternalDevice = 0x10,
838 // used to emulate some of the behaviour different between Qt2 and Qt3 (mainly for printing)
839 CompatibilityMode = 0x20
840 };
841};
842
843#endif // QNAMESPACE_H
diff --git a/qmake/include/qpair.h b/qmake/include/qpair.h
new file mode 100644
index 0000000..e7cd70e
--- a/dev/null
+++ b/qmake/include/qpair.h
@@ -0,0 +1,96 @@
1/****************************************************************************
2**
3** Definition of QPair class
4**
5**
6** Copyright (C) 1992-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#ifndef QPAIR_H
37#define QPAIR_H
38
39#ifndef QT_H
40#include "qglobal.h"
41#include "qdatastream.h"
42#endif // QT_H
43
44template <class T1, class T2>
45struct QPair
46{
47 typedef T1 first_type;
48 typedef T2 second_type;
49
50 QPair()
51 : first( T1() ), second( T2() )
52 {}
53 QPair( const T1& t1, const T2& t2 )
54 : first( t1 ), second( t2 )
55 {}
56
57 T1 first;
58 T2 second;
59};
60
61template <class T1, class T2>
62Q_INLINE_TEMPLATES bool operator==( const QPair<T1, T2>& x, const QPair<T1, T2>& y )
63{
64 return x.first == y.first && x.second == y.second;
65}
66
67template <class T1, class T2>
68Q_INLINE_TEMPLATES bool operator<( const QPair<T1, T2>& x, const QPair<T1, T2>& y )
69{
70 return x.first < y.first ||
71 ( !( y.first < x.first ) && x.second < y.second );
72}
73
74template <class T1, class T2>
75Q_INLINE_TEMPLATES QPair<T1, T2> qMakePair( const T1& x, const T2& y )
76{
77 return QPair<T1, T2>( x, y );
78}
79
80#ifndef QT_NO_DATASTREAM
81template <class T1, class T2>
82inline QDataStream& operator>>( QDataStream& s, QPair<T1, T2>& p )
83{
84 s >> p.first >> p.second;
85 return s;
86}
87
88template <class T1, class T2>
89inline QDataStream& operator<<( QDataStream& s, const QPair<T1, T2>& p )
90{
91 s << p.first << p.second;
92 return s;
93}
94#endif
95
96#endif
diff --git a/qmake/include/qptrcollection.h b/qmake/include/qptrcollection.h
new file mode 100644
index 0000000..4f121fa
--- a/dev/null
+++ b/qmake/include/qptrcollection.h
@@ -0,0 +1,76 @@
1/****************************************************************************
2**
3** Definition of base class for all pointer based collection classes
4**
5**
6** Copyright (C) 1992-2000 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#ifndef QPTRCOLLECTION_H
37#define QPTRCOLLECTION_H
38
39#ifndef QT_H
40#include "qglobal.h"
41#endif // QT_H
42
43
44class QGVector;
45class QGList;
46class QGDict;
47
48
49 class Q_EXPORT QPtrCollection // inherited by all collections
50{
51public:
52 bool autoDelete() const { return del_item; }
53 void setAutoDelete( bool enable ) { del_item = enable; }
54
55 virtual uint count() const = 0;
56 virtual void clear() = 0; // delete all objects
57
58 typedef void *Item; // generic collection item
59
60protected:
61 QPtrCollection() { del_item = FALSE; } // no deletion of objects
62 QPtrCollection(const QPtrCollection &) { del_item = FALSE; }
63 virtual ~QPtrCollection() {}
64
65 bool del_item; // default FALSE
66
67 virtual Item newItem( Item ); // create object
68 virtual void deleteItem( Item ) = 0;// delete object
69};
70
71
72#ifndef QT_NO_COMPAT
73#define QCollection QPtrCollection
74#endif
75
76#endif // QPTRCOLLECTION_H
diff --git a/qmake/include/qptrlist.h b/qmake/include/qptrlist.h
new file mode 100644
index 0000000..53fb605
--- a/dev/null
+++ b/qmake/include/qptrlist.h
@@ -0,0 +1,160 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QPtrList template/macro class
5**
6** Created :
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#ifndef QPTRLIST_H
39#define QPTRLIST_H
40
41#ifndef QT_H
42#include "qglist.h"
43#endif // QT_H
44
45
46template<class type>
47class QPtrList
48#ifdef Q_QDOC
49 : public QPtrCollection
50#else
51 : public QGList
52#endif
53{
54public:
55 QPtrList() {}
56 QPtrList( const QPtrList<type> &l ) : QGList(l) {}
57 ~QPtrList() { clear(); }
58 QPtrList<type> &operator=(const QPtrList<type> &l)
59 { return (QPtrList<type>&)QGList::operator=(l); }
60 bool operator==( const QPtrList<type> &list ) const
61 { return QGList::operator==( list ); }
62 bool operator!=( const QPtrList<type> &list ) const
63 { return !QGList::operator==( list ); }
64 uint count() const { return QGList::count(); }
65 bool isEmpty() const { return QGList::count() == 0; }
66 bool insert( uint i, const type *d){ return QGList::insertAt(i,(QPtrCollection::Item)d); }
67 void inSort( const type *d ){ QGList::inSort((QPtrCollection::Item)d); }
68 void prepend( const type *d ){ QGList::insertAt(0,(QPtrCollection::Item)d); }
69 void append( const type *d ){ QGList::append((QPtrCollection::Item)d); }
70 bool remove( uint i ) { return QGList::removeAt(i); }
71 bool remove() { return QGList::remove((QPtrCollection::Item)0); }
72 bool remove( const type *d ){ return QGList::remove((QPtrCollection::Item)d); }
73 bool removeRef( const type *d ){ return QGList::removeRef((QPtrCollection::Item)d); }
74 void removeNode( QLNode *n ){ QGList::removeNode(n); }
75 bool removeFirst() { return QGList::removeFirst(); }
76 bool removeLast() { return QGList::removeLast(); }
77 type *take( uint i ) { return (type *)QGList::takeAt(i); }
78 type *take() { return (type *)QGList::take(); }
79 type *takeNode( QLNode *n ) { return (type *)QGList::takeNode(n); }
80 void clear() { QGList::clear(); }
81 void sort() { QGList::sort(); }
82 int find( const type *d ) { return QGList::find((QPtrCollection::Item)d); }
83 int findNext( const type *d ){ return QGList::find((QPtrCollection::Item)d,FALSE); }
84 int findRef( const type *d ){ return QGList::findRef((QPtrCollection::Item)d); }
85 int findNextRef( const type *d ){ return QGList::findRef((QPtrCollection::Item)d,FALSE);}
86 uint contains( const type *d ) const { return QGList::contains((QPtrCollection::Item)d); }
87 uint containsRef( const type *d ) const
88 { return QGList::containsRef((QPtrCollection::Item)d); }
89 bool replace( uint i, const type *d ) { return QGList::replaceAt( i, (QPtrCollection::Item)d ); }
90 type *at( uint i ) { return (type *)QGList::at(i); }
91 int at() const { return QGList::at(); }
92 type *current() const { return (type *)QGList::get(); }
93 QLNode *currentNode() const{ return QGList::currentNode(); }
94 type *getFirst() const { return (type *)QGList::cfirst(); }
95 type *getLast() const { return (type *)QGList::clast(); }
96 type *first() { return (type *)QGList::first(); }
97 type *last() { return (type *)QGList::last(); }
98 type *next() { return (type *)QGList::next(); }
99 type *prev() { return (type *)QGList::prev(); }
100 void toVector( QGVector *vec )const{ QGList::toVector(vec); }
101
102#ifdef Q_QDOC
103protected:
104 virtual int compareItems( QPtrCollection::Item, QPtrCollection::Item );
105 virtual QDataStream& read( QDataStream&, QPtrCollection::Item& );
106 virtual QDataStream& write( QDataStream&, QPtrCollection::Item ) const;
107#endif
108
109private:
110 void deleteItem( Item d );
111};
112
113#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION)
114template<> inline void QPtrList<void>::deleteItem( QPtrCollection::Item )
115{
116}
117#endif
118
119template<class type> inline void QPtrList<type>::deleteItem( QPtrCollection::Item d )
120{
121 if ( del_item ) delete (type *)d;
122}
123
124template<class type>
125class QPtrListIterator : public QGListIterator
126{
127public:
128 QPtrListIterator(const QPtrList<type> &l) :QGListIterator((QGList &)l) {}
129 ~QPtrListIterator() {}
130 uint count() const { return list->count(); }
131 bool isEmpty() const { return list->count() == 0; }
132 bool atFirst() const { return QGListIterator::atFirst(); }
133 bool atLast() const { return QGListIterator::atLast(); }
134 type *toFirst() { return (type *)QGListIterator::toFirst(); }
135 type *toLast() { return (type *)QGListIterator::toLast(); }
136 operator type *() const { return (type *)QGListIterator::get(); }
137 type *operator*() { return (type *)QGListIterator::get(); }
138
139 // No good, since QPtrList<char> (ie. QStrList fails...
140 //
141 // MSVC++ gives warning
142 // Sunpro C++ 4.1 gives error
143 // type *operator->() { return (type *)QGListIterator::get(); }
144
145 type *current() const { return (type *)QGListIterator::get(); }
146 type *operator()() { return (type *)QGListIterator::operator()();}
147 type *operator++() { return (type *)QGListIterator::operator++(); }
148 type *operator+=(uint j) { return (type *)QGListIterator::operator+=(j);}
149 type *operator--() { return (type *)QGListIterator::operator--(); }
150 type *operator-=(uint j) { return (type *)QGListIterator::operator-=(j);}
151 QPtrListIterator<type>& operator=(const QPtrListIterator<type>&it)
152 { QGListIterator::operator=(it); return *this; }
153};
154
155#ifndef QT_NO_COMPAT
156#define QList QPtrList
157#define QListIterator QPtrListIterator
158#endif
159
160#endif // QPTRLIST_H
diff --git a/qmake/include/qptrvector.h b/qmake/include/qptrvector.h
new file mode 100644
index 0000000..f6d9623
--- a/dev/null
+++ b/qmake/include/qptrvector.h
@@ -0,0 +1,113 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QPtrVector pointer based template 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#ifndef QPTRVECTOR_H
39#define QPTRVECTOR_H
40
41#ifndef QT_H
42#include "qgvector.h"
43#endif // QT_H
44
45template<class type>
46class QPtrVector
47#ifdef Q_QDOC
48 : public QPtrCollection
49#else
50 : public QGVector
51#endif
52{
53public:
54 QPtrVector() { }
55 QPtrVector( uint size ) : QGVector(size) { }
56 QPtrVector( const QPtrVector<type> &v ) : QGVector( v ) { }
57 ~QPtrVector() { clear(); }
58 QPtrVector<type> &operator=(const QPtrVector<type> &v)
59 { return (QPtrVector<type>&)QGVector::operator=(v); }
60 bool operator==( const QPtrVector<type> &v ) const { return QGVector::operator==(v); }
61 type **data() const { return (type **)QGVector::data(); }
62 uint size() const { return QGVector::size(); }
63 uint count() const { return QGVector::count(); }
64 bool isEmpty() const { return QGVector::count() == 0; }
65 bool isNull() const { return QGVector::size() == 0; }
66 bool resize( uint size ) { return QGVector::resize(size); }
67 bool insert( uint i, const type *d){ return QGVector::insert(i,(Item)d); }
68 bool remove( uint i ) { return QGVector::remove(i); }
69 type *take( uint i ) { return (type *)QGVector::take(i); }
70 void clear() { QGVector::clear(); }
71 bool fill( const type *d, int size=-1 )
72 { return QGVector::fill((Item)d,size);}
73 void sort() { QGVector::sort(); }
74 int bsearch( const type *d ) const{ return QGVector::bsearch((Item)d); }
75 int findRef( const type *d, uint i=0 ) const
76 { return QGVector::findRef((Item)d,i);}
77 int find( const type *d, uint i= 0 ) const
78 { return QGVector::find((Item)d,i); }
79 uint containsRef( const type *d ) const
80 { return QGVector::containsRef((Item)d); }
81 uint contains( const type *d ) const
82 { return QGVector::contains((Item)d); }
83 type *operator[]( int i ) const{ return (type *)QGVector::at(i); }
84 type *at( uint i ) const { return (type *)QGVector::at(i); }
85 void toList( QGList *list ) const{ QGVector::toList(list); }
86
87#ifdef Q_QDOC
88protected:
89 virtual int compareItems( QPtrCollection::Item d1, QPtrCollection::Item d2 );
90 virtual QDataStream& read( QDataStream &s, QPtrCollection::Item &d );
91 virtual QDataStream& write( QDataStream &s, QPtrCollection::Item d ) const;
92#endif
93
94private:
95 void deleteItem( Item d );
96};
97
98#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION)
99template<> inline void QPtrVector<void>::deleteItem( QPtrCollection::Item )
100{
101}
102#endif
103
104template<class type> inline void QPtrVector<type>::deleteItem( QPtrCollection::Item d )
105{
106 if ( del_item ) delete (type *)d;
107}
108
109#ifndef QT_NO_COMPAT
110#define QVector QPtrVector
111#endif
112
113#endif // QVECTOR_H
diff --git a/qmake/include/qregexp.h b/qmake/include/qregexp.h
new file mode 100644
index 0000000..7bb777a
--- a/dev/null
+++ b/qmake/include/qregexp.h
@@ -0,0 +1,115 @@
1/****************************************************************************
2** $Id$
3**
4** Definition 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#ifndef QREGEXP_H
39#define QREGEXP_H
40
41#ifndef QT_H
42#include "qstringlist.h"
43#endif // QT_H
44
45#ifndef QT_NO_REGEXP
46class QRegExpEngine;
47struct QRegExpPrivate;
48
49class Q_EXPORT QRegExp
50{
51public:
52 enum CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch };
53
54 QRegExp();
55 QRegExp( const QString& pattern, bool caseSensitive = TRUE,
56 bool wildcard = FALSE );
57 QRegExp( const QRegExp& rx );
58 ~QRegExp();
59 QRegExp& operator=( const QRegExp& rx );
60
61 bool operator==( const QRegExp& rx ) const;
62 bool operator!=( const QRegExp& rx ) const { return !operator==( rx ); }
63
64 bool isEmpty() const;
65 bool isValid() const;
66 QString pattern() const;
67 void setPattern( const QString& pattern );
68 bool caseSensitive() const;
69 void setCaseSensitive( bool sensitive );
70#ifndef QT_NO_REGEXP_WILDCARD
71 bool wildcard() const;
72 void setWildcard( bool wildcard );
73#endif
74 bool minimal() const;
75 void setMinimal( bool minimal );
76
77 bool exactMatch( const QString& str ) const;
78#ifndef QT_NO_COMPAT
79 int match( const QString& str, int index = 0, int *len = 0,
80 bool indexIsStart = TRUE ) const;
81#endif
82
83#if defined(qdoc)
84 int search( const QString& str, int offset = 0,
85 CaretMode caretMode = CaretAtZero ) const;
86 int searchRev( const QString& str, int offset = -1,
87 CaretMode caretMode = CaretAtZero ) const;
88#else
89 // ### Qt 4.0: reduce these four to two functions
90 int search( const QString& str, int offset = 0 ) const;
91 int search( const QString& str, int offset, CaretMode caretMode ) const;
92 int searchRev( const QString& str, int offset = -1 ) const;
93 int searchRev( const QString& str, int offset, CaretMode caretMode ) const;
94#endif
95 int matchedLength() const;
96#ifndef QT_NO_REGEXP_CAPTURE
97 int numCaptures() const;
98 QStringList capturedTexts();
99 QString cap( int nth = 0 );
100 int pos( int nth = 0 );
101 QString errorString();
102#endif
103
104 static QString escape( const QString& str );
105
106private:
107 void compile( bool caseSensitive );
108
109 static int caretIndex( int offset, CaretMode caretMode );
110
111 QRegExpEngine *eng;
112 QRegExpPrivate *priv;
113};
114#endif // QT_NO_REGEXP
115#endif // QREGEXP_H
diff --git a/qmake/include/qshared.h b/qmake/include/qshared.h
new file mode 100644
index 0000000..3c2f97f
--- a/dev/null
+++ b/qmake/include/qshared.h
@@ -0,0 +1,55 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QShared struct
5**
6** Created : 940112
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#ifndef QSHARED_H
39#define QSHARED_H
40
41#ifndef QT_H
42#include "qglobal.h"
43#endif // QT_H
44
45
46struct Q_EXPORT QShared
47{
48 QShared() : count( 1 ) { }
49 void ref() { count++; }
50 bool deref(){ return !--count; }
51 uint count;
52};
53
54
55#endif // QSHARED_H
diff --git a/qmake/include/qstring.h b/qmake/include/qstring.h
new file mode 100644
index 0000000..2a87a5a
--- a/dev/null
+++ b/qmake/include/qstring.h
@@ -0,0 +1,950 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of the QString class, and related Unicode
5** functions.
6**
7** Created : 920609
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#ifndef QSTRING_H
40#define QSTRING_H
41
42#ifndef QT_H
43#include "qcstring.h"
44#endif // QT_H
45
46
47/*****************************************************************************
48 QString class
49 *****************************************************************************/
50
51class QRegExp;
52class QString;
53class QCharRef;
54template <class T> class QDeepCopy;
55
56class Q_EXPORT QChar {
57public:
58 QChar();
59 QChar( char c );
60 QChar( uchar c );
61 QChar( uchar c, uchar r );
62 QChar( const QChar& c );
63 QChar( ushort rc );
64 QChar( short rc );
65 QChar( uint rc );
66 QChar( int rc );
67
68 QT_STATIC_CONST QChar null; // 0000
69 QT_STATIC_CONST QChar replacement; // FFFD
70 QT_STATIC_CONST QChar byteOrderMark; // FEFF
71 QT_STATIC_CONST QChar byteOrderSwapped; // FFFE
72 QT_STATIC_CONST QChar nbsp; // 00A0
73
74 // Unicode information
75
76 enum Category
77 {
78 NoCategory,
79
80 Mark_NonSpacing, // Mn
81 Mark_SpacingCombining, // Mc
82 Mark_Enclosing, // Me
83
84 Number_DecimalDigit, // Nd
85 Number_Letter, // Nl
86 Number_Other, // No
87
88 Separator_Space, // Zs
89 Separator_Line, // Zl
90 Separator_Paragraph, // Zp
91
92 Other_Control, // Cc
93 Other_Format, // Cf
94 Other_Surrogate, // Cs
95 Other_PrivateUse, // Co
96 Other_NotAssigned, // Cn
97
98 Letter_Uppercase, // Lu
99 Letter_Lowercase, // Ll
100 Letter_Titlecase, // Lt
101 Letter_Modifier, // Lm
102 Letter_Other, // Lo
103
104 Punctuation_Connector, // Pc
105 Punctuation_Dash, // Pd
106 Punctuation_Dask = Punctuation_Dash, // oops
107 Punctuation_Open, // Ps
108 Punctuation_Close, // Pe
109 Punctuation_InitialQuote, // Pi
110 Punctuation_FinalQuote, // Pf
111 Punctuation_Other, // Po
112
113 Symbol_Math, // Sm
114 Symbol_Currency, // Sc
115 Symbol_Modifier, // Sk
116 Symbol_Other // So
117 };
118
119 enum Direction
120 {
121 DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
122 DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
123 };
124
125 enum Decomposition
126 {
127 Single, Canonical, Font, NoBreak, Initial, Medial,
128 Final, Isolated, Circle, Super, Sub, Vertical,
129 Wide, Narrow, Small, Square, Compat, Fraction
130 };
131
132 enum Joining
133 {
134 OtherJoining, Dual, Right, Center
135 };
136
137 enum CombiningClass
138 {
139 Combining_BelowLeftAttached = 200,
140 Combining_BelowAttached = 202,
141 Combining_BelowRightAttached = 204,
142 Combining_LeftAttached = 208,
143 Combining_RightAttached = 210,
144 Combining_AboveLeftAttached = 212,
145 Combining_AboveAttached = 214,
146 Combining_AboveRightAttached = 216,
147
148 Combining_BelowLeft = 218,
149 Combining_Below = 220,
150 Combining_BelowRight = 222,
151 Combining_Left = 224,
152 Combining_Right = 226,
153 Combining_AboveLeft = 228,
154 Combining_Above = 230,
155 Combining_AboveRight = 232,
156
157 Combining_DoubleBelow = 233,
158 Combining_DoubleAbove = 234,
159 Combining_IotaSubscript = 240
160 };
161
162 // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
163
164 int digitValue() const;
165 QChar lower() const;
166 QChar upper() const;
167
168 Category category() const;
169 Direction direction() const;
170 Joining joining() const;
171 bool mirrored() const;
172 QChar mirroredChar() const;
173 const QString &decomposition() const; // ### return just QString in 4.0
174 Decomposition decompositionTag() const;
175 unsigned char combiningClass() const;
176
177 char latin1() const { return ucs > 0xff ? 0 : (char) ucs; }
178 ushort unicode() const { return ucs; }
179 ushort &unicode() { return ucs; }
180#ifndef QT_NO_CAST_ASCII
181 // like all ifdef'd code this is undocumented
182 operator char() const { return latin1(); }
183#endif
184
185 bool isNull() const { return unicode()==0; }
186 bool isPrint() const;
187 bool isPunct() const;
188 bool isSpace() const;
189 bool isMark() const;
190 bool isLetter() const;
191 bool isNumber() const;
192 bool isLetterOrNumber() const;
193 bool isDigit() const;
194 bool isSymbol() const;
195
196 uchar cell() const { return ((uchar) ucs & 0xff); }
197 uchar row() const { return ((uchar) (ucs>>8)&0xff); }
198 void setCell( uchar cell ) { ucs = (ucs & 0xff00) + cell; }
199 void setRow( uchar row ) { ucs = (((ushort) row)<<8) + (ucs&0xff); }
200
201 static bool networkOrdered() {
202 int wordSize;
203 bool bigEndian = FALSE;
204 qSysInfo( &wordSize, &bigEndian );
205 return bigEndian;
206 }
207
208 friend inline bool operator==( char ch, QChar c );
209 friend inline bool operator==( QChar c, char ch );
210 friend inline bool operator==( QChar c1, QChar c2 );
211 friend inline bool operator!=( QChar c1, QChar c2 );
212 friend inline bool operator!=( char ch, QChar c );
213 friend inline bool operator!=( QChar c, char ch );
214 friend inline bool operator<=( QChar c, char ch );
215 friend inline bool operator<=( char ch, QChar c );
216 friend inline bool operator<=( QChar c1, QChar c2 );
217
218private:
219 ushort ucs;
220#if defined(QT_QSTRING_UCS_4)
221 ushort grp;
222#endif
223} Q_PACKED;
224
225inline QChar::QChar() : ucs( 0 )
226#ifdef QT_QSTRING_UCS_4
227 , grp( 0 )
228#endif
229{
230}
231inline QChar::QChar( char c ) : ucs( (uchar)c )
232#ifdef QT_QSTRING_UCS_4
233 , grp( 0 )
234#endif
235{
236}
237inline QChar::QChar( uchar c ) : ucs( c )
238#ifdef QT_QSTRING_UCS_4
239 , grp( 0 )
240#endif
241{
242}
243inline QChar::QChar( uchar c, uchar r ) : ucs( (r << 8) | c )
244#ifdef QT_QSTRING_UCS_4
245 , grp( 0 )
246#endif
247{
248}
249inline QChar::QChar( const QChar& c ) : ucs( c.ucs )
250#ifdef QT_QSTRING_UCS_4
251 , grp( c.grp )
252#endif
253{
254}
255
256inline QChar::QChar( ushort rc ) : ucs( rc )
257#ifdef QT_QSTRING_UCS_4
258 , grp( 0 )
259#endif
260{
261}
262inline QChar::QChar( short rc ) : ucs( (ushort) rc )
263#ifdef QT_QSTRING_UCS_4
264 , grp( 0 )
265#endif
266{
267}
268inline QChar::QChar( uint rc ) : ucs( (ushort ) (rc & 0xffff) )
269#ifdef QT_QSTRING_UCS_4
270 , grp( (ushort) ((rc >> 16) & 0xffff) )
271#endif
272{
273}
274inline QChar::QChar( int rc ) : ucs( (ushort) (rc & 0xffff) )
275#ifdef QT_QSTRING_UCS_4
276 , grp( (ushort) ((rc >> 16) & 0xffff) )
277#endif
278{
279}
280
281inline bool operator==( char ch, QChar c )
282{
283 return ((uchar) ch) == c.ucs;
284}
285
286inline bool operator==( QChar c, char ch )
287{
288 return ((uchar) ch) == c.ucs;
289}
290
291inline bool operator==( QChar c1, QChar c2 )
292{
293 return c1.ucs == c2.ucs;
294}
295
296inline bool operator!=( QChar c1, QChar c2 )
297{
298 return c1.ucs != c2.ucs;
299}
300
301inline bool operator!=( char ch, QChar c )
302{
303 return ((uchar)ch) != c.ucs;
304}
305
306inline bool operator!=( QChar c, char ch )
307{
308 return ((uchar) ch) != c.ucs;
309}
310
311inline bool operator<=( QChar c, char ch )
312{
313 return c.ucs <= ((uchar) ch);
314}
315
316inline bool operator<=( char ch, QChar c )
317{
318 return ((uchar) ch) <= c.ucs;
319}
320
321inline bool operator<=( QChar c1, QChar c2 )
322{
323 return c1.ucs <= c2.ucs;
324}
325
326inline bool operator>=( QChar c, char ch ) { return ch <= c; }
327inline bool operator>=( char ch, QChar c ) { return c <= ch; }
328inline bool operator>=( QChar c1, QChar c2 ) { return c2 <= c1; }
329inline bool operator<( QChar c, char ch ) { return !(ch<=c); }
330inline bool operator<( char ch, QChar c ) { return !(c<=ch); }
331inline bool operator<( QChar c1, QChar c2 ) { return !(c2<=c1); }
332inline bool operator>( QChar c, char ch ) { return !(ch>=c); }
333inline bool operator>( char ch, QChar c ) { return !(c>=ch); }
334inline bool operator>( QChar c1, QChar c2 ) { return !(c2>=c1); }
335
336// internal
337struct Q_EXPORT QStringData : public QShared {
338 QStringData() :
339 QShared(), unicode(0), ascii(0), len(0), simpletext(1), maxl(0), dirty(0) { ref(); }
340 QStringData(QChar *u, uint l, uint m) :
341 QShared(), unicode(u), ascii(0), len(l), simpletext(1), maxl(m), dirty(1) { }
342 ~QStringData() { if ( unicode ) delete[] ((char*)unicode);
343 if ( ascii ) delete[] ascii; }
344
345 void deleteSelf();
346 QChar *unicode;
347 char *ascii;
348 void setDirty() {
349 if ( ascii ) {
350 delete [] ascii;
351 ascii = 0;
352 }
353 dirty = 1;
354 }
355#ifdef Q_OS_MAC9
356 uint len;
357#else
358 uint len : 30;
359#endif
360 uint simpletext : 1;
361#ifdef Q_OS_MAC9
362 uint maxl;
363#else
364 uint maxl : 30;
365#endif
366 uint dirty : 1;
367
368private:
369#if defined(Q_DISABLE_COPY)
370 QStringData( const QStringData& );
371 QStringData& operator=( const QStringData& );
372#endif
373};
374
375
376class Q_EXPORT QString
377{
378public:
379 QString(); // make null string
380 QString( QChar ); // one-char string
381 QString( const QString & ); // impl-shared copy
382 QString( const QByteArray& ); // deep copy
383 QString( const QChar* unicode, uint length ); // deep copy
384#ifndef QT_NO_CAST_ASCII
385 QString( const char *str ); // deep copy
386#endif
387 ~QString();
388
389 QString &operator=( const QString & ); // impl-shared copy
390#ifndef QT_NO_CAST_ASCII
391 QString &operator=( const char * ); // deep copy
392#endif
393 QString &operator=( const QCString& ); // deep copy
394 QString &operator=( QChar c );
395 QString &operator=( char c );
396
397 QT_STATIC_CONST QString null;
398
399 bool isNull() const;
400 bool isEmpty() const;
401 uint length() const;
402 void truncate( uint pos );
403
404 QString & fill( QChar c, int len = -1 );
405
406 QString copy() const;
407
408 QString arg( long a, int fieldwidth=0, int base=10 ) const;
409 QString arg( ulong a, int fieldwidth=0, int base=10 ) const;
410 QString arg( int a, int fieldwidth=0, int base=10 ) const;
411 QString arg( uint a, int fieldwidth=0, int base=10 ) const;
412 QString arg( short a, int fieldwidth=0, int base=10 ) const;
413 QString arg( ushort a, int fieldwidth=0, int base=10 ) const;
414 QString arg( char a, int fieldwidth=0 ) const;
415 QString arg( QChar a, int fieldwidth=0 ) const;
416 QString arg( const QString& a, int fieldwidth=0 ) const;
417 QString arg( double a, int fieldwidth=0, char fmt='g', int prec=-1 ) const;
418
419#ifndef QT_NO_SPRINTF
420 QString &sprintf( const char* format, ... )
421#if defined(Q_CC_GNU) && !defined(__INSURE__)
422 __attribute__ ((format (printf, 2, 3)))
423#endif
424 ;
425#endif
426
427 int find( QChar c, int index=0, bool cs=TRUE ) const;
428 int find( char c, int index=0, bool cs=TRUE ) const;
429 int find( const QString &str, int index=0, bool cs=TRUE ) const;
430#ifndef QT_NO_REGEXP
431 int find( const QRegExp &, int index=0 ) const;
432#endif
433#ifndef QT_NO_CAST_ASCII
434 int find( const char* str, int index=0 ) const;
435#endif
436 int findRev( QChar c, int index=-1, bool cs=TRUE) const;
437 int findRev( char c, int index=-1, bool cs=TRUE) const;
438 int findRev( const QString &str, int index=-1, bool cs=TRUE) const;
439#ifndef QT_NO_REGEXP
440 int findRev( const QRegExp &, int index=-1 ) const;
441#endif
442#ifndef QT_NO_CAST_ASCII
443 int findRev( const char* str, int index=-1 ) const;
444#endif
445 int contains( QChar c, bool cs=TRUE ) const;
446 int contains( char c, bool cs=TRUE ) const
447 { return contains(QChar(c), cs); }
448#ifndef QT_NO_CAST_ASCII
449 int contains( const char* str, bool cs=TRUE ) const;
450#endif
451 int contains( const QString &str, bool cs=TRUE ) const;
452#ifndef QT_NO_REGEXP
453 int contains( const QRegExp & ) const;
454#endif
455
456 enum SectionFlags {
457 SectionDefault = 0x00,
458 SectionSkipEmpty = 0x01,
459 SectionIncludeLeadingSep = 0x02,
460 SectionIncludeTrailingSep = 0x04,
461 SectionCaseInsensitiveSeps = 0x08
462 };
463 QString section( QChar sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
464 QString section( char sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
465#ifndef QT_NO_CAST_ASCII
466 QString section( const char *in_sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
467#endif
468 QString section( const QString &in_sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
469#ifndef QT_NO_REGEXP
470 QString section( const QRegExp &reg, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
471#endif
472
473 QString left( uint len ) const;
474 QString right( uint len ) const;
475 QString mid( uint index, uint len=0xffffffff) const;
476
477 QString leftJustify( uint width, QChar fill=' ', bool trunc=FALSE)const;
478 QString rightJustify( uint width, QChar fill=' ',bool trunc=FALSE)const;
479
480 QString lower() const;
481 QString upper() const;
482
483 QString stripWhiteSpace() const;
484 QString simplifyWhiteSpace() const;
485
486 QString &insert( uint index, const QString & );
487 QString &insert( uint index, const QChar*, uint len );
488 QString &insert( uint index, QChar );
489 QString &insert( uint index, char c ) { return insert(index,QChar(c)); }
490 QString &append( char );
491 QString &append( QChar );
492 QString &append( const QString & );
493#ifndef QT_NO_CAST_ASCII
494 QString &append( const QByteArray & );
495 QString &append( const char * );
496#endif
497 QString &prepend( char );
498 QString &prepend( QChar );
499 QString &prepend( const QString & );
500#ifndef QT_NO_CAST_ASCII
501 QString &prepend( const QByteArray & );
502 QString &prepend( const char * );
503#endif
504 QString &remove( uint index, uint len );
505 QString &remove( QChar c );
506 QString &remove( char c ) { return remove( QChar(c) ); }
507 QString &remove( const QString & );
508#ifndef QT_NO_REGEXP
509 QString &remove( const QRegExp & );
510#endif
511#ifndef QT_NO_CAST_ASCII
512 QString &remove( const char * );
513#endif
514 QString &replace( uint index, uint len, const QString & );
515 QString &replace( uint index, uint len, const QChar*, uint clen );
516 QString &replace( uint index, uint len, QChar );
517 QString &replace( uint index, uint len, char c )
518 { return replace( index, len, QChar(c) ); }
519 QString &replace( QChar c, const QString & );
520 QString &replace( char c, const QString & after )
521 { return replace( QChar(c), after ); }
522 QString &replace( const QString &, const QString & );
523#ifndef QT_NO_REGEXP_CAPTURE
524 QString &replace( const QRegExp &, const QString & );
525#endif
526 QString &replace( QChar, QChar );
527
528 short toShort( bool *ok=0, int base=10 ) const;
529 ushort toUShort( bool *ok=0, int base=10 ) const;
530 int toInt( bool *ok=0, int base=10 ) const;
531 uint toUInt( bool *ok=0, int base=10 ) const;
532 long toLong( bool *ok=0, int base=10 ) const;
533 ulong toULong( bool *ok=0, int base=10 ) const;
534 float toFloat( bool *ok=0 ) const;
535 double toDouble( bool *ok=0 ) const;
536
537 QString &setNum( short, int base=10 );
538 QString &setNum( ushort, int base=10 );
539 QString &setNum( int, int base=10 );
540 QString &setNum( uint, int base=10 );
541 QString &setNum( long, int base=10 );
542 QString &setNum( ulong, int base=10 );
543 QString &setNum( float, char f='g', int prec=6 );
544 QString &setNum( double, char f='g', int prec=6 );
545
546 static QString number( long, int base=10 );
547 static QString number( ulong, int base=10);
548 static QString number( int, int base=10 );
549 static QString number( uint, int base=10);
550 static QString number( double, char f='g', int prec=6 );
551
552 void setExpand( uint index, QChar c );
553
554 QString &operator+=( const QString &str );
555#ifndef QT_NO_CAST_ASCII
556 QString &operator+=( const QByteArray &str );
557 QString &operator+=( const char *str );
558#endif
559 QString &operator+=( QChar c );
560 QString &operator+=( char c );
561
562 QChar at( uint i ) const
563 { return i < d->len ? d->unicode[i] : QChar::null; }
564 QChar operator[]( int i ) const { return at((uint)i); }
565 QCharRef at( uint i );
566 QCharRef operator[]( int i );
567
568 QChar constref(uint i) const
569 { return at(i); }
570 QChar& ref(uint i)
571 { // Optimized for easy-inlining by simple compilers.
572 if ( d->count != 1 || i >= d->len )
573 subat( i );
574 d->setDirty();
575 return d->unicode[i];
576 }
577
578 const QChar* unicode() const { return d->unicode; }
579 const char* ascii() const { return latin1(); }
580 const char* latin1() const;
581 static QString fromLatin1(const char*, int len=-1);
582 QCString utf8() const;
583 static QString fromUtf8(const char*, int len=-1);
584 QCString local8Bit() const;
585 static QString fromLocal8Bit(const char*, int len=-1);
586 bool operator!() const;
587#ifndef QT_NO_ASCII_CAST
588 operator const char *() const { return latin1(); }
589#endif
590 static QString fromUcs2( const unsigned short *ucs2 );
591 const unsigned short *ucs2() const;
592
593 QString &setUnicode( const QChar* unicode, uint len );
594 QString &setUnicodeCodes( const ushort* unicode_as_ushorts, uint len );
595 QString &setLatin1( const char*, int len=-1 );
596
597 int compare( const QString& s ) const;
598 static int compare( const QString& s1, const QString& s2 )
599 { return s1.compare( s2 ); }
600
601 int localeAwareCompare( const QString& s ) const;
602 static int localeAwareCompare( const QString& s1, const QString& s2 )
603 { return s1.localeAwareCompare( s2 ); }
604
605#ifndef QT_NO_DATASTREAM
606 friend Q_EXPORT QDataStream &operator>>( QDataStream &, QString & );
607#endif
608
609 void compose();
610
611#ifndef QT_NO_COMPAT
612 const char* data() const { return latin1(); }
613#endif
614
615 bool startsWith( const QString& ) const;
616 bool endsWith( const QString& ) const;
617
618 void setLength( uint newLength );
619
620 bool simpleText() const { if ( d->dirty ) checkSimpleText(); return (bool)d->simpletext; }
621 bool isRightToLeft() const;
622
623
624private:
625 QString( int size, bool /* dummy */ );// allocate size incl. \0
626
627 void deref();
628 void real_detach();
629 void subat( uint );
630 bool findArg(int& pos, int& len) const;
631
632 void checkSimpleText() const;
633
634 static QChar* asciiToUnicode( const char*, uint * len, uint maxlen=(uint)-1 );
635 static QChar* asciiToUnicode( const QByteArray&, uint * len );
636 static char* unicodeToAscii( const QChar*, uint len );
637
638 QStringData *d;
639 static QStringData* shared_null;
640 static QStringData* makeSharedNull();
641
642 friend class QConstString;
643 friend class QTextStream;
644 QString( QStringData* dd, bool /* dummy */ ) : d(dd) { }
645
646 // needed for QDeepCopy
647 void detach();
648 friend class QDeepCopy<QString>;
649};
650
651class Q_EXPORT QCharRef {
652 friend class QString;
653 QString& s;
654 uint p;
655 QCharRef(QString* str, uint pos) : s(*str), p(pos) { }
656
657public:
658 // most QChar operations repeated here...
659
660 // all this is not documented: We just say "like QChar" and let it be.
661#ifndef Q_QDOC
662 ushort unicode() const { return s.constref(p).unicode(); }
663 char latin1() const { return s.constref(p).latin1(); }
664
665 // An operator= for each QChar cast constructor...
666 QCharRef operator=(char c ) { s.ref(p)=c; return *this; }
667 QCharRef operator=(uchar c ) { s.ref(p)=c; return *this; }
668 QCharRef operator=(QChar c ) { s.ref(p)=c; return *this; }
669 QCharRef operator=(const QCharRef& c ) { s.ref(p)=c.unicode(); return *this; }
670 QCharRef operator=(ushort rc ) { s.ref(p)=rc; return *this; }
671 QCharRef operator=(short rc ) { s.ref(p)=rc; return *this; }
672 QCharRef operator=(uint rc ) { s.ref(p)=rc; return *this; }
673 QCharRef operator=(int rc ) { s.ref(p)=rc; return *this; }
674
675 operator QChar () const { return s.constref(p); }
676
677 // each function...
678 bool isNull() const { return unicode()==0; }
679 bool isPrint() const { return s.constref(p).isPrint(); }
680 bool isPunct() const { return s.constref(p).isPunct(); }
681 bool isSpace() const { return s.constref(p).isSpace(); }
682 bool isMark() const { return s.constref(p).isMark(); }
683 bool isLetter() const { return s.constref(p).isLetter(); }
684 bool isNumber() const { return s.constref(p).isNumber(); }
685 bool isLetterOrNumber() { return s.constref(p).isLetterOrNumber(); }
686 bool isDigit() const { return s.constref(p).isDigit(); }
687
688 int digitValue() const { return s.constref(p).digitValue(); }
689 QChar lower() const { return s.constref(p).lower(); }
690 QChar upper() const { return s.constref(p).upper(); }
691
692 QChar::Category category() const { return s.constref(p).category(); }
693 QChar::Direction direction() const { return s.constref(p).direction(); }
694 QChar::Joining joining() const { return s.constref(p).joining(); }
695 bool mirrored() const { return s.constref(p).mirrored(); }
696 QChar mirroredChar() const { return s.constref(p).mirroredChar(); }
697 const QString &decomposition() const { return s.constref(p).decomposition(); }
698 QChar::Decomposition decompositionTag() const { return s.constref(p).decompositionTag(); }
699 unsigned char combiningClass() const { return s.constref(p).combiningClass(); }
700
701 // Not the non-const ones of these.
702 uchar cell() const { return s.constref(p).cell(); }
703 uchar row() const { return s.constref(p).row(); }
704#endif
705};
706
707inline QCharRef QString::at( uint i ) { return QCharRef(this,i); }
708inline QCharRef QString::operator[]( int i ) { return at((uint)i); }
709
710
711class Q_EXPORT QConstString : private QString {
712public:
713 QConstString( const QChar* unicode, uint length );
714 ~QConstString();
715 const QString& string() const { return *this; }
716};
717
718
719/*****************************************************************************
720 QString stream functions
721 *****************************************************************************/
722#ifndef QT_NO_DATASTREAM
723Q_EXPORT QDataStream &operator<<( QDataStream &, const QString & );
724Q_EXPORT QDataStream &operator>>( QDataStream &, QString & );
725#endif
726
727/*****************************************************************************
728 QString inline functions
729 *****************************************************************************/
730
731// These two move code into makeSharedNull() and deletesData()
732// to improve cache-coherence (and reduce code bloat), while
733// keeping the common cases fast.
734//
735// No safe way to pre-init shared_null on ALL compilers/linkers.
736inline QString::QString() :
737 d(shared_null ? shared_null : makeSharedNull())
738{
739 d->ref();
740}
741//
742inline QString::~QString()
743{
744 if ( d->deref() ) {
745 if ( d != shared_null )
746 d->deleteSelf();
747 }
748}
749
750// needed for QDeepCopy
751inline void QString::detach()
752{ real_detach(); }
753
754inline QString QString::section( QChar sep, int start, int end, int flags ) const
755{ return section(QString(sep), start, end, flags); }
756
757inline QString QString::section( char sep, int start, int end, int flags ) const
758{ return section(QChar(sep), start, end, flags); }
759
760#ifndef QT_NO_CAST_ASCII
761inline QString QString::section( const char *in_sep, int start, int end, int flags ) const
762{ return section(QString(in_sep), start, end, flags); }
763#endif
764
765inline QString &QString::operator=( QChar c )
766{ *this = QString(c); return *this; }
767
768inline QString &QString::operator=( char c )
769{ *this = QString(QChar(c)); return *this; }
770
771inline bool QString::isNull() const
772{ return unicode() == 0; }
773
774inline bool QString::operator!() const
775{ return isNull(); }
776
777inline uint QString::length() const
778{ return d->len; }
779
780inline bool QString::isEmpty() const
781{ return length() == 0; }
782
783inline QString QString::copy() const
784{ return QString( *this ); }
785
786inline QString &QString::prepend( const QString & s )
787{ return insert(0,s); }
788
789inline QString &QString::prepend( QChar c )
790{ return insert(0,c); }
791
792inline QString &QString::prepend( char c )
793{ return insert(0,c); }
794
795#ifndef QT_NO_CAST_ASCII
796inline QString &QString::prepend( const QByteArray & s )
797{ return insert(0,s.data()); }
798#endif
799
800inline QString &QString::append( const QString & s )
801{ return operator+=(s); }
802
803#ifndef QT_NO_CAST_ASCII
804inline QString &QString::append( const QByteArray &s )
805{ return operator+=(s.data()); }
806
807inline QString &QString::append( const char * s )
808{ return operator+=(s); }
809#endif
810
811inline QString &QString::append( QChar c )
812{ return operator+=(c); }
813
814inline QString &QString::append( char c )
815{ return operator+=(c); }
816
817#ifndef QT_NO_CAST_ASCII
818inline QString &QString::operator+=( const QByteArray &s )
819{ return operator+=(s.data()); }
820#endif
821
822inline QString &QString::setNum( short n, int base )
823{ return setNum((long)n, base); }
824
825inline QString &QString::setNum( ushort n, int base )
826{ return setNum((ulong)n, base); }
827
828inline QString &QString::setNum( int n, int base )
829{ return setNum((long)n, base); }
830
831inline QString &QString::setNum( uint n, int base )
832{ return setNum((ulong)n, base); }
833
834inline QString &QString::setNum( float n, char f, int prec )
835{ return setNum((double)n,f,prec); }
836
837inline QString QString::arg(int a, int fieldwidth, int base) const
838{ return arg((long)a, fieldwidth, base); }
839
840inline QString QString::arg(uint a, int fieldwidth, int base) const
841{ return arg((ulong)a, fieldwidth, base); }
842
843inline QString QString::arg(short a, int fieldwidth, int base) const
844{ return arg((long)a, fieldwidth, base); }
845
846inline QString QString::arg(ushort a, int fieldwidth, int base) const
847{ return arg((ulong)a, fieldwidth, base); }
848
849inline int QString::find( char c, int index, bool cs ) const
850{ return find(QChar(c), index, cs); }
851
852inline int QString::findRev( char c, int index, bool cs) const
853{ return findRev( QChar(c), index, cs ); }
854
855#ifndef QT_NO_CAST_ASCII
856inline int QString::find( const char* str, int index ) const
857{ return find(QString::fromLatin1(str), index); }
858
859inline int QString::findRev( const char* str, int index ) const
860{ return findRev(QString::fromLatin1(str), index); }
861#endif
862
863
864/*****************************************************************************
865 QString non-member operators
866 *****************************************************************************/
867
868Q_EXPORT bool operator!=( const QString &s1, const QString &s2 );
869Q_EXPORT bool operator<( const QString &s1, const QString &s2 );
870Q_EXPORT bool operator<=( const QString &s1, const QString &s2 );
871Q_EXPORT bool operator==( const QString &s1, const QString &s2 );
872Q_EXPORT bool operator>( const QString &s1, const QString &s2 );
873Q_EXPORT bool operator>=( const QString &s1, const QString &s2 );
874#ifndef QT_NO_CAST_ASCII
875Q_EXPORT bool operator!=( const QString &s1, const char *s2 );
876Q_EXPORT bool operator<( const QString &s1, const char *s2 );
877Q_EXPORT bool operator<=( const QString &s1, const char *s2 );
878Q_EXPORT bool operator==( const QString &s1, const char *s2 );
879Q_EXPORT bool operator>( const QString &s1, const char *s2 );
880Q_EXPORT bool operator>=( const QString &s1, const char *s2 );
881Q_EXPORT bool operator!=( const char *s1, const QString &s2 );
882Q_EXPORT bool operator<( const char *s1, const QString &s2 );
883Q_EXPORT bool operator<=( const char *s1, const QString &s2 );
884Q_EXPORT bool operator==( const char *s1, const QString &s2 );
885//Q_EXPORT bool operator>( const char *s1, const QString &s2 ); // MSVC++
886Q_EXPORT bool operator>=( const char *s1, const QString &s2 );
887#endif
888
889Q_EXPORT inline const QString operator+( const QString &s1, const QString &s2 )
890{
891 QString tmp( s1 );
892 tmp += s2;
893 return tmp;
894}
895
896#ifndef QT_NO_CAST_ASCII
897Q_EXPORT inline const QString operator+( const QString &s1, const char *s2 )
898{
899 QString tmp( s1 );
900 tmp += QString::fromLatin1(s2);
901 return tmp;
902}
903
904Q_EXPORT inline const QString operator+( const char *s1, const QString &s2 )
905{
906 QString tmp = QString::fromLatin1( s1 );
907 tmp += s2;
908 return tmp;
909}
910#endif
911
912Q_EXPORT inline const QString operator+( const QString &s1, QChar c2 )
913{
914 QString tmp( s1 );
915 tmp += c2;
916 return tmp;
917}
918
919Q_EXPORT inline const QString operator+( const QString &s1, char c2 )
920{
921 QString tmp( s1 );
922 tmp += c2;
923 return tmp;
924}
925
926Q_EXPORT inline const QString operator+( QChar c1, const QString &s2 )
927{
928 QString tmp;
929 tmp += c1;
930 tmp += s2;
931 return tmp;
932}
933
934Q_EXPORT inline const QString operator+( char c1, const QString &s2 )
935{
936 QString tmp;
937 tmp += c1;
938 tmp += s2;
939 return tmp;
940}
941
942#if defined(Q_OS_WIN32)
943extern Q_EXPORT QString qt_winQString(void*);
944extern Q_EXPORT const void* qt_winTchar(const QString& str, bool addnul);
945extern Q_EXPORT void* qt_winTchar_new(const QString& str);
946extern Q_EXPORT QCString qt_winQString2MB( const QString& s, int len=-1 );
947extern Q_EXPORT QString qt_winMB2QString( const char* mb, int len=-1 );
948#endif
949
950#endif // QSTRING_H
diff --git a/qmake/include/qstringlist.h b/qmake/include/qstringlist.h
new file mode 100644
index 0000000..be9d6ae
--- a/dev/null
+++ b/qmake/include/qstringlist.h
@@ -0,0 +1,86 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QStringList class
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#ifndef QSTRINGLIST_H
39#define QSTRINGLIST_H
40
41#ifndef QT_H
42#include "qvaluelist.h"
43#include "qstring.h"
44#include "qstrlist.h"
45#endif // QT_H
46
47#ifndef QT_NO_STRINGLIST
48
49class QRegExp;
50
51class Q_EXPORT QStringList : public QValueList<QString>
52{
53public:
54 QStringList() { }
55 QStringList( const QStringList& l ) : QValueList<QString>(l) { }
56 QStringList( const QValueList<QString>& l ) : QValueList<QString>(l) { }
57 QStringList( const QString& i ) { append(i); }
58#ifndef QT_NO_CAST_ASCII
59 QStringList( const char* i ) { append(i); }
60#endif
61
62 static QStringList fromStrList(const QStrList&);
63
64 void sort();
65
66 static QStringList split( const QString &sep, const QString &str, bool allowEmptyEntries = FALSE );
67 static QStringList split( const QChar &sep, const QString &str, bool allowEmptyEntries = FALSE );
68#ifndef QT_NO_REGEXP
69 static QStringList split( const QRegExp &sep, const QString &str, bool allowEmptyEntries = FALSE );
70#endif
71 QString join( const QString &sep ) const;
72
73 QStringList grep( const QString &str, bool cs = TRUE ) const;
74#ifndef QT_NO_REGEXP
75 QStringList grep( const QRegExp &expr ) const;
76#endif
77};
78
79#ifndef QT_NO_DATASTREAM
80class QDataStream;
81extern Q_EXPORT QDataStream &operator>>( QDataStream &, QStringList& );
82extern Q_EXPORT QDataStream &operator<<( QDataStream &, const QStringList& );
83#endif
84
85#endif // QT_NO_STRINGLIST
86#endif // QSTRINGLIST_H
diff --git a/qmake/include/qstrlist.h b/qmake/include/qstrlist.h
new file mode 100644
index 0000000..86de328
--- a/dev/null
+++ b/qmake/include/qstrlist.h
@@ -0,0 +1,112 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QStrList, QStrIList and QStrListIterator classes
5**
6** Created : 920730
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#ifndef QSTRLIST_H
39#define QSTRLIST_H
40
41#ifndef QT_H
42#include "qstring.h"
43#include "qptrlist.h"
44#include "qdatastream.h"
45#endif // QT_H
46
47
48#if defined(Q_TEMPLATEDLL)
49Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrList<char>;
50Q_TEMPLATE_EXTERN template class Q_EXPORT QPtrListIterator<char>;
51#endif
52
53#if defined(Q_QDOC)
54class QStrListIterator : public QPtrListIterator<char>
55{
56};
57#else
58typedef QPtrListIterator<char> QStrListIterator;
59#endif
60
61class Q_EXPORT QStrList : public QPtrList<char>
62{
63public:
64 QStrList( bool deepCopies=TRUE ) { dc = deepCopies; del_item = deepCopies; }
65 QStrList( const QStrList & );
66 ~QStrList() { clear(); }
67 QStrList& operator=( const QStrList & );
68
69private:
70 QPtrCollection::Item newItem( QPtrCollection::Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
71 void deleteItem( QPtrCollection::Item d ) { if ( del_item ) delete[] (char*)d; }
72 int compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 ) { return qstrcmp((const char*)s1,
73 (const char*)s2); }
74#ifndef QT_NO_DATASTREAM
75 QDataStream &read( QDataStream &s, QPtrCollection::Item &d )
76 { s >> (char *&)d; return s; }
77 QDataStream &write( QDataStream &s, QPtrCollection::Item d ) const
78 { return s << (const char *)d; }
79#endif
80 bool dc;
81};
82
83
84 class Q_EXPORT QStrIList : public QStrList// case insensitive string list
85{
86public:
87 QStrIList( bool deepCopies=TRUE ) : QStrList( deepCopies ) {}
88 ~QStrIList() { clear(); }
89private:
90 int compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 )
91 { return qstricmp((const char*)s1,
92 (const char*)s2); }
93};
94
95
96inline QStrList & QStrList::operator=( const QStrList &strList )
97{
98 clear();
99 dc = strList.dc;
100 del_item = dc;
101 QPtrList<char>::operator=( strList );
102 return *this;
103}
104
105inline QStrList::QStrList( const QStrList &strList )
106 : QPtrList<char>( strList )
107{
108 dc = FALSE;
109 operator=( strList );
110}
111
112#endif // QSTRLIST_H
diff --git a/qmake/include/qtextcodec.h b/qmake/include/qtextcodec.h
new file mode 100644
index 0000000..149b5cb
--- a/dev/null
+++ b/qmake/include/qtextcodec.h
@@ -0,0 +1,114 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QTextCodec class
5**
6** Created : 981015
7**
8** Copyright (C) 1998-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#ifndef QTEXTCODEC_H
39#define QTEXTCODEC_H
40
41#ifndef QT_H
42#include "qstring.h"
43#endif // QT_H
44
45#ifndef QT_NO_TEXTCODEC
46
47class QTextCodec;
48class QIODevice;
49class QFont;
50
51class Q_EXPORT QTextEncoder {
52public:
53 virtual ~QTextEncoder();
54 virtual QCString fromUnicode(const QString& uc, int& lenInOut) = 0;
55};
56
57class Q_EXPORT QTextDecoder {
58public:
59 virtual ~QTextDecoder();
60 virtual QString toUnicode(const char* chars, int len) = 0;
61};
62
63class Q_EXPORT QTextCodec {
64public:
65 virtual ~QTextCodec();
66
67#ifndef QT_NO_CODECS
68 static QTextCodec* loadCharmap(QIODevice*);
69 static QTextCodec* loadCharmapFile(QString filename);
70#endif //QT_NO_CODECS
71 static QTextCodec* codecForMib(int mib);
72 static QTextCodec* codecForName(const char* hint, int accuracy=0);
73 static QTextCodec* codecForContent(const char* chars, int len);
74 static QTextCodec* codecForIndex(int i);
75 static QTextCodec* codecForLocale();
76 static void setCodecForLocale(QTextCodec *c);
77
78 static void deleteAllCodecs();
79
80 static const char* locale();
81
82 virtual const char* name() const = 0;
83 virtual const char* mimeName() const;
84 virtual int mibEnum() const = 0;
85
86 virtual QTextDecoder* makeDecoder() const;
87 virtual QTextEncoder* makeEncoder() const;
88
89 virtual QString toUnicode(const char* chars, int len) const;
90 virtual QCString fromUnicode(const QString& uc, int& lenInOut) const;
91
92 QCString fromUnicode(const QString& uc) const;
93 QString toUnicode(const QByteArray&, int len) const;
94 QString toUnicode(const QByteArray&) const;
95 QString toUnicode(const QCString&, int len) const;
96 QString toUnicode(const QCString&) const;
97 QString toUnicode(const char* chars) const;
98 virtual bool canEncode( QChar ) const;
99 virtual bool canEncode( const QString& ) const;
100
101 virtual int heuristicContentMatch(const char* chars, int len) const = 0;
102 virtual int heuristicNameMatch(const char* hint) const;
103
104 virtual QByteArray fromUnicode(const QString& uc, int from, int len) const;
105 virtual unsigned short characterFromUnicode(const QString &str, int pos) const;
106
107protected:
108 QTextCodec();
109 static int simpleHeuristicNameMatch(const char* name, const char* hint);
110
111 friend class QFont;
112};
113#endif // QT_NO_TEXTCODEC
114#endif // QTEXTCODEC_H
diff --git a/qmake/include/qtextstream.h b/qmake/include/qtextstream.h
new file mode 100644
index 0000000..6979ed7
--- a/dev/null
+++ b/qmake/include/qtextstream.h
@@ -0,0 +1,335 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QTextStream class
5**
6** Created : 940922
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#ifndef QTEXTSTREAM_H
39#define QTEXTSTREAM_H
40
41#ifndef QT_H
42#include "qiodevice.h"
43#include "qstring.h"
44#include <stdio.h>
45#endif // QT_H
46
47#ifndef QT_NO_TEXTSTREAM
48class QTextCodec;
49class QTextDecoder;
50
51class QTextStreamPrivate;
52
53 class Q_EXPORT QTextStream // text stream class
54{
55public:
56 enum Encoding { Locale, Latin1, Unicode, UnicodeNetworkOrder,
57 UnicodeReverse, RawUnicode, UnicodeUTF8 };
58
59 voidsetEncoding( Encoding );
60#ifndef QT_NO_TEXTCODEC
61 voidsetCodec( QTextCodec* );
62 QTextCodec *codec();
63#endif
64
65 QTextStream();
66 QTextStream( QIODevice * );
67 QTextStream( QString*, int mode );
68 QTextStream( QString&, int mode ); // obsolete
69 QTextStream( QByteArray, int mode );
70 QTextStream( FILE *, int mode );
71 virtual ~QTextStream();
72
73 QIODevice*device() const;
74 void setDevice( QIODevice * );
75 void unsetDevice();
76
77 bool atEnd() const;
78 bool eof() const;
79
80 QTextStream &operator>>( QChar & );
81 QTextStream &operator>>( char & );
82 QTextStream &operator>>( signed short & );
83 QTextStream &operator>>( unsigned short & );
84 QTextStream &operator>>( signed int & );
85 QTextStream &operator>>( unsigned int & );
86 QTextStream &operator>>( signed long & );
87 QTextStream &operator>>( unsigned long & );
88 QTextStream &operator>>( float & );
89 QTextStream &operator>>( double & );
90 QTextStream &operator>>( char * );
91 QTextStream &operator>>( QString & );
92 QTextStream &operator>>( QCString & );
93
94 QTextStream &operator<<( QChar );
95 QTextStream &operator<<( char );
96 QTextStream &operator<<( signed short );
97 QTextStream &operator<<( unsigned short );
98 QTextStream &operator<<( signed int );
99 QTextStream &operator<<( unsigned int );
100 QTextStream &operator<<( signed long );
101 QTextStream &operator<<( unsigned long );
102 QTextStream &operator<<( float );
103 QTextStream &operator<<( double );
104 QTextStream &operator<<( const char* );
105 QTextStream &operator<<( const QString & );
106 QTextStream &operator<<( const QCString & );
107 QTextStream &operator<<( void * ); // any pointer
108
109 QTextStream &readRawBytes( char *, uint len );
110 QTextStream &writeRawBytes( const char* , uint len );
111
112 QStringreadLine();
113 QStringread();
114 voidskipWhiteSpace();
115
116 enum {
117 skipws = 0x0001, // skip whitespace on input
118 left = 0x0002, // left-adjust output
119 right = 0x0004, // right-adjust output
120 internal = 0x0008, // pad after sign
121 bin = 0x0010, // binary format integer
122 oct = 0x0020, // octal format integer
123 dec = 0x0040, // decimal format integer
124 hex = 0x0080, // hex format integer
125 showbase = 0x0100, // show base indicator
126 showpoint = 0x0200, // force decimal point (float)
127 uppercase = 0x0400, // upper-case hex output
128 showpos = 0x0800, // add '+' to positive integers
129 scientific= 0x1000, // scientific float output
130 fixed = 0x2000 // fixed float output
131 };
132
133 static const int basefield; // bin | oct | dec | hex
134 static const int adjustfield; // left | right | internal
135 static const int floatfield; // scientific | fixed
136
137 int flags() const;
138 int flags( int f );
139 int setf( int bits );
140 int setf( int bits, int mask );
141 int unsetf( int bits );
142
143 void reset();
144
145 int width()const;
146 int width( int );
147 int fill()const;
148 int fill( int );
149 int precision()const;
150 int precision( int );
151
152private:
153 longinput_int();
154 voidinit();
155 QTextStream &output_int( int, ulong, bool );
156 QIODevice*dev;
157
158 int fflags;
159 int fwidth;
160 int fillchar;
161 int fprec;
162 booldoUnicodeHeader;
163 boolowndev;
164 QTextCodec *mapper;
165 QTextStreamPrivate * d;
166 QCharunused1; // ### remove in Qt 4.0
167 boollatin1;
168 bool internalOrder;
169 boolnetworkOrder;
170 void*unused2; // ### remove in Qt 4.0
171
172 QChareat_ws();
173 uint ts_getline( QChar* );
174 voidts_ungetc( QChar );
175 QCharts_getc();
176 uintts_getbuf( QChar*, uint );
177 voidts_putc(int);
178 voidts_putc(QChar);
179 boolts_isspace(QChar);
180 boolts_isdigit(QChar);
181 ulonginput_bin();
182 ulonginput_oct();
183 ulonginput_dec();
184 ulonginput_hex();
185 doubleinput_double();
186 QTextStream &writeBlock( const char* p, uint len );
187 QTextStream &writeBlock( const QChar* p, uint len );
188
189 private:// Disabled copy constructor and operator=
190#if defined(Q_DISABLE_COPY)
191 QTextStream( const QTextStream & );
192 QTextStream &operator=( const QTextStream & );
193#endif
194};
195
196typedef QTextStream QTS;
197
198class Q_EXPORT QTextIStream : public QTextStream {
199public:
200 QTextIStream( const QString* s ) :
201 QTextStream((QString*)s,IO_ReadOnly) { }
202 QTextIStream( QByteArray ba ) :
203 QTextStream(ba,IO_ReadOnly) { }
204 QTextIStream( FILE *f ) :
205 QTextStream(f,IO_ReadOnly) { }
206
207 private:// Disabled copy constructor and operator=
208#if defined(Q_DISABLE_COPY)
209 QTextIStream( const QTextIStream & );
210 QTextIStream &operator=( const QTextIStream & );
211#endif
212};
213
214class Q_EXPORT QTextOStream : public QTextStream {
215public:
216 QTextOStream( QString* s ) :
217 QTextStream(s,IO_WriteOnly) { }
218 QTextOStream( QByteArray ba ) :
219 QTextStream(ba,IO_WriteOnly) { }
220 QTextOStream( FILE *f ) :
221 QTextStream(f,IO_WriteOnly) { }
222
223 private:// Disabled copy constructor and operator=
224#if defined(Q_DISABLE_COPY)
225 QTextOStream( const QTextOStream & );
226 QTextOStream &operator=( const QTextOStream & );
227#endif
228};
229
230/*****************************************************************************
231 QTextStream inline functions
232 *****************************************************************************/
233
234inline QIODevice *QTextStream::device() const
235{ return dev; }
236
237inline bool QTextStream::atEnd() const
238{ return dev ? dev->atEnd() : FALSE; }
239
240inline bool QTextStream::eof() const
241{ return atEnd(); }
242
243inline int QTextStream::flags() const
244{ return fflags; }
245
246inline int QTextStream::flags( int f )
247{ int oldf = fflags; fflags = f; return oldf; }
248
249inline int QTextStream::setf( int bits )
250{ int oldf = fflags; fflags |= bits; return oldf; }
251
252inline int QTextStream::setf( int bits, int mask )
253{ int oldf = fflags; fflags = (fflags & ~mask) | (bits & mask); return oldf; }
254
255inline int QTextStream::unsetf( int bits )
256 { int oldf = fflags; fflags &= ~bits;return oldf; }
257
258inline int QTextStream::width() const
259{ return fwidth; }
260
261inline int QTextStream::width( int w )
262 { int oldw = fwidth; fwidth = w; return oldw; }
263
264inline int QTextStream::fill() const
265{ return fillchar; }
266
267inline int QTextStream::fill( int f )
268 { int oldc = fillchar;fillchar = f; return oldc; }
269
270inline int QTextStream::precision() const
271{ return fprec; }
272
273inline int QTextStream::precision( int p )
274 { int oldp = fprec; fprec = p; return oldp; }
275
276/*!
277 Returns one character from the stream, or EOF.
278*/
279inline QChar QTextStream::ts_getc()
280{ QChar r; return ( ts_getbuf( &r,1 ) == 1 ? r : QChar((ushort)0xffff) ); }
281
282/*****************************************************************************
283 QTextStream manipulators
284 *****************************************************************************/
285
286typedef QTextStream & (*QTSFUNC)(QTextStream &);// manipulator function
287 typedef int (QTextStream::*QTSMFI)(int);// manipulator w/int argument
288
289 class Q_EXPORT QTSManip { // text stream manipulator
290public:
291 QTSManip( QTSMFI m, int a ) { mf=m; arg=a; }
292 void exec( QTextStream &s ) { (s.*mf)(arg); }
293private:
294 QTSMFI mf; // QTextStream member function
295 int arg; // member function argument
296};
297
298Q_EXPORT inline QTextStream &operator>>( QTextStream &s, QTSFUNC f )
299{ return (*f)( s ); }
300
301Q_EXPORT inline QTextStream &operator<<( QTextStream &s, QTSFUNC f )
302{ return (*f)( s ); }
303
304Q_EXPORT inline QTextStream &operator<<( QTextStream &s, QTSManip m )
305{ m.exec(s); return s; }
306
307 Q_EXPORT QTextStream &bin( QTextStream &s );// set bin notation
308 Q_EXPORT QTextStream &oct( QTextStream &s );// set oct notation
309 Q_EXPORT QTextStream &dec( QTextStream &s );// set dec notation
310 Q_EXPORT QTextStream &hex( QTextStream &s );// set hex notation
311 Q_EXPORT QTextStream &endl( QTextStream &s );// insert EOL ('\n')
312 Q_EXPORT QTextStream &flush( QTextStream &s );// flush output
313 Q_EXPORT QTextStream &ws( QTextStream &s );// eat whitespace on input
314 Q_EXPORT QTextStream &reset( QTextStream &s );// set default flags
315
316Q_EXPORT inline QTSManip qSetW( int w )
317{
318 QTSMFI func = &QTextStream::width;
319 return QTSManip(func,w);
320}
321
322Q_EXPORT inline QTSManip qSetFill( int f )
323{
324 QTSMFI func = &QTextStream::fill;
325 return QTSManip(func,f);
326}
327
328Q_EXPORT inline QTSManip qSetPrecision( int p )
329{
330 QTSMFI func = &QTextStream::precision;
331 return QTSManip(func,p);
332}
333
334#endif // QT_NO_TEXTSTREAM
335#endif // QTEXTSTREAM_H
diff --git a/qmake/include/qtl.h b/qmake/include/qtl.h
new file mode 100644
index 0000000..346cecc
--- a/dev/null
+++ b/qmake/include/qtl.h
@@ -0,0 +1,321 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of Qt template library classes
5**
6** Created : 990128
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#ifndef QTL_H
39#define QTL_H
40
41#ifndef QT_H
42#include "qglobal.h"
43#include "qtextstream.h"
44#include "qstring.h"
45#endif // QT_H
46
47#ifndef QT_NO_TEXTSTREAM
48template <class T>
49class QTextOStreamIterator
50{
51protected:
52 QTextOStream& stream;
53 QString separator;
54
55public:
56 QTextOStreamIterator( QTextOStream& s) : stream( s ) {}
57 QTextOStreamIterator( QTextOStream& s, const QString& sep )
58 : stream( s ), separator( sep ) {}
59 QTextOStreamIterator<T>& operator= ( const T& x ) {
60 stream << x;
61 if ( !separator.isEmpty() )
62 stream << separator;
63 return *this;
64 }
65 QTextOStreamIterator<T>& operator*() { return *this; }
66 QTextOStreamIterator<T>& operator++() { return *this; }
67 QTextOStreamIterator<T>& operator++(int) { return *this; }
68};
69#endif //QT_NO_TEXTSTREAM
70
71template <class InputIterator, class OutputIterator>
72inline OutputIterator qCopy( InputIterator _begin, InputIterator _end,
73 OutputIterator _dest )
74{
75 while( _begin != _end )
76 *_dest++ = *_begin++;
77 return _dest;
78}
79
80template <class BiIterator, class BiOutputIterator>
81inline BiOutputIterator qCopyBackward( BiIterator _begin, BiIterator _end,
82 BiOutputIterator _dest )
83{
84 while ( _begin != _end )
85 *--_dest = *--_end;
86 return _dest;
87}
88
89template <class InputIterator1, class InputIterator2>
90inline bool qEqual( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
91{
92 for ( ; first1 != last1; ++first1, ++first2 )
93 if ( *first1 != *first2 )
94 return FALSE;
95 return TRUE;
96}
97
98template <class ForwardIterator, class T>
99inline void qFill( ForwardIterator first, ForwardIterator last, const T& val )
100{
101 for ( ; first != last; ++first )
102 *first = val;
103}
104
105#if 0
106template <class BiIterator, class OutputIterator>
107inline OutputIterator qReverseCopy( BiIterator _begin, BiIterator _end,
108 OutputIterator _dest )
109{
110 while ( _begin != _end ) {
111 --_end;
112 *_dest = *_end;
113 ++_dest;
114 }
115 return _dest;
116}
117#endif
118
119
120template <class InputIterator, class T>
121inline InputIterator qFind( InputIterator first, InputIterator last,
122 const T& val )
123{
124 while ( first != last && *first != val )
125 ++first;
126 return first;
127}
128
129template <class InputIterator, class T, class Size>
130inline void qCount( InputIterator first, InputIterator last, const T& value,
131 Size& n )
132{
133 for ( ; first != last; ++first )
134 if ( *first == value )
135 ++n;
136}
137
138template <class T>
139inline void qSwap( T& _value1, T& _value2 )
140{
141 T tmp = _value1;
142 _value1 = _value2;
143 _value2 = tmp;
144}
145
146
147template <class InputIterator>
148Q_INLINE_TEMPLATES void qBubbleSort( InputIterator b, InputIterator e )
149{
150 // Goto last element;
151 InputIterator last = e;
152 --last;
153 // only one element or no elements ?
154 if ( last == b )
155 return;
156
157 // So we have at least two elements in here
158 while( b != last ) {
159 bool swapped = FALSE;
160 InputIterator swap_pos = b;
161 InputIterator x = e;
162 InputIterator y = x;
163 y--;
164 do {
165 --x;
166 --y;
167 if ( *x < *y ) {
168 swapped = TRUE;
169 qSwap( *x, *y );
170 swap_pos = y;
171 }
172 } while( y != b );
173 if ( !swapped )
174 return;
175 b = swap_pos;
176 b++;
177 }
178}
179
180
181template <class Container>
182inline void qBubbleSort( Container &c )
183{
184 qBubbleSort( c.begin(), c.end() );
185}
186
187
188template <class Value>
189Q_INLINE_TEMPLATES void qHeapSortPushDown( Value* heap, int first, int last )
190{
191 int r = first;
192 while ( r <= last / 2 ) {
193 if ( last == 2 * r ) {
194 // node r has only one child
195 if ( heap[2 * r] < heap[r] )
196 qSwap( heap[r], heap[2 * r] );
197 r = last;
198 } else {
199 // node r has two children
200 if ( heap[2 * r] < heap[r] && !(heap[2 * r + 1] < heap[2 * r]) ) {
201 // swap with left child
202 qSwap( heap[r], heap[2 * r] );
203 r *= 2;
204 } else if ( heap[2 * r + 1] < heap[r]
205 && heap[2 * r + 1] < heap[2 * r] ) {
206 // swap with right child
207 qSwap( heap[r], heap[2 * r + 1] );
208 r = 2 * r + 1;
209 } else {
210 r = last;
211 }
212 }
213 }
214}
215
216
217template <class InputIterator, class Value>
218Q_INLINE_TEMPLATES void qHeapSortHelper( InputIterator b, InputIterator e, Value, uint n )
219{
220 // Create the heap
221 InputIterator insert = b;
222 Value* realheap = new Value[n];
223 // Wow, what a fake. But I want the heap to be indexed as 1...n
224 Value* heap = realheap - 1;
225 int size = 0;
226 for( ; insert != e; ++insert ) {
227 heap[++size] = *insert;
228 int i = size;
229 while( i > 1 && heap[i] < heap[i / 2] ) {
230 qSwap( heap[i], heap[i / 2] );
231 i /= 2;
232 }
233 }
234
235 // Now do the sorting
236 for( uint i = n; i > 0; i-- ) {
237 *b++ = heap[1];
238 if ( i > 1 ) {
239 heap[1] = heap[i];
240 qHeapSortPushDown( heap, 1, (int)i - 1 );
241 }
242 }
243
244 delete[] realheap;
245}
246
247
248template <class InputIterator>
249Q_INLINE_TEMPLATES void qHeapSort( InputIterator b, InputIterator e )
250{
251 // Empty ?
252 if ( b == e )
253 return;
254
255 // How many entries have to be sorted ?
256 InputIterator it = b;
257 uint n = 0;
258 while ( it != e ) {
259 ++n;
260 ++it;
261 }
262
263 // The second last parameter is a hack to retrieve the value type
264 // Do the real sorting here
265 qHeapSortHelper( b, e, *b, n );
266}
267
268
269template <class Container>
270Q_INLINE_TEMPLATES void qHeapSort( Container &c )
271{
272 if ( c.begin() == c.end() )
273 return;
274
275 // The second last parameter is a hack to retrieve the value type
276 // Do the real sorting here
277 qHeapSortHelper( c.begin(), c.end(), *(c.begin()), (uint)c.count() );
278}
279
280template <class Container>
281class QBackInsertIterator
282{
283public:
284 Q_EXPLICIT QBackInsertIterator( Container &c )
285 : container( &c )
286 {
287 }
288
289 QBackInsertIterator<Container>&
290 operator=( const Q_TYPENAME Container::value_type &value )
291 {
292 container->push_back( value );
293 return *this;
294 }
295
296 QBackInsertIterator<Container>& operator*()
297 {
298 return *this;
299 }
300
301 QBackInsertIterator<Container>& operator++()
302 {
303 return *this;
304 }
305
306 QBackInsertIterator<Container>& operator++(int)
307 {
308 return *this;
309 }
310
311protected:
312 Container *container;
313};
314
315template <class Container>
316inline QBackInsertIterator<Container> qBackInserter( Container &c )
317{
318 return QBackInsertIterator<Container>( c );
319}
320
321#endif
diff --git a/qmake/include/quuid.h b/qmake/include/quuid.h
new file mode 100644
index 0000000..591d2f1
--- a/dev/null
+++ b/qmake/include/quuid.h
@@ -0,0 +1,168 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QUuid class
5**
6** Created: 010523
7**
8** Copyright (C) 1992-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#ifndef QUUID_H
39#define QUUID_H
40
41#ifndef QT_H
42#include <qstring.h>
43#endif // QT_H
44
45#include <string.h>
46
47#if defined(Q_OS_WIN32)
48#ifndef GUID_DEFINED
49#define GUID_DEFINED
50typedef struct _GUID
51{
52 ulong Data1;
53 ushort Data2;
54 ushort Data3;
55 uchar Data4[ 8 ];
56} GUID;
57#endif
58#endif
59
60struct Q_EXPORT QUuid
61{
62 QUuid()
63 {
64 memset( this, 0, sizeof(QUuid) );
65 }
66 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 data1 = l;
69 data2 = w1;
70 data3 = w2;
71 data4[0] = b1;
72 data4[1] = b2;
73 data4[2] = b3;
74 data4[3] = b4;
75 data4[4] = b5;
76 data4[5] = b6;
77 data4[6] = b7;
78 data4[7] = b8;
79 }
80 QUuid( const QUuid &uuid )
81 {
82 memcpy( this, &uuid, sizeof(QUuid) );
83 }
84#ifndef QT_NO_QUUID_STRING
85 QUuid( const QString & );
86 QUuid( const char * );
87 QString toString() const;
88 operator QString() const { return toString(); }
89#endif
90 bool isNull() const;
91
92 QUuid &operator=(const QUuid &orig )
93 {
94 memcpy( this, &orig, sizeof(QUuid) );
95 return *this;
96 }
97
98 bool operator==(const QUuid &orig ) const
99 {
100 uint i;
101 if ( data1 != orig.data1 || data2 != orig.data2 ||
102 data3 != orig.data3 )
103 return FALSE;
104
105 for( i = 0; i < 8; i++ )
106 if ( data4[i] != orig.data4[i] )
107 return FALSE;
108
109 return TRUE;
110 }
111
112 bool operator!=(const QUuid &orig ) const
113 {
114 return !( *this == orig );
115 }
116
117#if defined(Q_OS_WIN32)
118 // On Windows we have a type GUID that is used by the platform API, so we
119 // provide convenience operators to cast from and to this type.
120 QUuid( const GUID &guid )
121 {
122 memcpy( this, &guid, sizeof(GUID) );
123 }
124
125 QUuid &operator=(const GUID &orig )
126 {
127 memcpy( this, &orig, sizeof(QUuid) );
128 return *this;
129 }
130
131 operator GUID() const
132 {
133 GUID guid = { data1, data2, data3, { data4[0], data4[1], data4[2], data4[3], data4[4], data4[5], data4[6], data4[7] } };
134 return guid;
135 }
136
137 bool operator==( const GUID &guid ) const
138 {
139 uint i;
140 if ( data1 != guid.Data1 || data2 != guid.Data2 ||
141 data3 != guid.Data3 )
142 return FALSE;
143
144 for( i = 0; i < 8; i++ )
145 if ( data4[i] != guid.Data4[i] )
146 return FALSE;
147
148 return TRUE;
149 }
150
151 bool operator!=( const GUID &guid ) const
152 {
153 return !( *this == guid );
154 }
155#endif
156
157 uint data1;
158 ushort data2;
159 ushort data3;
160 uchar data4[ 8 ];
161};
162
163#ifndef QT_NO_DATASTREAM
164Q_EXPORT QDataStream &operator<<( QDataStream &, const QUuid & );
165Q_EXPORT QDataStream &operator>>( QDataStream &, QUuid & );
166#endif
167
168#endif //QUUID_H
diff --git a/qmake/include/qvaluelist.h b/qmake/include/qvaluelist.h
new file mode 100644
index 0000000..54f7aec
--- a/dev/null
+++ b/qmake/include/qvaluelist.h
@@ -0,0 +1,665 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QValueList class
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#ifndef QVALUELIST_H
39#define QVALUELIST_H
40
41#ifndef QT_H
42#include "qtl.h"
43#include "qshared.h"
44#include "qdatastream.h"
45#endif // QT_H
46
47#ifndef QT_NO_STL
48#include <iterator>
49#include <list>
50#endif
51
52//#define QT_CHECK_VALUELIST_RANGE
53
54#if defined(Q_CC_MSVC)
55#pragma warning(disable:4284) // "return type for operator -> is not a UDT"
56#endif
57
58template <class T>
59class QValueListNode
60{
61public:
62 QValueListNode( const T& t ) : data( t ) { }
63 QValueListNode() { }
64#if defined(Q_TEMPLATEDLL)
65 // Workaround MS bug in memory de/allocation in DLL vs. EXE
66 virtual ~QValueListNode() { }
67#endif
68
69 QValueListNode<T>* next;
70 QValueListNode<T>* prev;
71 T data;
72};
73
74template<class T>
75class QValueListIterator
76{
77 public:
78 /**
79 * Typedefs
80 */
81 typedef QValueListNode<T>* NodePtr;
82#ifndef QT_NO_STL
83 typedef std::bidirectional_iterator_tag iterator_category;
84#endif
85 typedef T value_type;
86 typedef size_t size_type;
87#ifndef QT_NO_STL
88 typedef ptrdiff_t difference_type;
89#else
90 typedef int difference_type;
91#endif
92 typedef T* pointer;
93 typedef T& reference;
94
95 /**
96 * Variables
97 */
98 NodePtr node;
99
100 /**
101 * Functions
102 */
103 QValueListIterator() : node( 0 ) {}
104 QValueListIterator( NodePtr p ) : node( p ) {}
105 QValueListIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
106
107 bool operator==( const QValueListIterator<T>& it ) const { return node == it.node; }
108 bool operator!=( const QValueListIterator<T>& it ) const { return node != it.node; }
109 const T& operator*() const { return node->data; }
110 T& operator*() { return node->data; }
111 // UDT for T = x*
112 // T* operator->() const { return &node->data; }
113
114 QValueListIterator<T>& operator++() {
115 node = node->next;
116 return *this;
117 }
118
119 QValueListIterator<T> operator++(int) {
120 QValueListIterator<T> tmp = *this;
121 node = node->next;
122 return tmp;
123 }
124
125 QValueListIterator<T>& operator--() {
126 node = node->prev;
127 return *this;
128 }
129
130 QValueListIterator<T> operator--(int) {
131 QValueListIterator<T> tmp = *this;
132 node = node->prev;
133 return tmp;
134 }
135
136 QValueListIterator<T>& operator+=( int j ) {
137 while ( j-- )
138 node = node->next;
139 return *this;
140 }
141
142 QValueListIterator<T>& operator-=( int j ) {
143 while ( j-- )
144 node = node->prev;
145 return *this;
146 }
147
148};
149
150template<class T>
151class QValueListConstIterator
152{
153 public:
154 /**
155 * Typedefs
156 */
157 typedef QValueListNode<T>* NodePtr;
158#ifndef QT_NO_STL
159 typedef std::bidirectional_iterator_tag iterator_category;
160#endif
161 typedef T value_type;
162 typedef size_t size_type;
163#ifndef QT_NO_STL
164 typedef ptrdiff_t difference_type;
165#else
166 typedef int difference_type;
167#endif
168 typedef const T* pointer;
169 typedef const T& reference;
170
171 /**
172 * Variables
173 */
174 NodePtr node;
175
176 /**
177 * Functions
178 */
179 QValueListConstIterator() : node( 0 ) {}
180 QValueListConstIterator( NodePtr p ) : node( p ) {}
181 QValueListConstIterator( const QValueListConstIterator<T>& it ) : node( it.node ) {}
182 QValueListConstIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
183
184 bool operator==( const QValueListConstIterator<T>& it ) const { return node == it.node; }
185 bool operator!=( const QValueListConstIterator<T>& it ) const { return node != it.node; }
186 const T& operator*() const { return node->data; }
187 // UDT for T = x*
188 // const T* operator->() const { return &node->data; }
189
190 QValueListConstIterator<T>& operator++() {
191 node = node->next;
192 return *this;
193 }
194
195 QValueListConstIterator<T> operator++(int) {
196 QValueListConstIterator<T> tmp = *this;
197 node = node->next;
198 return tmp;
199 }
200
201 QValueListConstIterator<T>& operator--() {
202 node = node->prev;
203 return *this;
204 }
205
206 QValueListConstIterator<T> operator--(int) {
207 QValueListConstIterator<T> tmp = *this;
208 node = node->prev;
209 return tmp;
210 }
211};
212
213template <class T>
214class QValueListPrivate : public QShared
215{
216public:
217 /**
218 * Typedefs
219 */
220 typedef QValueListIterator<T> Iterator;
221 typedef QValueListConstIterator<T> ConstIterator;
222 typedef QValueListNode<T> Node;
223 typedef QValueListNode<T>* NodePtr;
224 typedef size_t size_type;
225
226 /**
227 * Functions
228 */
229 QValueListPrivate();
230 QValueListPrivate( const QValueListPrivate<T>& _p );
231
232 void derefAndDelete() // ### hack to get around hp-cc brain damage
233 {
234 if ( deref() )
235 delete this;
236 }
237
238#if defined(Q_TEMPLATEDLL)
239 // Workaround MS bug in memory de/allocation in DLL vs. EXE
240 virtual
241#endif
242 ~QValueListPrivate();
243
244 Iterator insert( Iterator it, const T& x );
245 Iterator remove( Iterator it );
246 NodePtr find( NodePtr start, const T& x ) const;
247 int findIndex( NodePtr start, const T& x ) const;
248 uint contains( const T& x ) const;
249 uint remove( const T& x );
250 NodePtr at( size_type i ) const;
251 void clear();
252
253 NodePtr node;
254 size_type nodes;
255};
256
257template <class T>
258Q_INLINE_TEMPLATES QValueListPrivate<T>::QValueListPrivate()
259{
260 node = new Node; node->next = node->prev = node; nodes = 0;
261}
262
263template <class T>
264Q_INLINE_TEMPLATES QValueListPrivate<T>::QValueListPrivate( const QValueListPrivate<T>& _p )
265 : QShared()
266{
267 node = new Node; node->next = node->prev = node; nodes = 0;
268 Iterator b( _p.node->next );
269 Iterator e( _p.node );
270 Iterator i( node );
271 while( b != e )
272 insert( i, *b++ );
273}
274
275template <class T>
276Q_INLINE_TEMPLATES QValueListPrivate<T>::~QValueListPrivate() {
277 NodePtr p = node->next;
278 while( p != node ) {
279 NodePtr x = p->next;
280 delete p;
281 p = x;
282 }
283 delete node;
284}
285
286template <class T>
287Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::Iterator QValueListPrivate<T>::insert( Q_TYPENAME QValueListPrivate<T>::Iterator it, const T& x )
288{
289 NodePtr p = new Node( x );
290 p->next = it.node;
291 p->prev = it.node->prev;
292 it.node->prev->next = p;
293 it.node->prev = p;
294 nodes++;
295 return p;
296}
297
298template <class T>
299Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::Iterator QValueListPrivate<T>::remove( Q_TYPENAME QValueListPrivate<T>::Iterator it )
300{
301 Q_ASSERT ( it.node != node );
302 NodePtr next = it.node->next;
303 NodePtr prev = it.node->prev;
304 prev->next = next;
305 next->prev = prev;
306 delete it.node;
307 nodes--;
308 return Iterator( next );
309}
310
311template <class T>
312Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::NodePtr QValueListPrivate<T>::find( Q_TYPENAME QValueListPrivate<T>::NodePtr start, const T& x ) const
313{
314 ConstIterator first( start );
315 ConstIterator last( node );
316 while( first != last) {
317 if ( *first == x )
318 return first.node;
319 ++first;
320 }
321 return last.node;
322}
323
324template <class T>
325Q_INLINE_TEMPLATES int QValueListPrivate<T>::findIndex( Q_TYPENAME QValueListPrivate<T>::NodePtr start, const T& x ) const
326{
327 ConstIterator first( start );
328 ConstIterator last( node );
329 int pos = 0;
330 while( first != last) {
331 if ( *first == x )
332 return pos;
333 ++first;
334 ++pos;
335 }
336 return -1;
337}
338
339template <class T>
340Q_INLINE_TEMPLATES uint QValueListPrivate<T>::contains( const T& x ) const
341{
342 uint result = 0;
343 Iterator first = Iterator( node->next );
344 Iterator last = Iterator( node );
345 while( first != last) {
346 if ( *first == x )
347 ++result;
348 ++first;
349 }
350 return result;
351}
352
353template <class T>
354Q_INLINE_TEMPLATES uint QValueListPrivate<T>::remove( const T& x )
355{
356 uint result = 0;
357 Iterator first = Iterator( node->next );
358 Iterator last = Iterator( node );
359 while( first != last) {
360 if ( *first == x ) {
361 first = remove( first );
362 ++result;
363 } else
364 ++first;
365 }
366 return result;
367}
368
369template <class T>
370Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::NodePtr QValueListPrivate<T>::at( size_type i ) const
371{
372 Q_ASSERT( i <= nodes );
373 NodePtr p = node->next;
374 for( size_type x = 0; x < i; ++x )
375 p = p->next;
376 return p;
377}
378
379template <class T>
380Q_INLINE_TEMPLATES void QValueListPrivate<T>::clear()
381{
382 nodes = 0;
383 NodePtr p = node->next;
384 while( p != node ) {
385 NodePtr next = p->next;
386 delete p;
387 p = next;
388 }
389 node->next = node->prev = node;
390}
391
392#ifdef QT_CHECK_RANGE
393# if !defined( QT_NO_DEBUG ) && defined( QT_CHECK_VALUELIST_RANGE )
394# define QT_CHECK_INVALID_LIST_ELEMENT if ( empty() ) qWarning( "QValueList: Warning invalid element" )
395# define QT_CHECK_INVALID_LIST_ELEMENT_FATAL Q_ASSERT( !empty() );
396# else
397# define QT_CHECK_INVALID_LIST_ELEMENT
398# define QT_CHECK_INVALID_LIST_ELEMENT_FATAL
399# endif
400#else
401# define QT_CHECK_INVALID_LIST_ELEMENT
402# define QT_CHECK_INVALID_LIST_ELEMENT_FATAL
403#endif
404
405template <class T> class QDeepCopy;
406
407template <class T>
408class QValueList
409{
410public:
411 /**
412 * Typedefs
413 */
414 typedef QValueListIterator<T> iterator;
415 typedef QValueListConstIterator<T> const_iterator;
416 typedef T value_type;
417 typedef value_type* pointer;
418 typedef const value_type* const_pointer;
419 typedef value_type& reference;
420 typedef const value_type& const_reference;
421 typedef size_t size_type;
422#ifndef QT_NO_STL
423 typedef ptrdiff_t difference_type;
424#else
425 typedef int difference_type;
426#endif
427
428 /**
429 * API
430 */
431 QValueList() { sh = new QValueListPrivate<T>; }
432 QValueList( const QValueList<T>& l ) { sh = l.sh; sh->ref(); }
433#ifndef QT_NO_STL
434# ifdef Q_CC_HPACC // HP-UX aCC does require typename in some place
435# undef Q_TYPENAME // but not accept them at others.
436# define Q_TYPENAME // also doesn't like re-defines ...
437# endif
438 QValueList( const Q_TYPENAME std::list<T>& l )
439 {
440 sh = new QValueListPrivate<T>;
441 qCopy( l.begin(), l.end(), std::back_inserter( *this ) );
442 }
443#endif
444 ~QValueList() { sh->derefAndDelete(); }
445
446 QValueList<T>& operator= ( const QValueList<T>& l )
447 {
448 l.sh->ref();
449 sh->derefAndDelete();
450 sh = l.sh;
451 return *this;
452 }
453#ifndef QT_NO_STL
454 QValueList<T>& operator= ( const Q_TYPENAME std::list<T>& l )
455 {
456 detach();
457 qCopy( l.begin(), l.end(), std::back_inserter( *this ) );
458 return *this;
459 }
460 bool operator== ( const Q_TYPENAME std::list<T>& l ) const
461 {
462 if ( size() != l.size() )
463 return FALSE;
464 const_iterator it2 = begin();
465#if !defined(Q_CC_MIPS)
466 typename
467#endif
468 std::list<T>::const_iterator it = l.begin();
469 for ( ; it2 != end(); ++it2, ++it )
470 if ( !((*it2) == (*it)) )
471 return FALSE;
472 return TRUE;
473 }
474# ifdef Q_CC_HPACC // undo the HP-UX aCC hackery done above
475# undef Q_TYPENAME
476# define Q_TYPENAME typename
477# endif
478#endif
479 bool operator== ( const QValueList<T>& l ) const;
480 bool operator!= ( const QValueList<T>& l ) const { return !( *this == l ); }
481 iterator begin() { detach(); return iterator( sh->node->next ); }
482 const_iterator begin() const { return const_iterator( sh->node->next ); }
483 iterator end() { detach(); return iterator( sh->node ); }
484 const_iterator end() const { return const_iterator( sh->node ); }
485 iterator insert( iterator it, const T& x ) { detach(); return sh->insert( it, x ); }
486 uint remove( const T& x ) { detach(); return sh->remove( x ); }
487 void clear();
488
489 QValueList<T>& operator<< ( const T& x )
490 {
491 append( x );
492 return *this;
493 }
494
495 size_type size() const { return sh->nodes; }
496 bool empty() const { return sh->nodes == 0; }
497 void push_front( const T& x ) { detach(); sh->insert( begin(), x ); }
498 void push_back( const T& x ) { detach(); sh->insert( end(), x ); }
499 iterator erase( iterator pos ) { detach(); return sh->remove( pos ); }
500 iterator erase( iterator first, iterator last );
501 reference front() { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *begin(); }
502 const_reference front() const { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *begin(); }
503 reference back() { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *(--end()); }
504 const_reference back() const { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *(--end()); }
505 void pop_front() { QT_CHECK_INVALID_LIST_ELEMENT; erase( begin() ); }
506 void pop_back() {
507 QT_CHECK_INVALID_LIST_ELEMENT;
508 iterator tmp = end();
509 erase( --tmp );
510 }
511 void insert( iterator pos, size_type n, const T& x );
512 // Some compilers (incl. vc++) would instantiate this function even if
513 // it is not used; this would constrain QValueList to classes that provide
514 // an operator<
515 /*
516 void sort()
517 {
518 qHeapSort( *this );
519 }
520 */
521
522 QValueList<T> operator+ ( const QValueList<T>& l ) const;
523 QValueList<T>& operator+= ( const QValueList<T>& l );
524
525 iterator fromLast() { detach(); return iterator( sh->node->prev ); }
526 const_iterator fromLast() const { return const_iterator( sh->node->prev ); }
527
528 bool isEmpty() const { return ( sh->nodes == 0 ); }
529
530 iterator append( const T& x ) { detach(); return sh->insert( end(), x ); }
531 iterator prepend( const T& x ) { detach(); return sh->insert( begin(), x ); }
532
533 iterator remove( iterator it ) { detach(); return sh->remove( it ); }
534
535 T& first() { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->node->next->data; }
536 const T& first() const { QT_CHECK_INVALID_LIST_ELEMENT; return sh->node->next->data; }
537 T& last() { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->node->prev->data; }
538 const T& last() const { QT_CHECK_INVALID_LIST_ELEMENT; return sh->node->prev->data; }
539
540 T& operator[] ( size_type i ) { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->at(i)->data; }
541 const T& operator[] ( size_type i ) const { QT_CHECK_INVALID_LIST_ELEMENT; return sh->at(i)->data; }
542 iterator at( size_type i ) { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return iterator( sh->at(i) ); }
543 const_iterator at( size_type i ) const { QT_CHECK_INVALID_LIST_ELEMENT; return const_iterator( sh->at(i) ); }
544 iterator find ( const T& x ) { detach(); return iterator( sh->find( sh->node->next, x) ); }
545 const_iterator find ( const T& x ) const { return const_iterator( sh->find( sh->node->next, x) ); }
546 iterator find ( iterator it, const T& x ) { detach(); return iterator( sh->find( it.node, x ) ); }
547 const_iterator find ( const_iterator it, const T& x ) const { return const_iterator( sh->find( it.node, x ) ); }
548 int findIndex( const T& x ) const { return sh->findIndex( sh->node->next, x) ; }
549 size_type contains( const T& x ) const { return sh->contains( x ); }
550
551 size_type count() const { return sh->nodes; }
552
553 QValueList<T>& operator+= ( const T& x )
554 {
555 append( x );
556 return *this;
557 }
558 typedef QValueListIterator<T> Iterator;
559 typedef QValueListConstIterator<T> ConstIterator;
560 typedef T ValueType;
561
562protected:
563 /**
564 * Helpers
565 */
566 void detach() { if ( sh->count > 1 ) detachInternal(); }
567
568 /**
569 * Variables
570 */
571 QValueListPrivate<T>* sh;
572
573private:
574 void detachInternal();
575
576 friend class QDeepCopy< QValueList<T> >;
577};
578
579template <class T>
580Q_INLINE_TEMPLATES bool QValueList<T>::operator== ( const QValueList<T>& l ) const
581{
582 if ( size() != l.size() )
583 return FALSE;
584 const_iterator it2 = begin();
585 const_iterator it = l.begin();
586 for( ; it != l.end(); ++it, ++it2 )
587 if ( !( *it == *it2 ) )
588 return FALSE;
589 return TRUE;
590}
591
592template <class T>
593Q_INLINE_TEMPLATES void QValueList<T>::clear()
594{
595 if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QValueListPrivate<T>; }
596}
597
598template <class T>
599Q_INLINE_TEMPLATES Q_TYPENAME QValueList<T>::iterator QValueList<T>::erase( Q_TYPENAME QValueList<T>::iterator first, Q_TYPENAME QValueList<T>::iterator last )
600{
601 while ( first != last )
602 erase( first++ );
603 return last;
604}
605
606
607template <class T>
608Q_INLINE_TEMPLATES void QValueList<T>::insert( Q_TYPENAME QValueList<T>::iterator pos, size_type n, const T& x )
609{
610 for ( ; n > 0; --n )
611 insert( pos, x );
612}
613
614template <class T>
615Q_INLINE_TEMPLATES QValueList<T> QValueList<T>::operator+ ( const QValueList<T>& l ) const
616{
617 QValueList<T> l2( *this );
618 for( const_iterator it = l.begin(); it != l.end(); ++it )
619 l2.append( *it );
620 return l2;
621}
622
623template <class T>
624Q_INLINE_TEMPLATES QValueList<T>& QValueList<T>::operator+= ( const QValueList<T>& l )
625{
626 for( const_iterator it = l.begin(); it != l.end(); ++it )
627 append( *it );
628 return *this;
629}
630
631template <class T>
632Q_INLINE_TEMPLATES void QValueList<T>::detachInternal()
633{
634 sh->deref(); sh = new QValueListPrivate<T>( *sh );
635}
636
637#ifndef QT_NO_DATASTREAM
638template <class T>
639Q_INLINE_TEMPLATES QDataStream& operator>>( QDataStream& s, QValueList<T>& l )
640{
641 l.clear();
642 Q_UINT32 c;
643 s >> c;
644 for( Q_UINT32 i = 0; i < c; ++i )
645 {
646 T t;
647 s >> t;
648 l.append( t );
649 if ( s.atEnd() )
650 break;
651 }
652 return s;
653}
654
655template <class T>
656Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QValueList<T>& l )
657{
658 s << (Q_UINT32)l.size();
659 QValueListConstIterator<T> it = l.begin();
660 for( ; it != l.end(); ++it )
661 s << *it;
662 return s;
663}
664#endif // QT_NO_DATASTREAM
665#endif // QVALUELIST_H
diff --git a/qmake/include/qvaluestack.h b/qmake/include/qvaluestack.h
new file mode 100644
index 0000000..7e9bc48
--- a/dev/null
+++ b/qmake/include/qvaluestack.h
@@ -0,0 +1,64 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of QValueStack class
5**
6** Created : 990925
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#ifndef QVALUESTACK_H
39#define QVALUESTACK_H
40
41#ifndef QT_H
42#include "qvaluelist.h"
43#endif // QT_H
44
45
46template<class T>
47class QValueStack : public QValueList<T>
48{
49public:
50 QValueStack() {}
51 ~QValueStack() {}
52 void push( const T& d ) { append(d); }
53 T pop()
54 {
55 T elem( this->last() );
56 if ( !this->isEmpty() )
57 remove( this->fromLast() );
58 return elem;
59 }
60 T& top() { return this->last(); }
61 const T& top() const { return this->last(); }
62};
63
64#endif
diff --git a/qmake/main.cpp b/qmake/main.cpp
new file mode 100644
index 0000000..eed1697
--- a/dev/null
+++ b/qmake/main.cpp
@@ -0,0 +1,153 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "project.h"
39#include "option.h"
40#include "makefile.h"
41#include <qnamespace.h>
42#include <qregexp.h>
43#include <qdir.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <ctype.h>
47#include <fcntl.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50
51// for Borland, main is defined to qMain which breaks qmake
52#undef main
53
54int main(int argc, char **argv)
55{
56 /* parse command line */
57 if(!Option::parseCommandLine(argc, argv))
58 return 666;
59
60 QDir sunworkshop42workaround = QDir::current();
61 QString oldpwd = sunworkshop42workaround.currentDirPath();
62 Option::output_dir = oldpwd; //for now this is the output dir
63 if(Option::output_dir.right(1) != QString(QChar(QDir::separator())))
64 Option::output_dir += QDir::separator();
65 QMakeProject proj;
66 int exit_val = 0;
67 QStringList files;
68 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
69 files << "(*hack*)"; //we don't even use files, but we do the for() body once
70 else
71 files = Option::mkfile::project_files;
72 for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) {
73 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
74 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
75 QString fn = (*pfile);
76
77 //setup pwd properly
78 debug_msg(1, "Resetting dir to: %s", oldpwd.latin1());
79 QDir::setCurrent(oldpwd); //reset the old pwd
80 int di = fn.findRev(Option::dir_sep);
81 if(di != -1) {
82 debug_msg(1, "Changing dir to: %s", fn.left(di).latin1());
83 if(!QDir::setCurrent(fn.left(fn.findRev(Option::dir_sep))))
84 fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).latin1());
85 fn = fn.right(fn.length() - di - 1);
86 }
87
88 /* read project.. */
89 if(!proj.read(fn, oldpwd)) {
90 fprintf(stderr, "Error processing project file: %s\n",
91 fn == "-" ? "(stdin)" : (*pfile).latin1());
92 exit_val = 2;
93 continue;
94 }
95 if(Option::mkfile::do_preprocess) //no need to create makefile
96 continue;
97
98 /* let Option post-process */
99 if(!Option::postProcessProject(&proj)) {
100 fprintf(stderr, "Error post-processing project file: %s",
101 fn == "-" ? "(stdin)" : (*pfile).latin1());
102 exit_val = 8;
103 continue;
104 }
105 }
106
107 bool using_stdout = FALSE;
108 MakefileGenerator *mkfile = MakefileGenerator::create(&proj); //figure out generator
109 if(mkfile && (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
110 Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)) {
111 //open output
112 if(!(Option::output.state() & IO_Open)) {
113 if(Option::output.name() == "-") {
114 Option::output.setName("");
115 Option::output_dir = QDir::currentDirPath();
116 Option::output.open(IO_WriteOnly | IO_Translate, stdout);
117 using_stdout = TRUE;
118 } else {
119 if(Option::output.name().isEmpty() && Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE)
120 Option::output.setName(proj.first("QMAKE_MAKEFILE"));
121 if(!mkfile->openOutput(Option::output)) {
122 fprintf(stderr, "Failure to open file: %s\n",
123 Option::output.name().isEmpty() ? "(stdout)" : Option::output.name().latin1());
124 return 5;
125 }
126 }
127 }
128 } else {
129 using_stdout = TRUE; //kind of..
130 }
131 if(mkfile && !mkfile->write()) {
132 if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
133 fprintf(stderr, "Unable to generate project file.\n");
134 else
135 fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).latin1());
136 if(!using_stdout)
137 QFile::remove(Option::output.name());
138 exit_val = 6;
139 }
140 delete mkfile;
141 mkfile = NULL;
142
143 /* debugging */
144 if(Option::debug_level) {
145 QMap<QString, QStringList> &vars = proj.variables();
146 for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) {
147 if(it.key().left(1) != "." && !it.data().isEmpty())
148 debug_msg(1, "%s === %s", it.key().latin1(), it.data().join(" :: ").latin1());
149 }
150 }
151 }
152 return exit_val;
153}
diff --git a/qmake/option.cpp b/qmake/option.cpp
new file mode 100644
index 0000000..34b3ee2
--- a/dev/null
+++ b/qmake/option.cpp
@@ -0,0 +1,449 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "option.h"
39#include <qdir.h>
40#include <qregexp.h>
41#include <stdlib.h>
42#include <stdarg.h>
43
44//convenience
45QString Option::prf_ext;
46QString Option::prl_ext;
47QString Option::ui_ext;
48QStringList Option::h_ext;
49QString Option::moc_ext;
50QStringList Option::cpp_ext;
51QString Option::obj_ext;
52QString Option::lex_ext;
53QString Option::yacc_ext;
54QString Option::dir_sep;
55QString Option::moc_mod;
56QString Option::yacc_mod;
57QString Option::lex_mod;
58
59//mode
60Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;
61
62//all modes
63int Option::warn_level = WarnLogic;
64int Option::debug_level = 0;
65QFile Option::output;
66QString Option::output_dir;
67QStringList Option::before_user_vars;
68QStringList Option::after_user_vars;
69QString Option::user_template;
70QString Option::user_template_prefix;
71#if defined(Q_OS_WIN32)
72Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE;
73#elif defined(Q_OS_MAC9)
74Option::TARG_MODE Option::target_mode = Option::TARG_MAC9_MODE;
75#elif defined(Q_OS_MACX)
76Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE;
77#elif defined(Q_OS_QNX6)
78Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE;
79#else
80Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE;
81#endif
82
83//QMAKE_GENERATE_PROJECT stuff
84bool Option::projfile::do_pwd = TRUE;
85bool Option::projfile::do_recursive = FALSE;
86QStringList Option::projfile::project_dirs;
87
88//QMAKE_GENERATE_MAKEFILE stuff
89QString Option::mkfile::qmakespec;
90int Option::mkfile::cachefile_depth = -1;
91bool Option::mkfile::do_deps = TRUE;
92bool Option::mkfile::do_mocs = TRUE;
93bool Option::mkfile::do_dep_heuristics = TRUE;
94bool Option::mkfile::do_preprocess = FALSE;
95bool Option::mkfile::do_cache = TRUE;
96QString Option::mkfile::cachefile;
97QStringList Option::mkfile::project_files;
98QString Option::mkfile::qmakespec_commandline;
99
100bool usage(const char *a0)
101{
102 fprintf(stdout, "Usage: %s [mode] [options] [files]\n"
103 "\n"
104 " QMake has two modes, one mode for generating project files based on\n"
105 "some heuristics, and the other for generating makefiles. Normally you\n"
106 "shouldn't need to specify a mode, as makefile generation is the default\n"
107 "mode for qmake, but you may use this to test qmake on an existing project\n"
108 "\n"
109 "Mode:\n"
110 "\t-project Put qmake into project file generation mode\n"
111 "\t In this mode qmake interprets files as files to\n"
112 "\t be built,\n"
113 "\t defaults to *.cpp; *.l; *.y; *.ui\n"
114 "\t-makefile Put qmake into makefile generation mode (default)\n"
115 "\t In this mode qmake interprets files as project files to\n"
116 "\t be processed, if skipped qmake will try to find a project\n"
117 "\t file in your current working directory\n"
118 "\n"
119 "Warnings Options:\n"
120 "\t-Wnone Turn off all warnings\n"
121 "\t-Wall Turn on all warnings\n"
122 "\t-Wparser Turn on parser warnings\n"
123 "\t-Wlogic Turn on logic warnings\n"
124 "\n"
125 "Options:\n"
126 "\t * You can place any variable assignment in options and it will be *\n"
127 "\t * processed as if it was in [files]. These assignments will be parsed *\n"
128 "\t * before [files]. *\n"
129 "\t-o file Write output to file\n"
130 "\t-unix Run in unix mode\n"
131 "\t-win32 Run in win32 mode\n"
132 "\t-macx Run in Mac OS X mode\n"
133 "\t-d Increase debug level\n"
134 "\t-t templ Overrides TEMPLATE as templ\n"
135 "\t-tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
136 "\t-help This help\n"
137 "\t-v Version information\n"
138 "\t-after All variable assignments after this will be\n"
139 "\t parsed after [files] [makefile mode only]\n"
140 "\t-cache file Use file as cache [makefile mode only]\n"
141 "\t-spec spec Use spec as QMAKESPEC [makefile mode only]\n"
142 "\t-nocache Don't use a cache file [makefile mode only]\n"
143 "\t-nodepend Don't generate dependencies [makefile mode only]\n"
144 "\t-nomoc Don't generate moc targets [makefile mode only]\n"
145 "\t-nopwd Don't look for files in pwd [ project mode only]\n"
146 "\t-r Recursive search [ project mode only]\n"
147 ,a0);
148 return FALSE;
149}
150static Option::QMAKE_MODE default_mode(QString progname)
151{
152 int s = progname.findRev(Option::dir_sep);
153 if(s != -1)
154 progname = progname.right(progname.length() - (s + 1));
155 if(progname == "qmakegen")
156 return Option::QMAKE_GENERATE_PROJECT;
157 return Option::QMAKE_GENERATE_MAKEFILE;
158}
159
160
161bool
162Option::parseCommandLine(int argc, char **argv)
163{
164 bool before = TRUE;
165 for(int x = 1; x < argc; x++) {
166 if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */
167 QString opt = argv[x] + 1;
168
169 //first param is a mode, or we default
170 if(x == 1) {
171 bool specified = TRUE;
172 if(opt == "project") {
173 Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
174 } else if(opt == "prl") {
175 Option::mkfile::do_deps = FALSE;
176 Option::mkfile::do_mocs = FALSE;
177 Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
178 } else if(opt == "makefile") {
179 Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
180 } else {
181 specified = FALSE;
182 Option::qmake_mode = default_mode(argv[0]);
183 }
184 if(specified)
185 continue;
186 }
187 //all modes
188 if(opt == "o" || opt == "output") {
189 Option::output.setName(argv[++x]);
190 } else if(opt == "after") {
191 before = FALSE;
192 } else if(opt == "t" || opt == "template") {
193 Option::user_template = argv[++x];
194 } else if(opt == "tp" || opt == "template_prefix") {
195 Option::user_template_prefix = argv[++x];
196 } else if(opt == "mac9") {
197 Option::target_mode = TARG_MAC9_MODE;
198 } else if(opt == "macx") {
199 Option::target_mode = TARG_MACX_MODE;
200 } else if(opt == "unix") {
201 Option::target_mode = TARG_UNIX_MODE;
202 } else if(opt == "win32") {
203 Option::target_mode = TARG_WIN_MODE;
204 } else if(opt == "d") {
205 Option::debug_level++;
206 } else if(opt == "version" || opt == "v" || opt == "-version") {
207 fprintf(stderr, "Qmake version: %s\n", qmake_version());
208 fprintf(stderr, "Qmake is free software from Trolltech AS.\n");
209 return FALSE;
210 } else if(opt == "h" || opt == "help") {
211 return usage(argv[0]);
212 } else if(opt == "Wall") {
213 Option::warn_level |= WarnAll;
214 } else if(opt == "Wparser") {
215 Option::warn_level |= WarnParser;
216 } else if(opt == "Wlogic") {
217 Option::warn_level |= WarnLogic;
218 } else if(opt == "Wnone") {
219 Option::warn_level = WarnNone;
220 } else {
221 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
222 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
223 if(opt == "nodepend") {
224 Option::mkfile::do_deps = FALSE;
225 } else if(opt == "nomoc") {
226 Option::mkfile::do_mocs = FALSE;
227 } else if(opt == "nocache") {
228 Option::mkfile::do_cache = FALSE;
229 } else if(opt == "nodependheuristics") {
230 Option::mkfile::do_dep_heuristics = FALSE;
231 } else if(opt == "E") {
232 Option::mkfile::do_preprocess = TRUE;
233 } else if(opt == "cache") {
234 Option::mkfile::cachefile = argv[++x];
235 } else if(opt == "platform" || opt == "spec") {
236 Option::mkfile::qmakespec = argv[++x];
237 Option::mkfile::qmakespec_commandline = argv[x];
238 } else {
239 fprintf(stderr, "***Unknown option -%s\n", opt.latin1());
240 return usage(argv[0]);
241 }
242 } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
243 if(opt == "nopwd") {
244 Option::projfile::do_pwd = FALSE;
245 } else if(opt == "r") {
246 Option::projfile::do_recursive = TRUE;
247 } else {
248 fprintf(stderr, "***Unknown option -%s\n", opt.latin1());
249 return usage(argv[0]);
250 }
251 }
252 }
253 } else {
254 if(x == 1)
255 Option::qmake_mode = default_mode(argv[0]);
256
257 QString arg = argv[x];
258 if(arg.find('=') != -1) {
259 if(before)
260 Option::before_user_vars.append(arg);
261 else
262 Option::after_user_vars.append(arg);
263 } else {
264 QFileInfo fi(arg);
265 if(!fi.convertToAbs()) //strange
266 arg = fi.filePath();
267 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
268 Option::qmake_mode == Option::QMAKE_GENERATE_PRL)
269 Option::mkfile::project_files.append(arg);
270 else
271 Option::projfile::project_dirs.append(arg);
272 }
273 }
274 }
275 if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
276 Option::qmake_mode = default_mode(argv[0]);
277
278 //last chance for defaults
279 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
280 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
281 if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty())
282 Option::mkfile::qmakespec = getenv("QMAKESPEC");
283
284 //try REALLY hard to do it for them, lazy..
285 if(Option::mkfile::project_files.isEmpty()) {
286 QString proj = QDir::currentDirPath();
287 proj = proj.right(proj.length() - (proj.findRev('/') + 1)) + ".pro";
288 if(QFile::exists(proj))
289 Option::mkfile::project_files.append(proj);
290 else
291 return usage(argv[0]);
292 }
293 }
294
295 //defaults for globals
296 Option::moc_mod = "moc_";
297 Option::lex_mod = "_lex";
298 Option::yacc_mod = "_yacc";
299 Option::prl_ext = ".prl";
300 Option::prf_ext = ".prf";
301 Option::ui_ext = ".ui";
302 Option::h_ext << ".h" << ".hpp" << ".hh" << ".H" << ".hxx";
303 Option::moc_ext = ".moc";
304 Option::cpp_ext << ".cpp" << ".cc" << ".cxx" << ".C";
305 Option::lex_ext = ".l";
306 Option::yacc_ext = ".y";
307 if(Option::target_mode == Option::TARG_WIN_MODE) {
308 Option::dir_sep = "\\";
309 Option::obj_ext = ".obj";
310 } else {
311 if(Option::target_mode == Option::TARG_MAC9_MODE)
312 Option::dir_sep = ":";
313 else
314 Option::dir_sep = "/";
315 Option::obj_ext = ".o";
316 }
317 return TRUE;
318}
319
320bool Option::postProcessProject(QMakeProject *project)
321{
322 Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"];
323 if(cpp_ext.isEmpty())
324 cpp_ext << ".cpp"; //something must be there
325 Option::h_ext = project->variables()["QMAKE_EXT_H"];
326 if(h_ext.isEmpty())
327 h_ext << ".h";
328
329 if(!project->isEmpty("QMAKE_EXT_PRL"))
330 Option::prl_ext = project->first("QMAKE_EXT_PRL");
331 if(!project->isEmpty("QMAKE_EXT_PRF"))
332 Option::prf_ext = project->first("QMAKE_EXT_PRF");
333 if(!project->isEmpty("QMAKE_EXT_UI"))
334 Option::ui_ext = project->first("QMAKE_EXT_UI");
335 if(!project->isEmpty("QMAKE_EXT_MOC"))
336 Option::moc_ext = project->first("QMAKE_EXT_MOC");
337 if(!project->isEmpty("QMAKE_EXT_LEX"))
338 Option::lex_ext = project->first("QMAKE_EXT_LEX");
339 if(!project->isEmpty("QMAKE_EXT_YACC"))
340 Option::yacc_ext = project->first("QMAKE_EXT_YACC");
341 if(!project->isEmpty("QMAKE_EXT_OBJ"))
342 Option::obj_ext = project->first("QMAKE_EXT_OBJ");
343 if(!project->isEmpty("QMAKE_MOD_MOC"))
344 Option::moc_mod = project->first("QMAKE_MOD_MOC");
345 if(!project->isEmpty("QMAKE_MOD_LEX"))
346 Option::lex_mod = project->first("QMAKE_MOD_LEX");
347 if(!project->isEmpty("QMAKE_MOD_YACC"))
348 Option::yacc_mod = project->first("QMAKE_MOD_YACC");
349 if(!project->isEmpty("QMAKE_DIR_SEP"))
350 Option::dir_sep = project->first("QMAKE_DIR_SEP");
351 return TRUE;
352}
353
354void fixEnvVariables(QString &x)
355{
356 int rep;
357 QRegExp reg_var("\\$\\(.*\\)");
358 reg_var.setMinimal( TRUE );
359 while((rep = reg_var.search(x)) != -1)
360 x.replace(rep, reg_var.matchedLength(), QString(getenv(x.mid(rep + 2, reg_var.matchedLength() - 3).latin1())));
361}
362static QString fixPath(QString x)
363{
364#if 0
365 QFileInfo fi(x);
366 if(fi.isDir()) {
367 QDir dir(x);
368 x = dir.canonicalPath();
369 } else {
370 QString dir = fi.dir().canonicalPath();
371 if(!dir.isEmpty() && dir.right(1) != Option::dir_sep)
372 dir += Option::dir_sep;
373 x = dir + fi.fileName();
374 }
375#endif
376 return QDir::cleanDirPath(x);
377}
378
379
380QString
381Option::fixPathToTargetOS(const QString& in, bool fix_env, bool canonical)
382{
383 QString tmp(in);
384 if(fix_env)
385 fixEnvVariables(tmp);
386 if(canonical)
387 tmp = fixPath(tmp);
388 QString rep;
389 if(Option::target_mode == TARG_MAC9_MODE)
390 rep = "[/\\\\]";
391 else if(Option::target_mode == TARG_WIN_MODE)
392 rep = "[/]";
393 else
394 rep = "[\\\\]";
395 return tmp.replace(QRegExp(rep), Option::dir_sep);
396}
397
398QString
399Option::fixPathToLocalOS(const QString& in, bool fix_env, bool canonical)
400{
401 QString tmp(in);
402 if(fix_env)
403 fixEnvVariables(tmp);
404 if(canonical)
405 tmp = fixPath(tmp);
406#if defined(Q_OS_WIN32)
407 return tmp.replace('/', '\\');
408#else
409 return tmp.replace('\\', '/');
410#endif
411}
412
413const char *qmake_version()
414{
415 static char *ret = NULL;
416 if(ret)
417 return ret;
418 ret = (char *)malloc(15);
419 sprintf(ret, "%d.%02d%c", QMAKE_VERSION_MAJOR, QMAKE_VERSION_MINOR, 'a' + QMAKE_VERSION_PATCH);
420 return ret;
421}
422
423void debug_msg(int level, const char *fmt, ...)
424{
425 if(Option::debug_level < level)
426 return;
427 fprintf(stderr, "DEBUG %d: ", level);
428 {
429 va_list ap;
430 va_start(ap, fmt);
431 vfprintf(stderr, fmt, ap);
432 va_end(ap);
433 }
434 fprintf(stderr, "\n");
435}
436
437void warn_msg(QMakeWarn type, const char *fmt, ...)
438{
439 if(!(Option::warn_level & type))
440 return;
441 fprintf(stderr, "WARNING: ");
442 {
443 va_list ap;
444 va_start(ap, fmt);
445 vfprintf(stderr, fmt, ap);
446 va_end(ap);
447 }
448 fprintf(stderr, "\n");
449}
diff --git a/qmake/option.h b/qmake/option.h
new file mode 100644
index 0000000..9a5a85a
--- a/dev/null
+++ b/qmake/option.h
@@ -0,0 +1,122 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __OPTION_H__
38#define __OPTION_H__
39
40#include "project.h"
41#include <qstring.h>
42#include <qstringlist.h>
43#include <qfile.h>
44
45#define QMAKE_VERSION_MAJOR 1
46#define QMAKE_VERSION_MINOR 4
47#define QMAKE_VERSION_PATCH 0
48const char *qmake_version();
49
50void fixEnvVariables(QString &x);
51void debug_msg(int level, const char *fmt, ...);
52enum QMakeWarn {
53 WarnNone = 0x00,
54 WarnParser = 0x01,
55 WarnLogic = 0x02,
56 WarnAll = 0xFF
57};
58void warn_msg(QMakeWarn t, const char *fmt, ...);
59
60struct Option
61{
62 //simply global convenience
63 static QString prf_ext;
64 static QString prl_ext;
65 static QString ui_ext;
66 static QStringList h_ext;
67 static QStringList cpp_ext;
68 static QString moc_ext;
69 static QString obj_ext;
70 static QString lex_ext;
71 static QString yacc_ext;
72 static QString moc_mod;
73 static QString lex_mod;
74 static QString yacc_mod;
75 static QString dir_sep;
76 //both of these must be called..
77 static bool parseCommandLine(int argc, char **argv); //parse cmdline
78 static bool postProcessProject(QMakeProject *);
79
80 //and convenience functions
81 static QString fixPathToLocalOS(const QString& in, bool fix_env=TRUE, bool canonical=TRUE);
82 static QString fixPathToTargetOS(const QString& in, bool fix_env=TRUE, bool canonical=TRUE);
83
84 //global qmake mode, can only be in one mode per invocation!
85 enum QMAKE_MODE { QMAKE_GENERATE_NOTHING, QMAKE_GENERATE_PROJECT, QMAKE_GENERATE_MAKEFILE,
86 QMAKE_GENERATE_PRL };
87 static QMAKE_MODE qmake_mode;
88
89 //all modes
90 static QFile output;
91 static QString output_dir;
92 static int debug_level;
93 static int warn_level;
94 static QStringList before_user_vars, after_user_vars;
95 enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE, TARG_QNX6_MODE };
96 static TARG_MODE target_mode;
97 static QString user_template, user_template_prefix;
98
99 //QMAKE_GENERATE_PROJECT options
100 struct projfile {
101 static bool do_pwd;
102 static bool do_recursive;
103 static QStringList project_dirs;
104 };
105
106 //QMAKE_GENERATE_MAKEFILE options
107 struct mkfile {
108 static QString qmakespec;
109 static bool do_cache;
110 static bool do_deps;
111 static bool do_mocs;
112 static bool do_dep_heuristics;
113 static bool do_preprocess;
114 static QString cachefile;
115 static int cachefile_depth;
116 static QStringList project_files;
117 static QString qmakespec_commandline;
118 };
119};
120
121
122#endif /* __OPTION_H__ */
diff --git a/qmake/project.cpp b/qmake/project.cpp
new file mode 100644
index 0000000..ae24193
--- a/dev/null
+++ b/qmake/project.cpp
@@ -0,0 +1,987 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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 "project.h"
39#include "option.h"
40#include <qfile.h>
41#include <qdir.h>
42#include <qregexp.h>
43#include <qtextstream.h>
44#include <qvaluestack.h>
45#ifdef Q_OS_UNIX
46# include <unistd.h>
47#endif
48#include <stdio.h>
49#include <stdlib.h>
50
51#ifdef Q_OS_WIN32
52#define QT_POPEN _popen
53#else
54#define QT_POPEN popen
55#endif
56
57struct parser_info {
58 QString file;
59 int line_no;
60} parser;
61static void qmake_error_msg(const char *msg)
62{
63 fprintf(stderr, "%s:%d: %s\n", parser.file.latin1(), parser.line_no, msg);
64}
65
66static QString varMap(const QString &x)
67{
68 QString ret(x);
69 ret.replace(QRegExp("^TMAKE"), "QMAKE");
70 if(ret == "INTERFACES")
71 ret = "FORMS";
72 return ret;
73}
74
75static QStringList split_arg_list(const QString &params)
76{
77 QStringList args;
78 int last = 0, parens = 0;
79 QChar quote = 0;
80 for(int x = 0; x < (int)params.length(); x++) {
81 if(params[x] == ')') {
82 parens--;
83 } else if(params[x] == '(') {
84 parens++;
85 } else if(params[x] == quote) {
86 quote = 0;
87 } else if(params[x] == '\'' || params[x] == '"') {
88 quote = params[x];
89 } else if(!parens && !quote && params[x] == ',') {
90 args << params.mid(last, x - last);
91 last = x+1;
92 }
93 }
94 if(last != (int)params.length())
95 args << params.mid(last);
96 return args;
97}
98
99static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE)
100{
101 int last = 0;
102 QStringList ret;
103 QValueStack<QChar> quote;
104 for(int x = 0; x < (int)vals.length(); x++) {
105 if(!quote.isEmpty() && vals[x] == quote.top()) {
106 quote.pop();
107 } else if(vals[x] == '\'' || vals[x] == '"') {
108 quote.push(vals[x]);
109 } else if(quote.isEmpty() &&
110 ((do_semicolon && vals[x] == ';') || vals[x] == ' ')) {
111 ret << vals.mid(last, x - last);
112 last = x+1;
113 }
114 }
115 if(last != (int)vals.length())
116 ret << vals.mid(last);
117 return ret;
118}
119
120QMakeProject::QMakeProject()
121{
122}
123
124bool
125QMakeProject::parse(QString t, QMap<QString, QStringList> &place)
126{
127 QString s = t.simplifyWhiteSpace();
128 s.replace(QRegExp("#.*$"), ""); /* bye comments */
129 if(s.isEmpty()) /* blank_line */
130 return TRUE;
131
132 if(s.stripWhiteSpace().left(1) == "}") {
133 debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(),
134 parser.line_no, scope_block);
135 test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek);
136 scope_block--;
137 s = s.mid(1).stripWhiteSpace();
138 if(s.isEmpty())
139 return TRUE;
140 }
141 if(!(scope_flag & (0x01 << scope_block))) {
142 /* adjust scope for each block which appears on a single line */
143 for(int i = (s.contains('{')-s.contains('}')); i; i--)
144 scope_flag &= ~(0x01 << (++scope_block));
145 debug_msg(1, "Project Parser: %s:%d : Ignored due to block being false.",
146 parser.file.latin1(), parser.line_no);
147 return TRUE;
148 }
149
150 QString scope, var, op;
151 QStringList val;
152#define SKIP_WS(d) while(*d && (*d == ' ' || *d == '\t')) d++
153 const char *d = s.latin1();
154 SKIP_WS(d);
155 bool scope_failed = FALSE, else_line = FALSE, or_op=FALSE;
156 int parens = 0, scope_count=0;
157 while(*d && *d != '=') {
158 if((*d == '+' || *d == '-' || *d == '*' || *d == '~')) {
159 if(*(d+1) == '=') {
160 break;
161 } else if(*(d+1) == ' ') {
162 const char *k = d + 1;
163 SKIP_WS(k);
164 if(*k == '=') {
165 QString msg;
166 qmake_error_msg(*d + "must be followed immediatly by =");
167 return FALSE;
168 }
169 }
170 }
171
172 if ( *d == '(' )
173 ++parens;
174 else if ( *d == ')' )
175 --parens;
176
177 if(!parens && (*d == ':' || *d == '{' || *d == ')' || *d == '|')) {
178 scope_count++;
179 scope = var.stripWhiteSpace();
180 if ( *d == ')' )
181 scope += *d; /* need this */
182 var = "";
183
184 bool test = scope_failed;
185 if(scope.lower() == "else") {
186 if(scope_count != 1 || test_status == TestNone) {
187 qmake_error_msg("Unexpected " + scope + " ('" + s + "')");
188 return FALSE;
189 }
190 else_line = TRUE;
191 test = (test_status == TestSeek);
192 debug_msg(1, "Project Parser: %s:%d : Else%s %s.", parser.file.latin1(), parser.line_no,
193 scope == "else" ? "" : QString(" (" + scope + ")").latin1(),
194 test ? "considered" : "excluded");
195 } else {
196 QString comp_scope = scope;
197 bool invert_test = (comp_scope.left(1) == "!");
198 if(invert_test)
199 comp_scope = comp_scope.right(comp_scope.length()-1);
200 int lparen = comp_scope.find('(');
201 if(or_op || !scope_failed) {
202 if(lparen != -1) { /* if there is an lparen in the scope, it IS a function */
203 int rparen = comp_scope.findRev(')');
204 if(rparen == -1) {
205 QCString error;
206 error.sprintf("Function missing right paren: %s ('%s')",
207 comp_scope.latin1(), s.latin1());
208 qmake_error_msg(error);
209 return FALSE;
210 }
211 QString func = comp_scope.left(lparen);
212 test = doProjectTest(func, comp_scope.mid(lparen+1, rparen - lparen - 1), place);
213 if ( *d == ')' && !*(d+1) ) {
214 if(invert_test)
215 test = !test;
216 test_status = (test ? TestFound : TestSeek);
217 return TRUE; /* assume we are done */
218 }
219 } else {
220 test = isActiveConfig(comp_scope.stripWhiteSpace());
221 }
222 if(invert_test)
223 test = !test;
224 }
225 }
226 if(!test && !scope_failed)
227 debug_msg(1, "Project Parser: %s:%d : Test (%s) failed.", parser.file.latin1(),
228 parser.line_no, scope.latin1());
229 if(test == or_op)
230 scope_failed = !test;
231 or_op = (*d == '|');
232 if(*d == '{') { /* scoping block */
233 if(!scope_failed)
234 scope_flag |= (0x01 << (++scope_block));
235 else
236 scope_flag &= ~(0x01 << (++scope_block));
237 debug_msg(1, "Project Parser: %s:%d : Entering block %d (%d).", parser.file.latin1(),
238 parser.line_no, scope_block, !scope_failed);
239 }
240 } else {
241 var += *d;
242 }
243 d++;
244 }
245 if(!scope_count || (scope_count == 1 && else_line))
246 test_status = TestNone;
247 else if(!else_line || test_status != TestFound)
248 test_status = (scope_failed ? TestSeek : TestFound);
249 if(scope_failed)
250 return TRUE; /* oh well */
251 if(!*d) {
252 if(!var.isEmpty())
253 qmake_error_msg("Parse Error ('" + s + "')");
254 return var.isEmpty(); /* allow just a scope */
255 }
256
257 SKIP_WS(d);
258 for( ; *d && op.find('=') == -1; op += *(d++));
259 op.replace(QRegExp("\\s"), "");
260
261 SKIP_WS(d);
262 QString vals(d); /* vals now contains the space separated list of values */
263 int rbraces = vals.contains('}'), lbraces = vals.contains('{');
264 if(scope_block && rbraces - lbraces == 1) {
265 debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(),
266 parser.line_no, scope_block);
267 test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek);
268 scope_block--;
269 vals.truncate(vals.length()-1);
270 } else if(rbraces != lbraces) {
271 warn_msg(WarnParser, "Possible braces mismatch {%s} %s:%d",
272 vals.latin1(), parser.file.latin1(), parser.line_no);
273 }
274 doVariableReplace(vals, place);
275
276 var = var.stripWhiteSpace();
277#undef SKIP_WS
278
279 if(!var.isEmpty() && Option::mkfile::do_preprocess) {
280 static QString last_file("*none*");
281 if(parser.file != last_file) {
282 fprintf(stderr, "#file %s:%d\n", parser.file.latin1(), parser.line_no);
283 last_file = parser.file;
284 }
285 fprintf(stderr, "%s %s %s\n", var.latin1(), op.latin1(), vals.latin1());
286 }
287 var = varMap(var); //backwards compatability
288
289 /* vallist is the broken up list of values */
290 QStringList vallist = split_value_list(vals, (var == "DEPENDPATH" || var == "INCLUDEPATH"));
291 if(!vallist.grep("=").isEmpty())
292 warn_msg(WarnParser, "Detected possible line continuation: {%s} %s:%d",
293 var.latin1(), parser.file.latin1(), parser.line_no);
294
295 QStringList &varlist = place[var]; /* varlist is the list in the symbol table */
296 debug_msg(1, "Project Parser: %s:%d :%s: :%s: (%s)", parser.file.latin1(), parser.line_no,
297 var.latin1(), op.latin1(), vallist.join(" :: ").latin1());
298
299 /* now do the operation */
300 if(op == "~=") {
301 if(vallist.count() != 1) {
302 qmake_error_msg("~= operator only accepts one right hand paramater ('" +
303 s + "')");
304 return FALSE;
305 }
306 QString val(vallist.first());
307 if(val.length() < 4 || val.at(0) != 's') {
308 qmake_error_msg("~= operator only can handle s/// function ('" +
309 s + "')");
310 return FALSE;
311 }
312 QChar sep = val.at(1);
313 QStringList func = QStringList::split(sep, val, TRUE);
314 if(func.count() < 3 || func.count() > 4) {
315 qmake_error_msg("~= operator only can handle s/// function ('" +
316 s + "')");
317 return FALSE;
318 }
319 bool global = FALSE, case_sense = TRUE;
320 if(func.count() == 4) {
321 global = func[3].find('g') != -1;
322 case_sense = func[3].find('i') == -1;
323 }
324 QRegExp regexp(func[1], case_sense);
325 for(QStringList::Iterator varit = varlist.begin();
326 varit != varlist.end(); ++varit) {
327 if((*varit).contains(regexp)) {
328 (*varit) = (*varit).replace(regexp, func[2]);
329 if(!global)
330 break;
331 }
332 }
333 } else {
334 if(op == "=") {
335 if(!varlist.isEmpty())
336 warn_msg(WarnParser, "Operator=(%s) clears variables previously set: %s:%d",
337 var.latin1(), parser.file.latin1(), parser.line_no);
338 varlist.clear();
339 }
340 for(QStringList::Iterator valit = vallist.begin();
341 valit != vallist.end(); ++valit) {
342 if((*valit).isEmpty())
343 continue;
344 if((op == "*=" && !(*varlist.find((*valit)))) ||
345 op == "=" || op == "+=")
346 varlist.append((*valit));
347 else if(op == "-=")
348 varlist.remove((*valit));
349 }
350 }
351 if(var == "REQUIRES") /* special case to get communicated to backends! */
352 doProjectCheckReqs(vallist, place);
353
354 return TRUE;
355}
356
357bool
358QMakeProject::read(QString file, QMap<QString, QStringList> &place)
359{
360 parser_info pi = parser;
361 /* scope blocks start at true */
362 test_status = TestNone;
363 scope_flag = 0x01;
364 scope_block = 0;
365
366 file = Option::fixPathToLocalOS(file);
367 doVariableReplace(file, place);
368 bool ret = FALSE, using_stdin = FALSE;
369 QFile qfile;
370 if(!strcmp(file, "-")) {
371 qfile.setName("");
372 ret = qfile.open(IO_ReadOnly, stdin);
373 using_stdin = TRUE;
374 } else {
375 qfile.setName(file);
376 ret = qfile.open(IO_ReadOnly);
377 }
378 if ( ret ) {
379 QTextStream t( &qfile );
380 QString s, line;
381 parser.file = file;
382 parser.line_no = 0;
383 while ( !t.eof() ) {
384 parser.line_no++;
385 line = t.readLine().stripWhiteSpace();
386 int prelen = line.length();
387 line.replace(QRegExp("#.*$"), ""); // bye comments
388 if(!line.isEmpty() && line.right(1) == "\\") {
389 line.truncate(line.length() - 1);
390 s += line + " ";
391 } else if(!line.isEmpty() || (line.isEmpty() && !prelen)) {
392 if(s.isEmpty() && line.isEmpty())
393 continue;
394 if(!line.isEmpty())
395 s += line;
396 if(!s.isEmpty()) {
397 if(!(ret = parse(s, place)))
398 break;
399 s = "";
400 }
401 }
402 }
403 if(!using_stdin)
404 qfile.close();
405 }
406 parser = pi;
407 return ret;
408}
409
410bool
411QMakeProject::read(QString project, QString)
412{
413 if(cfile.isEmpty()) {
414 // hack to get the Option stuff in there
415 base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext;
416 base_vars["QMAKE_EXT_H"] = Option::h_ext;
417
418 /* parse the cache */
419 if(Option::mkfile::do_cache) {
420 if(Option::mkfile::cachefile.isEmpty()) { //find it as it has not been specified
421 QString dir = QDir::convertSeparators(Option::output_dir);
422 while(!QFile::exists((Option::mkfile::cachefile = dir +
423 QDir::separator() + ".qmake.cache"))) {
424 dir = dir.left(dir.findRev(QDir::separator()));
425 if(dir.isEmpty() || dir.find(QDir::separator()) == -1) {
426 Option::mkfile::cachefile = "";
427 break;
428 }
429 if(Option::mkfile::cachefile_depth == -1)
430 Option::mkfile::cachefile_depth = 1;
431 else
432 Option::mkfile::cachefile_depth++;
433 }
434 }
435 if(!Option::mkfile::cachefile.isEmpty()) {
436 read(Option::mkfile::cachefile, cache);
437 if(Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty())
438 Option::mkfile::qmakespec = cache["QMAKESPEC"].first();
439 }
440 }
441 /* parse mkspec */
442 QStringList mkspec_roots;
443 /* prefer $QTDIR if it is set */
444 /* minor hack here, prefer QMAKESPECDIR -cl */
445
446 if (getenv("QMAKESPECDIR")){
447 mkspec_roots << getenv("QMAKESPECDIR");
448 } else if (getenv("QTDIR")) {
449 mkspec_roots << getenv("QTDIR");
450 }
451 mkspec_roots << qInstallPathData();
452 if(Option::mkfile::qmakespec.isEmpty()) {
453 for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
454 QString mkspec = (*it) + QDir::separator() + QString("mkspecs") +
455 QDir::separator() + "default";
456 if(QFile::exists(mkspec)) {
457 Option::mkfile::qmakespec = mkspec;
458 break;
459 }
460 }
461 if(Option::mkfile::qmakespec.isEmpty()) {
462 fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n");
463 return FALSE;
464 }
465 }
466
467 if(QDir::isRelativePath(Option::mkfile::qmakespec)) {
468 bool found_mkspec = FALSE;
469 for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
470 QString mkspec = (*it) + QDir::separator() + QString("mkspecs") +
471 QDir::separator() + Option::mkfile::qmakespec;
472 if(QFile::exists(mkspec)) {
473 found_mkspec = TRUE;
474 Option::mkfile::qmakespec = mkspec;
475 break;
476 }
477 }
478 if(!found_mkspec) {
479 fprintf(stderr, "Could not find mkspecs for your QMAKESPEC after trying:\n\t%s\n",
480 mkspec_roots.join("\n\t").latin1());
481 return FALSE;
482 }
483 }
484
485 /* parse qmake configuration */
486 QString spec = Option::mkfile::qmakespec + QDir::separator() + "qmake.conf";
487 debug_msg(1, "QMAKESPEC conf: reading %s", spec.latin1());
488 if(!read(spec, base_vars)) {
489 fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.latin1());
490 return FALSE;
491 }
492 if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) {
493 debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.latin1());
494 read(Option::mkfile::cachefile, base_vars);
495 }
496
497 /* commandline */
498 cfile = project;
499 parser.line_no = 1; //really arg count now.. duh
500 parser.file = "(internal)";
501 for(QStringList::Iterator it = Option::before_user_vars.begin();
502 it != Option::before_user_vars.end(); ++it) {
503 if(!parse((*it), base_vars)) {
504 fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1());
505 return FALSE;
506 }
507 parser.line_no++;
508 }
509 }
510
511 /* parse project file */
512 debug_msg(1, "Project file: reading %s", project.latin1());
513 vars = base_vars; /* start with the base */
514
515 pfile = project;
516 if(pfile != "-" && !QFile::exists(pfile) && pfile.right(4) != ".pro")
517 pfile += ".pro";
518
519 if(!read(pfile, vars))
520 return FALSE;
521
522 parser.line_no = 1; //really arg count now.. duh
523 parser.file = "(internal)";
524 for(QStringList::Iterator it = Option::after_user_vars.begin();
525 it != Option::after_user_vars.end(); ++it) {
526 if(!parse((*it), vars)) {
527 fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1());
528 return FALSE;
529 }
530 parser.line_no++;
531 }
532
533 /* now let the user override the template from an option.. */
534 if(!Option::user_template.isEmpty()) {
535 debug_msg(1, "Overriding TEMPLATE (%s) with: %s", vars["TEMPLATE"].first().latin1(), Option::user_template.latin1());
536 vars["TEMPLATE"].clear();
537 vars["TEMPLATE"].append(Option::user_template);
538 }
539
540 if(vars["TEMPLATE"].isEmpty())
541 vars["TEMPLATE"].append(QString("app"));
542 else
543 vars["TEMPLATE"].first().replace(QRegExp("\\.t$"), "");
544 if(!Option::user_template_prefix.isEmpty())
545 vars["TEMPLATE"].first().prepend(Option::user_template_prefix);
546
547 if(vars["TARGET"].isEmpty()) {
548 // ### why not simply use:
549 // QFileInfo fi(pfile);
550 // fi.baseName();
551 QString tmp = pfile;
552 if(tmp.findRev('/') != -1)
553 tmp = tmp.right( tmp.length() - tmp.findRev('/') - 1 );
554 if(tmp.findRev('.') != -1)
555 tmp = tmp.left(tmp.findRev('.'));
556 vars["TARGET"].append(tmp);
557 }
558
559 QString test_version = getenv("QTESTVERSION");
560 if (!test_version.isEmpty()) {
561 QString s = vars["TARGET"].first();
562 if (s == "qt" || s == "qt-mt" || s == "qte" || s == "qte-mt") {
563 QString &ver = vars["VERSION"].first();
564 // fprintf(stderr,"Current QT version number: " + ver + "\n");
565 if (ver != "" && ver != test_version) {
566 ver = test_version;
567 fprintf(stderr,"Changed QT version number to " + test_version + "!\n");
568 }
569 }
570 }
571 return TRUE;
572}
573
574bool
575QMakeProject::isActiveConfig(const QString &x)
576{
577 if(x.isEmpty())
578 return TRUE;
579
580 QRegExp re(x, FALSE, TRUE);
581 if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_UNIX_MODE) &&
582 x == "unix")
583 return TRUE;
584 else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx")
585 return TRUE;
586 else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6")
587 return TRUE;
588 else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9")
589 return TRUE;
590 else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) &&
591 x == "mac")
592 return TRUE;
593 else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32")
594 return TRUE;
595
596
597 QString spec = Option::mkfile::qmakespec.right(Option::mkfile::qmakespec.length() -
598 (Option::mkfile::qmakespec.findRev(QDir::separator())+1));
599 if(re.exactMatch(spec))
600 return TRUE;
601#ifdef Q_OS_UNIX
602 else if(spec == "default") {
603 static char *buffer = NULL;
604 if(!buffer)
605 buffer = (char *)malloc(1024);
606 int l = readlink(Option::mkfile::qmakespec, buffer, 1024);
607 if(l != -1) {
608 buffer[l] = '\0';
609 QString r = buffer;
610 if(r.findRev('/') != -1)
611 r = r.mid(r.findRev('/') + 1);
612 if(re.exactMatch(r))
613 return TRUE;
614 }
615 }
616#endif
617
618
619 QStringList &configs = vars["CONFIG"];
620 for(QStringList::Iterator it = configs.begin(); it != configs.end(); ++it) {
621 if(re.exactMatch((*it)))
622 return TRUE;
623 }
624 return FALSE;
625}
626
627bool
628QMakeProject::doProjectTest(QString func, const QString &params, QMap<QString, QStringList> &place)
629{
630 QStringList args = split_arg_list(params);
631 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
632 QString tmp = (*arit).stripWhiteSpace();
633 if((tmp[0] == '\'' || tmp[0] == '"') && tmp.right(1) == tmp.left(1))
634 tmp = tmp.mid(1, tmp.length() - 2);
635 }
636 return doProjectTest(func.stripWhiteSpace(), args, place);
637}
638
639bool
640QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place)
641{
642 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
643 (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space
644 doVariableReplace((*arit), place);
645 }
646 debug_msg(1, "Running project test: %s( %s )", func.latin1(), args.join("::").latin1());
647
648 if(func == "requires") {
649 return doProjectCheckReqs(args, place);
650 } else if(func == "exists") {
651 if(args.count() != 1) {
652 fprintf(stderr, "%s:%d: exists(file) requires one argument.\n", parser.file.latin1(),
653 parser.line_no);
654 return FALSE;
655 }
656 QString file = args.first();
657 file = Option::fixPathToLocalOS(file);
658 doVariableReplace(file, place);
659
660 if(QFile::exists(file))
661 return TRUE;
662 //regular expression I guess
663 QString dirstr = QDir::currentDirPath();
664 int slsh = file.findRev(Option::dir_sep);
665 if(slsh != -1) {
666 dirstr = file.left(slsh+1);
667 file = file.right(file.length() - slsh - 1);
668 }
669 QDir dir(dirstr, file);
670 return dir.count() != 0;
671 } else if(func == "system") {
672 if(args.count() != 1) {
673 fprintf(stderr, "%s:%d: system(exec) requires one argument.\n", parser.file.latin1(),
674 parser.line_no);
675 return FALSE;
676 }
677 return system(args.first().latin1()) == 0;
678 } else if(func == "contains") {
679 if(args.count() != 2) {
680 fprintf(stderr, "%s:%d: contains(var, val) requires two arguments.\n", parser.file.latin1(),
681 parser.line_no);
682 return FALSE;
683 }
684 QRegExp regx(args[1]);
685 QStringList &l = place[args[0]];
686 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
687 if(regx.exactMatch((*it)))
688 return TRUE;
689 }
690 return FALSE;
691 } else if(func == "infile") {
692 if(args.count() < 2 || args.count() > 3) {
693 fprintf(stderr, "%s:%d: infile(file, var, val) requires at least 2 arguments.\n",
694 parser.file.latin1(), parser.line_no);
695 return FALSE;
696 }
697 QMakeProject proj;
698 QString file = args[0];
699 doVariableReplace(file, place);
700 fixEnvVariables(file);
701 int di = file.findRev(Option::dir_sep);
702 QDir sunworkshop42workaround = QDir::current();
703 QString oldpwd = sunworkshop42workaround.currentDirPath();
704 if(di != -1) {
705 if(!QDir::setCurrent(file.left(file.findRev(Option::dir_sep)))) {
706 fprintf(stderr, "Cannot find directory: %s\n", file.left(di).latin1());
707 return FALSE;
708 }
709 file = file.right(file.length() - di - 1);
710 }
711 parser_info pi = parser;
712 bool ret = !proj.read(file, oldpwd);
713 parser = pi;
714 if(ret) {
715 fprintf(stderr, "Error processing project file: %s\n", file.latin1());
716 QDir::setCurrent(oldpwd);
717 return FALSE;
718 }
719 if(args.count() == 2) {
720 ret = !proj.isEmpty(args[1]);
721 } else {
722 QRegExp regx(args[2]);
723 QStringList &l = proj.values(args[1]);
724 for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
725 if(regx.exactMatch((*it))) {
726 ret = TRUE;
727 break;
728 }
729 }
730 }
731 QDir::setCurrent(oldpwd);
732 return ret;
733 } else if(func == "count") {
734 if(args.count() != 2) {
735 fprintf(stderr, "%s:%d: count(var, count) requires two arguments.\n", parser.file.latin1(),
736 parser.line_no);
737 return FALSE;
738 }
739 return vars[args[0]].count() == args[1].toUInt();
740 } else if(func == "isEmpty") {
741 if(args.count() != 1) {
742 fprintf(stderr, "%s:%d: isEmpty(var) requires one argument.\n", parser.file.latin1(),
743 parser.line_no);
744 return FALSE;
745 }
746 return vars[args[0]].isEmpty();
747 } else if(func == "include" || func == "load") {
748 if(args.count() != 1) {
749 QString func_desc = "include(file)";
750 if(func == "load")
751 func_desc = "load(feature)";
752 fprintf(stderr, "%s:%d: %s requires one argument.\n", parser.file.latin1(),
753 parser.line_no, func_desc.latin1());
754 return FALSE;
755 }
756
757 QString file = args.first();
758 file = Option::fixPathToLocalOS(file);
759 file.replace("\"", "");
760 doVariableReplace(file, place);
761 if(func == "load") {
762 if(!file.endsWith(Option::prf_ext))
763 file += Option::prf_ext;
764 if(file.find(Option::dir_sep) == -1 || !QFile::exists(file)) {
765 if(QFile::exists(Option::mkfile::qmakespec + QDir::separator() + file)) {
766 file.prepend(Option::mkfile::qmakespec + QDir::separator());
767 } else {
768 bool found = FALSE;
769 QStringList feature_roots;
770 if(getenv("QTDIR"))
771 feature_roots << getenv("QTDIR");
772#ifdef QT_INSTALL_PREFIX
773 feature_roots << QT_INSTALL_PREFIX;
774#endif
775#ifdef QT_INSTALL_DATA
776 feature_roots << QT_INSTALL_DATA;
777#endif
778 for(QStringList::Iterator it = feature_roots.begin(); it != feature_roots.end(); ++it) {
779 QString prf = (*it) + QDir::separator() + QString("mkspecs") +
780 QDir::separator() + QString("features") + QDir::separator() + file;
781 if(QFile::exists(prf)) {
782 found = TRUE;
783 file = prf;
784 break;
785 }
786 }
787 if(!found) {
788 printf("Project LOAD(): Feature %s cannot be found.\n", args.first().latin1());
789 exit(3);
790 }
791 }
792 }
793 }
794
795 debug_msg(1, "Project Parser: %s'ing file %s.", func.latin1(), file.latin1());
796 parser_info pi = parser;
797 int sb = scope_block;
798 int sf = scope_flag;
799 TestStatus sc = test_status;
800 bool r = read(file.latin1(), place);
801 if(r)
802 vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(file);
803 parser = pi;
804 test_status = sc;
805 scope_flag = sf;
806 scope_block = sb;
807 return r;
808 } else if(func == "error" || func == "message") {
809 if(args.count() != 1) {
810 fprintf(stderr, "%s:%d: %s(message) requires one argument.\n", parser.file.latin1(),
811 parser.line_no, func.latin1());
812 return FALSE;
813 }
814 QString msg = args.first();
815 doVariableReplace(msg, place);
816 fixEnvVariables(msg);
817 printf("Project %s: %s\n", func.upper().latin1(), msg.latin1());
818 if(func == "message")
819 return TRUE;
820 exit(2);
821 } else {
822 fprintf(stderr, "%s:%d: Unknown test function: %s\n", parser.file.latin1(), parser.line_no,
823 func.latin1());
824 }
825 return FALSE;
826}
827
828bool
829QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place)
830{
831 bool ret = FALSE;
832 for(QStringList::ConstIterator it = deps.begin(); it != deps.end(); ++it) {
833 QString chk = (*it);
834 if(chk.isEmpty())
835 continue;
836 bool invert_test = (chk.left(1) == "!");
837 if(invert_test)
838 chk = chk.right(chk.length() - 1);
839
840 bool test;
841 int lparen = chk.find('(');
842 if(lparen != -1) { /* if there is an lparen in the chk, it IS a function */
843 int rparen = chk.findRev(')');
844 if(rparen == -1) {
845 QCString error;
846 error.sprintf("Function (in REQUIRES) missing right paren: %s", chk.latin1());
847 qmake_error_msg(error);
848 } else {
849 QString func = chk.left(lparen);
850 test = doProjectTest(func, chk.mid(lparen+1, rparen - lparen - 1), place);
851 }
852 } else {
853 test = isActiveConfig(chk);
854 }
855 if(invert_test) {
856 chk.prepend("!");
857 test = !test;
858 }
859 if(!test) {
860 debug_msg(1, "Project Parser: %s:%d Failed test: REQUIRES = %s",
861 parser.file.latin1(), parser.line_no, chk.latin1());
862 place["QMAKE_FAILED_REQUIREMENTS"].append(chk);
863 ret = FALSE;
864 }
865 }
866 return ret;
867}
868
869
870QString
871QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> &place)
872{
873 for(int x = 0, rep; x < 5; x++) {
874 QRegExp reg_var;
875 reg_var.setMinimal(TRUE);
876 if( x == 0 ) //function blocked out by {}'s
877 reg_var = QRegExp("\\$\\$\\{([a-zA-Z0-9_]*)\\((\\(.|(.*)\\)*)\\)\\}");
878 else if( x == 1 ) //variables blocked out by {}'s
879 reg_var = QRegExp("\\$\\$\\{([a-zA-Z0-9_\\.-]*)\\}");
880 else if(x == 2) //environment
881 reg_var = QRegExp("\\$\\$\\(([a-zA-Z0-9_\\.-]*)\\)");
882 else if(x == 3) //function
883 reg_var = QRegExp("\\$\\$([a-zA-Z0-9_]*)\\((\\(.|(.*)\\)*)\\)");
884 else if(x == 4) //normal variable
885 reg_var = QRegExp("\\$\\$([a-zA-Z0-9_\\.-]*)");
886 while((rep = reg_var.search(str)) != -1) {
887 QString replacement;
888 if(x == 2) {//environment
889 replacement = getenv(reg_var.cap(1));
890 } else if(x == 0 || x == 3) { //function
891 QStringList args = split_arg_list(reg_var.cap(2));
892 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
893 (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space
894 doVariableReplace((*arit), place);
895 }
896 debug_msg(1, "Running function: %s( %s )", reg_var.cap(1).latin1(), args.join("::").latin1());
897 if(reg_var.cap(1).lower() == "member") {
898 if(args.count() < 1 || args.count() > 2) {
899 fprintf(stderr, "%s:%d: member(var, place) requires two arguments.\n",
900 parser.file.latin1(), parser.line_no);
901 } else {
902 uint pos = 0;
903 if(args.count() == 2)
904 pos = args[1].toInt();
905 const QStringList &var = place[varMap(args.first())];
906 if(var.count() >= pos)
907 replacement = var[pos];
908 }
909 } else if(reg_var.cap(1).lower() == "list") {
910 if(args.count() != 1) {
911 fprintf(stderr, "%s:%d: list(vals) requires one"
912 "argument.\n", parser.file.latin1(), parser.line_no);
913 } else {
914 static int x = 0;
915 replacement.sprintf(".QMAKE_INTERNAL_TMP_VAR_%d", x++);
916 (*((QMap<QString, QStringList>*)&place))[replacement] = split_value_list(args.first());
917 }
918 } else if(reg_var.cap(1).lower() == "join") {
919 if(args.count() < 1 || args.count() > 4) {
920 fprintf(stderr, "%s:%d: join(var, glue, before, after) requires four"
921 "arguments.\n", parser.file.latin1(), parser.line_no);
922 } else {
923 QString glue, before, after;
924 if(args.count() >= 2)
925 glue = args[1].replace("\"", "" );
926 if(args.count() >= 3)
927 before = args[2].replace("\"", "" );
928 if(args.count() == 4)
929 after = args[3].replace("\"", "" );
930 const QStringList &var = place[varMap(args.first())];
931 if(!var.isEmpty())
932 replacement = before + var.join(glue) + after;
933 }
934 } else if(reg_var.cap(1).lower() == "find") {
935 if(args.count() != 2) {
936 fprintf(stderr, "%s:%d find(var, str) requires two arguments\n",
937 parser.file.latin1(), parser.line_no);
938 } else {
939 QRegExp regx(args[1]);
940 const QStringList &var = place[varMap(args.first())];
941 for(QStringList::ConstIterator vit = var.begin();
942 vit != var.end(); ++vit) {
943 if(regx.search(*vit) != -1) {
944 if(!replacement.isEmpty())
945 replacement += " ";
946 replacement += (*vit);
947 }
948 }
949 }
950 } else if(reg_var.cap(1).lower() == "system") {
951 if(args.count() != 1) {
952 fprintf(stderr, "%s:%d system(execut) requires one argument\n",
953 parser.file.latin1(), parser.line_no);
954 } else {
955 char buff[256];
956 FILE *proc = QT_POPEN(args.join(" ").latin1(), "r");
957 while(proc && !feof(proc)) {
958 int read_in = fread(buff, 1, 255, proc);
959 if(!read_in)
960 break;
961 for(int i = 0; i < read_in; i++) {
962 if(buff[i] == '\n' || buff[i] == '\t')
963 buff[i] = ' ';
964 }
965 buff[read_in] = '\0';
966 replacement += buff;
967 }
968 }
969 } else {
970 fprintf(stderr, "%s:%d: Unknown replace function: %s\n",
971 parser.file.latin1(), parser.line_no, reg_var.cap(1).latin1());
972 }
973 } else { //variable
974 if(reg_var.cap(1).left(1) == ".")
975 replacement = "";
976 else if(reg_var.cap(1) == "LITERAL_WHITESPACE")
977 replacement = "\t";
978 else
979 replacement = place[varMap(reg_var.cap(1))].join(" ");
980 }
981 debug_msg(2, "Project parser: %d (%s) :: %s -> %s", x, str.latin1(),
982 reg_var.capturedTexts().join("::").latin1(), replacement.latin1());
983 str.replace(rep, reg_var.matchedLength(), replacement);
984 }
985 }
986 return str;
987}
diff --git a/qmake/project.h b/qmake/project.h
new file mode 100644
index 0000000..201e63c
--- a/dev/null
+++ b/qmake/project.h
@@ -0,0 +1,114 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network 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 licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** 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#ifndef __QMAKE_H__
38#define __QMAKE_H__
39
40#include <qstringlist.h>
41#include <qstring.h>
42#include <qmap.h>
43
44class QMakeProject
45{
46 enum TestStatus { TestNone, TestFound, TestSeek } test_status;
47 int scope_block, scope_flag;
48
49 QString pfile, cfile;
50 QMap<QString, QStringList> vars, base_vars, cache;
51 bool parse(QString text, QMap<QString, QStringList> &place);
52 bool doProjectTest(QString func, const QString &params, QMap<QString, QStringList> &place);
53 bool doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place);
54 bool doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place);
55 QString doVariableReplace(QString &str, const QMap<QString, QStringList> &place);
56
57public:
58 QMakeProject();
59
60 bool read(QString project, QString pwd);
61 QString projectFile();
62 QString configFile();
63
64 bool isEmpty(const QString &v);
65 QStringList &values(const QString &v);
66 QString first(const QString &v);
67 QMap<QString, QStringList> &variables();
68 bool isActiveConfig(const QString &x);
69
70protected:
71 friend class MakefileGenerator;
72 bool read(QString file, QMap<QString, QStringList> &place);
73
74};
75
76inline QString QMakeProject::projectFile()
77{
78#if defined(Q_CC_SUN) && (__SUNPRO_CC == 0x500) || defined(Q_CC_HP)
79 // workaround for Sun WorkShop 5.0 bug fixed in Forte 6
80 if (pfile == "-")
81 return QString("(stdin)");
82 else
83 return pfile;
84#else
85 return pfile == "-" ? QString("(stdin)") : pfile;
86#endif
87}
88
89inline QString QMakeProject::configFile()
90{ return cfile; }
91
92inline bool QMakeProject::isEmpty(const QString &v)
93{ return !vars.contains(v) || vars[v].isEmpty(); }
94
95inline QStringList &QMakeProject::values(const QString &v)
96{ return vars[v]; }
97
98inline QString QMakeProject::first(const QString &v)
99{
100#if defined(Q_CC_SUN) && (__SUNPRO_CC == 0x500) || defined(Q_CC_HP)
101 // workaround for Sun WorkShop 5.0 bug fixed in Forte 6
102 if (isEmpty(v))
103 return QString("");
104 else
105 return vars[v].first();
106#else
107 return isEmpty(v) ? QString("") : vars[v].first();
108#endif
109}
110
111inline QMap<QString, QStringList> &QMakeProject::variables()
112{ return vars; }
113
114#endif /* __QMAKE_H__ */
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